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