1#!/usr/bin/env python3
2
3r"""
4CLI FFDC Collector.
5"""
6
7import os
8import sys
9
10import click
11
12# ---------Set sys.path for cli command execution---------------------------------------
13# Absolute path to openbmc-test-automation/ffdc
14abs_path = os.path.abspath(os.path.dirname(sys.argv[0]))
15full_path = abs_path.split("ffdc")[0]
16sys.path.append(full_path)
17# Walk path and append to sys.path
18for root, dirs, files in os.walk(full_path):
19    for found_dir in dirs:
20        sys.path.append(os.path.join(root, found_dir))
21
22from ffdc_collector import ffdc_collector  # NOQA
23
24
25@click.command(context_settings=dict(help_option_names=["-h", "--help"]))
26@click.option("-r", "--remote", help="Hostname/IP of the remote host")
27@click.option("-u", "--username", help="Username of the remote host.")
28@click.option("-p", "--password", help="Password of the remote host.")
29@click.option(
30    "-port_ssh", default=22, show_default=True, help="SSH port value."
31)
32@click.option(
33    "-port_https", default=443, show_default=True, help="HTTPS port value."
34)
35@click.option(
36    "-port_ipmi", default=623, show_default=True, help="IPMI port value."
37)
38@click.option(
39    "-c",
40    "--config",
41    default=abs_path + "/ffdc_config.yaml",
42    show_default=True,
43    help="YAML Configuration file for log collection.",
44)
45@click.option(
46    "-l",
47    "--location",
48    default="/tmp",
49    show_default=True,
50    help="Location to save logs",
51)
52@click.option(
53    "-t",
54    "--type",
55    help=(
56        "OS type of the remote (targeting) host. OPENBMC, RHEL, UBUNTU,"
57        " SLES, AIX"
58    ),
59)
60@click.option(
61    "-rp",
62    "--protocol",
63    default="ALL",
64    show_default=True,
65    help="Select protocol to communicate with remote host.",
66)
67@click.option(
68    "-e",
69    "--env_vars",
70    show_default=True,
71    help="Environment variables e.g: {'var':value}",
72)
73@click.option(
74    "-ec",
75    "--econfig",
76    show_default=True,
77    help="Predefine environment variables, refer en_vars_template.yaml ",
78)
79@click.option(
80    "--log_level",
81    default="INFO",
82    show_default=True,
83    help="Log level (CRITICAL, ERROR, WARNING, INFO, DEBUG)",
84)
85def cli_ffdc(
86    remote,
87    username,
88    password,
89    port_ssh,
90    port_https,
91    port_ipmi,
92    config,
93    location,
94    type,
95    protocol,
96    env_vars,
97    econfig,
98    log_level,
99):
100    r"""
101    Stand alone CLI to generate and collect FFDC from the selected target.
102    """
103
104    click.echo(
105        "\n********** FFDC (First Failure Data Collection) Starts **********"
106    )
107
108    if input_options_ok(
109        remote,
110        username,
111        password,
112        port_ssh,
113        port_https,
114        port_ipmi,
115        config,
116        type,
117    ):
118        this_ffdc = ffdc_collector(
119            remote,
120            username,
121            password,
122            port_ssh,
123            port_https,
124            port_ipmi,
125            config,
126            location,
127            type,
128            protocol,
129            env_vars,
130            econfig,
131            log_level,
132        )
133        this_ffdc.collect_ffdc()
134
135        if len(os.listdir(this_ffdc.ffdc_dir_path)) == 0:
136            click.echo(
137                "\n\tFFDC Collection from " + remote + " has failed.\n\n"
138            )
139        else:
140            click.echo(
141                str(
142                    "\n\t"
143                    + str(len(os.listdir(this_ffdc.ffdc_dir_path)))
144                    + " files were retrieved from "
145                    + remote
146                )
147            )
148            click.echo("\tFiles are stored in " + this_ffdc.ffdc_dir_path)
149
150        click.echo("\tTotal elapsed time " + this_ffdc.elapsed_time + "\n\n")
151    click.echo("\n********** FFDC Finishes **********\n\n")
152
153
154def input_options_ok(
155    remote, username, password, port_ssh, port_https, port_ipmi, config, type
156):
157    r"""
158    Verify script options exist via CLI options or environment variables.
159    """
160
161    all_options_ok = True
162
163    if not remote:
164        all_options_ok = False
165        print(
166            "        \n\tERROR: Name/IP of the remote host is not specified in"
167            " CLI options."
168        )
169    if not username:
170        all_options_ok = False
171        print(
172            "        \n\tERROR: User of the remote host is not specified in"
173            " CLI options."
174        )
175    if not password:
176        all_options_ok = False
177        print(
178            "        \n\tERROR: Password of the user remote host is not"
179            " specified in CLI options."
180        )
181    if not type:
182        all_options_ok = False
183        print(
184            "        \n\tERROR: Remote host os type is not specified in CLI"
185            " options."
186        )
187    if not os.path.isfile(config):
188        all_options_ok = False
189        print(
190            "        \n\tERROR: Config file %s is not found.  Please verify"
191            " path and filename." % config
192        )
193
194    return all_options_ok
195
196
197if __name__ == "__main__":
198    cli_ffdc()
199