147f2e4c8SMichael Walsh#!/usr/bin/env python
247f2e4c8SMichael Walsh
347f2e4c8SMichael Walshr"""
447f2e4c8SMichael WalshThis program will get the system serial number from an OBMC machine and print
547f2e4c8SMichael Walshit to stdout.
647f2e4c8SMichael Walsh"""
747f2e4c8SMichael Walsh
847f2e4c8SMichael Walshimport sys
947f2e4c8SMichael Walshimport os
1047f2e4c8SMichael Walshimport requests
1147f2e4c8SMichael Walsh
1247f2e4c8SMichael Walshsave_path_0 = sys.path[0]
1347f2e4c8SMichael Walshdel sys.path[0]
1447f2e4c8SMichael Walsh
1547f2e4c8SMichael Walshfrom gen_arg import *
1647f2e4c8SMichael Walshfrom gen_print import *
1747f2e4c8SMichael Walshfrom gen_valid import *
1847f2e4c8SMichael Walsh
1947f2e4c8SMichael Walsh# Restore sys.path[0].
2047f2e4c8SMichael Walshsys.path.insert(0, save_path_0)
2147f2e4c8SMichael Walsh
2247f2e4c8SMichael Walshlogging.captureWarnings(True)
2347f2e4c8SMichael Walsh
2447f2e4c8SMichael Walshparser = argparse.ArgumentParser(
2547f2e4c8SMichael Walsh    usage='%(prog)s [OPTIONS]',
2647f2e4c8SMichael Walsh    description="%(prog)s will get the system serial number from an OBMC" +
2747f2e4c8SMichael Walsh                " machine and print it to stdout as follows:\n\n" +
2847f2e4c8SMichael Walsh                "mch_ser_num:<ser num>",
2947f2e4c8SMichael Walsh    formatter_class=argparse.RawTextHelpFormatter,
3047f2e4c8SMichael Walsh    prefix_chars='-+')
3147f2e4c8SMichael Walsh
3247f2e4c8SMichael Walshparser.add_argument(
3347f2e4c8SMichael Walsh    '--openbmc_username',
3447f2e4c8SMichael Walsh    default="root",
3547f2e4c8SMichael Walsh    help='The username for communicating with the OpenBMC machine.')
3647f2e4c8SMichael Walsh
3747f2e4c8SMichael Walshparser.add_argument(
3847f2e4c8SMichael Walsh    '--openbmc_password',
3947f2e4c8SMichael Walsh    default="0penBmc",
4047f2e4c8SMichael Walsh    help='The password for communicating with the OpenBMC machine.')
4147f2e4c8SMichael Walsh
4247f2e4c8SMichael Walshparser.add_argument(
4347f2e4c8SMichael Walsh    'openbmc_host',
4447f2e4c8SMichael Walsh    help='The host name or IP address of the OpenBMC machine.')
4547f2e4c8SMichael Walsh
4647f2e4c8SMichael Walsh# Populate stock_list with options we want.
4747f2e4c8SMichael Walshstock_list = [("test_mode", 0), ("quiet", 1)]
4847f2e4c8SMichael Walsh
4947f2e4c8SMichael Walsh
5047f2e4c8SMichael Walshdef exit_function(signal_number=0,
5147f2e4c8SMichael Walsh                  frame=None):
5247f2e4c8SMichael Walsh
5347f2e4c8SMichael Walsh    r"""
5447f2e4c8SMichael Walsh    Execute whenever the program ends normally or with the signals that we
5547f2e4c8SMichael Walsh    catch (i.e. TERM, INT).
5647f2e4c8SMichael Walsh    """
5747f2e4c8SMichael Walsh
5847f2e4c8SMichael Walsh    dprint_executing()
5947f2e4c8SMichael Walsh    dprint_var(signal_number)
6047f2e4c8SMichael Walsh
6147f2e4c8SMichael Walsh    qprint_pgm_footer()
6247f2e4c8SMichael Walsh
6347f2e4c8SMichael Walsh
6447f2e4c8SMichael Walshdef signal_handler(signal_number,
6547f2e4c8SMichael Walsh                   frame):
6647f2e4c8SMichael Walsh
6747f2e4c8SMichael Walsh    r"""
6847f2e4c8SMichael Walsh    Handle signals.  Without a function to catch a SIGTERM or SIGINT, our
6947f2e4c8SMichael Walsh    program would terminate immediately with return code 143 and without
7047f2e4c8SMichael Walsh    calling our exit_function.
7147f2e4c8SMichael Walsh    """
7247f2e4c8SMichael Walsh
7347f2e4c8SMichael Walsh    # Our convention is to set up exit_function with atexit.register() so
7447f2e4c8SMichael Walsh    # there is no need to explicitly call exit_function from here.
7547f2e4c8SMichael Walsh
7647f2e4c8SMichael Walsh    dprint_executing()
7747f2e4c8SMichael Walsh
7847f2e4c8SMichael Walsh    # Calling exit prevents us from returning to the code that was running
7947f2e4c8SMichael Walsh    # when we received the signal.
8047f2e4c8SMichael Walsh    exit(0)
8147f2e4c8SMichael Walsh
8247f2e4c8SMichael Walsh
8347f2e4c8SMichael Walshdef validate_parms():
8447f2e4c8SMichael Walsh
8547f2e4c8SMichael Walsh    r"""
8647f2e4c8SMichael Walsh    Validate program parameters, etc.  Return True or False (i.e. pass/fail)
8747f2e4c8SMichael Walsh    accordingly.
8847f2e4c8SMichael Walsh    """
8947f2e4c8SMichael Walsh
9047f2e4c8SMichael Walsh    gen_post_validation(exit_function, signal_handler)
9147f2e4c8SMichael Walsh
9247f2e4c8SMichael Walsh    return True
9347f2e4c8SMichael Walsh
9447f2e4c8SMichael Walsh
9547f2e4c8SMichael Walshdef create_http_prefix(host):
9647f2e4c8SMichael Walsh
9747f2e4c8SMichael Walsh    r"""
9847f2e4c8SMichael Walsh    Create and return an http prefix string.
9947f2e4c8SMichael Walsh
10047f2e4c8SMichael Walsh    Description of argument(s):
10147f2e4c8SMichael Walsh    host                            The host being communicated with via the
10247f2e4c8SMichael Walsh                                    curl command.
10347f2e4c8SMichael Walsh    """
10447f2e4c8SMichael Walsh
10547f2e4c8SMichael Walsh    return "https://" + host + "/"
10647f2e4c8SMichael Walsh
10747f2e4c8SMichael Walsh
10847f2e4c8SMichael Walshdef main():
10947f2e4c8SMichael Walsh
11047f2e4c8SMichael Walsh    if not gen_get_options(parser, stock_list):
11147f2e4c8SMichael Walsh        return False
11247f2e4c8SMichael Walsh
11347f2e4c8SMichael Walsh    if not validate_parms():
11447f2e4c8SMichael Walsh        return False
11547f2e4c8SMichael Walsh
11647f2e4c8SMichael Walsh    qprint_pgm_header()
11747f2e4c8SMichael Walsh
11847f2e4c8SMichael Walsh    session = requests.Session()
11947f2e4c8SMichael Walsh
12047f2e4c8SMichael Walsh    http_prefix = create_http_prefix(openbmc_host)
12147f2e4c8SMichael Walsh
12247f2e4c8SMichael Walsh    command = http_prefix + 'login'
12347f2e4c8SMichael Walsh    qprint_issuing(command)
12447f2e4c8SMichael Walsh    resp = session.post(command,
12547f2e4c8SMichael Walsh                        json={'data': [openbmc_username, openbmc_password]},
12647f2e4c8SMichael Walsh                        verify=False)
12747f2e4c8SMichael Walsh    if resp.json()['status'] != 'ok':
12847f2e4c8SMichael Walsh        json = resp.json()
12947f2e4c8SMichael Walsh        print_error_report("http request failed:\n" + sprint_var(command, 1))
13047f2e4c8SMichael Walsh        raise Exception("Login failed.\n")
13147f2e4c8SMichael Walsh
13247f2e4c8SMichael Walsh    command = http_prefix + "xyz/openbmc_project/inventory/system"
13347f2e4c8SMichael Walsh    qprint_issuing(command)
13447f2e4c8SMichael Walsh    resp = session.get(command, verify=False)
13547f2e4c8SMichael Walsh    json = resp.json()
13647f2e4c8SMichael Walsh    if json['status'] != 'ok':
13747f2e4c8SMichael Walsh        print_error_report("http request failed:\n" + sprint_var(command, 1))
13847f2e4c8SMichael Walsh        raise Exception("http request failed.\n")
13947f2e4c8SMichael Walsh
140*34162378SMichael Walsh    try:
14147f2e4c8SMichael Walsh        mch_ser_num = json['data']['SerialNumber']
142*34162378SMichael Walsh    except KeyError:
143*34162378SMichael Walsh        print_error_report("Failed to find 'SerialNumber' key in the" +
144*34162378SMichael Walsh                           " following data:\n" + sprint_var(json))
145*34162378SMichael Walsh        return False
14647f2e4c8SMichael Walsh    pvar(mch_ser_num, 0, 0, 0)
14747f2e4c8SMichael Walsh
14847f2e4c8SMichael Walsh    return True
14947f2e4c8SMichael Walsh
15047f2e4c8SMichael Walsh
15147f2e4c8SMichael Walsh# Main
15247f2e4c8SMichael Walsh
15347f2e4c8SMichael Walshif not main():
15447f2e4c8SMichael Walsh    exit(1)
155