Example #1
0
    def _sync_port_dhcp_options(self, ctx, ports_need_sync_dhcp_opts,
                                ovn_port_dhcp_options):
        if not config.is_ovn_dhcp():
            return

        LOG.debug('OVN-NB Sync DHCP options for Neutron ports with extra '
                  'dhcp options assigned started')

        txn_commands = []
        for port in ports_need_sync_dhcp_opts:
            if self.mode == SYNC_MODE_REPAIR:
                LOG.debug('Updating DHCP options for port %s in OVN NB DB',
                          port['id'])
                dhcp_opts = self.ovn_driver.get_port_dhcpv4_options(port)
                if not dhcp_opts:
                    # If the Logical_Switch_Port.dhcpv4_options no longer
                    # refers a port dhcp options created in DHCP_Options
                    # earlier, that port dhcp options will be deleted
                    # in the following ovn_port_dhcp_options handling.
                    txn_commands.append(
                        self.ovn_api.set_lswitch_port(lport_name=port['id'],
                                                      dhcpv4_options=[]))
                elif port['id'] in ovn_port_dhcp_options:
                    # When the Logical_Switch_Port.dhcpv4_options refers a port
                    # dhcp options in DHCP_Options earlier, if the extra dhcp
                    # options has changed, ovn_driver.get_port_dhcpv4_options
                    # should udpate it, if removed, it will be deleted
                    # in the following ovn_port_dhcp_options handling.
                    if dhcp_opts['external_ids'].get('port_id') is not None:
                        ovn_port_dhcp_options.pop(port['id'])
                elif 'uuid' in dhcp_opts:
                    # If the Logical_Switch_Port.dhcpv4_options is already
                    # in sync, then this transaction will be a no-op.
                    txn_commands.append(
                        self.ovn_api.set_lswitch_port(
                            lport_name=port['id'],
                            dhcpv4_options=[dhcp_opts['uuid']]))

        for port_id, dhcp_opt in ovn_port_dhcp_options.items():
            LOG.warning(
                _LW('Out of sync port DHCP options for (subnet %(subnet_id)s'
                    ' port %(port_id)s) found in OVN NB DB which needs to be '
                    'deleted'), {
                        'subnet_id': dhcp_opt['external_ids']['subnet_id'],
                        'port_id': port_id
                    })

            if self.mode == SYNC_MODE_REPAIR:
                LOG.debug(
                    'Deleting port DHCP options for (subnet %s, port '
                    '%s)', dhcp_opt['external_ids']['subnet_id'], port_id)
                txn_commands.append(
                    self.ovn_api.delete_dhcp_options(dhcp_opt['uuid']))

        if txn_commands:
            with self.ovn_api.transaction(check_error=True) as txn:
                for cmd in txn_commands:
                    txn.add(cmd)
        LOG.debug('OVN-NB Sync DHCP options for Neutron ports with extra '
                  'dhcp options assigned finished')
Example #2
0
 def delete_subnet_postcommit(self, context):
     subnet = context.current
     if config.is_ovn_dhcp():
         with self._nb_ovn.transaction(check_error=True) as txn:
             subnet_dhcp_options = self._nb_ovn.get_subnet_dhcp_options(subnet["id"])
             if subnet_dhcp_options:
                 txn.add(self._nb_ovn.delete_dhcp_options(subnet_dhcp_options["uuid"]))
Example #3
0
    def _sync_port_dhcp_options(self, ctx, ports_need_sync_dhcp_opts,
                                ovn_port_dhcp_options):
        if not config.is_ovn_dhcp():
            return

        LOG.debug('OVN-NB Sync DHCP options for Neutron ports with extra '
                  'dhcp options assigned started')

        txn_commands = []
        for port in ports_need_sync_dhcp_opts:
            if self.mode == SYNC_MODE_REPAIR:
                LOG.debug('Updating DHCP options for port %s in OVN NB DB',
                          port['id'])
                dhcp_opts = self.ovn_driver.get_port_dhcpv4_options(port)
                if not dhcp_opts:
                    # If the Logical_Switch_Port.dhcpv4_options no longer
                    # refers a port dhcp options created in DHCP_Options
                    # earlier, that port dhcp options will be deleted
                    # in the following ovn_port_dhcp_options handling.
                    txn_commands.append(self.ovn_api.set_lswitch_port(
                        lport_name=port['id'],
                        dhcpv4_options=[]))
                elif port['id'] in ovn_port_dhcp_options:
                    # When the Logical_Switch_Port.dhcpv4_options refers a port
                    # dhcp options in DHCP_Options earlier, if the extra dhcp
                    # options has changed, ovn_driver.get_port_dhcpv4_options
                    # should udpate it, if removed, it will be deleted
                    # in the following ovn_port_dhcp_options handling.
                    if dhcp_opts['external_ids'].get('port_id') is not None:
                        ovn_port_dhcp_options.pop(port['id'])
                elif 'uuid' in dhcp_opts:
                    # If the Logical_Switch_Port.dhcpv4_options is already
                    # in sync, then this transaction will be a no-op.
                    txn_commands.append(self.ovn_api.set_lswitch_port(
                        lport_name=port['id'],
                        dhcpv4_options=[dhcp_opts['uuid']]))

        for port_id, dhcp_opt in ovn_port_dhcp_options.items():
            LOG.warning(
                _LW('Out of sync port DHCP options for (subnet %(subnet_id)s'
                    ' port %(port_id)s) found in OVN NB DB which needs to be '
                    'deleted'),
                {'subnet_id': dhcp_opt['external_ids']['subnet_id'],
                 'port_id': port_id})

            if self.mode == SYNC_MODE_REPAIR:
                LOG.debug('Deleting port DHCP options for (subnet %s, port '
                          '%s)', dhcp_opt['external_ids']['subnet_id'],
                          port_id)
                txn_commands.append(self.ovn_api.delete_dhcp_options(
                    dhcp_opt['uuid']))

        if txn_commands:
            with self.ovn_api.transaction(check_error=True) as txn:
                for cmd in txn_commands:
                    txn.add(cmd)
        LOG.debug('OVN-NB Sync DHCP options for Neutron ports with extra '
                  'dhcp options assigned finished')
Example #4
0
 def delete_subnet_postcommit(self, context):
     subnet = context.current
     if config.is_ovn_dhcp():
         with self._nb_ovn.transaction(check_error=True) as txn:
             subnet_dhcp_options = self._nb_ovn.get_subnet_dhcp_options(
                 subnet['id'])
             if subnet_dhcp_options:
                 txn.add(
                     self._nb_ovn.delete_dhcp_options(
                         subnet_dhcp_options['uuid']))
Example #5
0
def add_acls(plugin, admin_context, port, sg_cache, subnet_cache):
    acl_list = []

    # Skip ACLs if security groups aren't enabled
    if not is_sg_enabled():
        return acl_list

    sec_groups = port.get('security_groups', [])
    if not sec_groups:
        return acl_list

    # Drop all IP traffic to and from the logical port by default.
    acl_list += drop_all_ip_traffic_for_port(port)

    # Add DHCP ACLs if not using OVN native DHCP.
    if not config.is_ovn_dhcp():
        port_subnet_ids = set()
        for ip in port['fixed_ips']:
            if netaddr.IPNetwork(ip['ip_address']).version != 4:
                continue
            subnet = _get_subnet_from_cache(plugin, admin_context,
                                            subnet_cache, ip['subnet_id'])
            # Ignore duplicate DHCP ACLs for the subnet.
            if subnet['id'] not in port_subnet_ids:
                acl_list += add_acl_dhcp(port, subnet)
                port_subnet_ids.add(subnet['id'])

    # We create an ACL entry for each rule on each security group applied
    # to this port.
    for sg_id in sec_groups:
        sg = _get_sg_from_cache(plugin, admin_context, sg_cache, sg_id)
        for r in sg['security_group_rules']:
            acl = _add_sg_rule_acl_for_port(port, r)
            if acl and acl not in acl_list:
                acl_list.append(acl)

    return acl_list
Example #6
0
def add_acls(plugin, admin_context, port, sg_cache, subnet_cache):
    acl_list = []

    # Skip ACLs if security groups aren't enabled
    if not is_sg_enabled():
        return acl_list

    sec_groups = port.get('security_groups', [])
    if not sec_groups:
        return acl_list

    # Drop all IP traffic to and from the logical port by default.
    acl_list += drop_all_ip_traffic_for_port(port)

    for ip in port['fixed_ips']:
        if netaddr.IPNetwork(ip['ip_address']).version != 4:
            continue
        if not config.is_ovn_dhcp():
            subnet = _get_subnet_from_cache(plugin,
                                            admin_context,
                                            subnet_cache,
                                            ip['subnet_id'])
            acl_list += add_acl_dhcp(port, subnet)

    # We create an ACL entry for each rule on each security group applied
    # to this port.
    for sg_id in sec_groups:
        sg = _get_sg_from_cache(plugin,
                                admin_context,
                                sg_cache,
                                sg_id)
        for r in sg['security_group_rules']:
            acl = _add_sg_rule_acl_for_port(port, r)
            if acl and acl not in acl_list:
                acl_list.append(acl)

    return acl_list
Example #7
0
def add_acls(plugin, admin_context, port, sg_cache, subnet_cache):
    acl_list = []

    # Skip ACLs if security groups aren't enabled
    if not is_sg_enabled():
        return acl_list

    sec_groups = port.get("security_groups", [])
    if not sec_groups:
        return acl_list

    # Drop all IP traffic to and from the logical port by default.
    acl_list += drop_all_ip_traffic_for_port(port)

    # Add DHCP ACLs if not using OVN native DHCP.
    if not config.is_ovn_dhcp():
        port_subnet_ids = set()
        for ip in port["fixed_ips"]:
            if netaddr.IPNetwork(ip["ip_address"]).version != 4:
                continue
            subnet = _get_subnet_from_cache(plugin, admin_context, subnet_cache, ip["subnet_id"])
            # Ignore duplicate DHCP ACLs for the subnet.
            if subnet["id"] not in port_subnet_ids:
                acl_list += add_acl_dhcp(port, subnet)
                port_subnet_ids.add(subnet["id"])

    # We create an ACL entry for each rule on each security group applied
    # to this port.
    for sg_id in sec_groups:
        sg = _get_sg_from_cache(plugin, admin_context, sg_cache, sg_id)
        for r in sg["security_group_rules"]:
            acl = _add_sg_rule_acl_for_port(port, r)
            if acl and acl not in acl_list:
                acl_list.append(acl)

    return acl_list
Example #8
0
    def _sync_port_dhcp_options(self, ctx, ports_need_sync_dhcp_opts,
                                ovn_port_dhcpv4_opts, ovn_port_dhcpv6_opts):
        if not config.is_ovn_dhcp():
            return

        LOG.debug('OVN-NB Sync DHCP options for Neutron ports with extra '
                  'dhcp options assigned started')

        txn_commands = []
        lsp_dhcp_key = {constants.IP_VERSION_4: 'dhcpv4_options',
                        constants.IP_VERSION_6: 'dhcpv6_options'}
        ovn_port_dhcp_opts = {constants.IP_VERSION_4: ovn_port_dhcpv4_opts,
                              constants.IP_VERSION_6: ovn_port_dhcpv6_opts}
        for port in ports_need_sync_dhcp_opts:
            if self.mode == SYNC_MODE_REPAIR:
                LOG.debug('Updating DHCP options for port %s in OVN NB DB',
                          port['id'])
                set_lsp = {}
                for ip_v in [constants.IP_VERSION_4, constants.IP_VERSION_6]:
                    dhcp_opts = self.ovn_driver.get_port_dhcp_options(
                        port, ip_v)
                    if not dhcp_opts or 'uuid' in dhcp_opts:
                        # If the Logical_Switch_Port.dhcpv4_options or
                        # dhcpv6_options no longer refers a port dhcp options
                        # created in DHCP_Options earlier, that port dhcp
                        # options will be deleted in the following
                        # ovn_port_dhcp_options handling.
                        set_lsp[lsp_dhcp_key[ip_v]] = (
                            dhcp_opts and [dhcp_opts['uuid']] or [])
                    else:
                        # If port has extra port dhcp options, a command will
                        # returned by ovn_driver.get_port_dhcp_options to add
                        # or update port dhcp options.
                        ovn_port_dhcp_opts[ip_v].pop(port['id'], None)
                        dhcp_options = dhcp_opts['cmd']
                        txn_commands.append(dhcp_options)
                        set_lsp[lsp_dhcp_key[ip_v]] = dhcp_options
                if set_lsp:
                    txn_commands.append(self.ovn_api.set_lswitch_port(
                        lport_name=port['id'], **set_lsp))

        for ip_v in [constants.IP_VERSION_4, constants.IP_VERSION_6]:
            for port_id, dhcp_opt in ovn_port_dhcp_opts[ip_v].items():
                LOG.warning(
                    _LW('Out of sync port DHCPv%(ip_version)d options for '
                        '(subnet %(subnet_id)s port %(port_id)s) found in OVN '
                        'NB DB which needs to be deleted'),
                    {'ip_version': ip_v,
                     'subnet_id': dhcp_opt['external_ids']['subnet_id'],
                     'port_id': port_id})

                if self.mode == SYNC_MODE_REPAIR:
                    LOG.debug('Deleting port DHCPv%d options for (subnet %s, '
                              'port %s)', ip_v,
                              dhcp_opt['external_ids']['subnet_id'], port_id)
                    txn_commands.append(self.ovn_api.delete_dhcp_options(
                        dhcp_opt['uuid']))

        if txn_commands:
            with self.ovn_api.transaction(check_error=True) as txn:
                for cmd in txn_commands:
                    txn.add(cmd)
        LOG.debug('OVN-NB Sync DHCP options for Neutron ports with extra '
                  'dhcp options assigned finished')
Example #9
0
    def _sync_subnet_dhcp_options(self, ctx, db_networks,
                                  ovn_subnet_dhcp_options):
        if not config.is_ovn_dhcp():
            return

        LOG.debug('OVN-NB Sync DHCP options for Neutron subnets started')

        db_subnets = {}
        filters = {'enable_dhcp': [1]}
        for subnet in self.core_plugin.get_subnets(ctx, filters=filters):
            if subnet['ip_version'] == constants.IP_VERSION_6 and (
                subnet.get('ipv6_address_mode') == constants.IPV6_SLAAC):
                continue
            db_subnets[subnet['id']] = subnet

        del_subnet_dhcp_opts_list = []
        for subnet_id, ovn_dhcp_opts in ovn_subnet_dhcp_options.items():
            if subnet_id in db_subnets:
                network = db_networks[utils.ovn_name(
                    db_subnets[subnet_id]['network_id'])]
                server_mac = ovn_dhcp_opts['options'].get('server_mac')
                dhcp_options = self.ovn_driver.get_ovn_dhcp_options(
                    db_subnets[subnet_id], network, server_mac=server_mac)
                # Verify that the cidr and options are also in sync.
                if dhcp_options['cidr'] == ovn_dhcp_opts['cidr'] and (
                        dhcp_options['options'] == ovn_dhcp_opts['options']):
                    del db_subnets[subnet_id]
                else:
                    db_subnets[subnet_id]['ovn_dhcp_options'] = dhcp_options
            else:
                del_subnet_dhcp_opts_list.append(ovn_dhcp_opts)

        for subnet_id, subnet in db_subnets.items():
            LOG.warning(_LW('DHCP options for subnet %s is present in '
                            'Neutron but out of sync for OVN'), subnet_id)
            if self.mode == SYNC_MODE_REPAIR:
                try:
                    LOG.debug('Adding/Updating DHCP options for subnet %s in '
                              ' OVN NB DB', subnet_id)
                    network = db_networks[utils.ovn_name(subnet['network_id'])]
                    # ovn_driver.add_subnet_dhcp_options_in_ovn doesn't create
                    # a new row in DHCP_Options if the row already exists.
                    # See commands.AddDHCPOptionsCommand.
                    self.ovn_driver.add_subnet_dhcp_options_in_ovn(
                        subnet, network, subnet.get('ovn_dhcp_options'))
                except RuntimeError:
                    LOG.warning(_LW('Adding/Updating DHCP options for subnet '
                                    '%s failed in OVN NB DB'), subnet_id)

        txn_commands = []
        for dhcp_opt in del_subnet_dhcp_opts_list:
            LOG.warning(_LW('Out of sync subnet DHCP options for subnet %s '
                            'found in OVN NB DB which needs to be deleted'),
                        dhcp_opt['external_ids']['subnet_id'])
            if self.mode == SYNC_MODE_REPAIR:
                LOG.debug('Deleting subnet DHCP options for subnet %s ',
                          dhcp_opt['external_ids']['subnet_id'])
                txn_commands.append(self.ovn_api.delete_dhcp_options(
                    dhcp_opt['uuid']))

        if txn_commands:
            with self.ovn_api.transaction(check_error=True) as txn:
                for cmd in txn_commands:
                    txn.add(cmd)
        LOG.debug('OVN-NB Sync DHCP options for Neutron subnets finished')
Example #10
0
    def _sync_port_dhcp_options(self, ctx, ports_need_sync_dhcp_opts,
                                ovn_port_dhcpv4_opts, ovn_port_dhcpv6_opts):
        if not config.is_ovn_dhcp():
            return

        LOG.debug('OVN-NB Sync DHCP options for Neutron ports with extra '
                  'dhcp options assigned started')

        txn_commands = []
        lsp_dhcp_key = {
            constants.IP_VERSION_4: 'dhcpv4_options',
            constants.IP_VERSION_6: 'dhcpv6_options'
        }
        ovn_port_dhcp_opts = {
            constants.IP_VERSION_4: ovn_port_dhcpv4_opts,
            constants.IP_VERSION_6: ovn_port_dhcpv6_opts
        }
        for port in ports_need_sync_dhcp_opts:
            if self.mode == SYNC_MODE_REPAIR:
                LOG.debug('Updating DHCP options for port %s in OVN NB DB',
                          port['id'])
                set_lsp = {}
                for ip_v in [constants.IP_VERSION_4, constants.IP_VERSION_6]:
                    dhcp_opts = self.ovn_driver.get_port_dhcp_options(
                        port, ip_v)
                    if not dhcp_opts:
                        # If the Logical_Switch_Port.dhcpv4_options or
                        # dhcpv6_options no longer refers a port dhcp options
                        # created in DHCP_Options earlier, that port dhcp
                        # options will be deleted in the following
                        # ovn_port_dhcp_options handling.
                        set_lsp[lsp_dhcp_key[ip_v]] = []
                    elif port['id'] in ovn_port_dhcp_opts[ip_v]:
                        # When the Logical_Switch_Port.dhcpv4_options or
                        # dhcpv6_options refers a port dhcp options in
                        # DHCP_Options earlier, if the extra dhcp options has
                        # changed, ovn_driver.get_port_dhcp_options should
                        # udpate it, if removed, it will be deleted in the
                        # following ovn_port_dhcp_options handling.
                        if dhcp_opts['external_ids'].get('port_id'):
                            ovn_port_dhcp_opts[ip_v].pop(port['id'])
                            # Ensure Logical_Switch_Port still have references
                            # to DHCP_Options rows.
                            set_lsp[lsp_dhcp_key[ip_v]] = [dhcp_opts['uuid']]
                    elif 'uuid' in dhcp_opts:
                        set_lsp[lsp_dhcp_key[ip_v]] = [dhcp_opts['uuid']]
                if set_lsp:
                    txn_commands.append(
                        self.ovn_api.set_lswitch_port(lport_name=port['id'],
                                                      **set_lsp))

        for ip_v in [constants.IP_VERSION_4, constants.IP_VERSION_6]:
            for port_id, dhcp_opt in ovn_port_dhcp_opts[ip_v].items():
                LOG.warning(
                    _LW('Out of sync port DHCPv%(ip_version)d options for '
                        '(subnet %(subnet_id)s port %(port_id)s) found in OVN '
                        'NB DB which needs to be deleted'), {
                            'ip_version': ip_v,
                            'subnet_id': dhcp_opt['external_ids']['subnet_id'],
                            'port_id': port_id
                        })

                if self.mode == SYNC_MODE_REPAIR:
                    LOG.debug(
                        'Deleting port DHCPv%d options for (subnet %s, '
                        'port %s)', ip_v,
                        dhcp_opt['external_ids']['subnet_id'], port_id)
                    txn_commands.append(
                        self.ovn_api.delete_dhcp_options(dhcp_opt['uuid']))

        if txn_commands:
            with self.ovn_api.transaction(check_error=True) as txn:
                for cmd in txn_commands:
                    txn.add(cmd)
        LOG.debug('OVN-NB Sync DHCP options for Neutron ports with extra '
                  'dhcp options assigned finished')
Example #11
0
    def _sync_subnet_dhcp_options(self, ctx, db_networks,
                                  ovn_subnet_dhcp_options):
        if not config.is_ovn_dhcp():
            return

        LOG.debug('OVN-NB Sync DHCP options for Neutron subnets started')

        db_subnets = {}
        filters = {'enable_dhcp': [1]}
        for subnet in self.core_plugin.get_subnets(ctx, filters=filters):
            if subnet['ip_version'] == constants.IP_VERSION_6 and (
                    subnet.get('ipv6_address_mode') == constants.IPV6_SLAAC):
                continue
            db_subnets[subnet['id']] = subnet

        del_subnet_dhcp_opts_list = []
        for subnet_id, ovn_dhcp_opts in ovn_subnet_dhcp_options.items():
            if subnet_id in db_subnets:
                network = db_networks[utils.ovn_name(
                    db_subnets[subnet_id]['network_id'])]
                server_mac = ovn_dhcp_opts['options'].get('server_mac')
                dhcp_options = self.ovn_driver.get_ovn_dhcp_options(
                    db_subnets[subnet_id], network, server_mac=server_mac)
                # Verify that the cidr and options are also in sync.
                if dhcp_options['cidr'] == ovn_dhcp_opts['cidr'] and (
                        dhcp_options['options'] == ovn_dhcp_opts['options']):
                    del db_subnets[subnet_id]
                else:
                    db_subnets[subnet_id]['ovn_dhcp_options'] = dhcp_options
            else:
                del_subnet_dhcp_opts_list.append(ovn_dhcp_opts)

        for subnet_id, subnet in db_subnets.items():
            LOG.warning(
                _LW('DHCP options for subnet %s is present in '
                    'Neutron but out of sync for OVN'), subnet_id)
            if self.mode == SYNC_MODE_REPAIR:
                try:
                    LOG.debug(
                        'Adding/Updating DHCP options for subnet %s in '
                        ' OVN NB DB', subnet_id)
                    network = db_networks[utils.ovn_name(subnet['network_id'])]
                    # ovn_driver.add_subnet_dhcp_options_in_ovn doesn't create
                    # a new row in DHCP_Options if the row already exists.
                    # See commands.AddDHCPOptionsCommand.
                    self.ovn_driver.add_subnet_dhcp_options_in_ovn(
                        subnet, network, subnet.get('ovn_dhcp_options'))
                except RuntimeError:
                    LOG.warning(
                        _LW('Adding/Updating DHCP options for subnet '
                            '%s failed in OVN NB DB'), subnet_id)

        txn_commands = []
        for dhcp_opt in del_subnet_dhcp_opts_list:
            LOG.warning(
                _LW('Out of sync subnet DHCP options for subnet %s '
                    'found in OVN NB DB which needs to be deleted'),
                dhcp_opt['external_ids']['subnet_id'])
            if self.mode == SYNC_MODE_REPAIR:
                LOG.debug('Deleting subnet DHCP options for subnet %s ',
                          dhcp_opt['external_ids']['subnet_id'])
                txn_commands.append(
                    self.ovn_api.delete_dhcp_options(dhcp_opt['uuid']))

        if txn_commands:
            with self.ovn_api.transaction(check_error=True) as txn:
                for cmd in txn_commands:
                    txn.add(cmd)
        LOG.debug('OVN-NB Sync DHCP options for Neutron subnets finished')
Example #12
0
 def update_subnet_postcommit(self, context):
     subnet = context.current
     if config.is_ovn_dhcp() and (subnet['enable_dhcp']
                                  or context.original['enable_dhcp']):
         self.add_subnet_dhcp_options_in_ovn(subnet,
                                             context.network.current)
Example #13
0
 def create_subnet_postcommit(self, context):
     subnet = context.current
     if subnet['enable_dhcp'] and config.is_ovn_dhcp():
         self.add_subnet_dhcp_options_in_ovn(subnet,
                                             context.network.current)
Example #14
0
    def _sync_port_dhcp_options(self, ctx, ports_need_sync_dhcp_opts,
                                ovn_port_dhcpv4_opts, ovn_port_dhcpv6_opts):
        if not config.is_ovn_dhcp():
            return

        LOG.debug('OVN-NB Sync DHCP options for Neutron ports with extra '
                  'dhcp options assigned started')

        txn_commands = []
        lsp_dhcp_key = {
            constants.IP_VERSION_4: 'dhcpv4_options',
            constants.IP_VERSION_6: 'dhcpv6_options'
        }
        ovn_port_dhcp_opts = {
            constants.IP_VERSION_4: ovn_port_dhcpv4_opts,
            constants.IP_VERSION_6: ovn_port_dhcpv6_opts
        }
        for port in ports_need_sync_dhcp_opts:
            # Ignore the floating ip ports with device_owner set to
            # constants.DEVICE_OWNER_FLOATINGIP
            if port.get('device_owner',
                        '').startswith(constants.DEVICE_OWNER_FLOATINGIP):
                continue

            if self.mode == SYNC_MODE_REPAIR:
                LOG.debug('Updating DHCP options for port %s in OVN NB DB',
                          port['id'])
                set_lsp = {}
                for ip_v in [constants.IP_VERSION_4, constants.IP_VERSION_6]:
                    dhcp_opts = self.ovn_driver.get_port_dhcp_options(
                        port, ip_v)
                    if not dhcp_opts or 'uuid' in dhcp_opts:
                        # If the Logical_Switch_Port.dhcpv4_options or
                        # dhcpv6_options no longer refers a port dhcp options
                        # created in DHCP_Options earlier, that port dhcp
                        # options will be deleted in the following
                        # ovn_port_dhcp_options handling.
                        set_lsp[lsp_dhcp_key[ip_v]] = (dhcp_opts
                                                       and [dhcp_opts['uuid']]
                                                       or [])
                    else:
                        # If port has extra port dhcp options, a command will
                        # returned by ovn_driver.get_port_dhcp_options to add
                        # or update port dhcp options.
                        ovn_port_dhcp_opts[ip_v].pop(port['id'], None)
                        dhcp_options = dhcp_opts['cmd']
                        txn_commands.append(dhcp_options)
                        set_lsp[lsp_dhcp_key[ip_v]] = dhcp_options
                if set_lsp:
                    txn_commands.append(
                        self.ovn_api.set_lswitch_port(lport_name=port['id'],
                                                      **set_lsp))

        for ip_v in [constants.IP_VERSION_4, constants.IP_VERSION_6]:
            for port_id, dhcp_opt in ovn_port_dhcp_opts[ip_v].items():
                LOG.warning(
                    _LW('Out of sync port DHCPv%(ip_version)d options for '
                        '(subnet %(subnet_id)s port %(port_id)s) found in OVN '
                        'NB DB which needs to be deleted'), {
                            'ip_version': ip_v,
                            'subnet_id': dhcp_opt['external_ids']['subnet_id'],
                            'port_id': port_id
                        })

                if self.mode == SYNC_MODE_REPAIR:
                    LOG.debug(
                        'Deleting port DHCPv%d options for (subnet %s, '
                        'port %s)', ip_v,
                        dhcp_opt['external_ids']['subnet_id'], port_id)
                    txn_commands.append(
                        self.ovn_api.delete_dhcp_options(dhcp_opt['uuid']))

        if txn_commands:
            with self.ovn_api.transaction(check_error=True) as txn:
                for cmd in txn_commands:
                    txn.add(cmd)
        LOG.debug('OVN-NB Sync DHCP options for Neutron ports with extra '
                  'dhcp options assigned finished')
Example #15
0
 def update_subnet_postcommit(self, context):
     subnet = context.current
     if config.is_ovn_dhcp() and (
         subnet['enable_dhcp'] or context.original['enable_dhcp']):
         self.add_subnet_dhcp_options_in_ovn(subnet,
                                             context.network.current)
Example #16
0
 def create_subnet_postcommit(self, context):
     subnet = context.current
     if subnet['enable_dhcp'] and config.is_ovn_dhcp():
         self.add_subnet_dhcp_options_in_ovn(subnet,
                                             context.network.current)