1#!/usr/bin/env python3
2
3r"""
4This program will get the system serial number from an OBMC machine and print it to stdout.
5"""
6
7import os
8import sys
9
10import requests
11from gen_arg import *
12from gen_print import *
13from gen_valid import *
14
15save_path_0 = sys.path[0]
16del sys.path[0]
17
18# Restore sys.path[0].
19sys.path.insert(0, save_path_0)
20
21logging.captureWarnings(True)
22
23parser = argparse.ArgumentParser(
24    usage="%(prog)s [OPTIONS]",
25    description="%(prog)s will get the system serial number from an OBMC"
26    + " machine and print it to stdout as follows:\n\n"
27    + "mch_ser_num:<ser num>",
28    formatter_class=argparse.ArgumentDefaultsHelpFormatter,
29    prefix_chars="-+",
30)
31
32parser.add_argument(
33    "--openbmc_username",
34    default="root",
35    help="The username for communicating with the OpenBMC machine.",
36)
37
38parser.add_argument(
39    "--openbmc_password",
40    default="0penBmc",
41    help="The password for communicating with the OpenBMC machine.",
42)
43
44parser.add_argument(
45    "openbmc_host", help="The host name or IP address of the OpenBMC machine."
46)
47
48# Populate stock_list with options we want.
49stock_list = [("test_mode", 0), ("quiet", 1)]
50
51
52def exit_function(signal_number=0, frame=None):
53    r"""
54    Execute whenever the program ends normally or with the signals that we catch (i.e. TERM, INT).
55    """
56
57    dprint_executing()
58    dprint_var(signal_number)
59
60    qprint_pgm_footer()
61
62
63def signal_handler(signal_number, frame):
64    r"""
65    Handle signals.  Without a function to catch a SIGTERM or SIGINT, our program would terminate immediately
66    with return code 143 and without calling our exit_function.
67    """
68
69    # Our convention is to set up exit_function with atexit.register() so there is no need to explicitly
70    # call exit_function from here.
71
72    dprint_executing()
73
74    # Calling exit prevents us from returning to the code that was running when we received the signal.
75    exit(0)
76
77
78def validate_parms():
79    r"""
80    Validate program parameters, etc.  Return True or False (i.e. pass/fail) accordingly.
81    """
82
83    gen_post_validation(exit_function, signal_handler)
84
85    return True
86
87
88def create_http_prefix(host):
89    r"""
90    Create and return an http prefix string.
91
92    Description of argument(s):
93    host                            The host being communicated with via the curl command.
94    """
95
96    return "https://" + host + "/"
97
98
99def main():
100    if not gen_get_options(parser, stock_list):
101        return False
102
103    if not validate_parms():
104        return False
105
106    qprint_pgm_header()
107
108    session = requests.Session()
109
110    http_prefix = create_http_prefix(openbmc_host)
111
112    command = http_prefix + "login"
113    qprint_issuing(command)
114    resp = session.post(
115        command,
116        json={"data": [openbmc_username, openbmc_password]},
117        verify=False,
118    )
119    if resp.json()["status"] != "ok":
120        json = resp.json()
121        print_error_report("http request failed:\n" + sprint_var(command))
122        raise Exception("Login failed.\n")
123
124    command = http_prefix + "xyz/openbmc_project/inventory/system"
125    qprint_issuing(command)
126    resp = session.get(command, verify=False)
127    json = resp.json()
128    if json["status"] != "ok":
129        print_error_report("http request failed:\n" + sprint_var(command))
130        raise Exception("http request failed.\n")
131
132    try:
133        mch_ser_num = json["data"]["SerialNumber"]
134    except KeyError:
135        print_error_report(
136            "Failed to find 'SerialNumber' key in the"
137            + " following data:\n"
138            + sprint_var(json)
139        )
140        return False
141    print_var(mch_ser_num, 0, 0, 0)
142
143    return True
144
145
146# Main
147
148if not main():
149    exit(1)
150