Ejemplo n.º 1
0
def _parse_driver_info(node):
    """Gets the information needed for accessing the node.

    :param node: the Node of interest.
    :returns: dictionary of information.
    :raises: InvalidParameterValue if any required parameters are incorrect.
    :raises: MissingParameterValue if any required parameters are missing.

    """
    info = node.driver_info or {}
    missing_info = [key for key in REQUIRED_PROPERTIES if not info.get(key)]
    if missing_info:
        raise exception.MissingParameterValue(
            _("SSHPowerDriver requires the following parameters to be set in "
              "node's driver_info: %s.") % missing_info)

    address = info.get('ssh_address')
    username = info.get('ssh_username')
    password = info.get('ssh_password')
    port = info.get('ssh_port', 22)
    port = utils.validate_network_port(port, 'ssh_port')
    key_contents = info.get('ssh_key_contents')
    key_filename = info.get('ssh_key_filename')
    virt_type = info.get('ssh_virt_type')
    terminal_port = info.get('ssh_terminal_port')

    if terminal_port is not None:
        terminal_port = utils.validate_network_port(terminal_port,
                                                    'ssh_terminal_port')

    # NOTE(deva): we map 'address' from API to 'host' for common utils
    res = {
        'host': address,
        'username': username,
        'port': port,
        'virt_type': virt_type,
        'uuid': node.uuid,
        'terminal_port': terminal_port
    }

    cmd_set = _get_command_sets(virt_type)
    res['cmd_set'] = cmd_set

    # Only one credential may be set (avoids complexity around having
    # precedence etc).
    if len([v for v in (password, key_filename, key_contents) if v]) != 1:
        raise exception.InvalidParameterValue(
            _("SSHPowerDriver requires one and only one of password, "
              "key_contents and key_filename to be set."))
    if password:
        res['password'] = password
    elif key_contents:
        res['key_contents'] = key_contents
    else:
        if not os.path.isfile(key_filename):
            raise exception.InvalidParameterValue(
                _("SSH key file %s not found.") % key_filename)
        res['key_filename'] = key_filename

    return res
def _parse_driver_info(node):
    """Gets the information needed for accessing the node.

    :param node: the Node of interest.
    :returns: dictionary of information.
    :raises: InvalidParameterValue if any required parameters are incorrect.
    :raises: MissingParameterValue if any required parameters are missing.

    """
    info = node.driver_info or {}
    missing_info = [key for key in REQUIRED_PROPERTIES if not info.get(key)]
    if missing_info:
        raise exception.MissingParameterValue(_(
            "SSHPowerDriver requires the following parameters to be set in "
            "node's driver_info: %s.") % missing_info)

    address = info.get('ssh_address')
    username = info.get('ssh_username')
    password = info.get('ssh_password')
    port = info.get('ssh_port', 22)
    port = utils.validate_network_port(port, 'ssh_port')
    key_contents = info.get('ssh_key_contents')
    key_filename = info.get('ssh_key_filename')
    virt_type = info.get('ssh_virt_type')
    terminal_port = info.get('ssh_terminal_port')

    if terminal_port is not None:
        terminal_port = utils.validate_network_port(terminal_port,
                                                    'ssh_terminal_port')

    # NOTE(deva): we map 'address' from API to 'host' for common utils
    res = {
        'host': address,
        'username': username,
        'port': port,
        'virt_type': virt_type,
        'uuid': node.uuid,
        'terminal_port': terminal_port
    }

    cmd_set = _get_command_sets(virt_type)
    res['cmd_set'] = cmd_set

    # Only one credential may be set (avoids complexity around having
    # precedence etc).
    if len([v for v in (password, key_filename, key_contents) if v]) != 1:
        raise exception.InvalidParameterValue(_(
            "SSHPowerDriver requires one and only one of password, "
            "key_contents and key_filename to be set."))
    if password:
        res['password'] = password
    elif key_contents:
        res['key_contents'] = key_contents
    else:
        if not os.path.isfile(key_filename):
            raise exception.InvalidParameterValue(_(
                "SSH key file %s not found.") % key_filename)
        res['key_filename'] = key_filename

    return res
Ejemplo n.º 3
0
def parse_driver_info(node):
    """Gets the driver specific Node info.

    This method validates whether the 'driver_info' property of the
    supplied node contains the required information for this driver.

    :param node: an ironic Node object.
    :returns: a dict containing information from driver_info (or where
        applicable, config values).
    :raises: InvalidParameterValue if any parameters are incorrect
    :raises: MissingParameterValue if some mandatory information
        is missing on the node
    """
    info = node.driver_info
    d_info = {}

    missing_info = []
    for param in REQUIRED_PROPERTIES:
        try:
            d_info[param] = info[param]
        except KeyError:
            missing_info.append(param)
    if missing_info:
        raise exception.MissingParameterValue(
            _("The following required iLO parameters are missing from the "
              "node's driver_info: %s") % missing_info)

    not_integers = []
    for param in OPTIONAL_PROPERTIES:
        value = info.get(param, CONF.ilo.get(param))
        if param == "client_port":
            d_info[param] = utils.validate_network_port(value, param)
        elif param == "ca_file":
            if value and not os.path.isfile(value):
                raise exception.InvalidParameterValue(
                    _('%(param)s "%(value)s" is not found.') % {
                        'param': param,
                        'value': value
                    })
            d_info[param] = value
        else:
            try:
                d_info[param] = int(value)
            except ValueError:
                not_integers.append(param)

    for param in CONSOLE_PROPERTIES:
        value = info.get(param)
        if value:
            # Currently there's only "console_port" parameter
            # in CONSOLE_PROPERTIES
            if param == "console_port":
                d_info[param] = utils.validate_network_port(value, param)

    if not_integers:
        raise exception.InvalidParameterValue(
            _("The following iLO parameters from the node's driver_info "
              "should be integers: %s") % not_integers)

    return d_info
Ejemplo n.º 4
0
def parse_driver_info(node):
    """Gets the driver specific Node info.

    This method validates whether the 'driver_info' property of the
    supplied node contains the required information for this driver.

    :param node: an ironic Node object.
    :returns: a dict containing information from driver_info (or where
        applicable, config values).
    :raises: InvalidParameterValue if any parameters are incorrect
    :raises: MissingParameterValue if some mandatory information
        is missing on the node
    """
    info = node.driver_info
    d_info = {}

    missing_info = []
    for param in REQUIRED_PROPERTIES:
        try:
            d_info[param] = info[param]
        except KeyError:
            missing_info.append(param)
    if missing_info:
        raise exception.MissingParameterValue(_(
            "The following required iLO parameters are missing from the "
            "node's driver_info: %s") % missing_info)

    not_integers = []
    for param in OPTIONAL_PROPERTIES:
        value = info.get(param, CONF.ilo.get(param))
        if param == "client_port":
            d_info[param] = utils.validate_network_port(value, param)
        elif param == "ca_file":
            if value and not os.path.isfile(value):
                raise exception.InvalidParameterValue(_(
                    '%(param)s "%(value)s" is not found.') %
                    {'param': param, 'value': value})
            d_info[param] = value
        else:
            try:
                d_info[param] = int(value)
            except ValueError:
                not_integers.append(param)

    for param in CONSOLE_PROPERTIES:
        value = info.get(param)
        if value:
            # Currently there's only "console_port" parameter
            # in CONSOLE_PROPERTIES
            if param == "console_port":
                d_info[param] = utils.validate_network_port(value, param)

    if not_integers:
        raise exception.InvalidParameterValue(_(
            "The following iLO parameters from the node's driver_info "
            "should be integers: %s") % not_integers)

    return d_info
Ejemplo n.º 5
0
def _parse_driver_info(node):
    """Gets the bmc access info for the given node.

    :raises: MissingParameterValue when required ipmi credentials
            are missing.
    :raises: InvalidParameterValue when the IPMI terminal port is not an
            integer.
    """

    info = node.driver_info or {}
    missing_info = [key for key in REQUIRED_PROPERTIES if not info.get(key)]
    if missing_info:
        raise exception.MissingParameterValue(
            _("Missing the following IPMI credentials in node's"
              " driver_info: %s.") % missing_info)

    bmc_info = {}
    bmc_info['address'] = info.get('ipmi_address')
    bmc_info['username'] = info.get('ipmi_username')
    bmc_info['password'] = info.get('ipmi_password')
    bmc_info['force_boot_device'] = info.get('ipmi_force_boot_device', False)

    # get additional info
    bmc_info['uuid'] = node.uuid

    # terminal port must be an integer
    port = info.get('ipmi_terminal_port')
    if port is not None:
        port = utils.validate_network_port(port, 'ipmi_terminal_port')
    bmc_info['port'] = port

    return bmc_info
Ejemplo n.º 6
0
def _parse_driver_info(node):
    info = node.driver_info or {}
    missing_info = [key for key in REQUIRED_PROPERTIES if not info.get(key)]
    if missing_info:
        raise exception.MissingParameterValue(
            _("Missing the following iBoot credentials in node's"
              " driver_info: %s.") % missing_info)

    address = info.get('iboot_address', None)
    username = info.get('iboot_username', None)
    password = info.get('iboot_password', None)

    relay_id = info.get('iboot_relay_id', 1)
    try:
        relay_id = int(relay_id)
    except ValueError:
        raise exception.InvalidParameterValue(
            _("iBoot PDU relay id must be an integer."))

    port = info.get('iboot_port', 9100)
    port = utils.validate_network_port(port, 'iboot_port')

    return {
        'address': address,
        'username': username,
        'password': password,
        'port': port,
        'relay_id': relay_id,
        'uuid': node.uuid,
    }
Ejemplo n.º 7
0
def _parse_driver_info(node):
    """Gets the bmc access info for the given node.

    :raises: MissingParameterValue when required ipmi credentials
            are missing.
    :raises: InvalidParameterValue when the IPMI terminal port is not an
            integer.
    """

    info = node.driver_info or {}
    missing_info = [key for key in REQUIRED_PROPERTIES if not info.get(key)]
    if missing_info:
        raise exception.MissingParameterValue(_(
            "Missing the following IPMI credentials in node's"
            " driver_info: %s.") % missing_info)

    bmc_info = {}
    bmc_info['address'] = info.get('ipmi_address')
    bmc_info['username'] = info.get('ipmi_username')
    bmc_info['password'] = info.get('ipmi_password')
    bmc_info['force_boot_device'] = info.get('ipmi_force_boot_device', False)

    # get additional info
    bmc_info['uuid'] = node.uuid

    # terminal port must be an integer
    port = info.get('ipmi_terminal_port')
    if port is not None:
        port = utils.validate_network_port(port, 'ipmi_terminal_port')
    bmc_info['port'] = port

    return bmc_info
Ejemplo n.º 8
0
def _parse_driver_info(node):
    """Parse a node's driver_info values.

    Return a dictionary of validated driver information, usable for
    SNMPDriver object creation.

    :param node: An Ironic node object.
    :returns: SNMP driver info.
    :raises: MissingParameterValue if any required parameters are missing.
    :raises: InvalidParameterValue if any parameters are invalid.
    """
    info = node.driver_info or {}
    missing_info = [key for key in REQUIRED_PROPERTIES if not info.get(key)]
    if missing_info:
        raise exception.MissingParameterValue(
            _("SNMP driver requires the following parameters to be set in " "node's driver_info: %s.") % missing_info
        )

    snmp_info = {}

    # Validate PDU driver type
    snmp_info["driver"] = info.get("snmp_driver")
    if snmp_info["driver"] not in DRIVER_CLASSES:
        raise exception.InvalidParameterValue(_("SNMPPowerDriver: unknown driver: '%s'") % snmp_info["driver"])

    # In absence of a version, default to SNMPv1
    snmp_info["version"] = info.get("snmp_version", SNMP_V1)
    if snmp_info["version"] not in (SNMP_V1, SNMP_V2C, SNMP_V3):
        raise exception.InvalidParameterValue(_("SNMPPowerDriver: unknown SNMP version: '%s'") % snmp_info["version"])

    # In absence of a configured UDP port, default to the standard port
    port_str = info.get("snmp_port", SNMP_PORT)
    snmp_info["port"] = utils.validate_network_port(port_str, "snmp_port")

    if snmp_info["port"] < 1 or snmp_info["port"] > 65535:
        raise exception.InvalidParameterValue(_("SNMPPowerDriver: SNMP UDP port out of range: %d") % snmp_info["port"])

    # Extract version-dependent required parameters
    if snmp_info["version"] in (SNMP_V1, SNMP_V2C):
        if "snmp_community" not in info:
            raise exception.MissingParameterValue(
                _("SNMP driver requires snmp_community to be set for version " "%s.") % snmp_info["version"]
            )
        snmp_info["community"] = info.get("snmp_community")
    elif snmp_info["version"] == SNMP_V3:
        if "snmp_security" not in info:
            raise exception.MissingParameterValue(
                _("SNMP driver requires snmp_security to be set for version %s.") % (SNMP_V3)
            )
        snmp_info["security"] = info.get("snmp_security")

    # Target PDU IP address and power outlet identification
    snmp_info["address"] = info.get("snmp_address")
    snmp_info["outlet"] = info.get("snmp_outlet")

    return snmp_info
Ejemplo n.º 9
0
def parse_driver_info(node):
    """Parse a node's driver_info values.

    Parses the driver_info of the node, reads default values
    and returns a dict containing the combination of both.

    :param node: an ironic node object to get informatin from.
    :returns: a dict containing information parsed from driver_info.
    :raises: InvalidParameterValue if some required information
             is missing on the node or inputs is invalid.
    """
    driver_info = node.driver_info
    parsed_driver_info = {}

    error_msgs = []
    for param in REQUIRED_ON_DRIVER_INFO:
        if param == "xclarity_hardware_id":
            try:
                parsed_driver_info[param] = str(driver_info[param])
            except KeyError:
                error_msgs.append(_("'%s' not provided to XClarity.") % param)
            except UnicodeEncodeError:
                error_msgs.append(_("'%s' contains non-ASCII symbol.") % param)
        else:
            # corresponding config names don't have 'xclarity_' prefix
            if param in driver_info:
                parsed_driver_info[param] = str(driver_info[param])
            elif param not in driver_info and\
                    CONF.xclarity.get(param[len('xclarity_'):]) is not None:
                parsed_driver_info[param] = str(
                    CONF.xclarity.get(param[len('xclarity_'):]))
                LOG.warning(
                    'The configuration [xclarity]/%(config)s '
                    'is deprecated and will be removed in the '
                    'Stein release. Please update the node '
                    '%(node_uuid)s driver_info field to use '
                    '"%(field)s" instead', {
                        'config': param[len('xclarity_'):],
                        'node_uuid': node.uuid,
                        'field': param
                    })
            else:
                error_msgs.append(_("'%s' not provided to XClarity.") % param)

    port = driver_info.get('xclarity_port', CONF.xclarity.get('port'))
    parsed_driver_info['xclarity_port'] = utils.validate_network_port(
        port, 'xclarity_port')

    if error_msgs:
        msg = (_('The following errors were encountered while parsing '
                 'driver_info:\n%s') % '\n'.join(error_msgs))
        raise exception.InvalidParameterValue(msg)

    return parsed_driver_info
Ejemplo n.º 10
0
def _parse_parameters(task):
    driver_info = task.node.driver_info
    host = driver_info.get('wol_host', '255.255.255.255')
    port = driver_info.get('wol_port', 9)
    port = utils.validate_network_port(port, 'wol_port')

    if len(task.ports) < 1:
        raise exception.MissingParameterValue(
            _('Wake-On-Lan needs at least one port resource to be '
              'registered in the node'))

    return {'host': host, 'port': port}
Ejemplo n.º 11
0
def parse_driver_info(node):
    """Parse a node's driver_info values.

    Parses the driver_info of the node, reads default values
    and returns a dict containing the combination of both.

    :param node: an ironic node object.
    :returns: a dict containing information from driver_info
              and default values.
    :raises: InvalidParameterValue if some mandatory information
             is missing on the node or on invalid inputs.
    """
    driver_info = node.driver_info
    parsed_driver_info = {}

    error_msgs = []
    for param in REQUIRED_PROPERTIES:
        try:
            parsed_driver_info[param] = str(driver_info[param])
        except KeyError:
            error_msgs.append(_("'%s' not supplied to DracDriver.") % param)
        except UnicodeEncodeError:
            error_msgs.append(_("'%s' contains non-ASCII symbol.") % param)

    parsed_driver_info['drac_port'] = driver_info.get('drac_port', 443)

    try:
        parsed_driver_info['drac_path'] = str(
            driver_info.get('drac_path', '/wsman'))
    except UnicodeEncodeError:
        error_msgs.append(_("'drac_path' contains non-ASCII symbol."))

    try:
        parsed_driver_info['drac_protocol'] = str(
            driver_info.get('drac_protocol', 'https'))

        if parsed_driver_info['drac_protocol'] not in ['http', 'https']:
            error_msgs.append(
                _("'drac_protocol' must be either 'http' or "
                  "'https'."))
    except UnicodeEncodeError:
        error_msgs.append(_("'drac_protocol' contains non-ASCII symbol."))

    if error_msgs:
        msg = (_('The following errors were encountered while parsing '
                 'driver_info:\n%s') % '\n'.join(error_msgs))
        raise exception.InvalidParameterValue(msg)

    port = parsed_driver_info['drac_port']
    parsed_driver_info['drac_port'] = utils.validate_network_port(
        port, 'drac_port')

    return parsed_driver_info
Ejemplo n.º 12
0
def _parse_parameters(task):
    driver_info = task.node.driver_info
    host = driver_info.get('wol_host', '255.255.255.255')
    port = driver_info.get('wol_port', 9)
    port = utils.validate_network_port(port, 'wol_port')

    if len(task.ports) < 1:
        raise exception.MissingParameterValue(_(
            'Wake-On-Lan needs at least one port resource to be '
            'registered in the node'))

    return {'host': host, 'port': port}
Ejemplo n.º 13
0
def parse_driver_info(node):
    """Parse a node's driver_info values.

    Parses the driver_info of the node, reads default values
    and returns a dict containing the combination of both.

    :param node: an ironic node object.
    :returns: a dict containing information from driver_info
              and default values.
    :raises: InvalidParameterValue if some mandatory information
             is missing on the node or on invalid inputs.
    """
    driver_info = node.driver_info
    parsed_driver_info = {}

    error_msgs = []
    for param in REQUIRED_PROPERTIES:
        try:
            parsed_driver_info[param] = str(driver_info[param])
        except KeyError:
            error_msgs.append(_("'%s' not supplied to DracDriver.") % param)
        except UnicodeEncodeError:
            error_msgs.append(_("'%s' contains non-ASCII symbol.") % param)

    parsed_driver_info['drac_port'] = driver_info.get('drac_port', 443)

    try:
        parsed_driver_info['drac_path'] = str(driver_info.get('drac_path',
                                                              '/wsman'))
    except UnicodeEncodeError:
        error_msgs.append(_("'drac_path' contains non-ASCII symbol."))

    try:
        parsed_driver_info['drac_protocol'] = str(
            driver_info.get('drac_protocol', 'https'))

        if parsed_driver_info['drac_protocol'] not in ['http', 'https']:
            error_msgs.append(_("'drac_protocol' must be either 'http' or "
                                "'https'."))
    except UnicodeEncodeError:
        error_msgs.append(_("'drac_protocol' contains non-ASCII symbol."))

    if error_msgs:
        msg = (_('The following errors were encountered while parsing '
                 'driver_info:\n%s') % '\n'.join(error_msgs))
        raise exception.InvalidParameterValue(msg)

    port = parsed_driver_info['drac_port']
    parsed_driver_info['drac_port'] = utils.validate_network_port(
        port, 'drac_port')

    return parsed_driver_info
Ejemplo n.º 14
0
def _parse_driver_info(node):
    """Parses and creates seamicro driver info

    :param node: An Ironic node object.
    :returns: SeaMicro driver info.
    :raises: MissingParameterValue if any required parameters are missing.
    :raises: InvalidParameterValue if required parameter are invalid.
    """

    info = node.driver_info or {}
    missing_info = [key for key in REQUIRED_PROPERTIES if not info.get(key)]
    if missing_info:
        raise exception.MissingParameterValue(
            _("SeaMicro driver requires the following parameters to be set in"
              " node's driver_info: %s.") % missing_info)

    api_endpoint = info.get('seamicro_api_endpoint')
    username = info.get('seamicro_username')
    password = info.get('seamicro_password')
    server_id = info.get('seamicro_server_id')
    api_version = info.get('seamicro_api_version', "2")
    port = info.get('seamicro_terminal_port')

    if port is not None:
        port = utils.validate_network_port(port, 'seamicro_terminal_port')

    r = re.compile(r"(^[0-9]+)/([0-9]+$)")
    if not r.match(server_id):
        raise exception.InvalidParameterValue(
            _("Invalid 'seamicro_server_id' parameter in node's "
              "driver_info. Expected format of 'seamicro_server_id' "
              "is <int>/<int>"))

    url = urlparse.urlparse(api_endpoint)
    if (not (url.scheme == "http") or not url.netloc):
        raise exception.InvalidParameterValue(
            _("Invalid 'seamicro_api_endpoint' parameter in node's "
              "driver_info."))

    res = {
        'username': username,
        'password': password,
        'api_endpoint': api_endpoint,
        'server_id': server_id,
        'api_version': api_version,
        'uuid': node.uuid,
        'port': port
    }

    return res
Ejemplo n.º 15
0
def _parse_driver_info(node):
    """Parses and creates seamicro driver info

    :param node: An Ironic node object.
    :returns: SeaMicro driver info.
    :raises: MissingParameterValue if any required parameters are missing.
    :raises: InvalidParameterValue if required parameter are invalid.
    """

    info = node.driver_info or {}
    missing_info = [key for key in REQUIRED_PROPERTIES if not info.get(key)]
    if missing_info:
        raise exception.MissingParameterValue(_(
            "SeaMicro driver requires the following parameters to be set in"
            " node's driver_info: %s.") % missing_info)

    api_endpoint = info.get('seamicro_api_endpoint')
    username = info.get('seamicro_username')
    password = info.get('seamicro_password')
    server_id = info.get('seamicro_server_id')
    api_version = info.get('seamicro_api_version', "2")
    port = info.get('seamicro_terminal_port')

    if port is not None:
        port = utils.validate_network_port(port, 'seamicro_terminal_port')

    r = re.compile(r"(^[0-9]+)/([0-9]+$)")
    if not r.match(server_id):
        raise exception.InvalidParameterValue(_(
            "Invalid 'seamicro_server_id' parameter in node's "
            "driver_info. Expected format of 'seamicro_server_id' "
            "is <int>/<int>"))

    url = urlparse.urlparse(api_endpoint)
    if (not (url.scheme == "http") or not url.netloc):
        raise exception.InvalidParameterValue(_(
            "Invalid 'seamicro_api_endpoint' parameter in node's "
            "driver_info."))

    res = {'username': username,
           'password': password,
           'api_endpoint': api_endpoint,
           'server_id': server_id,
           'api_version': api_version,
           'uuid': node.uuid,
           'port': port}

    return res
Ejemplo n.º 16
0
def parse_driver_info(node):
    """Gets the driver specific Node info.

    This method validates whether the 'driver_info' property of the
    supplied node contains the required information for this driver.

    :param node: an ironic Node object.
    :returns: a dict containing information from driver_info (or where
        applicable, config values).
    :raises: InvalidParameterValue if any parameters are incorrect
    :raises: MissingParameterValue if some mandatory information
        is missing on the node
    """
    info = node.driver_info
    d_info = {}

    missing_info = []
    for param in REQUIRED_PROPERTIES:
        try:
            d_info[param] = info[param]
        except KeyError:
            missing_info.append(param)
    if missing_info:
        raise exception.MissingParameterValue(
            _("The following required iLO parameters are missing from the "
              "node's driver_info: %s") % missing_info)

    optional_info = _parse_optional_driver_info(node)
    d_info.update(optional_info)

    snmp_info = _parse_snmp_driver_info(info)
    if snmp_info:
        d_info.update(snmp_info)

    for param in CONSOLE_PROPERTIES:
        value = info.get(param)
        if value:
            # Currently there's only "console_port" parameter
            # in CONSOLE_PROPERTIES
            if param == "console_port":
                d_info[param] = utils.validate_network_port(value, param)

    return d_info
Ejemplo n.º 17
0
def _parse_driver_info(node):
    """Gets the information needed for accessing the node.

    :param node: the Node of interest.
    :returns: dictionary of information.
    :raises: InvalidParameterValue if any required parameters are incorrect.
    :raises: MissingParameterValue if any required parameters are missing.

    """
    info = node.driver_info or {}
    missing_info = [key for key in REQUIRED_PROPERTIES if not info.get(key)]
    if missing_info:
        raise exception.MissingParameterValue(
            _("SSHPowerDriver requires the following parameters to be set in "
              "node's driver_info: %s.") % missing_info)

    address = info.get('ssh_address')
    username = info.get('ssh_username')
    key_contents = info.get('ssh_key_contents')
    terminal_port = info.get('ssh_terminal_port')

    if terminal_port is not None:
        terminal_port = utils.validate_network_port(terminal_port,
                                                    'ssh_terminal_port')

    # NOTE(deva): we map 'address' from API to 'host' for common utils
    res = {
        'host': address,
        'username': username,
        'port': 22,
        'uuid': node.uuid,
        'terminal_port': terminal_port
    }

    cmd_set = _get_command_sets()
    res['cmd_set'] = cmd_set

    if key_contents:
        res['key_contents'] = key_contents
    else:
        raise exception.InvalidParameterValue(
            _("ssh_virtmedia Driver requires ssh_key_contents to be set."))
    return res
Ejemplo n.º 18
0
def _parse_driver_info(node):
    """Gets the driver specific node driver info.

    This method validates whether the 'driver_info' property of the
    supplied node contains the required information for this driver.

    :param node: an Ironic Node object.
    :returns: a dict containing information from driver_info (or where
        applicable, config values).
    :raises: MissingParameterValue, if some required parameter(s) are missing
        in the node's driver_info.
    :raises: InvalidParameterValue, if some parameter(s) have invalid value(s)
        in the node's driver_info.
    """
    info = node.driver_info
    d_info = {}

    missing_params = []
    for param in REQUIRED_PROPERTIES:
        try:
            d_info_param_name = _strip_virtualbox_from_param_name(param)
            d_info[d_info_param_name] = info[param]
        except KeyError:
            missing_params.append(param)

    if missing_params:
        msg = (_("The following parameters are missing in driver_info: %s") %
               ', '.join(missing_params))
        raise exception.MissingParameterValue(msg)

    for param in OPTIONAL_PROPERTIES:
        if param in info:
            d_info_param_name = _strip_virtualbox_from_param_name(param)
            d_info[d_info_param_name] = info[param]

    port = d_info.get('port', CONF.virtualbox.port)
    d_info['port'] = utils.validate_network_port(port, 'virtualbox_port')

    return d_info
Ejemplo n.º 19
0
def _parse_driver_info(node):
    """Gets the driver specific node driver info.

    This method validates whether the 'driver_info' property of the
    supplied node contains the required information for this driver.

    :param node: an Ironic Node object.
    :returns: a dict containing information from driver_info (or where
        applicable, config values).
    :raises: MissingParameterValue, if some required parameter(s) are missing
        in the node's driver_info.
    :raises: InvalidParameterValue, if some parameter(s) have invalid value(s)
        in the node's driver_info.
    """
    info = node.driver_info
    d_info = {}

    missing_params = []
    for param in REQUIRED_PROPERTIES:
        try:
            d_info_param_name = _strip_virtualbox_from_param_name(param)
            d_info[d_info_param_name] = info[param]
        except KeyError:
            missing_params.append(param)

    if missing_params:
        msg = (_("The following parameters are missing in driver_info: %s") %
               ', '.join(missing_params))
        raise exception.MissingParameterValue(msg)

    for param in OPTIONAL_PROPERTIES:
        if param in info:
            d_info_param_name = _strip_virtualbox_from_param_name(param)
            d_info[d_info_param_name] = info[param]

    port = d_info.get('port', CONF.virtualbox.port)
    d_info['port'] = utils.validate_network_port(port, 'virtualbox_port')

    return d_info
Ejemplo n.º 20
0
def parse_driver_info(node):
    """Parse a node's driver_info values.

    Parses the driver_info of the node, reads default values
    and returns a dict containing the combination of both.

    :param node: an ironic node object.
    :returns: a dict containing information from driver_info
              and default values.
    :raises: InvalidParameterValue if some mandatory information
             is missing on the node or on invalid inputs.
    """
    driver_info = node.driver_info
    parsed_driver_info = {}

    if 'drac_host' in driver_info and 'drac_address' not in driver_info:
        LOG.warning(_LW('The driver_info["drac_host"] property is deprecated '
                        'and will be removed in the Pike release. Please '
                        'update the node %s driver_info field to use '
                        '"drac_address" instead'), node.uuid)
        address = driver_info.pop('drac_host', None)
        if address:
            driver_info['drac_address'] = address
    elif 'drac_host' in driver_info and 'drac_address' in driver_info:
        LOG.warning(_LW('Both driver_info["drac_address"] and '
                        'driver_info["drac_host"] properties are '
                        'specified for node %s. Please remove the '
                        '"drac_host" property from the node. Ignoring '
                        '"drac_host" for now'), node.uuid)

    error_msgs = []
    for param in REQUIRED_PROPERTIES:
        try:
            parsed_driver_info[param] = str(driver_info[param])
        except KeyError:
            error_msgs.append(_("'%s' not supplied to DracDriver.") % param)
        except UnicodeEncodeError:
            error_msgs.append(_("'%s' contains non-ASCII symbol.") % param)

    parsed_driver_info['drac_port'] = driver_info.get('drac_port', 443)

    try:
        parsed_driver_info['drac_path'] = str(driver_info.get('drac_path',
                                                              '/wsman'))
    except UnicodeEncodeError:
        error_msgs.append(_("'drac_path' contains non-ASCII symbol."))

    try:
        parsed_driver_info['drac_protocol'] = str(
            driver_info.get('drac_protocol', 'https'))

        if parsed_driver_info['drac_protocol'] not in ['http', 'https']:
            error_msgs.append(_("'drac_protocol' must be either 'http' or "
                                "'https'."))
    except UnicodeEncodeError:
        error_msgs.append(_("'drac_protocol' contains non-ASCII symbol."))

    if error_msgs:
        msg = (_('The following errors were encountered while parsing '
                 'driver_info:\n%s') % '\n'.join(error_msgs))
        raise exception.InvalidParameterValue(msg)

    port = parsed_driver_info['drac_port']
    parsed_driver_info['drac_port'] = utils.validate_network_port(
        port, 'drac_port')

    return parsed_driver_info
Ejemplo n.º 21
0
def _parse_driver_info(node):
    """Parse a node's driver_info values.

    Return a dictionary of validated driver information, usable for
    SNMPDriver object creation.

    :param node: An Ironic node object.
    :returns: SNMP driver info.
    :raises: MissingParameterValue if any required parameters are missing.
    :raises: InvalidParameterValue if any parameters are invalid.
    """
    info = node.driver_info or {}
    missing_info = [key for key in REQUIRED_PROPERTIES if not info.get(key)]
    if missing_info:
        raise exception.MissingParameterValue(_(
            "SNMP driver requires the following parameters to be set in "
            "node's driver_info: %s.") % missing_info)

    snmp_info = {}

    # Validate PDU driver type
    snmp_info['driver'] = info['snmp_driver']
    if snmp_info['driver'] not in DRIVER_CLASSES:
        raise exception.InvalidParameterValue(_(
            "SNMPPowerDriver: unknown driver: '%s'") % snmp_info['driver'])

    # In absence of a version, default to SNMPv1
    snmp_info['version'] = info.get('snmp_version', SNMP_V1)
    if snmp_info['version'] not in (SNMP_V1, SNMP_V2C, SNMP_V3):
        raise exception.InvalidParameterValue(_(
            "SNMPPowerDriver: unknown SNMP version: '%s'") %
            snmp_info['version'])

    # In absence of a configured UDP port, default to the standard port
    port_str = info.get('snmp_port', SNMP_PORT)
    snmp_info['port'] = utils.validate_network_port(port_str, 'snmp_port')

    if snmp_info['port'] < 1 or snmp_info['port'] > 65535:
        raise exception.InvalidParameterValue(_(
            "SNMPPowerDriver: SNMP UDP port out of range: %d")
            % snmp_info['port'])

    # Extract version-dependent required parameters
    if snmp_info['version'] in (SNMP_V1, SNMP_V2C):
        read_community = info.get('snmp_community_read')
        if read_community is None:
            read_community = info.get('snmp_community')

        write_community = info.get('snmp_community_write')
        if write_community is None:
            write_community = info.get('snmp_community')

        if not read_community or not write_community:
            raise exception.MissingParameterValue(_(
                "SNMP driver requires `snmp_community` or "
                "`snmp_community_read`/`snmp_community_write` properties "
                "to be set for version %s.") % snmp_info['version'])
        snmp_info['read_community'] = read_community
        snmp_info['write_community'] = write_community

    elif snmp_info['version'] == SNMP_V3:
        snmp_info.update(_parse_driver_info_snmpv3_user(node, info))
        snmp_info.update(_parse_driver_info_snmpv3_crypto(node, info))
        snmp_info.update(_parse_driver_info_snmpv3_context(node, info))

    # Target PDU IP address and power outlet identification
    snmp_info['address'] = info['snmp_address']
    outlet = info['snmp_outlet']
    try:
        snmp_info['outlet'] = int(outlet)
    except ValueError:
        raise exception.InvalidParameterValue(_(
            "SNMPPowerDriver: PDU power outlet index is not an integer: %s")
            % outlet)

    return snmp_info
Ejemplo n.º 22
0
def _parse_driver_info(node):
    """Parse a node's driver_info values.

    Return a dictionary of validated driver information, usable for
    SNMPDriver object creation.

    :param node: An Ironic node object.
    :returns: SNMP driver info.
    :raises: MissingParameterValue if any required parameters are missing.
    :raises: InvalidParameterValue if any parameters are invalid.
    """
    info = node.driver_info or {}
    missing_info = [key for key in REQUIRED_PROPERTIES if not info.get(key)]
    if missing_info:
        raise exception.MissingParameterValue(
            _("SNMP driver requires the following parameters to be set in "
              "node's driver_info: %s.") % missing_info)

    snmp_info = {}

    # Validate PDU driver type
    snmp_info['driver'] = info.get('snmp_driver')
    if snmp_info['driver'] not in DRIVER_CLASSES:
        raise exception.InvalidParameterValue(
            _("SNMPPowerDriver: unknown driver: '%s'") % snmp_info['driver'])

    # In absence of a version, default to SNMPv1
    snmp_info['version'] = info.get('snmp_version', SNMP_V1)
    if snmp_info['version'] not in (SNMP_V1, SNMP_V2C, SNMP_V3):
        raise exception.InvalidParameterValue(
            _("SNMPPowerDriver: unknown SNMP version: '%s'") %
            snmp_info['version'])

    # In absence of a configured UDP port, default to the standard port
    port_str = info.get('snmp_port', SNMP_PORT)
    snmp_info['port'] = utils.validate_network_port(port_str, 'snmp_port')

    if snmp_info['port'] < 1 or snmp_info['port'] > 65535:
        raise exception.InvalidParameterValue(
            _("SNMPPowerDriver: SNMP UDP port out of range: %d") %
            snmp_info['port'])

    # Extract version-dependent required parameters
    if snmp_info['version'] in (SNMP_V1, SNMP_V2C):
        if 'snmp_community' not in info:
            raise exception.MissingParameterValue(
                _("SNMP driver requires snmp_community to be set for version "
                  "%s.") % snmp_info['version'])
        snmp_info['community'] = info.get('snmp_community')
    elif snmp_info['version'] == SNMP_V3:
        if 'snmp_security' not in info:
            raise exception.MissingParameterValue(
                _("SNMP driver requires snmp_security to be set for version %s."
                  ) % (SNMP_V3))
        snmp_info['security'] = info.get('snmp_security')

    # Target PDU IP address and power outlet identification
    snmp_info['address'] = info.get('snmp_address')
    snmp_info['outlet'] = info.get('snmp_outlet')

    return snmp_info
Ejemplo n.º 23
0
def _parse_driver_info(node):
    """Gets the parameters required for ipmitool to access the node.

    :param node: the Node of interest.
    :returns: dictionary of parameters.
    :raises: InvalidParameterValue when an invalid value is specified
    :raises: MissingParameterValue when a required ipmi parameter is missing.

    """
    info = node.driver_info or {}
    bridging_types = ['single', 'dual']
    missing_info = [key for key in REQUIRED_PROPERTIES if not info.get(key)]
    if missing_info:
        raise exception.MissingParameterValue(_(
            "Missing the following IPMI credentials in node's"
            " driver_info: %s.") % missing_info)

    address = info.get('ipmi_address')
    username = info.get('ipmi_username')
    password = six.text_type(info.get('ipmi_password', ''))
    dest_port = info.get('ipmi_port')
    port = info.get('ipmi_terminal_port')
    priv_level = info.get('ipmi_priv_level', 'ADMINISTRATOR')
    bridging_type = info.get('ipmi_bridging', 'no')
    local_address = info.get('ipmi_local_address')
    transit_channel = info.get('ipmi_transit_channel')
    transit_address = info.get('ipmi_transit_address')
    target_channel = info.get('ipmi_target_channel')
    target_address = info.get('ipmi_target_address')
    protocol_version = str(info.get('ipmi_protocol_version', '2.0'))
    force_boot_device = info.get('ipmi_force_boot_device', False)

    if not username:
        LOG.warning(_LW('ipmi_username is not defined or empty for node %s: '
                        'NULL user will be utilized.') % node.uuid)
    if not password:
        LOG.warning(_LW('ipmi_password is not defined or empty for node %s: '
                        'NULL password will be utilized.') % node.uuid)

    if protocol_version not in VALID_PROTO_VERSIONS:
        valid_versions = ', '.join(VALID_PROTO_VERSIONS)
        raise exception.InvalidParameterValue(_(
            "Invalid IPMI protocol version value %(version)s, the valid "
            "value can be one of %(valid_versions)s") %
            {'version': protocol_version, 'valid_versions': valid_versions})

    if port is not None:
        port = utils.validate_network_port(port, 'ipmi_terminal_port')

    if dest_port is not None:
        dest_port = utils.validate_network_port(dest_port, 'ipmi_port')

    # check if ipmi_bridging has proper value
    if bridging_type == 'no':
        # if bridging is not selected, then set all bridging params to None
        (local_address, transit_channel, transit_address, target_channel,
         target_address) = (None,) * 5
    elif bridging_type in bridging_types:
        # check if the particular bridging option is supported on host
        if not _is_option_supported('%s_bridge' % bridging_type):
            raise exception.InvalidParameterValue(_(
                "Value for ipmi_bridging is provided as %s, but IPMI "
                "bridging is not supported by the IPMI utility installed "
                "on host. Ensure ipmitool version is > 1.8.11"
            ) % bridging_type)

        # ensure that all the required parameters are provided
        params_undefined = [param for param, value in [
            ("ipmi_target_channel", target_channel),
            ('ipmi_target_address', target_address)] if value is None]
        if bridging_type == 'dual':
            params_undefined2 = [param for param, value in [
                ("ipmi_transit_channel", transit_channel),
                ('ipmi_transit_address', transit_address)
            ] if value is None]
            params_undefined.extend(params_undefined2)
        else:
            # if single bridging was selected, set dual bridge params to None
            transit_channel = transit_address = None

        # If the required parameters were not provided,
        # raise an exception
        if params_undefined:
            raise exception.MissingParameterValue(_(
                "%(param)s not provided") % {'param': params_undefined})
    else:
        raise exception.InvalidParameterValue(_(
            "Invalid value for ipmi_bridging: %(bridging_type)s,"
            " the valid value can be one of: %(bridging_types)s"
        ) % {'bridging_type': bridging_type,
             'bridging_types': bridging_types + ['no']})

    if priv_level not in VALID_PRIV_LEVELS:
        valid_priv_lvls = ', '.join(VALID_PRIV_LEVELS)
        raise exception.InvalidParameterValue(_(
            "Invalid privilege level value:%(priv_level)s, the valid value"
            " can be one of %(valid_levels)s") %
            {'priv_level': priv_level, 'valid_levels': valid_priv_lvls})

    return {
        'address': address,
        'dest_port': dest_port,
        'username': username,
        'password': password,
        'port': port,
        'uuid': node.uuid,
        'priv_level': priv_level,
        'local_address': local_address,
        'transit_channel': transit_channel,
        'transit_address': transit_address,
        'target_channel': target_channel,
        'target_address': target_address,
        'protocol_version': protocol_version,
        'force_boot_device': force_boot_device,
    }
Ejemplo n.º 24
0
def parse_driver_info(node):
    """Parse a node's driver_info values.

    Parses the driver_info of the node, reads default values
    and returns a dict containing the combination of both.

    :param node: an ironic node object.
    :returns: a dict containing information from driver_info
              and default values.
    :raises: InvalidParameterValue if some mandatory information
             is missing on the node or on invalid inputs.
    """
    driver_info = node.driver_info
    parsed_driver_info = {}

    if 'drac_host' in driver_info and 'drac_address' not in driver_info:
        LOG.warning(
            'The driver_info["drac_host"] property is deprecated '
            'and will be removed in the Pike release. Please '
            'update the node %s driver_info field to use '
            '"drac_address" instead', node.uuid)
        address = driver_info.pop('drac_host', None)
        if address:
            driver_info['drac_address'] = address
    elif 'drac_host' in driver_info and 'drac_address' in driver_info:
        LOG.warning(
            'Both driver_info["drac_address"] and '
            'driver_info["drac_host"] properties are '
            'specified for node %s. Please remove the '
            '"drac_host" property from the node. Ignoring '
            '"drac_host" for now', node.uuid)

    error_msgs = []
    for param in REQUIRED_PROPERTIES:
        try:
            parsed_driver_info[param] = str(driver_info[param])
        except KeyError:
            error_msgs.append(_("'%s' not supplied to DracDriver.") % param)
        except UnicodeEncodeError:
            error_msgs.append(_("'%s' contains non-ASCII symbol.") % param)

    parsed_driver_info['drac_port'] = driver_info.get('drac_port', 443)

    try:
        parsed_driver_info['drac_path'] = str(
            driver_info.get('drac_path', '/wsman'))
    except UnicodeEncodeError:
        error_msgs.append(_("'drac_path' contains non-ASCII symbol."))

    try:
        parsed_driver_info['drac_protocol'] = str(
            driver_info.get('drac_protocol', 'https'))

        if parsed_driver_info['drac_protocol'] not in ['http', 'https']:
            error_msgs.append(
                _("'drac_protocol' must be either 'http' or "
                  "'https'."))
    except UnicodeEncodeError:
        error_msgs.append(_("'drac_protocol' contains non-ASCII symbol."))

    if error_msgs:
        msg = (_('The following errors were encountered while parsing '
                 'driver_info:\n%s') % '\n'.join(error_msgs))
        raise exception.InvalidParameterValue(msg)

    port = parsed_driver_info['drac_port']
    parsed_driver_info['drac_port'] = utils.validate_network_port(
        port, 'drac_port')

    return parsed_driver_info
Ejemplo n.º 25
0
 def test_validate_network_port(self):
     port = utils.validate_network_port('0', 'message')
     self.assertEqual(0, port)
     port = utils.validate_network_port('65535')
     self.assertEqual(65535, port)
Ejemplo n.º 26
0
def _parse_optional_driver_info(node):
    """Parses the optional driver_info parameters.

    :param node: an ironic Node object.
    :returns: a dictionary containing information of optional properties.
    :raises: InvalidParameterValue if any parameters are incorrect
    """
    info = node.driver_info
    optional_info = {}
    not_integers = []

    for param in OPTIONAL_PROPERTIES:
        if param != 'ilo_verify_ca':
            value = info.get(param, CONF.ilo.get(param))

        if param == "client_port":
            optional_info[param] = utils.validate_network_port(value, param)
        elif param == "client_timeout":
            try:
                optional_info[param] = int(value)
            except ValueError:
                not_integers.append(param)

    if not_integers:
        raise exception.InvalidParameterValue(
            _("The following iLO parameters from the node's driver_info "
              "should be integers: %s") % not_integers)

    ca_file_value = info.get('ca_file', CONF.ilo.get('ca_file'))
    verify_ca = info.get('ilo_verify_ca', CONF.ilo.get('verify_ca'))

    if ca_file_value:
        LOG.warning(
            "The `driver_info/ca_file` parameter is deprecated "
            "in favor of `driver_info/ilo_verify_ca` parameter. "
            "Please use `driver_info/ilo_verify_ca` instead of "
            "`driver_info/ca_file` in node %(node)s "
            "configuration.", {'node': node.uuid})

        if not os.path.isfile(ca_file_value):
            raise exception.InvalidParameterValue(
                _('ca_file "%(value)s" is not found.') %
                {'value': ca_file_value})
        optional_info['verify_ca'] = ca_file_value
    else:
        # Check if ilo_verify_ca is a Boolean or a file/directory
        # in the file-system
        if isinstance(verify_ca, str):
            if not os.path.isdir(verify_ca) and not os.path.isfile(verify_ca):
                try:
                    verify_ca = strutils.bool_from_string(verify_ca,
                                                          strict=True)
                except ValueError:
                    raise exception.InvalidParameterValue(
                        _('Invalid value type set in driver_info/'
                          'ilo_verify_ca on node %(node)s. '
                          'The value should be a Boolean or the path '
                          'to a file/directory, not "%(value)s"') % {
                              'value': verify_ca,
                              'node': node.uuid
                          })
        elif not isinstance(verify_ca, bool):
            raise exception.InvalidParameterValue(
                _('Invalid value type set in driver_info/ilo_verify_ca '
                  'on node %(node)s. The value should be a Boolean '
                  'or the path to a file/directory, not "%(value)s"') % {
                      'value': verify_ca,
                      'node': node.uuid
                  })
        optional_info['verify_ca'] = verify_ca

    return optional_info
Ejemplo n.º 27
0
 def test_validate_network_port(self):
     port = utils.validate_network_port("1", "message")
     self.assertEqual(1, port)
     port = utils.validate_network_port("65535")
     self.assertEqual(65535, port)
Ejemplo n.º 28
0
 def test_validate_network_port(self):
     port = utils.validate_network_port('1', 'message')
     self.assertEqual(1, port)
     port = utils.validate_network_port('65535')
     self.assertEqual(65535, port)
Ejemplo n.º 29
0
def _parse_driver_info(node):
    """Gets the parameters required for ipmitool to access the node.

    :param node: the Node of interest.
    :returns: dictionary of parameters.
    :raises: InvalidParameterValue when an invalid value is specified
    :raises: MissingParameterValue when a required ipmi parameter is missing.

    """
    info = node.driver_info or {}
    bridging_types = ['single', 'dual']
    missing_info = [key for key in REQUIRED_PROPERTIES if not info.get(key)]
    if missing_info:
        raise exception.MissingParameterValue(
            _("Missing the following IPMI credentials in node's"
              " driver_info: %s.") % missing_info)

    address = info.get('ipmi_address')
    username = info.get('ipmi_username')
    password = six.text_type(info.get('ipmi_password', ''))
    dest_port = info.get('ipmi_port')
    port = info.get('ipmi_terminal_port')
    priv_level = info.get('ipmi_priv_level', 'ADMINISTRATOR')
    bridging_type = info.get('ipmi_bridging', 'no')
    local_address = info.get('ipmi_local_address')
    transit_channel = info.get('ipmi_transit_channel')
    transit_address = info.get('ipmi_transit_address')
    target_channel = info.get('ipmi_target_channel')
    target_address = info.get('ipmi_target_address')
    protocol_version = str(info.get('ipmi_protocol_version', '2.0'))
    force_boot_device = info.get('ipmi_force_boot_device', False)

    if not username:
        LOG.warning(
            _LW('ipmi_username is not defined or empty for node %s: '
                'NULL user will be utilized.') % node.uuid)
    if not password:
        LOG.warning(
            _LW('ipmi_password is not defined or empty for node %s: '
                'NULL password will be utilized.') % node.uuid)

    if protocol_version not in VALID_PROTO_VERSIONS:
        valid_versions = ', '.join(VALID_PROTO_VERSIONS)
        raise exception.InvalidParameterValue(
            _("Invalid IPMI protocol version value %(version)s, the valid "
              "value can be one of %(valid_versions)s") % {
                  'version': protocol_version,
                  'valid_versions': valid_versions
              })

    if port is not None:
        port = utils.validate_network_port(port, 'ipmi_terminal_port')

    if dest_port is not None:
        dest_port = utils.validate_network_port(dest_port, 'ipmi_port')

    # check if ipmi_bridging has proper value
    if bridging_type == 'no':
        # if bridging is not selected, then set all bridging params to None
        (local_address, transit_channel, transit_address, target_channel,
         target_address) = (None, ) * 5
    elif bridging_type in bridging_types:
        # check if the particular bridging option is supported on host
        if not _is_option_supported('%s_bridge' % bridging_type):
            raise exception.InvalidParameterValue(
                _("Value for ipmi_bridging is provided as %s, but IPMI "
                  "bridging is not supported by the IPMI utility installed "
                  "on host. Ensure ipmitool version is > 1.8.11") %
                bridging_type)

        # ensure that all the required parameters are provided
        params_undefined = [
            param for param, value in [(
                "ipmi_target_channel",
                target_channel), ('ipmi_target_address', target_address)]
            if value is None
        ]
        if bridging_type == 'dual':
            params_undefined2 = [
                param for param, value in [(
                    "ipmi_transit_channel",
                    transit_channel), ('ipmi_transit_address',
                                       transit_address)] if value is None
            ]
            params_undefined.extend(params_undefined2)
        else:
            # if single bridging was selected, set dual bridge params to None
            transit_channel = transit_address = None

        # If the required parameters were not provided,
        # raise an exception
        if params_undefined:
            raise exception.MissingParameterValue(
                _("%(param)s not provided") % {'param': params_undefined})
    else:
        raise exception.InvalidParameterValue(
            _("Invalid value for ipmi_bridging: %(bridging_type)s,"
              " the valid value can be one of: %(bridging_types)s") % {
                  'bridging_type': bridging_type,
                  'bridging_types': bridging_types + ['no']
              })

    if priv_level not in VALID_PRIV_LEVELS:
        valid_priv_lvls = ', '.join(VALID_PRIV_LEVELS)
        raise exception.InvalidParameterValue(
            _("Invalid privilege level value:%(priv_level)s, the valid value"
              " can be one of %(valid_levels)s") % {
                  'priv_level': priv_level,
                  'valid_levels': valid_priv_lvls
              })

    return {
        'address': address,
        'dest_port': dest_port,
        'username': username,
        'password': password,
        'port': port,
        'uuid': node.uuid,
        'priv_level': priv_level,
        'local_address': local_address,
        'transit_channel': transit_channel,
        'transit_address': transit_address,
        'target_channel': target_channel,
        'target_address': target_address,
        'protocol_version': protocol_version,
        'force_boot_device': force_boot_device,
    }