Example #1
0
 def test_inspector_retries(self, mock_post):
     mock_post.side_effect = requests.exceptions.ConnectionError
     failures = utils.AccumulatedFailures()
     data = collections.OrderedDict(data=42)
     self.assertRaises(requests.exceptions.ConnectionError,
                       inspector.call_inspector, data, failures)
     self.assertEqual(5, mock_post.call_count)
def inspect():
    """Optionally run inspection on the current node.

    If ``inspection_callback_url`` is set in the configuration, get
    the hardware inventory from the node and post it back to the inspector.

    :return: node UUID if inspection was successful, None if associated node
             was not found in inspector cache. None is also returned if
             inspector support is not enabled.
    """
    if not CONF.inspection_callback_url:
        LOG.info('Inspection is disabled, skipping')
        return

    if CONF.inspection_callback_url == 'mdns':
        LOG.debug('Fetching the inspection URL from mDNS')
        url, params = mdns.get_endpoint('baremetal-introspection')
        # We expect a proper catalog URL, which doesn't include any path.
        CONF.set_override('inspection_callback_url',
                          url.rstrip('/') + '/v1/continue')
        config.override(params)

    collector_names = [
        x.strip() for x in CONF.inspection_collectors.split(',') if x.strip()
    ]
    LOG.info('inspection is enabled with collectors %s', collector_names)

    # NOTE(dtantsur): inspection process tries to delay raising any exceptions
    # until after we posted some data back to inspector. This is because
    # inspection is run automatically on (mostly) unknown nodes, so if it
    # fails, we don't have much information for debugging.
    failures = utils.AccumulatedFailures(exc_class=errors.InspectionError)
    data = {}

    try:
        ext_mgr = extension_manager(collector_names)
        collectors = [(ext.name, ext.plugin) for ext in ext_mgr]
    except Exception as exc:
        with excutils.save_and_reraise_exception():
            failures.add(exc)
            call_inspector(data, failures)

    for name, collector in collectors:
        try:
            collector(data, failures)
        except Exception as exc:
            # No reraise here, try to keep going
            failures.add('collector %s failed: %s', name, exc)

    resp = call_inspector(data, failures)

    # Now raise everything we were delaying
    failures.raise_if_needed()

    if resp is None:
        raise errors.InspectionError('stopping inspection, as inspector '
                                     'returned an error')

    LOG.info('inspection finished successfully')
    return resp.get('uuid')
Example #3
0
 def setUp(self):
     super(BaseDiscoverTest, self).setUp()
     self.inventory = {
         'interfaces': [
             hardware.NetworkInterface(name='em1',
                                       mac_addr='aa:bb:cc:dd:ee:ff',
                                       ipv4_address='1.1.1.1'),
             hardware.NetworkInterface(name='em2',
                                       mac_addr='11:22:33:44:55:66',
                                       ipv4_address=None),
         ],
         'cpu': hardware.CPU(model_name='generic', frequency='3000',
                             count=4, architecture='x86_64'),
         'memory': hardware.Memory(total=11998396 * 1024,
                                   physical_mb=12288),
         'disks': [
             hardware.BlockDevice(name='/dev/sdc',
                                  model='Disk 2',
                                  size=500107862016,
                                  rotational=False),
             hardware.BlockDevice(name='/dev/sda',
                                  model='Too Small Disk',
                                  size=4294967295,
                                  rotational=False),
             hardware.BlockDevice(name='/dev/sdb',
                                  model='Disk 1',
                                  size=500107862016,
                                  rotational=True)
         ],
         'bmc_address': '1.2.3.4',
         'boot': hardware.BootInfo(current_boot_mode='bios',
                                   pxe_interface='boot:if')
     }
     self.failures = utils.AccumulatedFailures()
     self.data = {}
Example #4
0
    def test_set_new_bmc_address_retry_failed(self, mock_manager, mock_get,
                                              mock_post, mock_exec):
        mock_manager.side_effect = [
            mock.Mock(product_name='fake_prouect',
                      serial_number="fake_sn",
                      manufacturer="fake_manufacturer"), "0.0.0.0",
            mock.Mock(product_name='fake_prouect',
                      serial_number="fake_sn",
                      manufacturer="fake_manufacturer"), "0.0.0.0",
            mock.Mock(product_name='fake_prouect',
                      serial_number="fake_sn",
                      manufacturer="fake_manufacturer"), "0.0.0.0",
            mock.Mock(product_name='fake_prouect',
                      serial_number="fake_sn",
                      manufacturer="fake_manufacturer"), "0.0.0.0"
        ]

        failures = utils.AccumulatedFailures(exc_class=errors.InspectionError)
        mock_json = mock.Mock()
        mock_json.json = mock.Mock(
            return_value={
                "ip_address": "192.168.2.20",
                "netmask": "255.255.255.0",
                "gateway": "192.168.2.254"
            })
        mock_get.side_effect = Exception()
        ipmi_setter.set_bm_ipmi(self.data, failures, retry=3)
        mock_get.assert_has_calls([
            mock.call('1.1.1.1/v1/bmc/fake_sn'),
            mock.call('1.1.1.1/v1/bmc/fake_sn'),
            mock.call('1.1.1.1/v1/bmc/fake_sn'),
            mock.call('1.1.1.1/v1/bmc/fake_sn')
        ])
        self.assertRaises(errors.InspectionError, failures.raise_if_needed)
    def test_raise(self):
        class FakeException(Exception):
            pass

        f = utils.AccumulatedFailures(exc_class=FakeException)
        self.assertIsNone(f.raise_if_needed())
        f.add('foo')
        self.assertRaisesRegexp(FakeException, 'foo', f.raise_if_needed)
    def test_inspector_error(self, mock_post):
        failures = utils.AccumulatedFailures()
        data = collections.OrderedDict(data=42)
        mock_post.return_value.status_code = 400

        res = inspector.call_inspector(data, failures)

        mock_post.assert_called_once_with('url',
                                          data='{"data": 42, "error": null}')
        self.assertIsNone(res)
Example #7
0
def inspect():
    """Optionally run inspection on the current node.

    If ``inspection_callback_url`` is set in the configuration, get
    the hardware inventory from the node and post it back to the inspector.

    :return: node UUID if inspection was successful, None if associated node
             was not found in inspector cache. None is also returned if
             inspector support is not enabled.
    """
    if not CONF.inspection_callback_url:
        LOG.info('Inspection is disabled, skipping')
        return
    collector_names = [
        x.strip() for x in CONF.inspection_collectors.split(',') if x.strip()
    ]
    LOG.info('inspection is enabled with collectors %s', collector_names)

    # NOTE(dtantsur): inspection process tries to delay raising any exceptions
    # until after we posted some data back to inspector. This is because
    # inspection is run automatically on (mostly) unknown nodes, so if it
    # fails, we don't have much information for debugging.
    failures = utils.AccumulatedFailures(exc_class=errors.InspectionError)
    data = {}

    try:
        ext_mgr = extension_manager(collector_names)
        collectors = [(ext.name, ext.plugin) for ext in ext_mgr]
    except Exception as exc:
        with excutils.save_and_reraise_exception():
            failures.add(exc)
            call_inspector(data, failures)

    for name, collector in collectors:
        try:
            collector(data, failures)
        except Exception as exc:
            # No reraise here, try to keep going
            failures.add('collector %s failed: %s', name, exc)

    resp = call_inspector(data, failures)

    # Now raise everything we were delaying
    failures.raise_if_needed()

    if resp is None:
        LOG.info('stopping inspection, as inspector returned an error')
        return

    # Optionally update IPMI credentials
    setup_ipmi_credentials(resp)

    LOG.info('inspection finished successfully')
    return resp.get('uuid')
Example #8
0
    def test_ok(self, mock_post):
        failures = utils.AccumulatedFailures()
        data = collections.OrderedDict(data=42)
        mock_post.return_value.status_code = 200

        res = inspector.call_inspector(data, failures)

        mock_post.assert_called_once_with('url',
                                          cert=None, verify=True,
                                          data='{"data": 42, "error": null}')
        self.assertEqual(mock_post.return_value.json.return_value, res)
    def test_get_error(self):
        f = utils.AccumulatedFailures()
        self.assertFalse(f)
        self.assertIsNone(f.get_error())

        f.add('foo')
        f.add('%s', 'bar')
        f.add(RuntimeError('baz'))
        self.assertTrue(f)

        exp = ('The following errors were encountered:\n* foo\n* bar\n* baz')
        self.assertEqual(exp, f.get_error())
Example #10
0
 def setUp(self):
     super(TestCollectPciDevicesInfo, self).setUp()
     self.data = {}
     self.failures = utils.AccumulatedFailures()
Example #11
0
 def setUp(self):
     super(TestCollectExtraHardware, self).setUp()
     self.data = {}
     self.failures = utils.AccumulatedFailures()
 def setUp(self):
     super(TestCollectNumaTopologyInfo, self).setUp()
     self.data = {}
     self.failures = utils.AccumulatedFailures()
Example #13
0
 def setUp(self):
     super(TestCollectDmidecodeInfo, self).setUp()
     self.data = {}
     self.failures = utils.AccumulatedFailures()
Example #14
0
 def setUp(self):
     super(TestIpmiSetter, self).setUp()
     self.data = {}
     self.failures = utils.AccumulatedFailures()
     self.set_defaults(inspection_callback_url="1.1.1.1")