Exemplo n.º 1
0
    def get_hosts(self):
        """
        Called by main function, it extracts main config file and also check for database
        Reads the yaml config file given by user and pass the extracted data to login function to
        read device details and connect them. Also checks sqlite key to check if user wants to
        create database for snapshots
        """
        self.logger.debug(
            colorama.Fore.BLUE +
            "jsnapy.cfg file location used : %s" % get_config_location(),
            extra=self.log_detail)
        self.logger.debug(colorama.Fore.BLUE +
                          "Configuration file location used : %s" %
                          get_path('DEFAULT', 'config_file_path'),
                          extra=self.log_detail)

        if self.args.pre_snapfile is not None:
            output_file = self.args.pre_snapfile
        elif self.args.snapcheck is True and self.args.pre_snapfile is None:
            output_file = "snap_temp"
            self.snap_del = True
        else:
            output_file = ""
        conf_file = self.args.file
        check = self.args.check
        snap = self.args.snap
        if os.path.isfile(conf_file):
            config_file = open(conf_file, 'r')
            self.main_file = yaml.load(config_file)
        elif os.path.isfile(
                os.path.join(get_path('DEFAULT', 'config_file_path'),
                             conf_file)):
            fpath = get_path('DEFAULT', 'config_file_path')
            config_file = open(os.path.join(fpath, conf_file), 'r')
            self.main_file = yaml.load(config_file)
        else:
            self.logger.error(
                colorama.Fore.RED +
                "ERROR!! Config file '%s' is not present " % conf_file,
                extra=self.log_detail)
            sys.exit(1)

        #### if --check option is given for sqlite, then snap file name is not compulsory  ####
        #### else exit the function saying arguments not correct  ####
        if self.main_file.__contains__('sqlite') and self.main_file[
                'sqlite'] and self.main_file['sqlite'][0]:
            self.chk_database(self.main_file, self.args.pre_snapfile,
                              self.args.post_snapfile, check, snap)
        else:
            if (self.args.check is True and
                (self.args.file is None or self.args.pre_snapfile is None
                 or self.args.post_snapfile is None)):
                self.logger.error(
                    colorama.Fore.RED +
                    "Arguments not given correctly, Please refer help message",
                    extra=self.log_detail)
                self.parser.print_help()
                sys.exit(1)
        self.login(output_file)
Exemplo n.º 2
0
    def get_config_file(self):
        """
        It extracts main config file and also check for database
        Checks sqlite key to check if user wants to create database for snapshots
        By end of this function, self.main_file has the passed file or arguments details
        """

        conf_file = self.args.file
        if conf_file is not None:
            if os.path.isfile(conf_file):
                config_file = open(conf_file, 'r')
                self.main_file = yaml.load(config_file, Loader=yaml.FullLoader)
            elif os.path.isfile(
                    os.path.join(get_path('DEFAULT', 'config_file_path'),
                                 conf_file)):
                fpath = get_path('DEFAULT', 'config_file_path')
                config_file = open(os.path.join(fpath, conf_file), 'r')
                self.main_file = yaml.load(config_file, Loader=yaml.FullLoader)
            else:
                self.logger.error(
                    colorama.Fore.RED +
                    "ERROR!! Config file '%s' is not present " % conf_file,
                    extra=self.log_detail)
                sys.exit(1)
        else:
            if self.args.hostname and self.args.testfiles:
                temp_dict = {
                    'hosts': [{
                        'device': '',
                        'username': '',
                        'passwd': ''
                    }],
                    'tests': []
                }
                temp_dict['hosts'][0]['device'] = self.args.hostname
                temp_dict['hosts'][0]['username'] = self.args.login
                temp_dict['hosts'][0]['passwd'] = self.args.passwd
                for tfile in self.args.testfiles:
                    temp_dict['tests'].append(tfile)
                self.main_file = temp_dict

        if self.main_file.__contains__('sqlite') and self.main_file[
                'sqlite'] and self.main_file['sqlite'][0]:
            self.chk_database(self.main_file, self.args.pre_snapfile,
                              self.args.post_snapfile, self.args.check,
                              self.args.snap)
        else:
            # if --check option is given for sqlite, then snap file name is not compulsory
            # else exit the function saying arguments not correct
            if (self.args.check is True
                    and (self.args.pre_snapfile is None
                         or self.args.post_snapfile is None)):
                self.logger.error(
                    colorama.Fore.RED +
                    "Arguments not given correctly, Please refer help message",
                    extra=self.log_detail)
                self.parser.print_help()
                sys.exit(1)
Exemplo n.º 3
0
    def test_get_path_custom(self, mock_config_loc):
        DirStore.custom_dir = '~/bogus'
        HOME = os.path.join(os.path.expanduser('~'), 'bogus/')
        conf_loc = get_path('DEFAULT', 'config_file_path')
        snap_loc = get_path('DEFAULT', 'snapshot_path')
        test_loc = get_path('DEFAULT', 'test_file_path')

        self.assertEqual(conf_loc, HOME)
        self.assertEqual(snap_loc, os.path.join(HOME, 'snapshots'))
        self.assertEqual(test_loc, os.path.join(HOME, 'testfiles'))
        self.assertFalse(mock_config_loc.called)
Exemplo n.º 4
0
    def test_get_path_custom(self, mock_config_loc):
        DirStore.custom_dir = '~/bogus'
        if 'win' in sys.platform:
            HOME = os.path.join(os.path.expanduser('~'), 'bogus\\')
        else:
            HOME = os.path.join(os.path.expanduser('~'), 'bogus/')
        conf_loc = get_path('DEFAULT', 'config_file_path')
        snap_loc = get_path('DEFAULT', 'snapshot_path')
        test_loc = get_path('DEFAULT', 'test_file_path')

        self.assertEqual(conf_loc, HOME)
        self.assertEqual(snap_loc, os.path.join(HOME, 'snapshots'))
        self.assertEqual(test_loc, os.path.join(HOME, 'testfiles'))
Exemplo n.º 5
0
    def generate_rpc_reply(self, dev, output_file, hostname, config_data):
        """
        Generates rpc-reply based on command/rpc given and stores them in snap_files
        :param dev: device handler
        :param output_file: filename to store snapshots
        :param hostname: hostname of device
        :param config_data : data of main config file
        """
        val = None
        test_files = []
        for tfile in config_data.get('tests'):
            if not os.path.isfile(tfile):
                tfile = os.path.join(
                    expanduser(get_path(
                        'DEFAULT',
                        'test_file_path')),
                    tfile)
            if os.path.isfile(tfile):
                test_file = open(tfile, 'r')
                test_files.append(yaml.load(test_file))
            else:
                self.logger.error(
                    colorama.Fore.RED +
                    "ERROR!! File %s is not found for taking snapshots" %
                    tfile, extra=self.log_detail)

        g = Parser()
        for tests in test_files:
            val = g.generate_reply(tests, dev, output_file, hostname, self.db)
        return val
Exemplo n.º 6
0
def setup_logging(
        default_path='logging.yml', default_level=logging.INFO,
        env_key='LOG_CFG'):
    config_location = get_config_location('logging.yml')
    path = os.path.join(config_location, default_path)
    value = os.getenv(env_key, None)
    if value:
        path = value
    if os.path.exists(path):
        with open(path, 'rt') as f:
            config = yaml.load(f.read())
        logging.config.dictConfig(config)
    else:
        logging.basicConfig(level=default_level)

    ###################################
    # Creating Folder path for SNAPSHOT
    ###################################
    if 'win32' not in sys.platform and not hasattr(sys, 'real_prefix'):
        snapshots_path = get_path('DEFAULT', 'snapshot_path')
        snapshots_path = os.path.expanduser(snapshots_path)
        if not os.path.isdir(snapshots_path):
            os.makedirs(snapshots_path)

    HOME = os.path.expanduser("~")  # correct cross platform way to do it
    home_folder = os.path.join(HOME, '.jsnapy')
    if not os.path.isdir(home_folder):
        os.mkdir(home_folder)
Exemplo n.º 7
0
 def test_get_path_normal(self, mock_config_location):
     DirStore.custom_dir = None
     mock_config_location.return_value = os.path.join(
         os.path.dirname(__file__), 'configs')
     loc = get_path('DEFAULT', 'config_file_path')
     self.assertTrue(mock_config_location.called)
     self.assertEqual(loc, '/throgus')
Exemplo n.º 8
0
def setup_logging(default_path='logging.yml',
                  default_level=logging.INFO,
                  env_key='LOG_CFG'):
    config_location = get_config_location('logging.yml')
    path = os.path.join(config_location, default_path)
    value = os.getenv(env_key, None)
    if value:
        path = value
    if os.path.exists(path):
        with open(path, 'rt') as f:
            config = yaml.load(f.read(), Loader=yaml.FullLoader)
        logging.config.dictConfig(config)
    else:
        logging.basicConfig(level=default_level)

    ###################################
    # Creating Folder path for SNAPSHOT
    ###################################
    # Modified by @gcasella to use the function created on lines 24-29 in the __init__.py.
    if 'win32' not in sys.platform and not venv_check:
        snapshots_path = get_path('DEFAULT', 'snapshot_path')
        snapshots_path = os.path.expanduser(snapshots_path)
        if not os.path.isdir(snapshots_path):
            os.makedirs(snapshots_path)

    HOME = os.path.expanduser("~")  # correct cross platform way to do it
    home_folder = os.path.join(HOME, '.jsnapy')
    if not os.path.isdir(home_folder):
        os.mkdir(home_folder)
Exemplo n.º 9
0
    def generate_rpc_reply(self, dev, output_file, hostname, config_data):
        """
        Generates rpc-reply based on command/rpc given and stores them in snap_files
        :param dev: device handler
        :param output_file: filename to store snapshots
        :param hostname: hostname of device
        :param config_data : data of main config file
        """
        val = None
        test_files = []
        for tfile in config_data.get('tests'):
            if not os.path.isfile(tfile):
                tfile = os.path.join(get_path('DEFAULT', 'test_file_path'),
                                     tfile)
            if os.path.isfile(tfile):
                test_file = open(tfile, 'r')
                test_files.append(yaml.load(test_file))
            else:
                self.logger.error(
                    colorama.Fore.RED +
                    "ERROR!! File %s is not found for taking snapshots" %
                    tfile,
                    extra=self.log_detail)

        g = Parser()
        for tests in test_files:
            val = g.generate_reply(tests, dev, output_file, hostname, self.db)
        return val
Exemplo n.º 10
0
 def __init__(self, host, db_name):
     self.logger_storesqlite = logging.getLogger(__name__)
     host = host.replace(".", "__")
     self.table_name = "table_" + host
     # Creating Schema
     self.db_filename = os.path.join(
         os.path.expanduser(get_path("DEFAULT", "snapshot_path")), db_name
     )
     try:
         with sqlite3.connect(self.db_filename) as conn:
             # Creating schema if it does not exists
             sqlstr = (
                 """create table if not exists '%s' (
                 id           integer not null,
                 filename     text,
                 cli_command  text,
                 snap_name    text,
                 data_format  text,
                 data     text
             );"""
                 % self.table_name
             )
             conn.execute(sqlstr)
     except Exception as ex:
         self.logger_storesqlite.error(
             "\nERROR occurred in database:    %s" % str(ex)
         )
Exemplo n.º 11
0
 def __init__(self, db_name):
     self.logger_sqlite = logging.getLogger(__name__)
     self.sqlite_logs = {'hostname': None}
     self.db_filename = os.path.join(
         os.path.expanduser(get_path('DEFAULT', 'snapshot_path')), db_name)
     if not os.path.isfile(self.db_filename):
         self.logger_sqlite.error(colorama.Fore.RED +
                                  "Database %s does not exist." % db_name,
                                  extra=self.sqlite_logs)
         sys.exit(1)
Exemplo n.º 12
0
 def pre_process_information(self):
     """
     The function provides the information mentioned in the configuration files
     """
     self.logger.debug(
         colorama.Fore.BLUE +
         "jsnapy.cfg file location used : %s" % get_config_location(),
         extra=self.log_detail)
     self.logger.debug(colorama.Fore.BLUE +
                       "Configuration file location used : %s" %
                       get_path('DEFAULT', 'config_file_path'),
                       extra=self.log_detail)
Exemplo n.º 13
0
 def generate_snap_file(self, device, prefix, name, reply_format):
     """
     This function generates name of snapshot files
     """
     if os.path.isfile(prefix):
         return prefix
     else:
         cmd_rpc_name = re.sub('/|\*|\.|-', '_', name)
         sfile = str(device) + '_' + prefix + '_' + \
             cmd_rpc_name + '.' + reply_format
         snapfile = os.path.join(
             expanduser(get_path('DEFAULT', 'snapshot_path')), sfile)
         return snapfile
Exemplo n.º 14
0
    def get_hosts_list(self, hosts_val, host_dict):
        """
        Function extracts list of hosts from the data given.
        :param hosts_val: has the list of hosts to be parsed
        :param host_dict: The dictionary to be created to store the parsed values
        """
        first_entry = hosts_val[0]
        if 'include' in first_entry:  # check if hosts are group based
            devices_file_name = first_entry['include']
            if os.path.isfile(devices_file_name):
                lfile = devices_file_name
            else:
                lfile = os.path.join(
                    expanduser(get_path('DEFAULT', 'test_file_path')),
                    devices_file_name)
            login_file = open(lfile, 'r')
            dev_file = yaml.load(login_file, Loader=yaml.FullLoader)
            gp = first_entry.get('group', 'all')

            dgroup = [i.strip().lower() for i in gp.split(',')]
            iter = 0  # initialize the counter from 0 to keep count of hosts
            for dgp in dev_file:
                if dgroup[0].lower() == 'all' or dgp.lower() in dgroup:
                    for val in dev_file[dgp]:
                        hostname = list(val)[0]
                        iter += 1
                        if val.get(
                                hostname
                        ) is not None and hostname not in self.host_list:
                            self.host_list.append(hostname)
                        host_dict[iter] = deepcopy(val.get(hostname))
                        host_dict[iter]["device"] = hostname
        else:
            iter = -1  # iterator keeps count of number of hosts
            for host in hosts_val:
                iter += 1
                try:
                    hostname = host['device']
                    self.log_detail = {'hostname': hostname}
                except KeyError as ex:
                    self.logger.error(
                        colorama.Fore.RED +
                        "ERROR!! KeyError 'device' key not found",
                        extra=self.log_detail)
                except Exception as ex:
                    self.logger.error(colorama.Fore.RED + "ERROR!! %s" % ex,
                                      extra=self.log_detail)
                else:
                    if hostname not in self.host_list:
                        self.host_list.append(hostname)
                    host_dict[iter] = deepcopy(host)
Exemplo n.º 15
0
 def __init__(self, db_name):
     self.logger_sqlite = logging.getLogger(__name__)
     self.sqlite_logs = {'hostname': None}
     self.db_filename = os.path.join(
         os.path.expanduser(get_path(
             'DEFAULT',
             'snapshot_path')),
         db_name)
     if not os.path.isfile(self.db_filename):
         self.logger_sqlite.error(
             colorama.Fore.RED +
             "Database %s does not exist." %
             db_name, extra=self.sqlite_logs)
         sys.exit(1)
Exemplo n.º 16
0
 def generate_snap_file(self, device, prefix, name, reply_format):
     """
     This function generates name of snapshot files
     """
     if self.port is not None:
         device = "{}_{}".format(device, self.port)
     if os.path.isfile(prefix):
         return prefix
     else:
         cmd_rpc_name = re.sub("/|\*|\.|-", "_", name)
         sfile = str(device) + "_" + prefix + "_" + cmd_rpc_name + "." + reply_format
         snapfile = os.path.join(
             expanduser(get_path("DEFAULT", "snapshot_path")), sfile
         )
         return snapfile
Exemplo n.º 17
0
 def generate_snap_file(self, output_file, hostname, name, cmd_format):
     """
     This will generate snapshot file name
     :param output_file: either complete file or file tag
     :param name: command or RPC
     :param cmd_format: xml/text
     :return: return output file
     """
     name = name.split('|')[0].strip()
     cmd_rpc = re.sub('/|\*|\.|-|\|', '_', name)
     if os.path.isfile(output_file):
         return output_file
     else:
         filename = hostname + '_' + output_file + \
             '_' + cmd_rpc + '.' + cmd_format
         output_file = os.path.join(get_path('DEFAULT', 'snapshot_path'),
                                    filename)
         return output_file
Exemplo n.º 18
0
 def multiple_device_details(self, host, config_data, pre_name, action,
                             post_name):
     """
     Called when multiple devices are given in config file
     :param host: hostname
     :param config_data: data of main config file
     :param pre_name: pre snapshot filename or file tag
     :param action: action to be taken, snap, snapcheck, check
     :param post_name: post snapshot filename or file tag
     :return: return object of testop.Operator containing test details
     """
     res_obj = []
     self.host_list = []
     login_file = host['include']
     login_file = login_file if os.path.isfile(
         host.get('include')) else os.path.join(
             get_path('DEFAULT', 'test_file_path'), login_file)
     login_file = open(login_file, 'r')
     dev_file = yaml.load(login_file)
     gp = host.get('group', 'all')
     dgroup = [i.strip().lower() for i in gp.split(',')]
     for dgp in dev_file:
         if dgroup[0].lower() == 'all' or dgp.lower() in dgroup:
             for val in dev_file[dgp]:
                 hostname = val.keys()[0]
                 self.host_list.append(hostname)
                 self.log_detail['hostname'] = hostname
                 username = val.get(hostname).get('username')
                 password = val.get(hostname).get('passwd')
                 key_value = val.get(hostname)
                 key_value = self.get_values(key_value)
                 t = Thread(target=self.connect,
                            args=(hostname, username, password, pre_name,
                                  config_data, action, post_name),
                            kwargs=key_value)
                 t.start()
                 if action == "snap":
                     res_obj.append(self.snap_q.get())
                 elif action in ["snapcheck", "check"]:
                     res_obj.append(self.q.get())
                 else:
                     res_obj.append(None)
                 t.join()
     return res_obj
Exemplo n.º 19
0
 def generate_snap_file(self, output_file, hostname, name, cmd_format):
     """
     This will generate snapshot file name
     :param output_file: either complete file or file tag
     :param name: command or RPC
     :param cmd_format: xml/text
     :return: return output file
     """
     if self.port is not None:
         hostname = "{}_{}".format(hostname, self.port)
     name = name.split("|")[0].strip()
     cmd_rpc = re.sub("/|\*|\.|-|\|", "_", name)
     if os.path.isfile(output_file):
         return output_file
     else:
         filename = hostname + "_" + output_file + "_" + cmd_rpc + "." + cmd_format
         output_file = os.path.join(
             os.path.expanduser(get_path("DEFAULT", "snapshot_path")), filename
         )
         return output_file
Exemplo n.º 20
0
 def generate_snap_file(self, output_file, hostname, name, cmd_format):
     """
     This will generate snapshot file name
     :param output_file: either complete file or file tag
     :param name: command or RPC
     :param cmd_format: xml/text
     :return: return output file
     """
     name = name.split('|')[0].strip()
     cmd_rpc = re.sub('/|\*|\.|-|\|', '_', name)
     if os.path.isfile(output_file):
         return output_file
     else:
         filename = hostname + '_' + output_file + \
             '_' + cmd_rpc + '.' + cmd_format
         output_file = os.path.join(
             os.path.expanduser(get_path(
                 'DEFAULT',
                 'snapshot_path')),
             filename)
         return output_file
Exemplo n.º 21
0
 def extract_test_cases(self, config_data):
     """
     :param config_data: the data passed in the config file
     :return: the list of testcases
     """
     test_files = []
     for tfile in config_data.get('tests'):
         # tfile gets details of the test/files to be parsed.
         if not os.path.isfile(tfile):
             tfile = os.path.join(
                 expanduser(get_path('DEFAULT', 'test_file_path')), tfile)
         if os.path.isfile(tfile):
             test_file = open(tfile, 'r')
             test_files.append(yaml.load(test_file, Loader=yaml.FullLoader))
         else:
             self.logger.error(
                 colorama.Fore.RED +
                 "ERROR!! File %s is not found for extracting test case" %
                 tfile,
                 extra=self.log_detail)
     return test_files
Exemplo n.º 22
0
    def get_test(self, config_data, hostname, snap_file, post_snap, action):
        """
        Analyse testfile and return object of testop.Operator containing test details
        called by connect() function and other functions of Jsnapy module functions
        :param config_data: data of main config file
        :param hostname: hostname
        :param snap_file: pre snapshot file name
        :param post_snap: post snapshot file name
        :param action: action to be taken (check, snapcheck, snap)
        :return: object of testop.Operator containing test details
        """
        res = Operator()
        if config_data.get("mail") and self.args.diff is not True:
            mfile = os.path.join(get_path('DEFAULT', 'test_file_path'), config_data.get('mail'))\
                if os.path.isfile(config_data.get('mail')) is False else config_data.get('mail')
            if os.path.isfile(mfile):
                mail_file = open(mfile, 'r')
                mail_file = yaml.load(mail_file)
                if "passwd" not in mail_file:
                    passwd = getpass.getpass("Please enter ur email password ")
                else:
                    passwd = mail_file['passwd']
                res = self.compare_tests(hostname, config_data, snap_file,
                                         post_snap, action)
                send_mail = Notification()
                send_mail.notify(mail_file, hostname, passwd, res)
            else:
                self.logger.error(
                    colorama.Fore.RED +
                    "ERROR!! Path of file containing mail content is not correct",
                    extra=self.log_detail)
        else:
            res = self.compare_tests(hostname, config_data, snap_file,
                                     post_snap, action)

        self.q.put(res)
        return res
Exemplo n.º 23
0
    def get_hosts(self):
        """
        Called by main function, it extracts main config file and also check for database
        Reads the yaml config file given by user and pass the extracted data to login function to
        read device details and connect them. Also checks sqlite key to check if user wants to
        create database for snapshots
        """
        self.logger.debug(colorama.Fore.BLUE +
                "jsnapy.cfg file location used : %s" %
                get_config_location(), extra=self.log_detail)
        self.logger.debug(colorama.Fore.BLUE +
                "Configuration file location used : %s" %
                get_path('DEFAULT', 'config_file_path'), extra=self.log_detail)
                        
        if self.args.pre_snapfile is not None:
            output_file = self.args.pre_snapfile
        elif self.args.snapcheck is True and self.args.pre_snapfile is None:
            output_file = "snap_temp"
            self.snap_del = True
        else:
            output_file = ""
        conf_file = self.args.file
        check = self.args.check
        snap = self.args.snap
        if conf_file is not None:
            if os.path.isfile(conf_file):
                config_file = open(conf_file, 'r')
                self.main_file = yaml.load(config_file)
            elif os.path.isfile(os.path.join(get_path('DEFAULT', 'config_file_path'), conf_file)):
                fpath = get_path('DEFAULT', 'config_file_path')
                config_file = open(os.path.join(fpath, conf_file), 'r')
                self.main_file = yaml.load(config_file)
            else:
                self.logger.error(
                    colorama.Fore.RED +
                    "ERROR!! Config file '%s' is not present " %
                    conf_file, extra=self.log_detail)
                sys.exit(1)
        else:
            if self.args.hostname and self.args.testfiles:
                temp_dict = {'hosts':[{'device':'', 'username':'', 'passwd':''}], 'tests':[]}
                temp_dict['hosts'][0]['device'] = self.args.hostname
                temp_dict['hosts'][0]['username'] = self.args.login
                temp_dict['hosts'][0]['passwd'] = self.args.passwd
                for tfile in self.args.testfiles:
                    temp_dict['tests'].append(tfile)
                self.main_file = temp_dict


        #### if --check option is given for sqlite, then snap file name is not compulsory  ####
        #### else exit the function saying arguments not correct  ####
        if self.main_file.__contains__(
                'sqlite') and self.main_file['sqlite'] and self.main_file['sqlite'][0]:
            self.chk_database(
                self.main_file,
                self.args.pre_snapfile,
                self.args.post_snapfile,
                check,
                snap)
        else:
            if (self.args.check is True and (
                    self.args.file is None or self.args.pre_snapfile is None or self.args.post_snapfile is None)):
                self.logger.error(colorama.Fore.RED +
                                  "Arguments not given correctly, Please refer help message",
                                  extra=self.log_detail)
                self.parser.print_help()
                sys.exit(1)
        self.login(output_file)
Exemplo n.º 24
0
    def login(self, output_file):
        """
        Extract device information from main config file. Stores device information and call connect function,
        device can be single or multiple. Instead of connecting to all devices mentioned in yaml file, user can
        connect to some particular group of device also.
        :param output_file: name of snapshot file
        """
        self.host_list = []
        if self.args.hostname is None:
            host_dict={}
            try:
                hosts_val = self.main_file['hosts']
            except KeyError as ex:
                self.logger.error(colorama.Fore.RED +
                "\nERROR occurred !! Hostname not given properly %s" %
                str(ex),
                extra=self.log_detail)
                #raise Exception(ex)
            except Exception as ex:
                self.logger.error(colorama.Fore.RED +
                "\nERROR occurred !! %s" %
                str(ex),
                extra=self.log_detail)
                #raise Exception(ex)
            else:
                # when group of devices are given, searching for include keyword in
                # hosts in main.yaml file
                first_entry = hosts_val[0]
                if 'include' in first_entry:
                    devices_file_name = first_entry['include']
                    if os.path.isfile(devices_file_name):
                        lfile = devices_file_name
                    else:
                        lfile = os.path.join(
                                    expanduser(get_path(
                                        'DEFAULT',
                                        'test_file_path')),
                                    devices_file_name)
                    login_file = open(lfile, 'r')
                    dev_file = yaml.load(login_file)
                    gp = first_entry.get('group', 'all')

                    dgroup = [i.strip().lower() for i in gp.split(',')]
                    for dgp in dev_file:
                        if dgroup[0].lower() == 'all' or dgp.lower() in dgroup:
                            for val in dev_file[dgp]:
                                hostname = list(val)[0]
                                self.log_detail = {'hostname': hostname}
                                if val.get(hostname) is not None and hostname not in host_dict:
                                    host_dict[hostname] = deepcopy(val.get(hostname))
                                    self.host_list.append(hostname)
                # login credentials are given in main config file, can connect to multiple devices
                else:
                    #key_value = deepcopy(k)
                    for host in hosts_val:
                        try:
                            hostname = host['device']
                            self.log_detail = {'hostname': hostname}
                        except KeyError as ex:
                            self.logger.error(
                            colorama.Fore.RED +
                            "ERROR!! KeyError 'device' key not found",
                            extra=self.log_detail)
                            #raise Exception(ex)
                        except Exception as ex:
                            self.logger.error(
                            colorama.Fore.RED +
                            "ERROR!! %s" %
                            ex,
                            extra=self.log_detail)
                            #raise Exception(ex)
                        else:
                            if hostname not in host_dict:
                                self.host_list.append(hostname)
                                # host.pop('device')
                                host_dict[hostname] = deepcopy(host)

            for (hostname, key_value) in iteritems(host_dict):
                #The file config takes precedence over cmd line params -- no changes made
                username = self.args.login or key_value.get('username') 
                password = self.args.passwd or key_value.get('passwd') 
                #if --port arg is given on the cmd then that takes precedence                
                port = self.args.port
                if port is not None:
                    key_value['port'] = port
                key_value = self.get_values(key_value)
                t = Thread(
                    target=self.connect,
                    args=(
                        hostname,
                        username,
                        password,
                        output_file
                    ),
                    kwargs= key_value
                )
                t.start()
                t.join()
        # login credentials are given from command line
        else:
            hostname = self.args.hostname
            self.log_detail = {'hostname': hostname}
            username = self.args.login
            password = self.args.passwd
            # if self.args.passwd is not None else getpass.getpass("\nEnter
            # Password: ")
            self.host_list.append(hostname)
            port = self.args.port
            key_value = {'port': port} if port is not None else {}
            self.connect(hostname, username, password, output_file, **key_value)
Exemplo n.º 25
0
    def login(self, output_file):
        """
        Extract device information from main config file. Stores device information and call connect function,
        device can be single or multiple. Instead of connecting to all devices mentioned in yaml file, user can
        connect to some particular group of device also.
        :param output_file: name of snapshot file
        """
        self.host_list = []
        if self.args.hostname is None:
            try:
                k = self.main_file['hosts'][0]
            except KeyError as ex:
                self.logger.error(
                    colorama.Fore.RED +
                    "\nERROR occurred !! Hostname not given properly %s" %
                    str(ex),
                    extra=self.log_detail)
                #raise Exception(ex)
            except Exception as ex:
                self.logger.error(colorama.Fore.RED +
                                  "\nERROR occurred !! %s" % str(ex),
                                  extra=self.log_detail)
                #raise Exception(ex)
            else:
                # when group of devices are given, searching for include keyword in
                # hosts in main.yaml file
                if k.__contains__('include'):
                    file_tag = k['include']
                    if os.path.isfile(file_tag):
                        lfile = file_tag
                    else:
                        lfile = os.path.join(
                            get_path('DEFAULT', 'test_file_path'), file_tag)
                    login_file = open(lfile, 'r')
                    dev_file = yaml.load(login_file)
                    gp = k.get('group', 'all')

                    dgroup = [i.strip().lower() for i in gp.split(',')]
                    for dgp in dev_file:
                        if dgroup[0].lower() == 'all' or dgp.lower() in dgroup:
                            for val in dev_file[dgp]:
                                hostname = val.keys()[0]
                                self.log_detail = {'hostname': hostname}
                                self.host_list.append(hostname)
                                key_value = deepcopy(val.get(hostname))
                                if val.get(
                                        hostname
                                ) is not None and 'username' in val.get(
                                        hostname).keys():
                                    username = val.get(hostname).get(
                                        'username')
                                else:
                                    username = self.args.login
                                if val.get(
                                        hostname
                                ) is not None and 'passwd' in val.get(
                                        hostname).keys():
                                    password = val.get(hostname).get('passwd')
                                else:
                                    password = self.args.passwd
                                    # if self.args.passwd is not None else
                                    # getpass.getpass("\nEnter Password for
                                    # username: %s " %username)
                                key_value = self.get_values(key_value)
                                t = Thread(target=self.connect,
                                           args=(hostname, username, password,
                                                 output_file),
                                           kwargs=key_value)
                                t.start()
                                t.join()
            # login credentials are given in main config file, can connect to only
            # one device
                else:
                    key_value = deepcopy(k)

                    try:
                        hostname = k['device']
                        self.log_detail = {'hostname': hostname}
                    except KeyError as ex:
                        self.logger.error(
                            colorama.Fore.RED +
                            "ERROR!! KeyError 'device' key not found",
                            extra=self.log_detail)
                        #raise Exception(ex)
                    except Exception as ex:
                        self.logger.error(colorama.Fore.RED +
                                          "ERROR!! %s" % ex,
                                          extra=self.log_detail)
                        #raise Exception(ex)
                    else:
                        username = k.get('username') or self.args.login
                        password = k.get('passwd') or self.args.passwd
                        self.host_list.append(hostname)
                        key_value = self.get_values(key_value)
                        self.connect(hostname, username, password, output_file,
                                     **key_value)

        # login credentials are given from command line
        else:
            hostname = self.args.hostname
            self.log_detail = {'hostname': hostname}
            username = self.args.login
            password = self.args.passwd
            # if self.args.passwd is not None else getpass.getpass("\nEnter
            # Password: ")
            self.host_list.append(hostname)
            port = self.args.port
            key_value = {'port': port} if port is not None else {}
            self.connect(hostname, username, password, output_file,
                         **key_value)
Exemplo n.º 26
0
    def generate_test_files(
            self, main_file, device, check, diff, db, snap_del, pre=None, action=None, post=None):
        """
        generate names of snap files from hostname and out files given by user,
        tests are performed on values stored in these snap files, in which test is
        to be performed
        :param main_file: main config file, to extract test files user wants to run
        :param device: device name
        :param check: variable to check if --check option is given or not
        :param diff: variable to check if --diff option is given or not
        :param db: database object
        :param snap_del: if --snapcheck operator is used without any test file name
                        it will create temprory file and then will delete it at the end
        :param pre: file name of pre snapshot
        :param post: file name of post snapshot
        :param action: given by module version, either snap, snapcheck or check
        :return: object of testop.Operator containing test details
        """
        op = Operator()
        op.device = device
        tests_files = []
        self.log_detail['hostname'] = device
        # get the test files from config.yml
        if main_file.get('tests') is None:
            self.logger_check.error(
                colorama.Fore.RED +
                "\nERROR!! No test file found, Please mention test files !!", extra=self.log_detail)
        else:
            # extract test files, first search in path given in jsnapy.cfg
            for tfile in main_file.get('tests'):
                if not os.path.isfile(tfile):
                    tfile = os.path.join(
                        get_path(
                            'DEFAULT',
                            'test_file_path'),
                        tfile)
                if os.path.isfile(tfile):
                    test_file = open(tfile, 'r')
                    tests_files.append(yaml.load(test_file))
                else:
                    self.logger_check.error(
                        colorama.Fore.RED +
                        "ERROR!! File %s not found for testing" %
                        tfile,
                        extra=self.log_detail)

            # check what all test cases need to be included, if nothing given
            # then include all test cases ####
            for tests in tests_files:
                tests_included = []
                if 'tests_include' in tests:
                    tests_included = tests.get('tests_include')
                else:
                    for t in tests:
                        tests_included.append(t)
                message= self._print_testmssg("Device: "+device, "*")
                self.logger_check.info(colorama.Fore.BLUE + message, extra=self.log_detail)
                for val in tests_included:
                    self.logger_check.info(
                        "Tests Included: %s " %
                        (val),
                        extra=self.log_detail)
                    try:
                        if tests[val][0].keys()[0] == 'command':
                            command = tests[val][0].get('command').split('|')[0].strip()
                            reply_format = tests[val][0].get('format', 'xml')
                            message = self._print_testmssg("Command: "+command, "*")
                        
                            self.logger_check.info(
                                colorama.Fore.BLUE +
                                message,
                                extra=self.log_detail)
                        
                            name = '_'.join(command.split())
                            teston = command
                        else:
                            rpc = tests[val][0]['rpc']
                            reply_format = tests[val][0].get('format', 'xml')
                            self.logger_check.info(colorama.Fore.BLUE + (25) * "*" + "RPC is " +
                                                   rpc + (25) * '*', extra=self.log_detail)
                            name = rpc
                            teston = rpc
                    except KeyError:
                        self.logger_check.error(
                            colorama.Fore.RED +
                            "ERROR occurred, test keys 'command' or 'rpc' not defined properly", extra=self.log_detail)
                    except Exception as ex:
                        self.logger_check.error(
                            colorama.Fore.RED +
                            "ERROR Occurred: %s" % str(ex), extra=self.log_detail)
                    else:
                        # extract snap files, if check from sqlite is true t
                        if db.get(
                                'check_from_sqlite') is True and (check is True or diff is True or action in ["check", "diff"]):
                            a = SqliteExtractXml(db.get('db_name'))
                            # while checking from database, preference is given
                            # to id and then snap name
                            if (db['first_snap_id'] is not None) and (
                                    db['second_snap_id'] is not None):
                                snapfile1, data_format1 = a.get_xml_using_snap_id(
                                    str(device), name, db['first_snap_id'])
                                snapfile2, data_format2 = a.get_xml_using_snap_id(
                                    str(device), name, db['second_snap_id'])
                            else:
                                snapfile1, data_format1 = a.get_xml_using_snapname(
                                    str(device), name, pre)
                                snapfile2, data_format2 = a.get_xml_using_snapname(
                                    str(device), name, post)
                            if reply_format != data_format1 or reply_format != data_format2:
                                self.logger_check.error(colorama.Fore.RED + "ERROR!! Data stored in database is not in %s format."
                                                        % reply_format, extra=self.log_detail)
                                pass
                                # sys.exit(1)
                        ###### taking snapshot for --snapcheck operation ####
                        elif db.get('check_from_sqlite') is True:
                            a = SqliteExtractXml(db.get('db_name'))
                            snapfile1, data_format1 = a.get_xml_using_snapname(
                                str(device), name, pre)
                            if reply_format != data_format1:
                                self.logger_check.error(
                                    colorama.Fore.RED +
                                    "ERROR!! Data stored in database is not in %s format." %
                                    reply_format,
                                    extra=self.log_detail)
                                pass
                                # sys.exit(1)
                        else:
                            snapfile1 = self.generate_snap_file(
                                device,
                                pre,
                                name,
                                reply_format)

                        # if check is true then call function to compare two
                        # snapshots ####
                        if (check is True or action is "check") and reply_format == 'xml':
                            if db.get('check_from_sqlite') is False:
                                snapfile2 = self.generate_snap_file(
                                    device,
                                    post,
                                    name,
                                    reply_format)
                            self.compare_reply(
                                op,
                                tests[val],
                                teston,
                                check,
                                db,
                                snapfile1,
                                snapfile2,
                                action)

                        # if --diff is true then call compare_diff to compare
                        # two snapshots word by word ####
                        elif(diff is True):
                            if db.get('check_from_sqlite') is False:
                                snapfile2 = self.generate_snap_file(
                                    device,
                                    post,
                                    name,
                                    reply_format)
                            self.compare_diff(
                                snapfile1,
                                snapfile2,
                                db.get('check_from_sqlite'))

                        # else call --snapcheck test operation, it works only
                        # for xml reply format   ####
                        elif (reply_format == 'xml'):
                            self.compare_reply(
                                op,
                                tests[val],
                                teston,
                                check,
                                db,
                                snapfile1,
                                action)
                            ######## bug here ############
                            # multiple testcases for single command and same device, its deleting that file
                            ####################
                            """
                            if snap_del is True:
                                snapfile1 = snapfile1 if os.path.isfile(snapfile1) else self.generate_snap_file(device, pre, name, reply_format)
                                os.remove(snapfile1)
                                """
                        else:
                            # give error message if snapshot in text format is
                            # used with operations other than --diff  ####
                            self.logger_check.error(
                                colorama.Fore.RED +
                                "ERROR!! for checking snapshots in text format use '--diff' option ", extra=self.log_detail)

            # print final result, if operation is --diff then message gets
            # printed compare_diff function only ####
            if (diff is not True):
                op.final_result(self.log_detail)

        return op
Exemplo n.º 27
0
    def generate_test_files(self,
                            main_file,
                            device,
                            check,
                            diff,
                            db,
                            snap_del,
                            pre=None,
                            action=None,
                            post=None):
        """
        generate names of snap files from hostname and out files given by user,
        tests are performed on values stored in these snap files, in which test is
        to be performed
        :param main_file: main config file, to extract test files user wants to run
        :param device: device name
        :param check: variable to check if --check option is given or not
        :param diff: variable to check if --diff option is given or not
        :param db: database object
        :param snap_del: if --snapcheck operator is used without any test file name
                        it will create temprory file and then will delete it at the end
        :param pre: file name of pre snapshot
        :param post: file name of post snapshot
        :param action: given by module version, either snap, snapcheck or check
        :return: object of operator.Operator containing test details
        """
        op = Operator()
        op.device = device
        tests_files = []
        self.log_detail['hostname'] = device
        # pre_user and post_user are the names of the snapshot files
        # that the user wants to keep and store the snapfiles
        # with these names
        pre_user = pre
        post_user = post
        # get the test files from config.yml
        if main_file.get('tests') is None:
            self.logger_check.error(
                colorama.Fore.RED +
                "\nERROR!! No test file found, Please mention test files !!",
                extra=self.log_detail)
        else:
            # extract test files, first search in path given in jsnapy.cfg
            for tfile in main_file.get('tests'):
                if not os.path.isfile(tfile):
                    tfile = os.path.join(
                        expanduser(get_path('DEFAULT', 'test_file_path')),
                        tfile)
                if os.path.isfile(tfile):
                    test_file = open(tfile, 'r')
                    tests_files.append(
                        yaml.load(test_file, Loader=yaml.FullLoader))
                else:
                    self.logger_check.error(
                        colorama.Fore.RED +
                        "ERROR!! File %s not found for testing" % tfile,
                        extra=self.log_detail)

            # check what all test cases need to be included, if nothing given
            # then include all test cases ####
            for tests in tests_files:
                tests_included = []
                if 'tests_include' in tests:
                    tests_included = tests.get('tests_include')
                else:
                    for t in tests:
                        tests_included.append(t)
                message = self._print_testmssg("Device: " + device, "*")
                self.logger_check.info(colorama.Fore.BLUE + message,
                                       extra=self.log_detail)
                for val in tests_included:
                    self.logger_check.info("Tests Included: %s " % (val),
                                           extra=self.log_detail)

                    # This is Where we are going to print the description mentioned by the user for the testcase
                    # Enumerate generate a tuple of index and corresponding element in the list
                    # index[0] is index and index[1] is the dictionary in which it will search.

                    description_index = [
                        index[0] for index in enumerate(tests[val])
                        if 'description' in index[1]
                    ]
                    if len(description_index) > 0:
                        description_index = description_index[0]
                        description = tests[val][description_index][
                            'description']
                        if description is not None:
                            self.logger_check.info("Description: %s " %
                                                   (description),
                                                   extra=self.log_detail)
                    try:
                        if any('command' in d for d in tests[val]):
                            index = next((i for i, x in enumerate(tests[val])
                                          if 'command' in x), 0)
                            command = tests[val][index].get('command').split(
                                '|')[0].strip()
                            reply_format = tests[val][0].get('format', 'xml')
                            message = self._print_testmssg(
                                "Command: " + command, "*")

                            self.logger_check.info(colorama.Fore.BLUE +
                                                   message,
                                                   extra=self.log_detail)

                            name = '_'.join(command.split())
                            teston = command

                            # this is necessary for the pre and post to be the same that user specified
                            # In a case when there are multiple rpc's with kwargs and a rpc with no kwargs
                            pre = pre_user
                            post = post_user
                        else:
                            index = next((i for i, x in enumerate(tests[val])
                                          if 'rpc' in x), 0)
                            index_kwargs = next(
                                (i for i, x in enumerate(tests[val])
                                 if 'kwargs' in x or 'args' in x), 1)
                            rpc = tests[val][index]['rpc']
                            reply_format = tests[val][index].get(
                                'format', 'xml')
                            self.logger_check.info(colorama.Fore.BLUE +
                                                   (25) * "*" + "RPC is " +
                                                   rpc + (25) * '*',
                                                   extra=self.log_detail)
                            name = rpc
                            teston = rpc
                            # this is necessary for the pre and post to be the same that user specified
                            # In a case when there are multiple rpc's with kwargs and a rpc with no kwargs
                            pre = pre_user
                            post = post_user

                            # here the user specified name is being used and the hash value generated for
                            # kwargs part is appended to the name

                            if 'kwargs' in tests[val][index_kwargs] and tests[
                                    val][index_kwargs].get('kwargs') is None:
                                del tests[val][index_kwargs]['kwargs']

                            if 'args' in tests[val][index_kwargs] and tests[
                                    val][index_kwargs].get('args') is None:
                                del tests[val][index_kwargs]['args']

                            if 'kwargs' in tests[val][
                                    index_kwargs] or 'args' in tests[val][
                                        index_kwargs]:
                                if tests[val][index_kwargs].get('kwargs'):
                                    data = tests[val][index_kwargs].get(
                                        'kwargs')
                                elif tests[val][index_kwargs].get('args'):
                                    data = tests[val][index_kwargs].get('args')
                                hash_kwargs = hashlib.md5(
                                    json.dumps(data, sort_keys=True).encode(
                                        'utf-8')).digest()
                                hash_kwargs = base64.urlsafe_b64encode(
                                    hash_kwargs).strip()
                                if action == 'check' and pre_user is not None and post_user is not None:
                                    pre = pre_user + '_' + hash_kwargs.decode(
                                        'utf-8')
                                    post = post_user + '_' + hash_kwargs.decode(
                                        'utf-8')
                                elif action == 'snapcheck' and pre_user is not None and post_user is None:
                                    pre = pre_user + '_' + hash_kwargs.decode(
                                        'utf-8')
                                elif diff is True and pre_user is not None and post_user is not None:
                                    pre = pre_user + '_' + hash_kwargs.decode(
                                        'utf-8')
                                    post = post_user + '_' + hash_kwargs.decode(
                                        'utf-8')
                    except KeyError:
                        self.logger_check.error(
                            colorama.Fore.RED +
                            "ERROR occurred, test keys 'command' or 'rpc' not defined properly",
                            extra=self.log_detail)
                    except Exception as ex:
                        self.logger_check.error(colorama.Fore.RED +
                                                "ERROR Occurred: %s" % str(ex),
                                                extra=self.log_detail)
                    else:
                        # extract snap files, if check from sqlite is true t
                        if db.get('check_from_sqlite') is True and (
                                check is True or diff is True
                                or action in ["check", "diff"]):
                            a = SqliteExtractXml(db.get('db_name'))
                            # while checking from database, preference is given
                            # to id and then snap name
                            if (db['first_snap_id']
                                    is not None) and (db['second_snap_id']
                                                      is not None):
                                snapfile1, data_format1 = a.get_xml_using_snap_id(
                                    str(device), name, db['first_snap_id'])
                                snapfile2, data_format2 = a.get_xml_using_snap_id(
                                    str(device), name, db['second_snap_id'])
                            else:
                                snapfile1, data_format1 = a.get_xml_using_snapname(
                                    str(device), name, pre)
                                snapfile2, data_format2 = a.get_xml_using_snapname(
                                    str(device), name, post)
                            if reply_format != data_format1 or reply_format != data_format2:
                                self.logger_check.error(
                                    colorama.Fore.RED +
                                    "ERROR!! Data stored in database is not in %s format."
                                    % reply_format,
                                    extra=self.log_detail)
                                pass
                                # sys.exit(1)
                        ###### taking snapshot for --snapcheck operation ####
                        elif db.get('check_from_sqlite') is True:
                            a = SqliteExtractXml(db.get('db_name'))
                            snapfile1, data_format1 = a.get_xml_using_snapname(
                                str(device), name, pre)
                            if reply_format != data_format1:
                                self.logger_check.error(
                                    colorama.Fore.RED +
                                    "ERROR!! Data stored in database is not in %s format."
                                    % reply_format,
                                    extra=self.log_detail)
                                pass
                                # sys.exit(1)
                        else:
                            snapfile1 = self.generate_snap_file(
                                device, pre, name, reply_format)

                        # if check is true then call function to compare two
                        # snapshots ####
                        if (check is True or action
                                == "check") and reply_format == 'xml':
                            if db.get('check_from_sqlite') is False:
                                snapfile2 = self.generate_snap_file(
                                    device, post, name, reply_format)
                            self.compare_reply(op, tests[val], val, teston,
                                               check, db, snapfile1, snapfile2,
                                               action)

                        # if --diff is true then call compare_diff to compare
                        # two snapshots word by word ####
                        elif (diff is True):
                            if db.get('check_from_sqlite') is False:
                                snapfile2 = self.generate_snap_file(
                                    device, post, name, reply_format)
                            self.compare_diff(snapfile1, snapfile2,
                                              db.get('check_from_sqlite'))

                        # else call --snapcheck test operation, it works only
                        # for xml reply format   ####
                        elif (reply_format == 'xml'):
                            self.compare_reply(op, tests[val], val, teston,
                                               check, db, snapfile1, action)
                            ######## bug here ############
                            # multiple testcases for single command and same device, its deleting that file
                            ####################
                            """
                            if snap_del is True:
                                snapfile1 = snapfile1 if os.path.isfile(snapfile1) else self.generate_snap_file(device, pre, name, reply_format)
                                os.remove(snapfile1)
                                """
                        else:
                            # give error message if snapshot in text format is
                            # used with operations other than --diff  ####
                            self.logger_check.error(
                                colorama.Fore.RED +
                                "ERROR!! for checking snapshots in text format use '--diff' option ",
                                extra=self.log_detail)

            # print final result, if operation is --diff then message gets
            # printed compare_diff function only ####
            if (diff is not True):
                op.final_result(self.log_detail)

        return op
Exemplo n.º 28
0
    def multiple_device_details(
            self, hosts, config_data, pre_name, action, post_name):
        """
        Called when multiple devices are given in config file
        :param hosts: List of devices or a includes a file
        :param config_data: data of main config file
        :param pre_name: pre snapshot filename or file tag
        :param action: action to be taken, snap, snapcheck, check
        :param post_name: post snapshot filename or file tag
        :return: return object of testop.Operator containing test details
        """
        res_obj = []
        self.host_list = []
        host_dict={}

        first_entry = hosts[0]
        if 'include' in first_entry:
            devices_file_name = first_entry['include']
            if os.path.isfile(devices_file_name):
                lfile = devices_file_name
            else:
                lfile = os.path.join(
                            expanduser(get_path(
                                'DEFAULT',
                                'test_file_path')),
                            devices_file_name)
            login_file = open(lfile, 'r')
            dev_file = yaml.load(login_file)
            gp = first_entry.get('group', 'all')

            dgroup = [i.strip().lower() for i in gp.split(',')]
            for dgp in dev_file:
                if dgroup[0].lower() == 'all' or dgp.lower() in dgroup:
                    for val in dev_file[dgp]:
                        hostname = list(val)[0]
                        self.log_detail = {'hostname': hostname}
                        if val.get(hostname) is not None and hostname not in host_dict:
                            host_dict[hostname] = deepcopy(val.get(hostname))
                            self.host_list.append(hostname)
        else:
            for host in hosts:
                try:
                    hostname = host['device']
                    self.log_detail = {'hostname': hostname}
                except KeyError as ex:
                    self.logger.error(
                    colorama.Fore.RED +
                    "ERROR!! KeyError 'device' key not found",
                    extra=self.log_detail)
                except Exception as ex:
                    self.logger.error(
                    colorama.Fore.RED +
                    "ERROR!! %s" %
                    ex,
                    extra=self.log_detail)
                else:
                    if hostname not in host_dict:
                        self.host_list.append(hostname)
                        host_dict[hostname] = deepcopy(host)

        for (hostname, key_value) in iteritems(host_dict):
            username = key_value.get('username')
            password = key_value.get('passwd')
            key_value = self.get_values(key_value)
            t = Thread(
                target=self.connect,
                args=(
                    hostname,
                    username,
                    password,
                    pre_name,
                    config_data,
                    action,
                    post_name),
                kwargs= key_value
            )
            t.start()
            t.join()
            if action == "snap":
                if not self.snap_q.empty():
                    res_obj.append(self.snap_q.get())
            elif action in ["snapcheck", "check"]:
                if not self.q.empty():
                    res_obj.append(self.q.get())
            else:
                res_obj.append(None)

        return res_obj
Exemplo n.º 29
0
    def get_test(self, config_data, hostname, snap_file, post_snap, action):
        """
        Analyse testfile and return object of operator.Operator containing test details
        called by connect() function and other functions of Jsnapy module functions
        :param config_data: data of main config file
        :param hostname: hostname
        :param snap_file: pre snapshot file name
        :param post_snap: post snapshot file name
        :param action: action to be taken (check, snapcheck, snap)
        :return: object of testop.Operator containing test details
        """
        res = Operator()

        res = self.compare_tests(
                hostname,
                config_data,
                snap_file,
                post_snap,
                action)

        result_status = res.result
        
        mail_condition = 'all'
        if result_status == 'Passed':
            mail_condition = 'pass'
        elif result_status == 'Failed':
            mail_condition = 'fail'

        mail_pref =  config_data.get("mail") 

        #we don't want to send mail when diff operation is run
        if  mail_pref is not None and self.args.diff is False:
            mail_file_path = None
            if type(mail_pref) is str:
                mail_file_path = mail_pref
            elif type(mail_pref) is dict: 
                if mail_condition in mail_pref:
                    mail_file_path = mail_pref.get(mail_condition)
            else:
                self.logger.error(
                    colorama.Fore.RED +
                    "ERROR!! Type of mail preferences should be either dictionary or string", extra=self.log_detail)
                    
            if mail_file_path is not None and mail_file_path != '' :
                mfile = os.path.join(expanduser(get_path('DEFAULT', 'test_file_path')), mail_file_path)\
                        if os.path.isfile(mail_file_path) is False else mail_file_path
                if os.path.isfile(mfile):
                    mail_file = open(mfile, 'r')
                    mail_file = yaml.load(mail_file)
                    if "passwd" not in mail_file:
                        passwd = getpass.getpass(
                            "Please enter ur email password ")
                    else:
                        passwd = mail_file['passwd']
                
                    send_mail = Notification()
                    send_mail.notify(mail_file, hostname, passwd, res)
                else:
                    self.logger.error(
                        colorama.Fore.RED +
                        "ERROR!! Path of file containing mail content is not correct", extra=self.log_detail)
        # else:
        #     res = self.compare_tests(
        #         hostname,
        #         config_data,
        #         snap_file,
        #         post_snap,
        #         action)

        self.q.put(res)
        return res
Exemplo n.º 30
0
    def multiple_device_details(
            self, hosts, config_data, pre_name, action, post_name):
        """
        Called when multiple devices are given in config file
        :param hosts: List of devices or a includes a file
        :param config_data: data of main config file
        :param pre_name: pre snapshot filename or file tag
        :param action: action to be taken, snap, snapcheck, check
        :param post_name: post snapshot filename or file tag
        :return: return object of testop.Operator containing test details
        """
        res_obj = []
        self.host_list = []
        host_dict={}

        first_entry = hosts[0]
        if 'include' in first_entry:
            devices_file_name = first_entry['include']
            if os.path.isfile(devices_file_name):
                lfile = devices_file_name
            else:
                lfile = os.path.join(
                            expanduser(get_path(
                                'DEFAULT',
                                'test_file_path')),
                            devices_file_name)
            login_file = open(lfile, 'r')
            dev_file = yaml.load(login_file, Loader=yaml.FullLoader)
            gp = first_entry.get('group', 'all')

            dgroup = [i.strip().lower() for i in gp.split(',')]
            iter = 0
            for dgp in dev_file:
                if dgroup[0].lower() == 'all' or dgp.lower() in dgroup:
                    for val in dev_file[dgp]:
                        hostname = list(val)[0]
                        self.log_detail = {'hostname': hostname}
                        iter += 1
                        if val.get(hostname) is not None and hostname not in self.host_list:
                            self.host_list.append(hostname)
                        host_dict[iter] = deepcopy(val.get(hostname))
                        host_dict[iter]["device"] = hostname
        else:
            # changes to support port
            self.get_hosts_list(hosts, host_dict)


        test_cases = self.extract_test_cases(config_data)
        for (iter, key_value) in iteritems(host_dict):
            hostname = key_value.get('device')
            username = key_value.get('username')
            password = key_value.get('passwd')
            key_value = self.get_values(key_value)
            t = Thread(
                target=self.connect,
                args=(
                    hostname,
                    username,
                    password,
                    pre_name,
                    test_cases,
                    config_data,
                    action,
                    post_name),
                kwargs= key_value
            )
            t.start()
            t.join()
            if action == "snap":
                if not self.snap_q.empty():
                    res_obj.append(self.snap_q.get())
            elif action in ["snapcheck", "check"]:
                if not self.q.empty():
                    res_obj.append(self.q.get())
            else:
                res_obj.append(None)

        return res_obj
Exemplo n.º 31
0
 def test_get_path_config_exception(self, mock_config_location):
     with self.assertRaises(Exception):
         DirStore.custom_dir = None
         mock_config_location.return_value = None
         loc = get_path('DEFAULT', 'config_file_path')
Exemplo n.º 32
0
    def login(self, output_file):
        """
        Extract device information from main config file. Stores device information and call connect function,
        device can be single or multiple. Instead of connecting to all devices mentioned in yaml file, user can
        connect to some particular group of device also.
        :param output_file: name of snapshot file
        """
        self.host_list = []
        if self.args.hostname is None:
            host_dict = {}
            try:
                hosts_val = self.main_file['hosts']
            except KeyError as ex:
                self.logger.error(
                    colorama.Fore.RED +
                    "\nERROR occurred !! Hostname not given properly %s" %
                    str(ex),
                    extra=self.log_detail)
                #raise Exception(ex)
            except Exception as ex:
                self.logger.error(colorama.Fore.RED +
                                  "\nERROR occurred !! %s" % str(ex),
                                  extra=self.log_detail)
                #raise Exception(ex)
            else:
                # when group of devices are given, searching for include keyword in
                # hosts in main.yaml file
                first_entry = hosts_val[0]
                if 'include' in first_entry:
                    devices_file_name = first_entry['include']
                    if os.path.isfile(devices_file_name):
                        lfile = devices_file_name
                    else:
                        lfile = os.path.join(
                            expanduser(get_path('DEFAULT', 'test_file_path')),
                            devices_file_name)
                    login_file = open(lfile, 'r')
                    dev_file = yaml.load(login_file)
                    gp = first_entry.get('group', 'all')

                    dgroup = [i.strip().lower() for i in gp.split(',')]
                    for dgp in dev_file:
                        if dgroup[0].lower() == 'all' or dgp.lower() in dgroup:
                            for val in dev_file[dgp]:
                                hostname = list(val)[0]
                                self.log_detail = {'hostname': hostname}
                                if val.get(
                                        hostname
                                ) is not None and hostname not in host_dict:
                                    host_dict[hostname] = deepcopy(
                                        val.get(hostname))
                                    self.host_list.append(hostname)
                # login credentials are given in main config file, can connect to multiple devices
                else:
                    #key_value = deepcopy(k)
                    for host in hosts_val:
                        try:
                            hostname = host['device']
                            self.log_detail = {'hostname': hostname}
                        except KeyError as ex:
                            self.logger.error(
                                colorama.Fore.RED +
                                "ERROR!! KeyError 'device' key not found",
                                extra=self.log_detail)
                            #raise Exception(ex)
                        except Exception as ex:
                            self.logger.error(colorama.Fore.RED +
                                              "ERROR!! %s" % ex,
                                              extra=self.log_detail)
                            #raise Exception(ex)
                        else:
                            if hostname not in host_dict:
                                self.host_list.append(hostname)
                                # host.pop('device')
                                host_dict[hostname] = deepcopy(host)

            for (hostname, key_value) in iteritems(host_dict):
                #The file config takes precedence over cmd line params -- no changes made
                username = self.args.login or key_value.get('username')
                password = self.args.passwd or key_value.get('passwd')
                #if --port arg is given on the cmd then that takes precedence
                port = self.args.port
                if port is not None:
                    key_value['port'] = port
                key_value = self.get_values(key_value)
                t = Thread(target=self.connect,
                           args=(hostname, username, password, output_file),
                           kwargs=key_value)
                t.start()
                t.join()
        # login credentials are given from command line
        else:
            hostname = self.args.hostname
            self.log_detail = {'hostname': hostname}
            username = self.args.login
            password = self.args.passwd
            # if self.args.passwd is not None else getpass.getpass("\nEnter
            # Password: ")
            self.host_list.append(hostname)
            port = self.args.port
            key_value = {'port': port} if port is not None else {}
            self.connect(hostname, username, password, output_file,
                         **key_value)
Exemplo n.º 33
0
    def multiple_device_details(self, hosts, config_data, pre_name, action,
                                post_name):
        """
        Called when multiple devices are given in config file
        :param hosts: List of devices or a includes a file
        :param config_data: data of main config file
        :param pre_name: pre snapshot filename or file tag
        :param action: action to be taken, snap, snapcheck, check
        :param post_name: post snapshot filename or file tag
        :return: return object of testop.Operator containing test details
        """
        res_obj = []
        self.host_list = []
        host_dict = {}

        first_entry = hosts[0]
        if 'include' in first_entry:
            devices_file_name = first_entry['include']
            if os.path.isfile(devices_file_name):
                lfile = devices_file_name
            else:
                lfile = os.path.join(
                    expanduser(get_path('DEFAULT', 'test_file_path')),
                    devices_file_name)
            login_file = open(lfile, 'r')
            dev_file = yaml.load(login_file)
            gp = first_entry.get('group', 'all')

            dgroup = [i.strip().lower() for i in gp.split(',')]
            for dgp in dev_file:
                if dgroup[0].lower() == 'all' or dgp.lower() in dgroup:
                    for val in dev_file[dgp]:
                        hostname = list(val)[0]
                        self.log_detail = {'hostname': hostname}
                        if val.get(hostname
                                   ) is not None and hostname not in host_dict:
                            host_dict[hostname] = deepcopy(val.get(hostname))
                            self.host_list.append(hostname)
        else:
            for host in hosts:
                try:
                    hostname = host['device']
                    self.log_detail = {'hostname': hostname}
                except KeyError as ex:
                    self.logger.error(
                        colorama.Fore.RED +
                        "ERROR!! KeyError 'device' key not found",
                        extra=self.log_detail)
                except Exception as ex:
                    self.logger.error(colorama.Fore.RED + "ERROR!! %s" % ex,
                                      extra=self.log_detail)
                else:
                    if hostname not in host_dict:
                        self.host_list.append(hostname)
                        host_dict[hostname] = deepcopy(host)

        for (hostname, key_value) in iteritems(host_dict):
            username = key_value.get('username')
            password = key_value.get('passwd')
            key_value = self.get_values(key_value)
            t = Thread(target=self.connect,
                       args=(hostname, username, password, pre_name,
                             config_data, action, post_name),
                       kwargs=key_value)
            t.start()
            t.join()
            if action == "snap":
                if not self.snap_q.empty():
                    res_obj.append(self.snap_q.get())
            elif action in ["snapcheck", "check"]:
                if not self.q.empty():
                    res_obj.append(self.q.get())
            else:
                res_obj.append(None)

        return res_obj
Exemplo n.º 34
0
    def get_test(self, config_data, hostname, snap_file, post_snap, action):
        """
        Analyse testfile and return object of operator.Operator containing test details
        called by connect() function and other functions of Jsnapy module functions
        :param config_data: data of main config file
        :param hostname: hostname
        :param snap_file: pre snapshot file name
        :param post_snap: post snapshot file name
        :param action: action to be taken (check, snapcheck, snap)
        :return: object of testop.Operator containing test details
        """
        res = Operator()

        res = self.compare_tests(hostname, config_data, snap_file, post_snap,
                                 action)

        result_status = res.result

        mail_condition = 'all'
        if result_status == 'Passed':
            mail_condition = 'pass'
        elif result_status == 'Failed':
            mail_condition = 'fail'

        mail_pref = config_data.get("mail")

        #we don't want to send mail when diff operation is run
        if mail_pref is not None and self.args.diff is False:
            mail_file_path = None
            if type(mail_pref) is str:
                mail_file_path = mail_pref
            elif type(mail_pref) is dict:
                if mail_condition in mail_pref:
                    mail_file_path = mail_pref.get(mail_condition)
            else:
                self.logger.error(
                    colorama.Fore.RED +
                    "ERROR!! Type of mail preferences should be either dictionary or string",
                    extra=self.log_detail)

            if mail_file_path is not None and mail_file_path != '':
                mfile = os.path.join(expanduser(get_path('DEFAULT', 'test_file_path')), mail_file_path)\
                        if os.path.isfile(mail_file_path) is False else mail_file_path
                if os.path.isfile(mfile):
                    mail_file = open(mfile, 'r')
                    mail_file = yaml.load(mail_file)
                    if "passwd" not in mail_file:
                        passwd = getpass.getpass(
                            "Please enter ur email password ")
                    else:
                        passwd = mail_file['passwd']

                    send_mail = Notification()
                    send_mail.notify(mail_file, hostname, passwd, res)
                else:
                    self.logger.error(
                        colorama.Fore.RED +
                        "ERROR!! Path of file containing mail content is not correct",
                        extra=self.log_detail)
        # else:
        #     res = self.compare_tests(
        #         hostname,
        #         config_data,
        #         snap_file,
        #         post_snap,
        #         action)

        self.q.put(res)
        return res