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    "-c",
31    "--config",
32    default=abs_path + "/ffdc_config.yaml",
33    show_default=True,
34    help="YAML Configuration file for log collection.",
35)
36@click.option(
37    "-l",
38    "--location",
39    default="/tmp",
40    show_default=True,
41    help="Location to save logs",
42)
43@click.option(
44    "-t",
45    "--type",
46    help=(
47        "OS type of the remote (targeting) host. OPENBMC, RHEL, UBUNTU,"
48        " SLES, AIX"
49    ),
50)
51@click.option(
52    "-rp",
53    "--protocol",
54    default="ALL",
55    show_default=True,
56    help="Select protocol to communicate with remote host.",
57)
58@click.option(
59    "-e",
60    "--env_vars",
61    show_default=True,
62    help="Environment variables e.g: {'var':value}",
63)
64@click.option(
65    "-ec",
66    "--econfig",
67    show_default=True,
68    help="Predefine environment variables, refer en_vars_template.yaml ",
69)
70@click.option(
71    "--log_level",
72    default="INFO",
73    show_default=True,
74    help="Log level (CRITICAL, ERROR, WARNING, INFO, DEBUG)",
75)
76def cli_ffdc(
77    remote,
78    username,
79    password,
80    config,
81    location,
82    type,
83    protocol,
84    env_vars,
85    econfig,
86    log_level,
87):
88    r"""
89    Stand alone CLI to generate and collect FFDC from the selected target.
90    """
91
92    click.echo(
93        "\n********** FFDC (First Failure Data Collection) Starts **********"
94    )
95
96    if input_options_ok(remote, username, password, config, type):
97        this_ffdc = ffdc_collector(
98            remote,
99            username,
100            password,
101            config,
102            location,
103            type,
104            protocol,
105            env_vars,
106            econfig,
107            log_level,
108        )
109        this_ffdc.collect_ffdc()
110
111        if len(os.listdir(this_ffdc.ffdc_dir_path)) == 0:
112            click.echo(
113                "\n\tFFDC Collection from " + remote + " has failed.\n\n"
114            )
115        else:
116            click.echo(
117                str(
118                    "\n\t"
119                    + str(len(os.listdir(this_ffdc.ffdc_dir_path)))
120                    + " files were retrieved from "
121                    + remote
122                )
123            )
124            click.echo("\tFiles are stored in " + this_ffdc.ffdc_dir_path)
125
126        click.echo("\tTotal elapsed time " + this_ffdc.elapsed_time + "\n\n")
127    click.echo("\n********** FFDC Finishes **********\n\n")
128
129
130def input_options_ok(remote, username, password, config, type):
131    r"""
132    Verify script options exist via CLI options or environment variables.
133    """
134
135    all_options_ok = True
136
137    if not remote:
138        all_options_ok = False
139        print(
140            "        \n\tERROR: Name/IP of the remote host is not specified in"
141            " CLI options."
142        )
143    if not username:
144        all_options_ok = False
145        print(
146            "        \n\tERROR: User of the remote host is not specified in"
147            " CLI options."
148        )
149    if not password:
150        all_options_ok = False
151        print(
152            "        \n\tERROR: Password of the user remote host is not"
153            " specified in CLI options."
154        )
155    if not type:
156        all_options_ok = False
157        print(
158            "        \n\tERROR: Remote host os type is not specified in CLI"
159            " options."
160        )
161    if not os.path.isfile(config):
162        all_options_ok = False
163        print(
164            "        \n\tERROR: Config file %s is not found.  Please verify"
165            " path and filename." % config
166        )
167
168    return all_options_ok
169
170
171if __name__ == "__main__":
172    cli_ffdc()
173