Beispiel #1
0
def default_interface(hw_type, interface_type,
                      driver_name=None, node=None):
    """Calculate and return the default interface implementation.

    Finds the first implementation that is supported by the hardware type
    and is enabled in the configuration.

    :param hw_type: hardware type instance object.
    :param interface_type: type of the interface (e.g. 'boot').
    :param driver_name: entrypoint name of the hw_type object. Is
                        used for exception message.
    :param node: the identifier of a node. If specified, is used for exception
                 message.
    :returns: an entrypoint name of the calculated default implementation.
    :raises: InterfaceNotFoundInEntrypoint if the entry point was not found.
    :raises: NoValidDefaultForInterface if no default interface can be found.
    """

    factory = _INTERFACE_LOADERS[interface_type]

    # The fallback default from the configuration
    impl_name = getattr(CONF, 'default_%s_interface' % interface_type)

    if impl_name is not None:
        try:
            # Check that the default is correct for this type
            get_interface(hw_type, interface_type, impl_name)
        except exception.IncompatibleInterface:
            raise exception.NoValidDefaultForInterface(
                interface_type=interface_type, driver=driver_name)

    else:
        supported = getattr(hw_type,
                            'supported_%s_interfaces' % interface_type)
        # Mapping of classes to entry points
        enabled = {obj.__class__: name for (name, obj) in factory().items()}

        # Order of the supported list matters
        for impl_class in supported:
            try:
                impl_name = enabled[impl_class]
                break
            except KeyError:
                continue

    if impl_name is None:
        # NOTE(rloo). No i18n on driver_type_str because translating substrings
        #             on their own may cause the final string to look odd.
        driver_name = driver_name or hw_type.__class__.__name__
        node_info = ""
        if node is not None:
            node_info = _(' node %s with') % node
        raise exception.NoValidDefaultForInterface(
            interface_type=interface_type, driver=driver_name,
            node_info=node_info)

    return impl_name
Beispiel #2
0
 def test_get_properties_none(self, mock_def_iface):
     hardware_type = driver_factory.get_hardware_type("manual-management")
     mock_def_iface.side_effect = exception.NoValidDefaultForInterface("no")
     properties = hardware_type.get_properties()
     self.assertEqual({}, properties)
     self.assertEqual(len(driver_base.ALL_INTERFACES),
                      mock_def_iface.call_count)
Beispiel #3
0
    def test__register_and_validate_no_valid_default(self,
                                                     esi_mock,
                                                     default_mock,
                                                     reg_mock,
                                                     unreg_mock):
        # these must be same order as esi_mock side effect
        hardware_types = collections.OrderedDict((
            ('fake-hardware', fake_hardware.FakeHardware()),
        ))
        esi_mock.side_effect = [
            collections.OrderedDict((
                ('management', ['fake', 'noop']),
                ('deploy', ['agent', 'iscsi']),
            )),
        ]
        default_mock.side_effect = exception.NoValidDefaultForInterface("boo")

        self.assertRaises(
            exception.NoValidDefaultForInterface,
            self.service._register_and_validate_hardware_interfaces,
            hardware_types)

        default_mock.assert_called_once_with(
            hardware_types['fake-hardware'],
            mock.ANY, driver_name='fake-hardware')
        unreg_mock.assert_called_once_with(mock.ANY)
        self.assertFalse(reg_mock.called)
Beispiel #4
0
def default_interface(driver_or_hw_type,
                      interface_type,
                      driver_name=None,
                      node=None):
    """Calculate and return the default interface implementation.

    Finds the first implementation that is supported by the hardware type
    and is enabled in the configuration.

    :param driver_or_hw_type: classic driver or hardware type instance object.
    :param interface_type: type of the interface (e.g. 'boot').
    :param driver_name: entrypoint name of the driver_or_hw_type object. Is
                        used for exception message.
    :param node: the identifier of a node. If specified, is used for exception
                 message.
    :returns: an entrypoint name of the calculated default implementation.
    :raises: InterfaceNotFoundInEntrypoint if the entry point was not found.
    :raises: NoValidDefaultForInterface if no default interface can be found.
    """
    factory = _INTERFACE_LOADERS[interface_type]
    is_hardware_type = isinstance(driver_or_hw_type,
                                  hardware_type.AbstractHardwareType)
    # Explicit interface defaults
    additional_defaults = {'storage': 'noop'}

    if not is_hardware_type:
        # For non hardware types we need to set a fallback for the network
        # interface however hardware_types specify their own defaults if not in
        # the config file.
        if (CONF.dhcp.dhcp_provider == 'neutron'
                and 'flat' in CONF.enabled_network_interfaces):
            additional_defaults['network'] = 'flat'
        elif 'noop' in CONF.enabled_network_interfaces:
            additional_defaults['network'] = 'noop'

    # The fallback default from the configuration
    impl_name = getattr(CONF, 'default_%s_interface' % interface_type)
    if impl_name is None:
        impl_name = additional_defaults.get(interface_type)

    if impl_name is not None:
        # Check that the default is correct for this type
        get_interface(driver_or_hw_type, interface_type, impl_name)
    elif is_hardware_type:
        supported = getattr(driver_or_hw_type,
                            'supported_%s_interfaces' % interface_type)
        # Mapping of classes to entry points
        enabled = {obj.__class__: name for (name, obj) in factory().items()}

        # Order of the supported list matters
        for impl_class in supported:
            try:
                impl_name = enabled[impl_class]
                break
            except KeyError:
                continue

    if impl_name is None:
        # NOTE(rloo). No i18n on driver_type_str because translating substrings
        #             on their own may cause the final string to look odd.
        if is_hardware_type:
            driver_type_str = 'hardware type'
        else:
            driver_type_str = 'driver'
        driver_name = driver_name or driver_or_hw_type.__class__.__name__
        node_info = ""
        if node is not None:
            node_info = _(' node %s with') % node
        raise exception.NoValidDefaultForInterface(
            interface_type=interface_type,
            driver_type=driver_type_str,
            driver=driver_name,
            node_info=node_info)

    return impl_name
Beispiel #5
0
def check_and_update_node_interfaces(node, driver_or_hw_type=None):
    """Ensure that node interfaces (e.g. for creation or updating) are valid.

    Updates (but doesn't save to the database) hardware interfaces with
    calculated defaults, if they are not provided.

    This function is run on node updating and creation, as well as each time
    a driver instance is built for a node.

    :param node: node object to check and potentially update
    :param driver_or_hw_type: classic driver or hardware type instance object;
                              will be detected from node.driver if missing
    :returns: True if any changes were made to the node, otherwise False
    :raises: InterfaceNotFoundInEntrypoint on validation failure
    :raises: NoValidDefaultForInterface if the default value cannot be
             calculated and is not provided in the configuration
    :raises: DriverNotFound if the node's driver or hardware type is not found
    """
    if driver_or_hw_type is None:
        driver_or_hw_type = get_driver_or_hardware_type(node.driver)
    is_hardware_type = isinstance(driver_or_hw_type,
                                  hardware_type.AbstractHardwareType)

    # Explicit interface defaults
    additional_defaults = {
        'network': 'flat' if CONF.dhcp.dhcp_provider == 'neutron' else 'noop',
        'storage': 'noop'
    }

    if is_hardware_type:
        factories = _INTERFACE_LOADERS
    else:
        # Only network and storage interfaces are dynamic for classic drivers
        factories = {
            'network': _INTERFACE_LOADERS['network'],
            'storage': _INTERFACE_LOADERS['storage']
        }

    # Result - whether the node object was modified
    result = False

    # Walk through all dynamic interfaces and check/update them
    for iface, factory in factories.items():
        field_name = '%s_interface' % iface
        # NOTE(dtantsur): objects raise NotImplementedError on accessing fields
        # that are known, but missing from an object. Thus, we cannot just use
        # getattr(node, field_name, None) here.
        if field_name in node:
            impl_name = getattr(node, field_name)
            if impl_name is not None:
                # Check that the provided value is correct for this type
                _get_interface(driver_or_hw_type, iface, impl_name)
                # Not changing the result, proceeding with the next interface
                continue

        # The fallback default from the configuration
        impl_name = getattr(CONF, 'default_%s_interface' % iface)
        if impl_name is None:
            impl_name = additional_defaults.get(iface)

        if impl_name is not None:
            # Check that the default is correct for this type
            _get_interface(driver_or_hw_type, iface, impl_name)
        elif is_hardware_type:
            impl_name = _default_interface(driver_or_hw_type, iface, factory)

        if impl_name is None:
            raise exception.NoValidDefaultForInterface(interface_type=iface,
                                                       node=node.uuid,
                                                       driver=node.driver)

        # Set the calculated default and set result to True
        setattr(node, field_name, impl_name)
        result = True

    return result