def test_additional_fields(self): node = mock.Mock(spec=["driver_info", "uuid"], driver_info={"foo": "192.168.1.1"}) self.assertIsNone(utils.get_ipmi_address(node)) CONF.set_override("ipmi_address_fields", ["foo", "bar", "baz"]) ip = utils.get_ipmi_address(node) self.assertEqual(ip, "192.168.1.1")
def test_additional_fields(self): node = mock.Mock(spec=['driver_info', 'uuid'], driver_info={'foo': '192.168.1.1'}) self.assertIsNone(utils.get_ipmi_address(node)) CONF.set_override('ipmi_address_fields', ['foo', 'bar', 'baz']) ip = utils.get_ipmi_address(node) self.assertEqual(ip, '192.168.1.1')
def test_ipmi_bridging_enabled(self): node = mock.Mock(spec=['driver_info', 'uuid'], driver_info={ 'ipmi_address': 'www.example.com', 'ipmi_bridging': 'single' }) self.assertIsNone(utils.get_ipmi_address(node))
def test_good_hostname_resolves(self, mock_socket): node = mock.Mock(spec=['driver_info', 'uuid'], driver_info={'ipmi_address': 'www.example.com'}) mock_socket.return_value = '192.168.1.1' ip = utils.get_ipmi_address(node) mock_socket.assert_called_once_with('www.example.com') self.assertEqual(ip, '192.168.1.1')
def _finish_set_ipmi_credentials(ironic, node, node_info, introspection_data, new_username, new_password): patch = [{'op': 'add', 'path': '/driver_info/ipmi_username', 'value': new_username}, {'op': 'add', 'path': '/driver_info/ipmi_password', 'value': new_password}] if (not utils.get_ipmi_address(node) and introspection_data.get('ipmi_address')): patch.append({'op': 'add', 'path': '/driver_info/ipmi_address', 'value': introspection_data['ipmi_address']}) node_info.patch(patch) for attempt in range(_CREDENTIALS_WAIT_RETRIES): try: # We use this call because it requires valid credentials. # We don't care about boot device, obviously. ironic.node.get_boot_device(node_info.uuid) except Exception as exc: LOG.info(_LI('Waiting for credentials update on node %(node)s,' ' attempt %(attempt)d current error is %(exc)s') % {'node': node_info.uuid, 'attempt': attempt, 'exc': exc}) eventlet.greenthread.sleep(_CREDENTIALS_WAIT_PERIOD) else: _finish(ironic, node_info) return msg = (_('Failed to validate updated IPMI credentials for node ' '%s, node might require maintenance') % node_info.uuid) node_info.finished(error=msg) raise utils.Error(msg)
def introspect(uuid, new_ipmi_credentials=None, token=None): """Initiate hardware properties introspection for a given node. :param uuid: node uuid :param new_ipmi_credentials: tuple (new username, new password) or None :param token: authentication token :raises: Error """ ironic = utils.get_client(token) try: node = ironic.node.get(uuid) except exceptions.NotFound: raise utils.Error(_("Cannot find node %s") % uuid, code=404) except exceptions.HttpError as exc: raise utils.Error( _("Cannot get node %(node)s: %(exc)s") % { 'node': uuid, 'exc': exc }) utils.check_provision_state(node, with_credentials=new_ipmi_credentials) if new_ipmi_credentials: new_ipmi_credentials = (_validate_ipmi_credentials( node, new_ipmi_credentials)) else: validation = ironic.node.validate(node.uuid) if not validation.power['result']: msg = _('Failed validation of power interface for node %(node)s, ' 'reason: %(reason)s') raise utils.Error(msg % { 'node': node.uuid, 'reason': validation.power['reason'] }) node_info = node_cache.add_node(node.uuid, bmc_address=utils.get_ipmi_address(node), ironic=ironic) node_info.set_option('new_ipmi_credentials', new_ipmi_credentials) def _handle_exceptions(): try: _background_introspect(ironic, node_info) except utils.Error as exc: node_info.finished(error=str(exc)) except Exception as exc: msg = _('Unexpected exception in background introspection thread') LOG.exception(msg) node_info.finished(error=msg) utils.spawn_n(_handle_exceptions)
def introspect(uuid, new_ipmi_credentials=None, token=None): """Initiate hardware properties introspection for a given node. :param uuid: node uuid :param new_ipmi_credentials: tuple (new username, new password) or None :param token: authentication token :raises: Error """ ironic = utils.get_client(token) try: node = ironic.node.get(uuid) except exceptions.NotFound: raise utils.Error(_("Cannot find node %s") % uuid, code=404) except exceptions.HttpError as exc: raise utils.Error(_("Cannot get node %(node)s: %(exc)s") % {'node': uuid, 'exc': exc}) utils.check_provision_state(node, with_credentials=new_ipmi_credentials) if new_ipmi_credentials: new_ipmi_credentials = ( _validate_ipmi_credentials(node, new_ipmi_credentials)) else: validation = ironic.node.validate(node.uuid) if not validation.power['result']: msg = _('Failed validation of power interface for node %(node)s, ' 'reason: %(reason)s') raise utils.Error(msg % {'node': node.uuid, 'reason': validation.power['reason']}) node_info = node_cache.add_node(node.uuid, bmc_address=utils.get_ipmi_address(node), ironic=ironic) node_info.set_option('new_ipmi_credentials', new_ipmi_credentials) def _handle_exceptions(): try: _background_introspect(ironic, node_info) except utils.Error as exc: node_info.finished(error=str(exc)) except Exception as exc: msg = _('Unexpected exception in background introspection thread') LOG.exception(msg) node_info.finished(error=msg) utils.spawn_n(_handle_exceptions)
def _finish_set_ipmi_credentials(ironic, node, node_info, introspection_data, new_username, new_password): patch = [{ 'op': 'add', 'path': '/driver_info/ipmi_username', 'value': new_username }, { 'op': 'add', 'path': '/driver_info/ipmi_password', 'value': new_password }] if (not utils.get_ipmi_address(node) and introspection_data.get('ipmi_address')): patch.append({ 'op': 'add', 'path': '/driver_info/ipmi_address', 'value': introspection_data['ipmi_address'] }) node_info.patch(patch) for attempt in range(_CREDENTIALS_WAIT_RETRIES): try: # We use this call because it requires valid credentials. # We don't care about boot device, obviously. ironic.node.get_boot_device(node_info.uuid) except Exception as exc: LOG.info( _LI('Waiting for credentials update on node %(node)s,' ' attempt %(attempt)d current error is %(exc)s') % { 'node': node_info.uuid, 'attempt': attempt, 'exc': exc }) eventlet.greenthread.sleep(_CREDENTIALS_WAIT_PERIOD) else: _finish(ironic, node_info) return msg = (_('Failed to validate updated IPMI credentials for node ' '%s, node might require maintenance') % node_info.uuid) node_info.finished(error=msg) raise utils.Error(msg)
def test_ipv4_in_resolves(self): node = mock.Mock(spec=['driver_info', 'uuid'], driver_info={'ipmi_address': '192.168.1.1'}) ip = utils.get_ipmi_address(node) self.assertEqual(ip, '192.168.1.1')
def test_ipmi_bridging_enabled(self): node = mock.Mock( spec=["driver_info", "uuid"], driver_info={"ipmi_address": "www.example.com", "ipmi_bridging": "single"} ) self.assertIsNone(utils.get_ipmi_address(node))
def test_good_hostname_resolves(self, mock_socket): node = mock.Mock(spec=["driver_info", "uuid"], driver_info={"ipmi_address": "www.example.com"}) mock_socket.return_value = "192.168.1.1" ip = utils.get_ipmi_address(node) mock_socket.assert_called_once_with("www.example.com") self.assertEqual(ip, "192.168.1.1")
def test_ipv4_in_resolves(self): node = mock.Mock(spec=["driver_info", "uuid"], driver_info={"ipmi_address": "192.168.1.1"}) ip = utils.get_ipmi_address(node) self.assertEqual(ip, "192.168.1.1")
def test_ipmi_bridging_enabled(self): node = mock.Mock(spec=['driver_info', 'uuid'], driver_info={'ipmi_address': 'www.example.com', 'ipmi_bridging': 'single'}) self.assertIsNone(utils.get_ipmi_address(node))