Example #1
0
def periodic_clean_up():  # pragma: no cover
    try:
        if node_cache.clean_up():
            firewall.update_filters()
        sync_with_ironic()
    except Exception:
        LOG.exception(_LE('Periodic clean up of node cache failed'))
def _abort(node_info, ironic):
    # runs in background
    if node_info.finished_at is not None:
        # introspection already finished; nothing to do
        LOG.info(_LI('Cannot abort introspection as it is already '
                     'finished'), node_info=node_info)
        node_info.release_lock()
        return

    # block this node from PXE Booting the introspection image
    try:
        firewall.update_filters(ironic)
    except Exception as exc:
        # Note(mkovacik): this will be retried in firewall update
        # periodic task; we continue aborting
        LOG.warning(_LW('Failed to update firewall filters: %s'), exc,
                    node_info=node_info)

    # finish the introspection
    LOG.debug('Forcing power-off', node_info=node_info)
    try:
        ironic.node.set_power_state(node_info.uuid, 'off')
    except Exception as exc:
        LOG.warning(_LW('Failed to power off node: %s'), exc,
                    node_info=node_info)

    node_info.finished(error=_('Canceled by operator'))
    LOG.info(_LI('Introspection aborted'), node_info=node_info)
Example #3
0
def _process_node(node_info, node, introspection_data):
    # NOTE(dtantsur): repeat the check in case something changed
    ir_utils.check_provision_state(node)
    interfaces = introspection_data.get('interfaces')
    node_info.create_ports(list(interfaces.values()))
    _run_post_hooks(node_info, introspection_data)
    _store_data(node_info, introspection_data)

    ironic = ir_utils.get_client()
    firewall.update_filters(ironic)

    node_info.invalidate_cache()
    rules.apply(node_info, introspection_data)

    resp = {'uuid': node.uuid}

    if node_info.options.get('new_ipmi_credentials'):
        new_username, new_password = (
            node_info.options.get('new_ipmi_credentials'))
        utils.executor().submit(_finish_set_ipmi_credentials,
                                node_info, ironic, node, introspection_data,
                                new_username, new_password)
        resp['ipmi_setup_credentials'] = True
        resp['ipmi_username'] = new_username
        resp['ipmi_password'] = new_password
    else:
        utils.executor().submit(_finish, node_info, ironic, introspection_data,
                                power_off=CONF.processing.power_off)

    return resp
Example #4
0
    def test_update_filters_kwargs(self, mock_call, mock_get_client,
                                   mock_iptables):
        firewall.init()

        update_filters_expected_kwargs = [{
            'ignore': True
        }, {
            'ignore': True
        }, {
            'ignore': True
        }, {}, {
            'ignore': True
        }, {
            'ignore': True
        }, {
            'ignore': True
        }, {}, {}, {}, {
            'ignore': True
        }, {
            'ignore': True
        }, {
            'ignore': True
        }]

        firewall.update_filters()
        call_args_list = mock_iptables.call_args_list

        for (kwargs, call) in zip(update_filters_expected_kwargs,
                                  call_args_list):
            self.assertEqual(kwargs, call[1])
Example #5
0
    def test_update_filters_args(self, mock_call, mock_get_client,
                                 mock_iptables):
        # Pretend that we have nodes on introspection
        node_cache.add_node(self.node.uuid,
                            state=istate.States.waiting,
                            bmc_address='1.2.3.4')

        firewall.init()

        update_filters_expected_args = [
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport', '67',
             '-j', CONF.firewall.firewall_chain),
            ('-F', CONF.firewall.firewall_chain),
            ('-X', CONF.firewall.firewall_chain),
            ('-N', CONF.firewall.firewall_chain),
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport', '67',
             '-j', firewall.NEW_CHAIN), ('-F', firewall.NEW_CHAIN),
            ('-X', firewall.NEW_CHAIN), ('-N', firewall.NEW_CHAIN),
            ('-A', firewall.NEW_CHAIN, '-j', 'ACCEPT'),
            ('-I', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport', '67',
             '-j', firewall.NEW_CHAIN),
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport', '67',
             '-j', CONF.firewall.firewall_chain),
            ('-F', CONF.firewall.firewall_chain),
            ('-X', CONF.firewall.firewall_chain),
            ('-E', firewall.NEW_CHAIN, CONF.firewall.firewall_chain)
        ]

        firewall.update_filters()
        call_args_list = mock_iptables.call_args_list

        for (args, call) in zip(update_filters_expected_args, call_args_list):
            self.assertEqual(args, call[0])
Example #6
0
    def test_update_filters_args_node_not_found_hook(self, mock_call,
                                                     mock_get_client,
                                                     mock_iptables):
        # DHCP should be always opened if node_not_found hook is set
        CONF.set_override('node_not_found_hook', 'enroll', 'processing')

        firewall.init()

        update_filters_expected_args = [
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport', '67',
             '-j', CONF.firewall.firewall_chain),
            ('-F', CONF.firewall.firewall_chain),
            ('-X', CONF.firewall.firewall_chain),
            ('-N', CONF.firewall.firewall_chain),
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport', '67',
             '-j', firewall.NEW_CHAIN), ('-F', firewall.NEW_CHAIN),
            ('-X', firewall.NEW_CHAIN), ('-N', firewall.NEW_CHAIN),
            ('-A', firewall.NEW_CHAIN, '-j', 'ACCEPT'),
            ('-I', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport', '67',
             '-j', firewall.NEW_CHAIN),
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport', '67',
             '-j', CONF.firewall.firewall_chain),
            ('-F', CONF.firewall.firewall_chain),
            ('-X', CONF.firewall.firewall_chain),
            ('-E', firewall.NEW_CHAIN, CONF.firewall.firewall_chain)
        ]

        firewall.update_filters()
        call_args_list = mock_iptables.call_args_list

        for (args, call) in zip(update_filters_expected_args, call_args_list):
            self.assertEqual(args, call[0])
def periodic_clean_up():  # pragma: no cover
    try:
        if node_cache.clean_up():
            firewall.update_filters()
        sync_with_ironic()
    except Exception:
        LOG.exception('Periodic clean up of node cache failed')
Example #8
0
def _process_node(node, introspection_data, node_info):
    # NOTE(dtantsur): repeat the check in case something changed
    ir_utils.check_provision_state(node)

    node_info.create_ports(introspection_data.get('macs') or ())

    _run_post_hooks(node_info, introspection_data)
    _store_data(node_info, introspection_data)

    ironic = ir_utils.get_client()
    firewall.update_filters(ironic)

    node_info.invalidate_cache()
    rules.apply(node_info, introspection_data)

    resp = {'uuid': node.uuid}

    if node_info.options.get('new_ipmi_credentials'):
        new_username, new_password = (
            node_info.options.get('new_ipmi_credentials'))
        utils.executor().submit(_finish_set_ipmi_credentials,
                                ironic, node, node_info, introspection_data,
                                new_username, new_password)
        resp['ipmi_setup_credentials'] = True
        resp['ipmi_username'] = new_username
        resp['ipmi_password'] = new_password
    else:
        utils.executor().submit(_finish, ironic, node_info, introspection_data)

    return resp
    def test_update_filters_kwargs(self, mock_call, mock_get_client,
                                   mock_iptables):
        firewall.init()

        update_filters_expected_kwargs = [
            {'ignore': True},
            {'ignore': True},
            {'ignore': True},
            {},
            {'ignore': True},
            {'ignore': True},
            {'ignore': True},
            {},
            {},
            {},
            {'ignore': True},
            {'ignore': True},
            {'ignore': True}
        ]

        firewall.update_filters()
        call_args_list = mock_iptables.call_args_list

        for (kwargs, call) in zip(update_filters_expected_kwargs,
                                  call_args_list):
            self.assertEqual(kwargs, call[1])
Example #10
0
    def test_update_filters_args(self, mock_call, mock_get_client,
                                 mock_iptables):
        firewall.init()

        update_filters_expected_args = [
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
             '67', '-j', CONF.firewall.firewall_chain),
            ('-F', CONF.firewall.firewall_chain),
            ('-X', CONF.firewall.firewall_chain),
            ('-N', CONF.firewall.firewall_chain),
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
             '67', '-j', firewall.NEW_CHAIN),
            ('-F', firewall.NEW_CHAIN),
            ('-X', firewall.NEW_CHAIN),
            ('-N', firewall.NEW_CHAIN),
            ('-A', firewall.NEW_CHAIN, '-j', 'ACCEPT'),
            ('-I', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
             '67', '-j', firewall.NEW_CHAIN),
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
             '67', '-j', CONF.firewall.firewall_chain),
            ('-F', CONF.firewall.firewall_chain),
            ('-X', CONF.firewall.firewall_chain),
            ('-E', firewall.NEW_CHAIN, CONF.firewall.firewall_chain)
        ]

        firewall.update_filters()
        call_args_list = mock_iptables.call_args_list

        for (args, call) in zip(update_filters_expected_args,
                                call_args_list):
            self.assertEqual(args, call[0])
    def test_update_filters_args_node_not_found_hook(self, mock_call,
                                                     mock_get_client,
                                                     mock_iptables):
        # DHCP should be always opened if node_not_found hook is set
        CONF.set_override('node_not_found_hook', 'enroll', 'processing')

        firewall.init()

        update_filters_expected_args = [
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
             '67', '-j', CONF.firewall.firewall_chain),
            ('-F', CONF.firewall.firewall_chain),
            ('-X', CONF.firewall.firewall_chain),
            ('-N', CONF.firewall.firewall_chain),
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
             '67', '-j', firewall.NEW_CHAIN),
            ('-F', firewall.NEW_CHAIN),
            ('-X', firewall.NEW_CHAIN),
            ('-N', firewall.NEW_CHAIN),
            ('-A', firewall.NEW_CHAIN, '-j', 'ACCEPT'),
            ('-I', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
             '67', '-j', firewall.NEW_CHAIN),
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
             '67', '-j', CONF.firewall.firewall_chain),
            ('-F', CONF.firewall.firewall_chain),
            ('-X', CONF.firewall.firewall_chain),
            ('-E', firewall.NEW_CHAIN, CONF.firewall.firewall_chain)
        ]

        firewall.update_filters()
        call_args_list = mock_iptables.call_args_list

        for (args, call) in zip(update_filters_expected_args,
                                call_args_list):
            self.assertEqual(args, call[0])
    def test_update_filters_args(self, mock_call, mock_get_client,
                                 mock_iptables):
        # Pretend that we have nodes on introspection
        node_cache.add_node(self.node.uuid, state=istate.States.waiting,
                            bmc_address='1.2.3.4')

        firewall.init()

        update_filters_expected_args = [
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
             '67', '-j', CONF.firewall.firewall_chain),
            ('-F', CONF.firewall.firewall_chain),
            ('-X', CONF.firewall.firewall_chain),
            ('-N', CONF.firewall.firewall_chain),
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
             '67', '-j', firewall.NEW_CHAIN),
            ('-F', firewall.NEW_CHAIN),
            ('-X', firewall.NEW_CHAIN),
            ('-N', firewall.NEW_CHAIN),
            ('-A', firewall.NEW_CHAIN, '-j', 'ACCEPT'),
            ('-I', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
             '67', '-j', firewall.NEW_CHAIN),
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
             '67', '-j', CONF.firewall.firewall_chain),
            ('-F', CONF.firewall.firewall_chain),
            ('-X', CONF.firewall.firewall_chain),
            ('-E', firewall.NEW_CHAIN, CONF.firewall.firewall_chain)
        ]

        firewall.update_filters()
        call_args_list = mock_iptables.call_args_list

        for (args, call) in zip(update_filters_expected_args,
                                call_args_list):
            self.assertEqual(args, call[0])
Example #13
0
def _abort(node_info, ironic):
    # runs in background
    if node_info.finished_at is not None:
        # introspection already finished; nothing to do
        LOG.info('Cannot abort introspection as it is already '
                 'finished',
                 node_info=node_info)
        node_info.release_lock()
        return

    # finish the introspection
    LOG.debug('Forcing power-off', node_info=node_info)
    try:
        ironic.node.set_power_state(node_info.uuid, 'off')
    except Exception as exc:
        LOG.warning('Failed to power off node: %s', exc, node_info=node_info)

    node_info.finished(error=_('Canceled by operator'))

    # block this node from PXE Booting the introspection image
    try:
        firewall.update_filters(ironic)
    except Exception as exc:
        # Note(mkovacik): this will be retried in firewall update
        # periodic task; we continue aborting
        LOG.warning('Failed to update firewall filters: %s',
                    exc,
                    node_info=node_info)
    LOG.info('Introspection aborted', node_info=node_info)
Example #14
0
    def test_update_filters_args(self, mock_call, mock_get_client,
                                 mock_iptables):
        firewall.init()

        update_filters_expected_args = [
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport', '67',
             '-j', CONF.firewall.firewall_chain),
            ('-F', CONF.firewall.firewall_chain),
            ('-X', CONF.firewall.firewall_chain),
            ('-N', CONF.firewall.firewall_chain),
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport', '67',
             '-j', firewall.NEW_CHAIN), ('-F', firewall.NEW_CHAIN),
            ('-X', firewall.NEW_CHAIN), ('-N', firewall.NEW_CHAIN),
            ('-A', firewall.NEW_CHAIN, '-j', 'ACCEPT'),
            ('-I', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport', '67',
             '-j', firewall.NEW_CHAIN),
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport', '67',
             '-j', CONF.firewall.firewall_chain),
            ('-F', CONF.firewall.firewall_chain),
            ('-X', CONF.firewall.firewall_chain),
            ('-E', firewall.NEW_CHAIN, CONF.firewall.firewall_chain)
        ]

        firewall.update_filters()
        call_args_list = mock_iptables.call_args_list

        for (args, call) in zip(update_filters_expected_args, call_args_list):
            self.assertEqual(args, call[0])
Example #15
0
def _background_introspect_locked(ironic, node_info):
    # TODO(dtantsur): pagination
    macs = list(node_info.ports())
    if macs:
        node_info.add_attribute(node_cache.MACS_ATTRIBUTE, macs)
        LOG.info(
            _LI('Whitelisting MAC\'s %(macs)s for node %(node)s on the'
                ' firewall') % {
                    'macs': macs,
                    'node': node_info.uuid
                })
        firewall.update_filters(ironic)

    attrs = node_info.attributes
    if CONF.processing.node_not_found_hook is None and not attrs:
        raise utils.Error(
            _('No lookup attributes were found for node %s, inspector won\'t '
              'be able to find it after introspection. Consider creating '
              'ironic ports or providing an IPMI address.') % node_info.uuid)

    LOG.info(
        _LI('The following attributes will be used for looking up '
            'node %(uuid)s: %(attrs)s'), {
                'attrs': attrs,
                'uuid': node_info.uuid
            })

    if not node_info.options.get('new_ipmi_credentials'):
        try:
            ironic.node.set_boot_device(node_info.uuid,
                                        'pxe',
                                        persistent=False)
        except Exception as exc:
            LOG.warning(
                _LW('Failed to set boot device to PXE for'
                    ' node %(node)s: %(exc)s') % {
                        'node': node_info.uuid,
                        'exc': exc
                    })

        try:
            ironic.node.set_power_state(node_info.uuid, 'reboot')
        except Exception as exc:
            raise utils.Error(
                _('Failed to power on node %(node)s,'
                  ' check it\'s power '
                  'management configuration:\n%(exc)s') % {
                      'node': node_info.uuid,
                      'exc': exc
                  })
        LOG.info(_LI('Introspection started successfully for node %s'),
                 node_info.uuid)
    else:
        LOG.info(
            _LI('Introspection environment is ready for node %(node)s, '
                'manual power on is required within %(timeout)d seconds') % {
                    'node': node_info.uuid,
                    'timeout': CONF.timeout
                })
Example #16
0
def periodic_update(period):  # pragma: no cover
    while True:
        LOG.debug('Running periodic update of filters')
        try:
            firewall.update_filters()
        except Exception:
            LOG.exception(_LE('Periodic update failed'))
        eventlet.greenthread.sleep(period)
Example #17
0
def periodic_update(period):  # pragma: no cover
    while True:
        LOG.debug('Running periodic update of filters')
        try:
            firewall.update_filters()
        except Exception:
            LOG.exception(_LE('Periodic update failed'))
        eventlet.greenthread.sleep(period)
Example #18
0
def _background_introspect(ironic, node_info):
    global _LAST_INTROSPECTION_TIME

    # TODO(dtantsur): pagination
    macs = list(node_info.ports())
    if macs:
        node_info.add_attribute(node_cache.MACS_ATTRIBUTE, macs)
        LOG.info(_LI('Whitelisting MAC\'s %(macs)s for node %(node)s on the'
                     ' firewall') %
                 {'macs': macs, 'node': node_info.uuid})
        firewall.update_filters(ironic)

    attrs = node_info.attributes
    if CONF.processing.node_not_found_hook is None and not attrs:
        raise utils.Error(
            _('No lookup attributes were found for node %s, inspector won\'t '
              'be able to find it after introspection. Consider creating '
              'ironic ports or providing an IPMI address.') % node_info.uuid)

    LOG.info(_LI('The following attributes will be used for looking up '
                 'node %(uuid)s: %(attrs)s'),
             {'attrs': attrs, 'uuid': node_info.uuid})

    if not node_info.options.get('new_ipmi_credentials'):
        try:
            ironic.node.set_boot_device(node_info.uuid, 'pxe',
                                        persistent=False)
        except Exception as exc:
            LOG.warning(_LW('Failed to set boot device to PXE for'
                            ' node %(node)s: %(exc)s') %
                        {'node': node_info.uuid, 'exc': exc})

        if re.match(CONF.introspection_delay_drivers, node_info.node().driver):
            LOG.debug('Attempting to acquire lock on last introspection time')
            with _LAST_INTROSPECTION_LOCK:
                delay = (_LAST_INTROSPECTION_TIME - time.time()
                         + CONF.introspection_delay)
                if delay > 0:
                    LOG.debug('Waiting %d seconds before sending the next '
                              'node on introspection', delay)
                    time.sleep(delay)
                _LAST_INTROSPECTION_TIME = time.time()

        try:
            ironic.node.set_power_state(node_info.uuid, 'reboot')
        except Exception as exc:
            raise utils.Error(_('Failed to power on node %(node)s,'
                                ' check it\'s power '
                                'management configuration:\n%(exc)s')
                              % {'node': node_info.uuid, 'exc': exc})
        LOG.info(_LI('Introspection started successfully for node %s'),
                 node_info.uuid)
    else:
        LOG.info(_LI('Introspection environment is ready for node %(node)s, '
                 'manual power on is required within %(timeout)d seconds') %
                 {'node': node_info.uuid,
                  'timeout': CONF.timeout})
Example #19
0
def periodic_clean_up(period):  # pragma: no cover
    while True:
        LOG.debug('Running periodic clean up of node cache')
        try:
            if node_cache.clean_up():
                firewall.update_filters()
            sync_with_ironic()
        except Exception:
            LOG.exception(_LE('Periodic clean up of node cache failed'))
        eventlet.greenthread.sleep(period)
Example #20
0
def periodic_clean_up(period):  # pragma: no cover
    while True:
        LOG.debug('Running periodic clean up of node cache')
        try:
            if node_cache.clean_up():
                firewall.update_filters()
            sync_with_ironic()
        except Exception:
            LOG.exception(_LE('Periodic clean up of node cache failed'))
        eventlet.greenthread.sleep(period)
Example #21
0
    def test_update_filters_infiniband(self, mock_call, mock_get_client,
                                       mock_iptables):

        CONF.set_override('ethoib_interfaces', ['eth0'], 'firewall')
        active_macs = ['11:22:33:44:55:66', '66:55:44:33:22:11']
        expected_rmac = '02:00:00:61:00:02'
        ports = [mock.Mock(address=m) for m in active_macs]
        ports.append(
            mock.Mock(address='7c:fe:90:29:24:4f',
                      extra={'client-id': self.CLIENT_ID},
                      spec=['address', 'extra']))
        mock_get_client.port.list.return_value = ports
        node_cache.add_node(self.node.uuid,
                            mac=active_macs,
                            state=istate.States.finished,
                            bmc_address='1.2.3.4',
                            foo=None)
        firewall.init()

        update_filters_expected_args = [
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport', '67',
             '-j', CONF.firewall.firewall_chain),
            ('-F', CONF.firewall.firewall_chain),
            ('-X', CONF.firewall.firewall_chain),
            ('-N', CONF.firewall.firewall_chain),
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport', '67',
             '-j', firewall.NEW_CHAIN),
            ('-F', firewall.NEW_CHAIN),
            ('-X', firewall.NEW_CHAIN),
            ('-N', firewall.NEW_CHAIN),
            # Blacklist
            ('-A', firewall.NEW_CHAIN, '-m', 'mac', '--mac-source',
             expected_rmac, '-j', 'DROP'),
            ('-A', firewall.NEW_CHAIN, '-j', 'ACCEPT'),
            ('-I', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport', '67',
             '-j', firewall.NEW_CHAIN),
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport', '67',
             '-j', CONF.firewall.firewall_chain),
            ('-F', CONF.firewall.firewall_chain),
            ('-X', CONF.firewall.firewall_chain),
            ('-E', firewall.NEW_CHAIN, CONF.firewall.firewall_chain)
        ]

        fileobj = mock.mock_open(read_data=IB_DATA)
        with mock.patch('six.moves.builtins.open', fileobj, create=True):
            firewall.update_filters(mock_get_client)
        call_args_list = mock_iptables.call_args_list

        for (args, call) in zip(update_filters_expected_args, call_args_list):
            self.assertEqual(args, call[0])
Example #22
0
    def test_update_filters_with_blacklist(self, mock_call, mock_get_client,
                                           mock_iptables):
        active_macs = ['11:22:33:44:55:66', '66:55:44:33:22:11']
        inactive_mac = ['AA:BB:CC:DD:EE:FF']
        self.macs = active_macs + inactive_mac
        self.ports = [mock.Mock(address=m) for m in self.macs]
        mock_get_client.port.list.return_value = self.ports
        node_cache.add_node(self.node.uuid,
                            mac=active_macs,
                            state=istate.States.finished,
                            bmc_address='1.2.3.4',
                            foo=None)
        firewall.init()

        update_filters_expected_args = [
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport', '67',
             '-j', CONF.firewall.firewall_chain),
            ('-F', CONF.firewall.firewall_chain),
            ('-X', CONF.firewall.firewall_chain),
            ('-N', CONF.firewall.firewall_chain),
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport', '67',
             '-j', firewall.NEW_CHAIN),
            ('-F', firewall.NEW_CHAIN),
            ('-X', firewall.NEW_CHAIN),
            ('-N', firewall.NEW_CHAIN),
            # Blacklist
            ('-A', firewall.NEW_CHAIN, '-m', 'mac', '--mac-source',
             inactive_mac[0], '-j', 'DROP'),
            ('-A', firewall.NEW_CHAIN, '-j', 'ACCEPT'),
            ('-I', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport', '67',
             '-j', firewall.NEW_CHAIN),
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport', '67',
             '-j', CONF.firewall.firewall_chain),
            ('-F', CONF.firewall.firewall_chain),
            ('-X', CONF.firewall.firewall_chain),
            ('-E', firewall.NEW_CHAIN, CONF.firewall.firewall_chain)
        ]

        firewall.update_filters(mock_get_client)
        call_args_list = mock_iptables.call_args_list

        for (args, call) in zip(update_filters_expected_args, call_args_list):
            self.assertEqual(args, call[0])

        # check caching

        mock_iptables.reset_mock()
        firewall.update_filters(mock_get_client)
        self.assertFalse(mock_iptables.called)
    def test_update_filters_with_blacklist(self, mock_call, mock_get_client,
                                           mock_iptables):
        active_macs = ['11:22:33:44:55:66', '66:55:44:33:22:11']
        inactive_mac = ['AA:BB:CC:DD:EE:FF']
        self.macs = active_macs + inactive_mac
        self.ports = [mock.Mock(address=m) for m in self.macs]
        mock_get_client.port.list.return_value = self.ports
        node_cache.add_node(self.node.uuid, mac=active_macs,
                            state=istate.States.finished,
                            bmc_address='1.2.3.4', foo=None)
        firewall.init()

        update_filters_expected_args = [
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
             '67', '-j', CONF.firewall.firewall_chain),
            ('-F', CONF.firewall.firewall_chain),
            ('-X', CONF.firewall.firewall_chain),
            ('-N', CONF.firewall.firewall_chain),
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
             '67', '-j', firewall.NEW_CHAIN),
            ('-F', firewall.NEW_CHAIN),
            ('-X', firewall.NEW_CHAIN),
            ('-N', firewall.NEW_CHAIN),
            # Blacklist
            ('-A', firewall.NEW_CHAIN, '-m', 'mac', '--mac-source',
             inactive_mac[0], '-j', 'DROP'),
            ('-A', firewall.NEW_CHAIN, '-j', 'ACCEPT'),
            ('-I', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
             '67', '-j', firewall.NEW_CHAIN),
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
             '67', '-j', CONF.firewall.firewall_chain),
            ('-F', CONF.firewall.firewall_chain),
            ('-X', CONF.firewall.firewall_chain),
            ('-E', firewall.NEW_CHAIN, CONF.firewall.firewall_chain)
        ]

        firewall.update_filters(mock_get_client)
        call_args_list = mock_iptables.call_args_list

        for (args, call) in zip(update_filters_expected_args,
                                call_args_list):
            self.assertEqual(args, call[0])

        # check caching

        mock_iptables.reset_mock()
        firewall.update_filters(mock_get_client)
        self.assertFalse(mock_iptables.called)
Example #24
0
def _process_node(node, introspection_data, node_info):
    # NOTE(dtantsur): repeat the check in case something changed
    utils.check_provision_state(node)

    node_info.create_ports(introspection_data.get('macs') or ())

    _run_post_hooks(node_info, introspection_data)

    if CONF.processing.store_data == 'swift':
        swift_object_name = swift.store_introspection_data(
            introspection_data, node_info.uuid)
        LOG.info(
            _LI('Introspection data for node %(node)s was stored in '
                'Swift in object %(obj)s'), {
                    'node': node_info.uuid,
                    'obj': swift_object_name
                })
        if CONF.processing.store_data_location:
            node_info.patch([{
                'op': 'add',
                'path': '/extra/%s' % CONF.processing.store_data_location,
                'value': swift_object_name
            }])
    else:
        LOG.debug(
            'Swift support is disabled, introspection data for node %s '
            'won\'t be stored', node_info.uuid)

    ironic = utils.get_client()
    firewall.update_filters(ironic)

    node_info.invalidate_cache()
    rules.apply(node_info, introspection_data)

    resp = {'uuid': node.uuid}

    if node_info.options.get('new_ipmi_credentials'):
        new_username, new_password = (
            node_info.options.get('new_ipmi_credentials'))
        utils.spawn_n(_finish_set_ipmi_credentials, ironic, node, node_info,
                      introspection_data, new_username, new_password)
        resp['ipmi_setup_credentials'] = True
        resp['ipmi_username'] = new_username
        resp['ipmi_password'] = new_password
    else:
        utils.spawn_n(_finish, ironic, node_info)

    return resp
Example #25
0
def _process_node(node, introspection_data, node_info):
    # NOTE(dtantsur): repeat the check in case something changed
    ir_utils.check_provision_state(node)

    node_info.create_ports(introspection_data.get('macs') or ())

    _run_post_hooks(node_info, introspection_data)

    if CONF.processing.store_data == 'swift':
        stored_data = {k: v for k, v in introspection_data.items()
                       if k not in _STORAGE_EXCLUDED_KEYS}
        swift_object_name = swift.store_introspection_data(stored_data,
                                                           node_info.uuid)
        LOG.info(_LI('Introspection data was stored in Swift in object %s'),
                 swift_object_name,
                 node_info=node_info, data=introspection_data)
        if CONF.processing.store_data_location:
            node_info.patch([{'op': 'add', 'path': '/extra/%s' %
                              CONF.processing.store_data_location,
                              'value': swift_object_name}])
    else:
        LOG.debug('Swift support is disabled, introspection data '
                  'won\'t be stored',
                  node_info=node_info, data=introspection_data)

    ironic = ir_utils.get_client()
    firewall.update_filters(ironic)

    node_info.invalidate_cache()
    rules.apply(node_info, introspection_data)

    resp = {'uuid': node.uuid}

    if node_info.options.get('new_ipmi_credentials'):
        new_username, new_password = (
            node_info.options.get('new_ipmi_credentials'))
        utils.executor().submit(_finish_set_ipmi_credentials,
                                ironic, node, node_info, introspection_data,
                                new_username, new_password)
        resp['ipmi_setup_credentials'] = True
        resp['ipmi_username'] = new_username
        resp['ipmi_password'] = new_password
    else:
        utils.executor().submit(_finish, ironic, node_info, introspection_data)

    return resp
Example #26
0
def _background_introspect_locked(ironic, node_info):
    # TODO(dtantsur): pagination
    macs = list(node_info.ports())
    if macs:
        node_info.add_attribute(node_cache.MACS_ATTRIBUTE, macs)
        LOG.info(_LI('Whitelisting MAC\'s %s on the firewall'),
                 macs,
                 node_info=node_info)
        firewall.update_filters(ironic)

    attrs = node_info.attributes
    if CONF.processing.node_not_found_hook is None and not attrs:
        raise utils.Error(_(
            'No lookup attributes were found, inspector won\'t '
            'be able to find it after introspection, consider creating '
            'ironic ports or providing an IPMI address'),
                          node_info=node_info)

    LOG.info(_LI('The following attributes will be used for look up: %s'),
             attrs,
             node_info=node_info)

    if not node_info.options.get('new_ipmi_credentials'):
        try:
            ironic.node.set_boot_device(node_info.uuid,
                                        'pxe',
                                        persistent=False)
        except Exception as exc:
            LOG.warning(_LW('Failed to set boot device to PXE: %s'),
                        exc,
                        node_info=node_info)

        try:
            ironic.node.set_power_state(node_info.uuid, 'reboot')
        except Exception as exc:
            raise utils.Error(_('Failed to power on the node, check it\'s '
                                'power management configuration: %s'),
                              exc,
                              node_info=node_info)
        LOG.info(_LI('Introspection started successfully'),
                 node_info=node_info)
    else:
        LOG.info(_LI('Introspection environment is ready, manual power on is '
                     'required within %d seconds'),
                 CONF.timeout,
                 node_info=node_info)
Example #27
0
def _process_node(node, introspection_data, node_info):
    # NOTE(dtantsur): repeat the check in case something changed
    utils.check_provision_state(node)

    node_info.create_ports(introspection_data.get('macs') or ())

    _run_post_hooks(node_info, introspection_data)

    if CONF.processing.store_data == 'swift':
        swift_object_name = swift.store_introspection_data(introspection_data,
                                                           node_info.uuid)
        LOG.info(_LI('Introspection data for node %(node)s was stored in '
                     'Swift in object %(obj)s'),
                 {'node': node_info.uuid, 'obj': swift_object_name})
        if CONF.processing.store_data_location:
            node_info.patch([{'op': 'add', 'path': '/extra/%s' %
                              CONF.processing.store_data_location,
                              'value': swift_object_name}])
    else:
        LOG.debug('Swift support is disabled, introspection data for node %s '
                  'won\'t be stored', node_info.uuid)

    ironic = utils.get_client()
    firewall.update_filters(ironic)

    node_info.invalidate_cache()
    rules.apply(node_info, introspection_data)

    resp = {'uuid': node.uuid}

    if node_info.options.get('new_ipmi_credentials'):
        new_username, new_password = (
            node_info.options.get('new_ipmi_credentials'))
        utils.spawn_n(_finish_set_ipmi_credentials,
                      ironic, node, node_info, introspection_data,
                      new_username, new_password)
        resp['ipmi_setup_credentials'] = True
        resp['ipmi_username'] = new_username
        resp['ipmi_password'] = new_password
    else:
        utils.spawn_n(_finish, ironic, node_info)

    return resp
Example #28
0
def _process_node(node_info, node, introspection_data):
    # NOTE(dtantsur): repeat the check in case something changed
    ir_utils.check_provision_state(node)
    _run_post_hooks(node_info, introspection_data)
    _store_data(node_info, introspection_data)

    ironic = ir_utils.get_client()
    firewall.update_filters(ironic)

    node_info.invalidate_cache()
    rules.apply(node_info, introspection_data)

    resp = {'uuid': node.uuid}

    utils.executor().submit(_finish,
                            node_info,
                            ironic,
                            introspection_data,
                            power_off=CONF.processing.power_off)

    return resp
def _background_introspect_locked(ironic, node_info):
    # TODO(dtantsur): pagination
    macs = list(node_info.ports())
    if macs:
        node_info.add_attribute(node_cache.MACS_ATTRIBUTE, macs)
        LOG.info(_LI('Whitelisting MAC\'s %s on the firewall'), macs,
                 node_info=node_info)
        firewall.update_filters(ironic)

    attrs = node_info.attributes
    if CONF.processing.node_not_found_hook is None and not attrs:
        raise utils.Error(
            _('No lookup attributes were found, inspector won\'t '
              'be able to find it after introspection, consider creating '
              'ironic ports or providing an IPMI address'),
            node_info=node_info)

    LOG.info(_LI('The following attributes will be used for look up: %s'),
             attrs, node_info=node_info)

    if not node_info.options.get('new_ipmi_credentials'):
        try:
            ironic.node.set_boot_device(node_info.uuid, 'pxe',
                                        persistent=False)
        except Exception as exc:
            LOG.warning(_LW('Failed to set boot device to PXE: %s'),
                        exc, node_info=node_info)

        try:
            ironic.node.set_power_state(node_info.uuid, 'reboot')
        except Exception as exc:
            raise utils.Error(_('Failed to power on the node, check it\'s '
                                'power management configuration: %s'),
                              exc, node_info=node_info)
        LOG.info(_LI('Introspection started successfully'),
                 node_info=node_info)
    else:
        LOG.info(_LI('Introspection environment is ready, manual power on is '
                     'required within %d seconds'), CONF.timeout,
                 node_info=node_info)
    def test_update_filters_args_no_introspection(self, mock_call,
                                                  mock_get_client,
                                                  mock_iptables):
        firewall.init()
        firewall.BLACKLIST_CACHE = ['foo']
        mock_get_client.return_value.port.list.return_value = [
            mock.Mock(address='foobar')]

        update_filters_expected_args = [
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
             '67', '-j', CONF.firewall.firewall_chain),
            ('-F', CONF.firewall.firewall_chain),
            ('-X', CONF.firewall.firewall_chain),
            ('-N', CONF.firewall.firewall_chain),
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
             '67', '-j', firewall.NEW_CHAIN),
            ('-F', firewall.NEW_CHAIN),
            ('-X', firewall.NEW_CHAIN),
            ('-N', firewall.NEW_CHAIN),
            ('-A', firewall.NEW_CHAIN, '-j', 'REJECT'),
            ('-I', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
             '67', '-j', firewall.NEW_CHAIN),
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
             '67', '-j', CONF.firewall.firewall_chain),
            ('-F', CONF.firewall.firewall_chain),
            ('-X', CONF.firewall.firewall_chain),
            ('-E', firewall.NEW_CHAIN, CONF.firewall.firewall_chain)
        ]

        firewall.update_filters()
        call_args_list = mock_iptables.call_args_list

        for (args, call) in zip(update_filters_expected_args,
                                call_args_list):
            self.assertEqual(args, call[0])

        self.assertIsNone(firewall.BLACKLIST_CACHE)

        # Check caching enabled flag

        mock_iptables.reset_mock()
        firewall.update_filters()
        self.assertFalse(mock_iptables.called)

        # Adding a node changes it back

        node_cache.add_node(self.node.uuid, state=istate.States.starting,
                            bmc_address='1.2.3.4')
        mock_iptables.reset_mock()
        firewall.update_filters()

        mock_iptables.assert_any_call('-A', firewall.NEW_CHAIN, '-j', 'ACCEPT')
        self.assertEqual({'foobar'}, firewall.BLACKLIST_CACHE)
Example #31
0
    def test_update_filters_args_no_introspection(self, mock_call,
                                                  mock_get_client,
                                                  mock_iptables):
        firewall.init()
        firewall.BLACKLIST_CACHE = ['foo']
        mock_get_client.return_value.port.list.return_value = [
            mock.Mock(address='foobar')
        ]

        update_filters_expected_args = [
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport', '67',
             '-j', CONF.firewall.firewall_chain),
            ('-F', CONF.firewall.firewall_chain),
            ('-X', CONF.firewall.firewall_chain),
            ('-N', CONF.firewall.firewall_chain),
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport', '67',
             '-j', firewall.NEW_CHAIN), ('-F', firewall.NEW_CHAIN),
            ('-X', firewall.NEW_CHAIN), ('-N', firewall.NEW_CHAIN),
            ('-A', firewall.NEW_CHAIN, '-j', 'REJECT'),
            ('-I', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport', '67',
             '-j', firewall.NEW_CHAIN),
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport', '67',
             '-j', CONF.firewall.firewall_chain),
            ('-F', CONF.firewall.firewall_chain),
            ('-X', CONF.firewall.firewall_chain),
            ('-E', firewall.NEW_CHAIN, CONF.firewall.firewall_chain)
        ]

        firewall.update_filters()
        call_args_list = mock_iptables.call_args_list

        for (args, call) in zip(update_filters_expected_args, call_args_list):
            self.assertEqual(args, call[0])

        self.assertIsNone(firewall.BLACKLIST_CACHE)

        # Check caching enabled flag

        mock_iptables.reset_mock()
        firewall.update_filters()
        self.assertFalse(mock_iptables.called)

        # Adding a node changes it back

        node_cache.add_node(self.node.uuid,
                            state=istate.States.starting,
                            bmc_address='1.2.3.4')
        mock_iptables.reset_mock()
        firewall.update_filters()

        mock_iptables.assert_any_call('-A', firewall.NEW_CHAIN, '-j', 'ACCEPT')
        self.assertEqual({'foobar'}, firewall.BLACKLIST_CACHE)
Example #32
0
    def test_update_filters_args_no_introspection(self, mock_call,
                                                  mock_get_client,
                                                  mock_iptables):
        firewall.init()

        update_filters_expected_args = [
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport', '67',
             '-j', CONF.firewall.firewall_chain),
            ('-F', CONF.firewall.firewall_chain),
            ('-X', CONF.firewall.firewall_chain),
            ('-N', CONF.firewall.firewall_chain),
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport', '67',
             '-j', firewall.NEW_CHAIN), ('-F', firewall.NEW_CHAIN),
            ('-X', firewall.NEW_CHAIN), ('-N', firewall.NEW_CHAIN),
            ('-A', firewall.NEW_CHAIN, '-j', 'REJECT'),
            ('-I', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport', '67',
             '-j', firewall.NEW_CHAIN),
            ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport', '67',
             '-j', CONF.firewall.firewall_chain),
            ('-F', CONF.firewall.firewall_chain),
            ('-X', CONF.firewall.firewall_chain),
            ('-E', firewall.NEW_CHAIN, CONF.firewall.firewall_chain)
        ]

        firewall.update_filters()
        call_args_list = mock_iptables.call_args_list

        for (args, call) in zip(update_filters_expected_args, call_args_list):
            self.assertEqual(args, call[0])

        # Check caching enabled flag

        mock_iptables.reset_mock()
        firewall.update_filters()
        self.assertFalse(mock_iptables.called)

        # Adding a node changes it back

        node_cache.add_node(self.node.uuid, bmc_address='1.2.3.4')
        mock_iptables.reset_mock()
        firewall.update_filters()

        mock_iptables.assert_any_call('-A', firewall.NEW_CHAIN, '-j', 'ACCEPT')
Example #33
0
 def test_update_filters_without_manage_firewall(self, mock_call,
                                                 mock_get_client,
                                                 mock_iptables):
     CONF.set_override('manage_firewall', False, 'firewall')
     firewall.update_filters()
     self.assertEqual(0, mock_iptables.call_count)
 def test_update_filters_without_manage_firewall(self, mock_call,
                                                 mock_get_client,
                                                 mock_iptables):
     CONF.set_override('manage_firewall', False, 'firewall')
     firewall.update_filters()
     self.assertEqual(0, mock_iptables.call_count)
def periodic_update():  # pragma: no cover
    try:
        firewall.update_filters()
    except Exception:
        LOG.exception('Periodic update of firewall rules failed')
Example #36
0
def periodic_update():  # pragma: no cover
    try:
        firewall.update_filters()
    except Exception:
        LOG.exception(_LE('Periodic update of firewall rules failed'))