コード例 #1
0
ファイル: dnsmasq.py プロジェクト: bestjie/ironic-inspector
    def _sync(self, ironic):
        """Sync the inspector, ironic and dnsmasq state. Locked.

        :raises: IOError, OSError.
        :returns: None.
        """
        LOG.debug('Syncing the driver')
        timestamp_start = timeutils.utcnow()
        active_macs = node_cache.active_macs()
        ironic_macs = set(port.address for port in ir_utils.call_with_retries(
            ironic.port.list, limit=0, fields=['address']))
        blacklist_macs = _get_blacklist()
        # NOTE(milan) whitelist MACs of ports not kept in ironic anymore
        # also whitelist active MACs that are still blacklisted in the
        # dnsmasq configuration but have just been asked to be introspected
        for mac in ((blacklist_macs - ironic_macs) |
                    (blacklist_macs & active_macs)):
            _whitelist_mac(mac)
        # blacklist new ports that aren't being inspected
        for mac in ironic_macs - (blacklist_macs | active_macs):
            _blacklist_mac(mac)

        _configure_unknown_hosts()

        timestamp_end = timeutils.utcnow()
        LOG.debug('The dnsmasq PXE filter was synchronized (took %s)',
                  timestamp_end - timestamp_start)
コード例 #2
0
ファイル: iptables.py プロジェクト: gudrutis/ironic-inspector
def _get_blacklist(ironic):
    ports = [port for port in
             ir_utils.call_with_retries(ironic.port.list, limit=0,
                                        fields=['address', 'extra'])
             if port.address not in node_cache.active_macs()]
    _ib_mac_to_rmac_mapping(ports)
    return [port.address for port in ports]
コード例 #3
0
def _get_blacklist(ironic):
    ports = [port.address for port in
             ir_utils.call_with_retries(ironic.port.list, limit=0,
                                        fields=['address', 'extra'])
             if port.address not in node_cache.active_macs()]
    _ib_mac_to_rmac_mapping(ports)
    return ports
コード例 #4
0
def _get_blacklist(ironic):
    ports = [
        port.address
        for port in ironic.port.list(limit=0, fields=['address', 'extra'])
        if port.address not in node_cache.active_macs()
    ]
    _ib_mac_to_rmac_mapping(ports)
    return ports
コード例 #5
0
def get_active_macs(ironic):
    ports = [
        port for port in ir_utils.call_with_retries(
            ironic.ports, limit=None, fields=['address', 'extra'])
        if port.address in node_cache.active_macs()
    ]
    _ib_mac_to_rmac_mapping(ports)
    return {port.address for port in ports}
コード例 #6
0
ファイル: firewall.py プロジェクト: KanM/ironic-inspector
def update_filters(ironic=None):
    """Update firewall filter rules for introspection.

    Gives access to PXE boot port for any machine, except for those,
    whose MAC is registered in Ironic and is not on introspection right now.

    This function is called from both introspection initialization code and
    from periodic task. This function is supposed to be resistant to unexpected
    iptables state.

    ``init()`` function must be called once before any call to this function.
    This function is using ``eventlet`` semaphore to serialize access from
    different green threads.

    Does nothing, if firewall management is disabled in configuration.

    :param ironic: Ironic client instance, optional.
    """
    if not CONF.firewall.manage_firewall:
        return

    assert INTERFACE is not None
    ironic = utils.get_client() if ironic is None else ironic

    with LOCK:
        macs_active = set(p.address for p in ironic.port.list(limit=0))
        to_blacklist = macs_active - node_cache.active_macs()
        LOG.debug('Blacklisting active MAC\'s %s', to_blacklist)

        # Clean up a bit to account for possible troubles on previous run
        _clean_up(NEW_CHAIN)
        # Operate on temporary chain
        _iptables('-N', NEW_CHAIN)
        # - Blacklist active macs, so that nova can boot them
        for mac in to_blacklist:
            _iptables('-A', NEW_CHAIN, '-m', 'mac', '--mac-source', mac, '-j',
                      'DROP')
        # - Whitelist everything else
        _iptables('-A', NEW_CHAIN, '-j', 'ACCEPT')

        # Swap chains
        _iptables('-I', 'INPUT', '-i', INTERFACE, '-p', 'udp', '--dport', '67',
                  '-j', NEW_CHAIN)
        _iptables('-D',
                  'INPUT',
                  '-i',
                  INTERFACE,
                  '-p',
                  'udp',
                  '--dport',
                  '67',
                  '-j',
                  CHAIN,
                  ignore=True)
        _iptables('-F', CHAIN, ignore=True)
        _iptables('-X', CHAIN, ignore=True)
        _iptables('-E', NEW_CHAIN, CHAIN)
コード例 #7
0
ファイル: firewall.py プロジェクト: stackhpc/ironic-inspector
def update_filters(ironic=None):
    """Update firewall filter rules for introspection.

    Gives access to PXE boot port for any machine, except for those,
    whose MAC is registered in Ironic and is not on introspection right now.

    This function is called from both introspection initialization code and
    from periodic task. This function is supposed to be resistant to unexpected
    iptables state.

    ``init()`` function must be called once before any call to this function.
    This function is using ``eventlet`` semaphore to serialize access from
    different green threads.

    Does nothing, if firewall management is disabled in configuration.

    :param ironic: Ironic client instance, optional.
    """
    global BLACKLIST_CACHE, ENABLED

    if not CONF.firewall.manage_firewall:
        return

    assert INTERFACE is not None
    ironic = ir_utils.get_client() if ironic is None else ironic
    with LOCK:
        if not _should_enable_dhcp():
            _disable_dhcp()
            return

        ports_active = ironic.port.list(limit=0, fields=['address', 'extra'])
        macs_active = set(p.address for p in ports_active)
        to_blacklist = macs_active - node_cache.active_macs()
        ib_mac_mapping = (_ib_mac_to_rmac_mapping(to_blacklist, ports_active))

        if (BLACKLIST_CACHE is not None and to_blacklist == BLACKLIST_CACHE
                and not ib_mac_mapping):
            LOG.debug('Not updating iptables - no changes in MAC list %s',
                      to_blacklist)
            return

        LOG.debug('Blacklisting active MAC\'s %s', to_blacklist)
        # Force update on the next iteration if this attempt fails
        BLACKLIST_CACHE = None

        with _temporary_chain(NEW_CHAIN, CHAIN):
            # - Blacklist active macs, so that nova can boot them
            for mac in to_blacklist:
                mac = ib_mac_mapping.get(mac) or mac
                _iptables('-A', NEW_CHAIN, '-m', 'mac', '--mac-source', mac,
                          '-j', 'DROP')
            # - Whitelist everything else
            _iptables('-A', NEW_CHAIN, '-j', 'ACCEPT')

        # Cache result of successful iptables update
        ENABLED = True
        BLACKLIST_CACHE = to_blacklist
コード例 #8
0
 def test_active_macs(self):
     session = db.get_session()
     with session.begin():
         db.Node(uuid=self.node.uuid).save(session)
         values = [('mac', '11:22:11:22:11:22', self.uuid),
                   ('mac', '22:11:22:11:22:11', self.uuid)]
         for value in values:
             db.Attribute(name=value[0], value=value[1],
                          uuid=value[2]).save(session)
     self.assertEqual({'11:22:11:22:11:22', '22:11:22:11:22:11'},
                      node_cache.active_macs())
コード例 #9
0
 def test_active_macs(self):
     session = db.get_session()
     with session.begin():
         db.Node(uuid=self.node.uuid).save(session)
         values = [('mac', '11:22:11:22:11:22', self.uuid),
                   ('mac', '22:11:22:11:22:11', self.uuid)]
         for value in values:
             db.Attribute(name=value[0], value=value[1],
                          uuid=value[2]).save(session)
     self.assertEqual({'11:22:11:22:11:22', '22:11:22:11:22:11'},
                      node_cache.active_macs())
コード例 #10
0
ファイル: firewall.py プロジェクト: keedya/ironic-inspector
def update_filters(ironic=None):
    """Update firewall filter rules for introspection.

    Gives access to PXE boot port for any machine, except for those,
    whose MAC is registered in Ironic and is not on introspection right now.

    This function is called from both introspection initialization code and
    from periodic task. This function is supposed to be resistant to unexpected
    iptables state.

    ``init()`` function must be called once before any call to this function.
    This function is using ``eventlet`` semaphore to serialize access from
    different green threads.

    Does nothing, if firewall management is disabled in configuration.

    :param ironic: Ironic client instance, optional.
    """
    global BLACKLIST_CACHE, ENABLED

    if not CONF.firewall.manage_firewall:
        return

    assert INTERFACE is not None
    ironic = ir_utils.get_client() if ironic is None else ironic

    with LOCK:
        if not _should_enable_dhcp():
            _disable_dhcp()
            return

        macs_active = set(p.address for p in ironic.port.list(limit=0))
        to_blacklist = macs_active - node_cache.active_macs()
        if BLACKLIST_CACHE is not None and to_blacklist == BLACKLIST_CACHE:
            LOG.debug('Not updating iptables - no changes in MAC list %s',
                      to_blacklist)
            return

        LOG.debug('Blacklisting active MAC\'s %s', to_blacklist)
        # Force update on the next iteration if this attempt fails
        BLACKLIST_CACHE = None

        with _temporary_chain(NEW_CHAIN, CHAIN):
            # - Blacklist active macs, so that nova can boot them
            for mac in to_blacklist:
                _iptables('-A', NEW_CHAIN, '-m', 'mac',
                          '--mac-source', mac, '-j', 'DROP')
            # - Whitelist everything else
            _iptables('-A', NEW_CHAIN, '-j', 'ACCEPT')

        # Cache result of successful iptables update
        ENABLED = True
        BLACKLIST_CACHE = to_blacklist
コード例 #11
0
 def test_active_macs(self):
     session = db.get_session()
     with session.begin():
         db.Node(uuid=self.node.uuid,
                 state=istate.States.starting).save(session)
         values = [('mac', '11:22:11:22:11:22', self.uuid),
                   ('mac', '22:11:22:11:22:11', self.uuid)]
         for value in values:
             db.Attribute(uuid=uuidutils.generate_uuid(),
                          name=value[0],
                          value=value[1],
                          node_uuid=value[2]).save(session)
     self.assertEqual({'11:22:11:22:11:22', '22:11:22:11:22:11'},
                      node_cache.active_macs())
コード例 #12
0
ファイル: firewall.py プロジェクト: KanM/ironic-inspector
def update_filters(ironic=None):
    """Update firewall filter rules for introspection.

    Gives access to PXE boot port for any machine, except for those,
    whose MAC is registered in Ironic and is not on introspection right now.

    This function is called from both introspection initialization code and
    from periodic task. This function is supposed to be resistant to unexpected
    iptables state.

    ``init()`` function must be called once before any call to this function.
    This function is using ``eventlet`` semaphore to serialize access from
    different green threads.

    Does nothing, if firewall management is disabled in configuration.

    :param ironic: Ironic client instance, optional.
    """
    if not CONF.firewall.manage_firewall:
        return

    assert INTERFACE is not None
    ironic = utils.get_client() if ironic is None else ironic

    with LOCK:
        macs_active = set(p.address for p in ironic.port.list(limit=0))
        to_blacklist = macs_active - node_cache.active_macs()
        LOG.debug('Blacklisting active MAC\'s %s', to_blacklist)

        # Clean up a bit to account for possible troubles on previous run
        _clean_up(NEW_CHAIN)
        # Operate on temporary chain
        _iptables('-N', NEW_CHAIN)
        # - Blacklist active macs, so that nova can boot them
        for mac in to_blacklist:
            _iptables('-A', NEW_CHAIN, '-m', 'mac',
                      '--mac-source', mac, '-j', 'DROP')
        # - Whitelist everything else
        _iptables('-A', NEW_CHAIN, '-j', 'ACCEPT')

        # Swap chains
        _iptables('-I', 'INPUT', '-i', INTERFACE, '-p', 'udp',
                  '--dport', '67', '-j', NEW_CHAIN)
        _iptables('-D', 'INPUT', '-i', INTERFACE, '-p', 'udp',
                  '--dport', '67', '-j', CHAIN,
                  ignore=True)
        _iptables('-F', CHAIN, ignore=True)
        _iptables('-X', CHAIN, ignore=True)
        _iptables('-E', NEW_CHAIN, CHAIN)
コード例 #13
0
ファイル: dnsmasq.py プロジェクト: openstack/ironic-inspector
    def _sync(self, ironic):
        """Sync the inspector, ironic and dnsmasq state. Locked.

        :raises: IOError, OSError.
        :returns: None.
        """
        LOG.debug('Syncing the driver')
        timestamp_start = timeutils.utcnow()

        # active_macs are the MACs for which introspection is active
        active_macs = node_cache.active_macs()
        # ironic_macs are all the MACs know to ironic (all ironic ports)
        ironic_macs = set(port.address for port in
                          ir_utils.call_with_retries(ironic.port.list, limit=0,
                                                     fields=['address']))
        blacklist, whitelist = _get_black_white_lists()
        # removedlist are the MACs that are in either blacklist or whitelist,
        # but not kept in ironic (ironic_macs) any more
        removedlist = blacklist.union(whitelist).difference(ironic_macs)

        # Whitelist active MACs that are not already whitelisted
        for mac in active_macs.difference(whitelist):
            _whitelist_mac(mac)
        # Blacklist any ironic MACs that is not active for introspection unless
        # it is already blacklisted
        for mac in ironic_macs.difference(blacklist.union(active_macs)):
            _blacklist_mac(mac)

        # Whitelist or Blacklist unknown hosts and MACs not kept in ironic
        # NOTE(hjensas): Treat unknown hosts and MACs not kept in ironic the
        # same. Neither should boot the inspection image unless introspection
        # is active. Deleted MACs must be whitelisted when introspection is
        # active in case the host is re-enrolled.
        _configure_unknown_hosts()
        _configure_removedlist(removedlist)

        timestamp_end = timeutils.utcnow()
        LOG.debug('The dnsmasq PXE filter was synchronized (took %s)',
                  timestamp_end - timestamp_start)
コード例 #14
0
    def _sync(self, ironic):
        """Sync the inspector, ironic and dnsmasq state. Locked.

        :raises: IOError, OSError.
        :returns: None.
        """
        LOG.debug('Syncing the driver')
        timestamp_start = timeutils.utcnow()

        # active_macs are the MACs for which introspection is active
        active_macs = node_cache.active_macs()
        # ironic_macs are all the MACs know to ironic (all ironic ports)
        ironic_macs = set(port.address for port in ir_utils.call_with_retries(
            ironic.port.list, limit=0, fields=['address']))
        blacklist, whitelist = _get_black_white_lists()
        # removedlist are the MACs that are in either blacklist or whitelist,
        # but not kept in ironic (ironic_macs) any more
        removedlist = blacklist.union(whitelist).difference(ironic_macs)

        # Whitelist active MACs that are not already whitelisted
        for mac in active_macs.difference(whitelist):
            _whitelist_mac(mac)
        # Blacklist any ironic MACs that is not active for introspection unless
        # it is already blacklisted
        for mac in ironic_macs.difference(blacklist.union(active_macs)):
            _blacklist_mac(mac)

        # Whitelist or Blacklist unknown hosts and MACs not kept in ironic
        # NOTE(hjensas): Treat unknown hosts and MACs not kept in ironic the
        # same. Neither should boot the inspection image unless introspection
        # is active. Deleted MACs must be whitelisted when introspection is
        # active in case the host is re-enrolled.
        _configure_unknown_hosts()
        _configure_removedlist(removedlist)

        timestamp_end = timeutils.utcnow()
        LOG.debug('The dnsmasq PXE filter was synchronized (took %s)',
                  timestamp_end - timestamp_start)