1#!/usr/bin/env python
2
3r"""
4A python companion file for ipmi_client.robot.
5"""
6
7import collections
8import gen_print as gp
9import gen_cmd as gc
10from robot.libraries.BuiltIn import BuiltIn
11
12
13# Set default values for required IPMI options.
14ipmi_interface = 'lanplus'
15ipmi_cipher_suite = BuiltIn().get_variable_value("${IPMI_CIPHER_LEVEL}", '3')
16ipmi_username = BuiltIn().get_variable_value("${IPMI_USERNAME}", "root")
17ipmi_password = BuiltIn().get_variable_value("${IPMI_PASSWORD}", "0penBmc")
18ipmi_host = BuiltIn().get_variable_value("${OPENBMC_HOST}")
19
20# Create a list of the required IPMI options.
21ipmi_required_options = ['I', 'C', 'U', 'P', 'H']
22# The following dictionary maps the ipmitool option names (e.g. "I") to our
23# more descriptive names (e.g. "interface") for the required options.
24ipmi_option_name_map = {
25    'I': 'interface',
26    'C': 'cipher_suite',
27    'U': 'username',
28    'P': 'password',
29    'H': 'host',
30}
31
32
33def create_ipmi_ext_command_string(command, **options):
34    r"""
35    Create and return an IPMI external command string which is fit to be run
36    from a bash command line.
37
38    Example:
39
40    ipmi_ext_cmd = create_ipmi_ext_command_string('power status')
41
42    Result:
43    ipmitool -I lanplus -C 3 -P ******** -H x.x.x.x power status
44
45    Example:
46
47    ipmi_ext_cmd = create_ipmi_ext_command_string('power status', C='4')
48
49    Result:
50    ipmitool -I lanplus -C 4 -P ******** -H x.x.x.x power status
51
52    Description of argument(s):
53    command                         The ipmitool command (e.g. 'power status').
54    options                         Any desired options that are understood by
55                                    ipmitool (see iptmitool's help text for a
56                                    complete list).  If the caller does NOT
57                                    provide any of several required options
58                                    (e.g. "P", i.e. password), this function
59                                    will include them on the caller's behalf
60                                    using default values.
61    """
62
63    new_options = collections.OrderedDict()
64    for option in ipmi_required_options:
65        if option in options:
66            # If the caller has specified this particular option, use it in
67            # preference to the default value.
68            new_options[option] = options[option]
69            # Delete the value from the caller's options.
70            del options[option]
71        else:
72            # The caller hasn't specified this required option so specify it
73            # for them using the global value.
74            var_name = 'ipmi_' + ipmi_option_name_map[option]
75            value = eval(var_name)
76            new_options[option] = value
77    # Include the remainder of the caller's options in the new options
78    # dictionary.
79    for key, value in options.items():
80        new_options[key] = value
81
82    return gc.create_command_string('ipmitool', command, new_options)
83
84
85def verify_ipmi_user_parm_accepted():
86    r"""
87    Deterimine whether the OBMC accepts the '-U' ipmitool option and adjust
88    the global ipmi_required_options accordingly.
89    """
90
91    # Assumption: "U" is in the global ipmi_required_options.
92    global ipmi_required_options
93    print_output = 0
94
95    command_string = create_ipmi_ext_command_string('power status')
96    rc, stdout = gc.shell_cmd(command_string,
97                              print_output=print_output,
98                              show_err=0,
99                              ignore_err=1)
100    gp.qprint_var(rc, 1)
101    if rc == 0:
102        # The OBMC accepts the ipmitool "-U" option so new further work needs
103        # to be done.
104        return
105
106    # Remove the "U" option from ipmi_required_options to allow us to create a
107    # command string without the "U" option.
108    if 'U' in ipmi_required_options:
109        del ipmi_required_options[ipmi_required_options.index('U')]
110    command_string = create_ipmi_ext_command_string('power status')
111    rc, stdout = gc.shell_cmd(command_string,
112                              print_output=print_output,
113                              show_err=0,
114                              ignore_err=1)
115    gp.qprint_var(rc, 1)
116    if rc == 0:
117        # The "U" option has been removed from the ipmi_required_options
118        # global variable.
119        return
120
121    message = "Unable to run ipmitool (with or without the '-U' option).\n"
122    gp.print_error(message)
123
124    # Revert to original ipmi_required_options by inserting 'U' right before
125    # 'P'.
126    ipmi_required_options.insert(ipmi_required_options.index('P'), 'U')
127
128
129def ipmi_setup():
130    r"""
131    Perform all required setup for running iptmitool commands.
132    """
133
134    verify_ipmi_user_parm_accepted()
135
136
137ipmi_setup()
138
139
140def process_ipmi_user_options(command):
141    r"""
142    Return the buffer with any ipmi_user_options pre-pended.
143
144    Description of argument(s):
145    command                         An IPMI command (e.g. "power status").
146    """
147
148    ipmi_user_options = BuiltIn().get_variable_value("${IPMI_USER_OPTIONS}", '')
149    if ipmi_user_options == "":
150        return command
151    return ipmi_user_options + " " + command
152