1#!/usr/bin/env python3
2
3import os
4import sys
5
6
7sys.path.append(__file__.split(__file__.split("/")[-1])[0] + "../ffdc")
8from ffdc_collector import ffdc_collector
9
10from robot.libraries.BuiltIn import BuiltIn as robotBuildIn
11
12# (Sub) String constants used for input dictionary key search
13HOST = "HOST"
14USER = "USERNAME"
15PASSWD = "PASSWORD"
16CONFIG = "CONFIG"
17TYPE = "TYPE"
18LOC = "LOCATION"
19PROTOCOL = "PROTOCOL"
20ENV_VARS = "ENV_VARS"
21ECONFIG = "ECONFIG"
22LOGLEVEL = "LOG"
23
24
25def ffdc_robot_script_cli(**kwargs):
26    r"""
27
28    For the specified host, this method provide automation testcases the interface to
29    the new ffdc collector ../ffdc/ffdc_collector.py via robot variable FFDC_DEFAULT
30
31    variable FFDC_DEFAULT:1, by default use the existing ffdc collection method.
32    variable FFDC_DEFAULT:0 use the new ffdc method
33
34    Command examples:
35    (1) Legacy ffdc collection
36    python3 -m robot -v OPENBMC_HOST:<> -v OPENBMC_USERNAME:<> \
37                                        -v OPENBMC_PASSWORD:<> ./tools/myffdc.robot
38    (2) New ffdc collection
39    python3 -m robot -v OPENBMC_HOST:<> -v OPENBMC_USERNAME:<> \
40                        -v OPENBMC_PASSWORD:<> -v FFDC_DEFAULT:0  ./tools/myffdc.robot
41
42    Description of argument(s)in dictionary: xx can be anything appropriate
43
44        xx_HOST:hostname                name/ip of the targeted (remote) system
45        xx_USERNAME:username            user on the targeted system with access to FFDC files
46        xx_PASSWORD:password            password for user on targeted system
47        xx_CONFIG:ffdc_config           configuration file listing commands and files for FFDC
48        xx_LOCATION:location            where to store collected FFDC.  Default: <current dir>/logs/
49        xx_TYPE:remote_type             os type of the remote host.
50        xx_PROTOCOL:remote_protocol     Protocol to use to collect data. Default: 'ALL'
51        ENV_VAR:env_vars                User define CLI env vars '{"key : "value"}'. Default: ""
52        ECONFIG:econfig                 User define env vars YAML file. Default: ""
53        LOG_LEVEL:log_level             CRITICAL, ERROR, WARNING, INFO, DEBUG. Default: INFO
54
55    Code examples:
56    (1) openbmc_ffdc.robot activate this method with no parm
57        Run Keyword If  ${FFDC_DEFAULT} == ${1}  FFDC
58    ...    ELSE  ffdc_robot_script_cli
59
60    (2) Method invocation with parms
61        ffdc_from = {'OS_HOST' : 'os host name or ip',
62                     'OS_USERNAME' : 'os username',
63                     'OS_PASSWORD' : 'password for os_username',
64                     'OS_TYPE'     : 'os_type, ubuntu, rhel, aix, etc',
65                    }
66        ffdc_robot_script_cli(ffdc_from)
67
68    """
69
70    robotBuildIn().log_to_console("Collecting FFDC - CLI log collector script")
71
72    if not kwargs:
73        dict_of_parms = {}
74        # When method is invoked with no parm,
75        # use robot variables
76        # OPENBMC_HOST, OPENBMC_USERNAME, OPENBMC_PASSWORD, OPENBMC (type)
77        dict_of_parms["OPENBMC_HOST"] = \
78            robotBuildIn().get_variable_value("${OPENBMC_HOST}", default=None)
79        dict_of_parms["OPENBMC_USERNAME"] = \
80            robotBuildIn().get_variable_value("${OPENBMC_USERNAME}", default=None)
81        dict_of_parms["OPENBMC_PASSWORD"] = \
82            robotBuildIn().get_variable_value("${OPENBMC_PASSWORD}", default=None)
83        dict_of_parms["REMOTE_TYPE"] = "OPENBMC"
84
85        run_ffdc_collector(dict_of_parms)
86
87    else:
88        if isinstance(kwargs, dict):
89            # When method is invoked with user defined dictionary,
90            # dictionary keys has the following format
91            # xx_HOST; xx_USERNAME, xx_PASSWORD, xx_TYPE
92            # where xx is one of OPENBMC, OS, or os_type LINUX/UBUNTU/AIX
93            run_ffdc_collector(**kwargs)
94
95
96def run_ffdc_collector(dict_of_parm):
97    r"""
98
99    Process input parameters and collect information
100
101    Description of argument(s)in dictionary: xx can be anything appropriate
102
103        xx_HOST:hostname                name/ip of the targeted (remote) system
104        xx_USERNAME:username            user on the targeted system with access to FFDC files
105        xx_PASSWORD:password            password for user on targeted system
106        xx_CONFIG:ffdc_config           configuration file listing commands and files for FFDC
107        xx_LOCATION:location            where to store collected FFDC.  Default: <current dir>/logs/
108        xx_TYPE:remote_type             os type of the remote host.
109        xx_PROTOCOL:remote_protocol     Protocol to use to collect data. Default: 'ALL'
110        ENV_VAR:env_vars                User define CLI env vars '{"key : "value"}'. Default: ""
111        ECONFIG:econfig                 User define env vars YAML file. Default: ""
112        LOG_LEVEL:log_level             CRITICAL, ERROR, WARNING, INFO, DEBUG. Default: INFO
113
114    """
115
116    # Clear local variables
117    remote = None
118    username = None
119    password = None
120    config = None
121    location = None
122    remote_type = None
123    protocol = None
124    env_vars = None
125    econfig = None
126    log_level = None
127
128    # Process input key/value pairs
129    for key in dict_of_parm.keys():
130        if HOST in key:
131            remote = dict_of_parm[key]
132        elif USER in key:
133            username = dict_of_parm[key]
134        elif PASSWD in key:
135            password = dict_of_parm[key]
136        elif CONFIG in key:
137            config = dict_of_parm[key]
138        elif LOC in key:
139            location = dict_of_parm[key]
140        elif TYPE in key:
141            remote_type = dict_of_parm[key]
142        elif PROTOCOL in key:
143            protocol = dict_of_parm[key]
144        elif ENV_VARS in key:
145            env_vars = dict_of_parm[key]
146        elif ECONFIG in key:
147            econfig = dict_of_parm[key]
148        elif LOGLEVEL in key:
149            log_level = dict_of_parm[key]
150
151    # Set defaults values for parms
152    # that are not specified with input and have acceptable defaults.
153    if not location:
154        # Default FFDC store location
155        location = robotBuildIn().get_variable_value("${EXECDIR}", default=None) + "/logs"
156        ffdc_collector.validate_local_store(location)
157
158    if not config:
159        # Default FFDC configuration
160        script_path = os.path.dirname(os.path.abspath(__file__))
161        config = script_path + "/../ffdc/ffdc_config.yaml"
162
163    if not protocol:
164        protocol = "ALL"
165
166    if not env_vars:
167        env_vars = ""
168
169    if not econfig:
170        econfig = ""
171
172    if not log_level:
173        log_level = "INFO"
174
175    # If minimum required inputs are met, go collect.
176    if (remote and username and password and remote_type):
177        # Execute data collection
178        this_ffdc = ffdc_collector(remote,
179                                   username,
180                                   password,
181                                   config,
182                                   location,
183                                   remote_type,
184                                   protocol,
185                                   env_vars,
186                                   econfig,
187                                   log_level)
188        this_ffdc.collect_ffdc()
189