1e7e9171eSGeorge Keishing#!/usr/bin/env python3
247f2e4c8SMichael Walsh
347f2e4c8SMichael Walshr"""
4410b1787SMichael WalshThis program will get the system serial number from an OBMC machine and print it to stdout.
547f2e4c8SMichael Walsh"""
647f2e4c8SMichael Walsh
7e635ddc0SGeorge Keishingimport sys
8e635ddc0SGeorge Keishingimport os
9e635ddc0SGeorge Keishingimport requests
10e635ddc0SGeorge Keishing
1147f2e4c8SMichael Walshsave_path_0 = sys.path[0]
1247f2e4c8SMichael Walshdel sys.path[0]
1347f2e4c8SMichael Walsh
14*37c58c8cSGeorge Keishingfrom gen_arg import *
15*37c58c8cSGeorge Keishingfrom gen_print import *
16*37c58c8cSGeorge Keishingfrom gen_valid import *
17*37c58c8cSGeorge Keishing
1847f2e4c8SMichael Walsh# Restore sys.path[0].
1947f2e4c8SMichael Walshsys.path.insert(0, save_path_0)
2047f2e4c8SMichael Walsh
2147f2e4c8SMichael Walshlogging.captureWarnings(True)
2247f2e4c8SMichael Walsh
2347f2e4c8SMichael Walshparser = argparse.ArgumentParser(
24e635ddc0SGeorge Keishing    usage='%(prog)s [OPTIONS]',
25a57fef4aSPatrick Williams    description="%(prog)s will get the system serial number from an OBMC"
26a57fef4aSPatrick Williams    + " machine and print it to stdout as follows:\n\n"
27a57fef4aSPatrick Williams    + "mch_ser_num:<ser num>",
28d0741f8aSMichael Walsh    formatter_class=argparse.ArgumentDefaultsHelpFormatter,
29e635ddc0SGeorge Keishing    prefix_chars='-+')
3047f2e4c8SMichael Walsh
3147f2e4c8SMichael Walshparser.add_argument(
32e635ddc0SGeorge Keishing    '--openbmc_username',
3347f2e4c8SMichael Walsh    default="root",
34e635ddc0SGeorge Keishing    help='The username for communicating with the OpenBMC machine.')
3547f2e4c8SMichael Walsh
3647f2e4c8SMichael Walshparser.add_argument(
37e635ddc0SGeorge Keishing    '--openbmc_password',
3847f2e4c8SMichael Walsh    default="0penBmc",
39e635ddc0SGeorge Keishing    help='The password for communicating with the OpenBMC machine.')
4047f2e4c8SMichael Walsh
4147f2e4c8SMichael Walshparser.add_argument(
42e635ddc0SGeorge Keishing    'openbmc_host',
43e635ddc0SGeorge Keishing    help='The host name or IP address of the OpenBMC machine.')
4447f2e4c8SMichael Walsh
4547f2e4c8SMichael Walsh# Populate stock_list with options we want.
4647f2e4c8SMichael Walshstock_list = [("test_mode", 0), ("quiet", 1)]
4747f2e4c8SMichael Walsh
4847f2e4c8SMichael Walsh
49e635ddc0SGeorge Keishingdef exit_function(signal_number=0,
50e635ddc0SGeorge Keishing                  frame=None):
5147f2e4c8SMichael Walsh    r"""
52410b1787SMichael Walsh    Execute whenever the program ends normally or with the signals that we catch (i.e. TERM, INT).
5347f2e4c8SMichael Walsh    """
5447f2e4c8SMichael Walsh
5547f2e4c8SMichael Walsh    dprint_executing()
5647f2e4c8SMichael Walsh    dprint_var(signal_number)
5747f2e4c8SMichael Walsh
5847f2e4c8SMichael Walsh    qprint_pgm_footer()
5947f2e4c8SMichael Walsh
6047f2e4c8SMichael Walsh
61e635ddc0SGeorge Keishingdef signal_handler(signal_number,
62e635ddc0SGeorge Keishing                   frame):
6347f2e4c8SMichael Walsh    r"""
64410b1787SMichael Walsh    Handle signals.  Without a function to catch a SIGTERM or SIGINT, our program would terminate immediately
65410b1787SMichael Walsh    with return code 143 and without calling our exit_function.
6647f2e4c8SMichael Walsh    """
6747f2e4c8SMichael Walsh
68410b1787SMichael Walsh    # Our convention is to set up exit_function with atexit.register() so there is no need to explicitly
69410b1787SMichael Walsh    # call exit_function from here.
7047f2e4c8SMichael Walsh
7147f2e4c8SMichael Walsh    dprint_executing()
7247f2e4c8SMichael Walsh
73410b1787SMichael Walsh    # Calling exit prevents us from returning to the code that was running when we received the signal.
7447f2e4c8SMichael Walsh    exit(0)
7547f2e4c8SMichael Walsh
7647f2e4c8SMichael Walsh
7747f2e4c8SMichael Walshdef validate_parms():
7847f2e4c8SMichael Walsh    r"""
79410b1787SMichael Walsh    Validate program parameters, etc.  Return True or False (i.e. pass/fail) accordingly.
8047f2e4c8SMichael Walsh    """
8147f2e4c8SMichael Walsh
8247f2e4c8SMichael Walsh    gen_post_validation(exit_function, signal_handler)
8347f2e4c8SMichael Walsh
8447f2e4c8SMichael Walsh    return True
8547f2e4c8SMichael Walsh
8647f2e4c8SMichael Walsh
8747f2e4c8SMichael Walshdef create_http_prefix(host):
8847f2e4c8SMichael Walsh    r"""
8947f2e4c8SMichael Walsh    Create and return an http prefix string.
9047f2e4c8SMichael Walsh
9147f2e4c8SMichael Walsh    Description of argument(s):
92410b1787SMichael Walsh    host                            The host being communicated with via the curl command.
9347f2e4c8SMichael Walsh    """
9447f2e4c8SMichael Walsh
9547f2e4c8SMichael Walsh    return "https://" + host + "/"
9647f2e4c8SMichael Walsh
9747f2e4c8SMichael Walsh
9847f2e4c8SMichael Walshdef main():
99e635ddc0SGeorge Keishing
10047f2e4c8SMichael Walsh    if not gen_get_options(parser, stock_list):
10147f2e4c8SMichael Walsh        return False
10247f2e4c8SMichael Walsh
10347f2e4c8SMichael Walsh    if not validate_parms():
10447f2e4c8SMichael Walsh        return False
10547f2e4c8SMichael Walsh
10647f2e4c8SMichael Walsh    qprint_pgm_header()
10747f2e4c8SMichael Walsh
10847f2e4c8SMichael Walsh    session = requests.Session()
10947f2e4c8SMichael Walsh
11047f2e4c8SMichael Walsh    http_prefix = create_http_prefix(openbmc_host)
11147f2e4c8SMichael Walsh
112e635ddc0SGeorge Keishing    command = http_prefix + 'login'
11347f2e4c8SMichael Walsh    qprint_issuing(command)
114e635ddc0SGeorge Keishing    resp = session.post(command,
115e635ddc0SGeorge Keishing                        json={'data': [openbmc_username, openbmc_password]},
116e635ddc0SGeorge Keishing                        verify=False)
117e635ddc0SGeorge Keishing    if resp.json()['status'] != 'ok':
11847f2e4c8SMichael Walsh        json = resp.json()
119c2762f62SMichael Walsh        print_error_report("http request failed:\n" + sprint_var(command))
12047f2e4c8SMichael Walsh        raise Exception("Login failed.\n")
12147f2e4c8SMichael Walsh
12247f2e4c8SMichael Walsh    command = http_prefix + "xyz/openbmc_project/inventory/system"
12347f2e4c8SMichael Walsh    qprint_issuing(command)
12447f2e4c8SMichael Walsh    resp = session.get(command, verify=False)
12547f2e4c8SMichael Walsh    json = resp.json()
126e635ddc0SGeorge Keishing    if json['status'] != 'ok':
127c2762f62SMichael Walsh        print_error_report("http request failed:\n" + sprint_var(command))
12847f2e4c8SMichael Walsh        raise Exception("http request failed.\n")
12947f2e4c8SMichael Walsh
13034162378SMichael Walsh    try:
131e635ddc0SGeorge Keishing        mch_ser_num = json['data']['SerialNumber']
13234162378SMichael Walsh    except KeyError:
133e635ddc0SGeorge Keishing        print_error_report("Failed to find 'SerialNumber' key in the"
134e635ddc0SGeorge Keishing                           + " following data:\n" + sprint_var(json))
13534162378SMichael Walsh        return False
136c2762f62SMichael Walsh    print_var(mch_ser_num, 0, 0, 0)
13747f2e4c8SMichael Walsh
13847f2e4c8SMichael Walsh    return True
13947f2e4c8SMichael Walsh
14047f2e4c8SMichael Walsh
14147f2e4c8SMichael Walsh# Main
14247f2e4c8SMichael Walsh
14347f2e4c8SMichael Walshif not main():
14447f2e4c8SMichael Walsh    exit(1)
145