From 134aa82330f952bba2f4516d952c46c4fd5610f7 Mon Sep 17 00:00:00 2001 From: Calvo Date: Tue, 3 Oct 2023 12:12:50 +0200 Subject: [PATCH] Deleted mysql app added by mistake --- .../pandorafms.mysql/discovery_definition.ini | 172 --- .../discovery/pandorafms.mysql/logo.png | Bin 12952 -> 0 bytes .../pandorafms.mysql/pandora_mysql.py | 979 ------------------ .../pandorafms.mysql/pandora_mysql.req | 2 - 4 files changed, 1153 deletions(-) delete mode 100644 pandora_console/attachment/discovery/pandorafms.mysql/discovery_definition.ini delete mode 100644 pandora_console/attachment/discovery/pandorafms.mysql/logo.png delete mode 100644 pandora_console/attachment/discovery/pandorafms.mysql/pandora_mysql.py delete mode 100644 pandora_console/attachment/discovery/pandorafms.mysql/pandora_mysql.req diff --git a/pandora_console/attachment/discovery/pandorafms.mysql/discovery_definition.ini b/pandora_console/attachment/discovery/pandorafms.mysql/discovery_definition.ini deleted file mode 100644 index 7345f5f1d9..0000000000 --- a/pandora_console/attachment/discovery/pandorafms.mysql/discovery_definition.ini +++ /dev/null @@ -1,172 +0,0 @@ -[discovery_extension_definition] - -short_name = pandorafms.mysql -section = app -name = MySQL -version = "1.0" -description = Monitor MySQL databases - -execution_file[_exec1_] = "bin/pandora_mysql" - -exec[] = "'_exec1_' --conf '_tempfileConf_' --target_databases '_tempfileTargetDatabases_' --target_agents '_tempfileTargetAgents_' --custom_queries '_tempfileCustomQueries_'" - -default_value[_dbstrings_] = "" -default_value[_dbuser_] = "" -default_value[_dbpass_] = "" -default_value[_threads_] = 1 -default_value[_engineAgent_] = "" -default_value[_prefixModuleName_] = "" -default_value[_scanDatabases_] = false -default_value[_agentPerDatabase_] = false -default_value[_prefixAgent_] = "" -default_value[_checkUptime_] = true -default_value[_queryStats_] = true -default_value[_checkConnections_] = true -default_value[_checkInnodb_] = true -default_value[_checkCache_] = true -default_value[_executeCustomQueries_] = true -default_value[_customQueries_] = "# ======================================================================= -# Custom queries definition guide -# ======================================================================= -# Definition example -# check_begin -# target_databases database where should be executed, default (all) -# name custom name chosen by the user -# description custom description chosen by the user -# operation value | full, -# value returns a simple value, -# full returns all rows in a string -# target query to be executed, -# you can use reserved word $__self_dbname to -# reference current analyzed database name -# datatype module datatype, could be: -# generic_data | generic_data_string | -# generic_proc -# min_warning minimum warning -# max_warning maximum warning -# min_critical minimum critical -# max_critical maximum critical -# inverse_warning if set to 1, warning thresholds has inverse meaning -# inverse_critical if set to 1, warning thresholds has inverse meaning -# str_warning string warning -# str_critical string critical -# unit unit to be displayed in module view -# interval module interval -# parent module parent for this module (name) -# check_end - -" - -[config_steps] - -name[1] = MySQL Base -custom_fields[1] = mysql_base -fields_columns[1] = 1 - -name[2] = MySQL Detailed -custom_fields[2] = mysql_detailed -fields_columns[2] = 1 - -[mysql_base] - -macro[1] = _dbstrings_ -name[1] = MySQL target strings -tip[1] = "SERVER:PORT, comma separated or line by line, as many targets as you need. Use # symbol to comment a line." -type[1] = textarea - -macro[2] = _dbuser_ -name[2] = User -type[2] = string - -macro[3] = _dbpass_ -name[3] = Password -type[3] = password - -[mysql_detailed] - -macro[1] = _threads_ -name[1] = Max threads -type[1] = number -mandatory_field[1] = false - -macro[2] = _engineAgent_ -name[2] = Target agent -tip[2] = Defines a target agent where this task will store data detected, if you have defined multiple targets, define a comma separated or line by line list of names here or leave in blank to use server IP address/FQDN. -type[2] = textarea -mandatory_field[2] = false - -macro[3] = _prefixModuleName_ -name[3] = Custom module prefix -tip[3] = Defines a custom prefix to be concatenated before module names generated by this task. -type[3] = string -mandatory_field[3] = false - -macro[4] = _scanDatabases_ -name[4] = Scan databases -type[4] = checkbox - -macro[5] = _agentPerDatabase_ -name[5] = Create agent per database -type[5] = checkbox - -macro[6] = _prefixAgent_ -name[6] = Custom database agent prefix -tip[6] = Defines a custom prefix to be concatenated before database agent names generated by this task. -type[6] = string -show_on_true[6] = _agentPerDatabase_ -mandatory_field[6] = false - -macro[7] = _checkUptime_ -name[7] = Check engine uptime -type[7] = checkbox - -macro[8] = _queryStats_ -name[8] = Retrieve query statistics -type[8] = checkbox - -macro[9] = _checkConnections_ -name[9] = Analyze connections -type[9] = checkbox - -macro[10] = _checkInnodb_ -name[10] = Retrieve InnoDB statistics -type[10] = checkbox - -macro[11] = _checkCache_ -name[11] = Retrieve cache statistics -type[11] = checkbox - -macro[12] = _executeCustomQueries_ -name[12] = Execute custom queries -type[12] = checkbox - -macro[13] = _customQueries_ -name[13] = Custom queries -tip[13] = Define here your custom queries. -type[13] = textarea -show_on_true[13] = _executeCustomQueries_ -mandatory_field[13] = false - -[tempfile_confs] - -file[_tempfileConf_] = "agents_group_id = __taskGroupID__ -interval = __taskInterval__ -user = _dbuser_ -password = _dbpass_ -threads = _threads_ -modules_prefix = _prefixModuleName_ -execute_custom_queries = _executeCustomQueries_ -analyze_connections = _checkConnections_ -scan_databases = _scanDatabases_ -agent_per_database = _agentPerDatabase_ -db_agent_prefix = _prefixAgent_ -innodb_stats = _checkInnodb_ -engine_uptime = _checkUptime_ -query_stats = _queryStats_ -cache_stats = _checkCache_" - -file[_tempfileTargetDatabases_] = "_dbstrings_" - -file[_tempfileTargetAgents_] = "_engineAgent_" - -file[_tempfileCustomQueries_] = "_customQueries_" \ No newline at end of file diff --git a/pandora_console/attachment/discovery/pandorafms.mysql/logo.png b/pandora_console/attachment/discovery/pandorafms.mysql/logo.png deleted file mode 100644 index b24a84ceea0c3ad8590bc2721ebda93108a0b8f7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12952 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 0: - uptime_string += f"{days} days " - if hours > 0: - uptime_string += f"{hours} hours " - if minutes > 0: - uptime_string += f"{minutes} minutes " - uptime_string += f"{seconds} seconds" - - return uptime_string - -#### -# Scan engine databases -########################################### -def get_databases_modules(db_object=None): - global interval - global agents_group_id - global modules_prefix - global agent_per_database - global db_agent_prefix - - # Initialize modules - modules = [] - - if db_object: - # Get all databases - databases = db_object.run_query(f"SHOW DATABASES")[0] - - for db in databases: - # Get database name - db_name = db["Database"] - - # Skip core databases. - if db_name == "mysql": - continue - if db_name == "information_schema": - continue - if db_name == "performance_schema": - continue - if db_name == "sys": - continue - - # Add modules - modules.append({ - "name": get_module_name(db_name+" availability"), - "type": "generic_proc", - "data": 1, - "description": "Database available" - }) - - modules.append({ - "name": get_module_name(db_name+" fragmentation ratio"), - "type": "generic_data", - "data": db_object.run_query(f"SELECT AVG(DATA_FREE/(DATA_LENGTH + INDEX_LENGTH)) AS average_fragmentation_ratio FROM information_schema.tables WHERE table_schema = '{db_name}' GROUP BY table_schema", single_value=True)[0], - "unit": "%", - "description": "Database fragmentation" - }) - - modules.append({ - "name": get_module_name(db_name+" size"), - "type": "generic_data", - "data": db_object.run_query(f"SELECT ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS size FROM information_schema.tables WHERE table_schema = '{db_name}' GROUP BY table_schema", single_value=True)[0], - "unit": "MB", - "description": "Database size" - }) - - modules += db_object.get_custom_queries(db_name) - - # Add a new agent if agent per database and reset modules - if agent_per_database == 1: - add_monitoring_data({ - "agent_data" : { - "agent_name" : db_agent_prefix+db_object.agent+" "+db_name, - "agent_alias" : db_agent_prefix+db_object.agent+" "+db_name, - "os" : db_object.type, - "os_version" : db_object.version, - "interval" : interval, - "id_group" : agents_group_id, - "address" : db_object.host, - "description" : "", - "parent_agent_name" : db_object.agent, - }, - "module_data" : modules - }) - add_summary_value("Total agents", 1) - add_summary_value("Databases agents", 1) - modules = [] - - return modules - -############# -## CLASSES ## -############# - -#### -# Remote database object -########################################### -class RemoteDB: - def __init__(self, target="", agent=""): - self.type = "MySQL" - self.target = target - self.agent = self.get_agent(agent) - self.parse_target() - self.connected = 0 - self.connector = None - - self.connect() - - self.version = self.get_version() - - def connect(self): - global user - global password - - # Try to connect and capture errors - error = "" - try: - connection = pymysql.connect( - host=self.host, - port=self.port, - user=user, - password=password, - connect_timeout=5 - ) - - # Execute a test query - with connection.cursor() as cursor: - cursor.execute("SELECT 1") - result = cursor.fetchone() - if result: - self.connector = connection - self.connected = 1 - else: - error = "Connection failed" - - except pymysql.Error as e: - error = str(e) - - # Add error to info if cna't connect - if self.connector is None: - add_info_value("["+self.target+"]"+error+"\n") - add_summary_value("Targets down", 1) - else: - add_summary_value("Targets up", 1) - - def disconnect(self): - if self.connected == 1: - self.connector.close() - - def run_query(self, query="", single_row=False, single_value=False, db=""): - if self.connected == 1 and query: - try: - with self.connector.cursor() as cursor: - if db: - cursor.execute(f"USE {db}") - - # Execute your query - cursor.execute(query) - - # Get query fields - fields = [field[0] for field in cursor.description] - - if single_row or single_value: - # Fetch first row - row = cursor.fetchone() - - if single_value: - if row: - # Get first field value - result = str(row[0]) - else: - result = "" - - else: - # Read row - row_item = {} - if row: - i = 0 - # Assign each value for each field in row item - for field in fields: - row_item[field] = str(row[i]) - i += 1 - - result = row_item - - else: - # Fetch all rows - row_items = [] - rows = cursor.fetchall() - - # Read each row - for row in rows: - row_item = {} - i = 0 - # Assign each value for each field in row item - for field in fields: - row_item[field] = str(row[i]) - i += 1 - - # Add row item to row items - row_items.append(row_item) - - result = row_items - - # Close cursor and return result - cursor.close() - return result, True, "" - - except pymysql.Error as e: - add_info_value("["+self.target+"]"+str(e)+"\n") - return None, False, str(e) - else: - return None, False, "Not connected to database" - - def get_agent(self, agent=""): - if agent: - return agent - else: - return self.target.split(":")[0] - - def get_version(self): - version = self.run_query(f"SELECT @@VERSION", single_value=True)[0] - if version is None: - version = "Discovery" - return version - - def parse_target(self): - # Default values - self.port = 3306 - - if ":" in self.target: - target = self.target.split(":") - self.host = target[0] - self.port = int(target[1]) - - else: - self.host = self.target - - def get_statistics(self): - global interval - global modules_prefix - global engine_uptime - global query_stats - global analyze_connections - global innodb_stats - global cache_stats - - # Initialize modules - modules = [] - - # Get status values - status = {} - for var in self.run_query(f"SHOW GLOBAL STATUS")[0]: - status[var["Variable_name"]] = var["Value"] - - # Get svariables values - variables = {} - for var in self.run_query(f"SHOW VARIABLES")[0]: - variables[var["Variable_name"]] = var["Value"] - - # Get modules - if engine_uptime == 1: - modules.append({ - "name": get_module_name("restart detection"), - "type": "generic_proc", - "data": 1 if int(status["Uptime"]) < 2 * interval else 0, - "description": f"Running for {format_uptime(int(status['Uptime']))} (value is 0 if restart detected)" - }) - - if query_stats == 1: - modules.append({ - "name": get_module_name("queries"), - "type": "generic_data_inc_abs", - "data": status["Queries"], - "description": "" - }) - - modules.append({ - "name": get_module_name("query rate"), - "type": "generic_data_inc", - "data": status["Queries"], - }) - - modules.append({ - "name": get_module_name("query select"), - "type": "generic_data_inc_abs", - "data": status["Com_select"], - }) - - modules.append({ - "name": get_module_name("query update"), - "type": "generic_data_inc_abs", - "data": status["Com_update"] - }) - - modules.append({ - "name": get_module_name("query delete"), - "type": "generic_data_inc_abs", - "data": status["Com_delete"] - }) - - modules.append({ - "name": get_module_name("query insert"), - "type": "generic_data_inc_abs", - "data": status["Com_insert"] - }) - - if analyze_connections == 1: - modules.append({ - "name": get_module_name("current connections"), - "type": "generic_data", - "data": status["Threads_connected"], - "description": "Current connections to MySQL engine (global)", - "min_warning": int(variables["max_connections"]) * 0.90, - "min_critical": int(variables["max_connections"]) * 0.98 - }) - - modules.append({ - "name": get_module_name("connections ratio"), - "type": "generic_data", - "data": (int(status["Max_used_connections"]) / int(variables["max_connections"])) * 100, - "description": "This metric indicates if you could run out soon of connection slots.", - "unit": "%", - "min_warning": 85, - "min_critical": 90 - }) - - modules.append({ - "name": get_module_name("aborted connections"), - "type": "generic_data_inc_abs", - "data": status["Aborted_connects"], - "description": "This metric indicates if the ammount of aborted connections in the last interval." - }) - - if innodb_stats == 1: - modules.append({ - "name": get_module_name("Innodb buffer pool pages total"), - "type": "generic_data", - "data": status["Innodb_data_written"], - "description": "Total number of pages in the buffer pool (utilization)." - }) - - modules.append({ - "name": get_module_name("Innodb buffer pool read requests"), - "type": "generic_data_inc_abs", - "data": status["Innodb_buffer_pool_read_requests"], - "description": "Reads from innodb buffer pool." - }) - - modules.append({ - "name": get_module_name("Innodb buffer pool write requests"), - "type": "generic_data_inc_abs", - "data": status["Innodb_buffer_pool_write_requests"], - "description": "Writes in innodb buffer pool." - }) - - modules.append({ - "name": get_module_name("Innodb disk reads"), - "type": "generic_data_inc_abs", - "data": status["Innodb_data_reads"], - "description": "Amount of read operations." - }) - - modules.append({ - "name": get_module_name("Innodb disk writes"), - "type": "generic_data_inc_abs", - "data": status["Innodb_data_writes"], - "description": "Amount of write operations." - }) - - modules.append({ - "name": get_module_name("Innodb disk data read"), - "type": "generic_data_inc_abs", - "data": int(status["Innodb_data_read"])/(1024*1024), - "description": "Amount of data read from disk.", - "unit": "MB" - }) - - modules.append({ - "name": get_module_name("Innodb disk data written"), - "type": "generic_data_inc_abs", - "data": int(status["Innodb_data_written"])/(1024*1024), - "description": "Amount of data written to disk.", - "unit": "MB" - }) - - if cache_stats == 1: - modules.append({ - "name": get_module_name("query cache enabled"), - "type": "generic_proc", - "data": 1 if variables["have_query_cache"] == "YES" else 0, - "description": "Query cache enabled." if variables["have_query_cache"] == "YES" else "Query cache not found, check query_cache_type in your my.cnf" - }) - - if variables["have_query_cache"] == "YES": - if int(status["Qcache_hits"]) + int(status["Qcache_inserts"]) + int(status["Qcache_not_cached"]) != 0: - ratio = 100 * int(status["Qcache_hits"]) / int(status["Qcache_inserts"]) + int(status["Qcache_inserts"]) + int(status["Qcache_not_cached"]) - - modules.append({ - "name": get_module_name("query hit ratio"), - "type": "generic_data", - "data": ratio, - "unit": "%" - }) - - return modules - - def get_custom_queries(self, db=""): - global modules_prefix - global execute_custom_queries - global custom_queries - - # Initialize modules - modules = [] - - # Run if enabled execute custom queries - if execute_custom_queries == 1: - - # Run each custom query - for custom_query in custom_queries: - - # Run if target database match - if "all" in custom_query["target_databases"] or len(custom_query["target_databases"]) == 0 or db in custom_query["target_databases"]: - - # Skipt if empty required parameters - if "target" not in custom_query or not custom_query["target"]: - continue - if "name" not in custom_query or not custom_query["name"]: - continue - - # Reset error - error = "" - # Reset result - data = "" - - # Prepare parameters - sql = custom_query["target"] - sql = re.sub(r'\$__self_dbname', db, sql) - - module_name = custom_query["name"] - module_name = re.sub(r'\$__self_dbname', db, module_name) - - desc = custom_query["description"] if "description" in custom_query else "" - datatype = custom_query["datatype"] if "datatype" in custom_query else "generic_data_string" - - # Set single query - if "operation" not in custom_query or not custom_query["operation"]: - single_value=False - elif custom_query["operation"] == "value": - single_value=True - else: - single_value=False - - # Adjust module type if needed - if(single_value == False): - datatype = "generic_data_string" - - # Run query - rows, status, err = self.run_query(sql, single_value=single_value, db=db) - - # Get query data - if rows is not None: - if isinstance(rows, list): - for row in rows: - for key, value in row.items(): - data += str(value) + "|" - # Remove last pipe - data = data[:-1] - data += "\n" - else: - data = rows - - # Adjust data - if data == "" and "string" in datatype: - data = "No output." - - # Verify query status and set description - if status == False: - desc = "Failed to execute query: " + err; - elif desc == "": - desc = "Execution OK" - - modules.append({ - "name": get_module_name(module_name), - "type": datatype, - "data": data, - "description": desc, - "min_critical": custom_query["min_critical"] if "min_critical" in custom_query else "", - "max_critical": custom_query["max_critical"] if "max_critical" in custom_query else "", - "min_warning": custom_query["min_warning"] if "min_warning" in custom_query else "", - "max_warning": custom_query["max_warning"] if "max_warning" in custom_query else "", - "critical_inverse": custom_query["critical_inverse"] if "critical_inverse" in custom_query else "", - "warning_inverse": custom_query["warning_inverse"] if "warning_inverse" in custom_query else "", - "str_warning": custom_query["str_warning"] if "str_warning" in custom_query else "", - "str_critical": custom_query["str_critical"] if "str_critical" in custom_query else "", - "module_interval":custom_query["module_interval"] if "module_interval" in custom_query else "" - }) - - return modules - - def get_modules(self): - # Initialize modules - modules = [] - - # Get statistics modules - modules += self.get_statistics() - # Get custom queries modules - modules += self.get_custom_queries() - - return modules - -############# -## THREADS ## -############# - -#### -# Function per agent -########################################### -def monitor_items(thread_agents=[]): - global target_agents - global interval - global agents_group_id - - for thread_agent in thread_agents: - # Get target agent - agent = "" - if 0 <= thread_agent["id"] < len(target_agents): - agent = target_agents[thread_agent["id"]] - - # Initialize modules - modules=[] - - # Get DB object - db_object = RemoteDB(thread_agent["db_target"], agent) - - # Add connection module - modules.append({ - "name" : get_module_name(db_object.type+" connection"), - "type" : "generic_proc", - "description" : db_object.type+" availability", - "data" : db_object.connected - }) - - # Get global connection modules if connected - if(db_object.connected == 1): - modules += db_object.get_modules() - - # Get engine databases modules - if scan_databases == 1: - modules += get_databases_modules(db_object) - - # Add new monitoring data - add_monitoring_data({ - "agent_data" : { - "agent_name" : db_object.agent, - "agent_alias" : db_object.agent, - "os" : db_object.type, - "os_version" : db_object.version, - "interval" : interval, - "id_group" : agents_group_id, - "address" : db_object.host, - "description" : "", - }, - "module_data" : modules - }) - add_summary_value("Total agents", 1) - add_summary_value("Target agents", 1) - - # Disconnect from target - db_object.disconnect() - - -#### -# Function per thread -########################################### -def monitor_threads(): - global q - - thread_agents=q.get() - try: - monitor_items(thread_agents) - q.task_done() - except Exception as e: - q.task_done() - set_error_level(1) - add_info_value("Error while runing single thread: "+str(e)+"\n") - - -########## -## MAIN ## -########## - -# Parse arguments -parser = argparse.ArgumentParser(description= "", formatter_class=argparse.RawTextHelpFormatter) -parser.add_argument('--conf', help='Path to configuration file', metavar='', required=True) -parser.add_argument('--target_databases', help='Path to target databases file', metavar='', required=True) -parser.add_argument('--target_agents', help='Path to target agents file', metavar='', required=False) -parser.add_argument('--custom_queries', help='Path to custom queries file', metavar='', required=False) -args = parser.parse_args() - -# Parse configuration file -config = configparser.ConfigParser() -try: - config.read_string('[CONF]\n' + open(args.conf).read()) -except Exception as e: - set_error_level(1) - set_info_value("Error while reading configuration file file: "+str(e)+"\n") - print_output() - -agents_group_id = param_int(parse_parameter(config, agents_group_id, "agents_group_id")) -interval = param_int(parse_parameter(config, interval, "interval")) -user = parse_parameter(config, user, "user") -password = parse_parameter(config, password, "password") -threads = param_int(parse_parameter(config, threads, "threads")) -modules_prefix = parse_parameter(config, modules_prefix, "modules_prefix") -execute_custom_queries = param_int(parse_parameter(config, execute_custom_queries, "execute_custom_queries")) -analyze_connections = param_int(parse_parameter(config, analyze_connections, "analyze_connections")) -scan_databases = param_int(parse_parameter(config, scan_databases, "scan_databases")) -agent_per_database = param_int(parse_parameter(config, agent_per_database, "agent_per_database")) -db_agent_prefix = parse_parameter(config, db_agent_prefix, "db_agent_prefix") -innodb_stats = param_int(parse_parameter(config, innodb_stats, "innodb_stats")) -engine_uptime = param_int(parse_parameter(config, engine_uptime, "engine_uptime")) -query_stats = param_int(parse_parameter(config, query_stats, "query_stats")) -cache_stats = param_int(parse_parameter(config, cache_stats, "cache_stats")) - -# Parse rest of files -t_file = args.target_databases -a_file = args.target_agents -cq_file = args.custom_queries - -# Parse DB targets -if t_file: - try: - lines = open(t_file, "r") - for line in lines: - line = line.strip() - # SKIP EMPTY AND COMMENTED LINES - if not line: - continue - if line == "\n": - continue - if line[0] == '#': - continue - - db_targets += [element.strip() for element in line.split(",")] - lines = [] - - except Exception as e: - set_error_level(1) - add_info_value("Error while reading DB targets file: "+str(e)+"\n") - -# Parse target agents -if a_file: - try: - lines = open(a_file, "r") - for line in lines: - line = line.strip() - # SKIP EMPTY AND COMMENTED LINES - if not line: - continue - if line == "\n": - continue - if line[0] == '#': - continue - - target_agents += [element.strip() for element in line.split(",")] - lines = [] - - except Exception as e: - set_error_level(1) - add_info_value("Error while reading target agents file: "+str(e)+"\n") - -# Parse custom queries -if cq_file: - try: - custom_query = {} - save = False - - lines = open(cq_file, "r") - for line in lines: - line = line.strip() - # SKIP EMPTY AND COMMENTED LINES - if not line: - continue - if line == "\n": - continue - if line[0] == '#': - continue - - # Start parsing module - if line == "check_begin": - save = True - continue - - # Read next line until new module - if save == False: - continue - - # End parsing module - if line == "check_end": - if "target_databases" not in custom_query: - custom_query["target_databases"] = ["all"] - custom_queries.append(custom_query) - custom_query = {} - save = False - continue - - # Get line key value pair - key, value = [element.strip() for element in line.split(maxsplit=1)] - - # Add target databases to query - if key == "target_databases": - custom_query["target_databases"] = [element.strip() for element in value.split(",")] - continue - - # Skip not select queries - if key == "target" and not re.search(r'^select', value, re.IGNORECASE): - add_info_value("Removed ["+value+"] from custom queries, only select queries are allowed.\n") - continue - - # Add other parameters to query - custom_query[key] = value - lines = [] - - except Exception as e: - set_error_level(1) - add_info_value("Error while reading custom queries file: "+str(e)+"\n") - -# Verify required arguments -required_params = True -if not user: - add_info_value("Parameter [user] not defined\n") - required_params = False -if not password: - add_info_value("Parameter [password] not defined\n") - required_params = False -if not db_targets: - add_info_value("Database targets not defined\n") - required_params = False - -if required_params == False: - set_error_level(1) - print_output() - -# Initialize summary -set_summary_value("Total agents", 0) -set_summary_value("Target agents", 0) -set_summary_value("Databases agents", 0) -set_summary_value("Targets up", 0) -set_summary_value("Targets down", 0) - -# Assign threads -if threads > len(db_targets): - threads = len(db_targets) - -if threads < 1: - threads = 1 - -# Distribute agents per thread -agents_per_thread = [] -thread = 0 -i = 0 -for db_target in db_targets: - if not 0 <= thread < len(agents_per_thread): - agents_per_thread.append([]) - - agents_per_thread[thread].append({ - "id": i, - "db_target": db_target - }) - - thread += 1 - if thread >= threads: - thread=0 - - i += 1 - -# Run threads -try: - q=Queue() - for n_thread in range(threads) : - q.put(agents_per_thread[n_thread]) - - run_threads = [] - for n_thread in range(threads): - t = Thread(target=monitor_threads) - t.daemon=True - t.start() - run_threads.append(t) - - for t in run_threads: - t.join() - - q.join() - -except Exception as e: - add_info_value("Error while running threads: "+str(e)+"\n") - set_error_level(1) - -# Print output and exit script -print_output() \ No newline at end of file diff --git a/pandora_console/attachment/discovery/pandorafms.mysql/pandora_mysql.req b/pandora_console/attachment/discovery/pandorafms.mysql/pandora_mysql.req deleted file mode 100644 index 057adf64fc..0000000000 --- a/pandora_console/attachment/discovery/pandorafms.mysql/pandora_mysql.req +++ /dev/null @@ -1,2 +0,0 @@ -[deps] -pymysql \ No newline at end of file