Exemple #1
0
    def test_additional_fields(self):
        node = mock.Mock(spec=['driver_info', 'uuid'],
                         driver_info={'foo': self.ipmi_ipv4})
        self.assertEqual((None, None, None), ir_utils.get_ipmi_address(node))

        self.cfg.config(ipmi_address_fields=['foo', 'bar', 'baz'])
        self.assertEqual((self.ipmi_ipv4, self.ipmi_ipv4, None),
                         ir_utils.get_ipmi_address(node))
    def test_additional_fields(self):
        node = mock.Mock(spec=['driver_info', 'uuid'],
                         driver_info={'foo': '192.168.1.1'})
        self.assertIsNone(ir_utils.get_ipmi_address(node))

        CONF.set_override('ipmi_address_fields', ['foo', 'bar', 'baz'])
        ip = ir_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(ir_utils.get_ipmi_address(node))

        self.cfg.config(ipmi_address_fields=['foo', 'bar', 'baz'])
        ip = ir_utils.get_ipmi_address(node)
        self.assertEqual('192.168.1.1', ip)
    def test_additional_fields(self):
        node = mock.Mock(spec=['driver_info', 'uuid'],
                         driver_info={'foo': '192.168.1.1'})
        self.assertIsNone(ir_utils.get_ipmi_address(node))

        CONF.set_override('ipmi_address_fields', ['foo', 'bar', 'baz'])
        ip = ir_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(ir_utils.get_ipmi_address(node))

        self.cfg.config(ipmi_address_fields=['foo', 'bar', 'baz'])
        ip = ir_utils.get_ipmi_address(node)
        self.assertEqual('192.168.1.1', ip)
    def test_additional_fields(self):
        node = mock.Mock(spec=['driver_info', 'uuid'],
                         driver_info={'foo': self.ipmi_ipv4})
        self.assertEqual((None, None, None),
                         ir_utils.get_ipmi_address(node))

        self.cfg.config(ipmi_address_fields=['foo', 'bar', 'baz'])
        self.assertEqual((self.ipmi_ipv4, self.ipmi_ipv4, None),
                         ir_utils.get_ipmi_address(node))
def _check_existing_nodes(introspection_data, node_driver_info, ironic):
    macs = utils.get_valid_macs(introspection_data)
    if macs:
        # verify existing ports
        for mac in macs:
            ports = ironic.port.list(address=mac)
            if not ports:
                continue
            raise utils.Error(
                _('Port %(mac)s already exists, uuid: %(uuid)s') %
                {'mac': mac, 'uuid': ports[0].uuid}, data=introspection_data)
    else:
        LOG.warning('No suitable interfaces found for discovered node. '
                    'Check that validate_interfaces hook is listed in '
                    '[processing]default_processing_hooks config option')

    # verify existing node with discovered ipmi address
    ipmi_address = node_driver_info.get('ipmi_address')
    if ipmi_address:
        # FIXME(aarefiev): it's not effective to fetch all nodes, and may
        #                  impact on performance on big clusters
        nodes = ironic.node.list(fields=('uuid', 'driver_info'), limit=0)
        for node in nodes:
            bmc_address, bmc_ipv4, bmc_ipv6 = ir_utils.get_ipmi_address(node)
            if ipmi_address in (bmc_ipv4, bmc_ipv6):
                raise utils.Error(
                    _('Node %(uuid)s already has BMC address '
                      '%(ipmi_address)s, not enrolling') %
                    {'ipmi_address': ipmi_address, 'uuid': node.uuid},
                    data=introspection_data)
Exemple #8
0
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 ir_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, attempt %(attempt)d '
                         'current error is %(exc)s') %
                     {'attempt': attempt, 'exc': exc},
                     node_info=node_info, data=introspection_data)
            eventlet.greenthread.sleep(_CREDENTIALS_WAIT_PERIOD)
        else:
            _finish(ironic, node_info, introspection_data)
            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, node_info=node_info, data=introspection_data)
 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 = ir_utils.get_ipmi_address(node)
     mock_socket.assert_called_once_with('www.example.com')
     self.assertEqual(ip, '192.168.1.1')
def introspect(node_id, manage_boot=True, token=None):
    """Initiate hardware properties introspection for a given node.

    :param node_id: node UUID or name
    :param manage_boot: whether to manage boot for this node
    :param token: authentication token
    :raises: Error
    """
    ironic = ir_utils.get_client(token)
    node = ir_utils.get_node(node_id, ironic=ironic)

    ir_utils.check_provision_state(node)
    if manage_boot:
        validation = ironic.node.validate(node.uuid)
        if not validation.power['result']:
            msg = _('Failed validation of power interface, reason: %s')
            raise utils.Error(msg % validation.power['reason'],
                              node_info=node)

    bmc_address, bmc_ipv4, bmc_ipv6 = ir_utils.get_ipmi_address(node)
    lookup_attrs = list(filter(None, [bmc_ipv4, bmc_ipv6]))
    node_info = node_cache.start_introspection(node.uuid,
                                               bmc_address=lookup_attrs,
                                               manage_boot=manage_boot,
                                               ironic=ironic)

    utils.executor().submit(_background_introspect, node_info, ironic)
Exemple #11
0
def _finish_set_ipmi_credentials(node_info, ironic, node, 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}]
    new_ipmi_address = utils.get_ipmi_address_from_data(introspection_data)
    if not ir_utils.get_ipmi_address(node) and new_ipmi_address:
        patch.append({'op': 'add', 'path': '/driver_info/ipmi_address',
                      'value': new_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, attempt %(attempt)d '
                         'current error is %(exc)s'),
                     {'attempt': attempt, 'exc': exc},
                     node_info=node_info, data=introspection_data)
            eventlet.greenthread.sleep(_CREDENTIALS_WAIT_PERIOD)
        else:
            _finish_common(node_info, ironic, introspection_data)
            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, node_info=node_info, data=introspection_data)
Exemple #12
0
def introspect(node_id, manage_boot=True, token=None):
    """Initiate hardware properties introspection for a given node.

    :param node_id: node UUID or name
    :param manage_boot: whether to manage boot for this node
    :param token: authentication token
    :raises: Error
    """
    ironic = ir_utils.get_client(token)
    node = ir_utils.get_node(node_id, ironic=ironic)

    ir_utils.check_provision_state(node)
    if manage_boot:
        validation = ironic.node.validate(node.uuid)
        if not validation.power['result']:
            msg = _('Failed validation of power interface, reason: %s')
            raise utils.Error(msg % validation.power['reason'], node_info=node)

    bmc_address = ir_utils.get_ipmi_address(node)
    node_info = node_cache.start_introspection(node.uuid,
                                               bmc_address=bmc_address,
                                               manage_boot=manage_boot,
                                               ironic=ironic)

    utils.executor().submit(_background_introspect, node_info, ironic)
Exemple #13
0
def introspect(node_id, manage_boot=True, token=None):
    """Initiate hardware properties introspection for a given node.

    :param node_id: node UUID or name
    :param manage_boot: whether to manage boot for this node
    :param token: authentication token
    :raises: Error
    """
    ironic = ir_utils.get_client(token)
    node = ir_utils.get_node(node_id, ironic=ironic)

    ir_utils.check_provision_state(node)
    if manage_boot:
        try:
            ironic.validate_node(node.id, required='power')
        except os_exc.ValidationException as exc:
            msg = _('Failed validation of power interface: %s')
            raise utils.Error(msg % exc, node_info=node)

    bmc_address, bmc_ipv4, bmc_ipv6 = ir_utils.get_ipmi_address(node)
    lookup_attrs = list(filter(None, [bmc_ipv4, bmc_ipv6]))
    node_info = node_cache.start_introspection(node.id,
                                               bmc_address=lookup_attrs,
                                               manage_boot=manage_boot,
                                               ironic=ironic)

    if manage_boot:
        try:
            utils.executor().submit(_do_introspect, node_info, ironic)
        except Exception as exc:
            msg = _('Failed to submit introspection job: %s')
            raise utils.Error(msg % exc, node_info=node)
    else:
        _do_introspect(node_info, ironic)
Exemple #14
0
def introspect(node_id, token=None):
    """Initiate hardware properties introspection for a given node.

    :param node_id: node UUID or name
    :param token: authentication token
    :raises: Error
    """
    ironic = ir_utils.get_client(token)
    node = ir_utils.get_node(node_id, ironic=ironic)

    ir_utils.check_provision_state(node)
    validation = ironic.node.validate(node.uuid)
    if not validation.power['result']:
        msg = _('Failed validation of power interface, reason: %s')
        raise utils.Error(msg % validation.power['reason'], node_info=node)

    bmc_address = ir_utils.get_ipmi_address(node)
    node_info = node_cache.start_introspection(node.uuid,
                                               bmc_address=bmc_address,
                                               ironic=ironic)

    def _handle_exceptions(fut):
        try:
            fut.result()
        except utils.Error as exc:
            # Logging has already happened in Error.__init__
            node_info.finished(error=str(exc))
        except Exception as exc:
            msg = _('Unexpected exception in background introspection thread')
            LOG.exception(msg, node_info=node_info)
            node_info.finished(error=msg)

    future = utils.executor().submit(_background_introspect, ironic, node_info)
    future.add_done_callback(_handle_exceptions)
Exemple #15
0
def _check_existing_nodes(introspection_data, node_driver_info, ironic):
    macs = utils.get_valid_macs(introspection_data)
    if macs:
        # verify existing ports
        for mac in macs:
            ports = ironic.port.list(address=mac)
            if not ports:
                continue
            raise utils.Error(
                _('Port %(mac)s already exists, uuid: %(uuid)s') % {
                    'mac': mac,
                    'uuid': ports[0].uuid
                },
                data=introspection_data)
    else:
        LOG.warning('No suitable interfaces found for discovered node. '
                    'Check that validate_interfaces hook is listed in '
                    '[processing]default_processing_hooks config option')

    # verify existing node with discovered ipmi address
    ipmi_address = node_driver_info.get('ipmi_address')
    if ipmi_address:
        # FIXME(aarefiev): it's not effective to fetch all nodes, and may
        #                  impact on performance on big clusters
        nodes = ironic.node.list(fields=('uuid', 'driver_info'), limit=0)
        for node in nodes:
            bmc_address, bmc_ipv4, bmc_ipv6 = ir_utils.get_ipmi_address(node)
            if ipmi_address in (bmc_ipv4, bmc_ipv6):
                raise utils.Error(_('Node %(uuid)s already has BMC address '
                                    '%(ipmi_address)s, not enrolling') % {
                                        'ipmi_address': ipmi_address,
                                        'uuid': node.uuid
                                    },
                                  data=introspection_data)
 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(ir_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 = ir_utils.get_ipmi_address(node)
     mock_socket.assert_called_once_with('www.example.com')
     self.assertEqual(ip, '192.168.1.1')
 def test_good_hostname_resolves(self, mock_socket):
     node = mock.Mock(spec=['driver_info', 'uuid'],
                      driver_info={'ipmi_address': self.ipmi_address})
     mock_socket.return_value = [
         (socket.AF_INET, None, None, None, (self.ipmi_ipv4,)),
         (socket.AF_INET6, None, None, None, (self.ipmi_ipv6,))]
     self.assertEqual((self.ipmi_address, self.ipmi_ipv4, self.ipmi_ipv6),
                      ir_utils.get_ipmi_address(node))
     mock_socket.assert_called_once_with(self.ipmi_address, None, 0, 0,
                                         socket.SOL_TCP)
Exemple #19
0
 def test_redfish_bmc_address_ipv6(self, mock_socket):
     self.cfg.config(ipmi_address_fields=['redfish_address'])
     url = 'https://[{}]::443/path'.format(self.ipmi_ipv6)
     node = mock.Mock(spec=['driver_info', 'uuid'],
                      driver_info={'redfish_address': url})
     mock_socket.return_value = [(socket.AF_INET6, None, None, None,
                                  (self.ipmi_ipv6, ))]
     self.assertEqual((self.ipmi_ipv6, None, self.ipmi_ipv6),
                      ir_utils.get_ipmi_address(node))
     mock_socket.assert_called_once_with(self.ipmi_ipv6, None, 0, 0, 6)
 def test_good_hostname_resolves(self, mock_socket):
     node = mock.Mock(spec=['driver_info', 'uuid'],
                      driver_info={'ipmi_address': self.ipmi_address})
     mock_socket.return_value = [
         (socket.AF_INET, None, None, None, (self.ipmi_ipv4,)),
         (socket.AF_INET6, None, None, None, (self.ipmi_ipv6,))]
     self.assertEqual((self.ipmi_address, self.ipmi_ipv4, self.ipmi_ipv6),
                      ir_utils.get_ipmi_address(node))
     mock_socket.assert_called_once_with(self.ipmi_address, None, 0, 0,
                                         socket.SOL_TCP)
Exemple #21
0
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 = ir_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
            })

    ir_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, reason: %s')
            raise utils.Error(msg % validation.power['reason'], node_info=node)

    bmc_address = ir_utils.get_ipmi_address(node)
    node_info = node_cache.add_node(node.uuid,
                                    bmc_address=bmc_address,
                                    ironic=ironic)
    node_info.set_option('new_ipmi_credentials', new_ipmi_credentials)

    def _handle_exceptions(fut):
        try:
            fut.result()
        except utils.Error as exc:
            # Logging has already happened in Error.__init__
            node_info.finished(error=str(exc))
        except Exception as exc:
            msg = _('Unexpected exception in background introspection thread')
            LOG.exception(msg, node_info=node_info)
            node_info.finished(error=msg)

    future = utils.executor().submit(_background_introspect, ironic, node_info)
    future.add_done_callback(_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 = ir_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})

    ir_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, reason: %s')
            raise utils.Error(msg % validation.power['reason'],
                              node_info=node)

    bmc_address = ir_utils.get_ipmi_address(node)
    node_info = node_cache.add_node(node.uuid,
                                    bmc_address=bmc_address,
                                    ironic=ironic)
    node_info.set_option('new_ipmi_credentials', new_ipmi_credentials)

    def _handle_exceptions(fut):
        try:
            fut.result()
        except utils.Error as exc:
            # Logging has already happened in Error.__init__
            node_info.finished(error=str(exc))
        except Exception as exc:
            msg = _('Unexpected exception in background introspection thread')
            LOG.exception(msg, node_info=node_info)
            node_info.finished(error=msg)

    future = utils.executor().submit(_background_introspect, ironic, node_info)
    future.add_done_callback(_handle_exceptions)
 def test_ipv4_in_resolves(self):
     node = mock.Mock(spec=['driver_info', 'uuid'],
                      driver_info={'ipmi_address': self.ipmi_ipv4})
     self.assertEqual((self.ipmi_ipv4, self.ipmi_ipv4, None),
                      ir_utils.get_ipmi_address(node))
 def test_loopback_address(self):
     node = mock.Mock(spec=['driver_info', 'uuid'],
                      driver_info={'ipmi_address': '127.0.0.2'})
     self.assertEqual((None, None, None),
                      ir_utils.get_ipmi_address(node))
 def test_ipmi_bridging_enabled(self):
     node = mock.Mock(spec=['driver_info', 'uuid'],
                      driver_info={'ipmi_address': 'www.example.com',
                                   'ipmi_bridging': 'single'})
     self.assertEqual((None, None, None),
                      ir_utils.get_ipmi_address(node))
 def test_ipv4_in_resolves(self):
     node = mock.Mock(spec=['driver_info', 'uuid'],
                      driver_info={'ipmi_address': '192.168.1.1'})
     ip = ir_utils.get_ipmi_address(node)
     self.assertEqual(ip, '192.168.1.1')
 def test_loopback_address(self):
     node = mock.Mock(spec=['driver_info', 'uuid'],
                      driver_info={'ipmi_address': '127.0.0.2'})
     ip = ir_utils.get_ipmi_address(node)
     self.assertIsNone(ip)
Exemple #28
0
 def test_loopback_address(self):
     node = mock.Mock(spec=['driver_info', 'uuid'],
                      driver_info={'ipmi_address': '127.0.0.2'})
     self.assertEqual((None, None, None), ir_utils.get_ipmi_address(node))
 def test_ipv4_in_resolves(self):
     node = mock.Mock(spec=['driver_info', 'uuid'],
                      driver_info={'ipmi_address': '192.168.1.1'})
     ip = ir_utils.get_ipmi_address(node)
     self.assertEqual(ip, '192.168.1.1')
Exemple #30
0
 def test_ipv6_in_resolves(self):
     node = mock.Mock(spec=['driver_info', 'uuid'],
                      driver_info={'ipmi_address': self.ipmi_ipv6})
     self.assertEqual((self.ipmi_ipv6, None, self.ipmi_ipv6),
                      ir_utils.get_ipmi_address(node))
 def test_loopback_address(self):
     node = mock.Mock(spec=['driver_info', 'uuid'],
                      driver_info={'ipmi_address': '127.0.0.2'})
     ip = ir_utils.get_ipmi_address(node)
     self.assertIsNone(ip)