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 os
8*20f38712SPatrick Williamsimport sys
9*20f38712SPatrick Williams
10e635ddc0SGeorge Keishingimport requests
11e635ddc0SGeorge Keishing
1247f2e4c8SMichael Walshsave_path_0 = sys.path[0]
1347f2e4c8SMichael Walshdel sys.path[0]
1447f2e4c8SMichael Walsh
1509679890SGeorge Keishingfrom gen_arg import *  # NOQA
1609679890SGeorge Keishingfrom gen_print import *  # NOQA
1709679890SGeorge Keishingfrom gen_valid import *  # NOQA
1837c58c8cSGeorge Keishing
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(
25*20f38712SPatrick Williams    usage="%(prog)s [OPTIONS]",
26a57fef4aSPatrick Williams    description="%(prog)s will get the system serial number from an OBMC"
27a57fef4aSPatrick Williams    + " machine and print it to stdout as follows:\n\n"
28a57fef4aSPatrick Williams    + "mch_ser_num:<ser num>",
29d0741f8aSMichael Walsh    formatter_class=argparse.ArgumentDefaultsHelpFormatter,
30*20f38712SPatrick Williams    prefix_chars="-+",
31*20f38712SPatrick Williams)
3247f2e4c8SMichael Walsh
3347f2e4c8SMichael Walshparser.add_argument(
34*20f38712SPatrick Williams    "--openbmc_username",
3547f2e4c8SMichael Walsh    default="root",
36*20f38712SPatrick Williams    help="The username for communicating with the OpenBMC machine.",
37*20f38712SPatrick Williams)
3847f2e4c8SMichael Walsh
3947f2e4c8SMichael Walshparser.add_argument(
40*20f38712SPatrick Williams    "--openbmc_password",
4147f2e4c8SMichael Walsh    default="0penBmc",
42*20f38712SPatrick Williams    help="The password for communicating with the OpenBMC machine.",
43*20f38712SPatrick Williams)
4447f2e4c8SMichael Walsh
4547f2e4c8SMichael Walshparser.add_argument(
46*20f38712SPatrick Williams    "openbmc_host", help="The host name or IP address of the OpenBMC machine."
47*20f38712SPatrick Williams)
4847f2e4c8SMichael Walsh
4947f2e4c8SMichael Walsh# Populate stock_list with options we want.
5047f2e4c8SMichael Walshstock_list = [("test_mode", 0), ("quiet", 1)]
5147f2e4c8SMichael Walsh
5247f2e4c8SMichael Walsh
53*20f38712SPatrick Williamsdef exit_function(signal_number=0, frame=None):
5447f2e4c8SMichael Walsh    r"""
55410b1787SMichael Walsh    Execute whenever the program ends normally or with the signals that we 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
64*20f38712SPatrick Williamsdef signal_handler(signal_number, frame):
6547f2e4c8SMichael Walsh    r"""
66410b1787SMichael Walsh    Handle signals.  Without a function to catch a SIGTERM or SIGINT, our program would terminate immediately
67410b1787SMichael Walsh    with return code 143 and without calling our exit_function.
6847f2e4c8SMichael Walsh    """
6947f2e4c8SMichael Walsh
70410b1787SMichael Walsh    # Our convention is to set up exit_function with atexit.register() so there is no need to explicitly
71410b1787SMichael Walsh    # call exit_function from here.
7247f2e4c8SMichael Walsh
7347f2e4c8SMichael Walsh    dprint_executing()
7447f2e4c8SMichael Walsh
75410b1787SMichael Walsh    # Calling exit prevents us from returning to the code that was running when we received the signal.
7647f2e4c8SMichael Walsh    exit(0)
7747f2e4c8SMichael Walsh
7847f2e4c8SMichael Walsh
7947f2e4c8SMichael Walshdef validate_parms():
8047f2e4c8SMichael Walsh    r"""
81410b1787SMichael Walsh    Validate program parameters, etc.  Return True or False (i.e. pass/fail) accordingly.
8247f2e4c8SMichael Walsh    """
8347f2e4c8SMichael Walsh
8447f2e4c8SMichael Walsh    gen_post_validation(exit_function, signal_handler)
8547f2e4c8SMichael Walsh
8647f2e4c8SMichael Walsh    return True
8747f2e4c8SMichael Walsh
8847f2e4c8SMichael Walsh
8947f2e4c8SMichael Walshdef create_http_prefix(host):
9047f2e4c8SMichael Walsh    r"""
9147f2e4c8SMichael Walsh    Create and return an http prefix string.
9247f2e4c8SMichael Walsh
9347f2e4c8SMichael Walsh    Description of argument(s):
94410b1787SMichael Walsh    host                            The host being communicated with via the curl command.
9547f2e4c8SMichael Walsh    """
9647f2e4c8SMichael Walsh
9747f2e4c8SMichael Walsh    return "https://" + host + "/"
9847f2e4c8SMichael Walsh
9947f2e4c8SMichael Walsh
10047f2e4c8SMichael Walshdef main():
10147f2e4c8SMichael Walsh    if not gen_get_options(parser, stock_list):
10247f2e4c8SMichael Walsh        return False
10347f2e4c8SMichael Walsh
10447f2e4c8SMichael Walsh    if not validate_parms():
10547f2e4c8SMichael Walsh        return False
10647f2e4c8SMichael Walsh
10747f2e4c8SMichael Walsh    qprint_pgm_header()
10847f2e4c8SMichael Walsh
10947f2e4c8SMichael Walsh    session = requests.Session()
11047f2e4c8SMichael Walsh
11147f2e4c8SMichael Walsh    http_prefix = create_http_prefix(openbmc_host)
11247f2e4c8SMichael Walsh
113*20f38712SPatrick Williams    command = http_prefix + "login"
11447f2e4c8SMichael Walsh    qprint_issuing(command)
115*20f38712SPatrick Williams    resp = session.post(
116*20f38712SPatrick Williams        command,
117*20f38712SPatrick Williams        json={"data": [openbmc_username, openbmc_password]},
118*20f38712SPatrick Williams        verify=False,
119*20f38712SPatrick Williams    )
120*20f38712SPatrick Williams    if resp.json()["status"] != "ok":
12147f2e4c8SMichael Walsh        json = resp.json()
122c2762f62SMichael Walsh        print_error_report("http request failed:\n" + sprint_var(command))
12347f2e4c8SMichael Walsh        raise Exception("Login failed.\n")
12447f2e4c8SMichael Walsh
12547f2e4c8SMichael Walsh    command = http_prefix + "xyz/openbmc_project/inventory/system"
12647f2e4c8SMichael Walsh    qprint_issuing(command)
12747f2e4c8SMichael Walsh    resp = session.get(command, verify=False)
12847f2e4c8SMichael Walsh    json = resp.json()
129*20f38712SPatrick Williams    if json["status"] != "ok":
130c2762f62SMichael Walsh        print_error_report("http request failed:\n" + sprint_var(command))
13147f2e4c8SMichael Walsh        raise Exception("http request failed.\n")
13247f2e4c8SMichael Walsh
13334162378SMichael Walsh    try:
134*20f38712SPatrick Williams        mch_ser_num = json["data"]["SerialNumber"]
13534162378SMichael Walsh    except KeyError:
136*20f38712SPatrick Williams        print_error_report(
137*20f38712SPatrick Williams            "Failed to find 'SerialNumber' key in the"
138*20f38712SPatrick Williams            + " following data:\n"
139*20f38712SPatrick Williams            + sprint_var(json)
140*20f38712SPatrick Williams        )
14134162378SMichael Walsh        return False
142c2762f62SMichael Walsh    print_var(mch_ser_num, 0, 0, 0)
14347f2e4c8SMichael Walsh
14447f2e4c8SMichael Walsh    return True
14547f2e4c8SMichael Walsh
14647f2e4c8SMichael Walsh
14747f2e4c8SMichael Walsh# Main
14847f2e4c8SMichael Walsh
14947f2e4c8SMichael Walshif not main():
15047f2e4c8SMichael Walsh    exit(1)
151