def parse_conf_dir(conf_dir): if not isdir(conf_dir): return list(), '%s is not a directory' % conf_dir jail_local = list( filter(lambda local: is_accessible(local, R_OK), glob(conf_dir + '/*.local'))) jail_conf = list( filter(lambda conf: is_accessible(conf, R_OK), glob(conf_dir + '/*.conf'))) if not (jail_local or jail_conf): return list(), '%s is empty or not readable' % conf_dir # According "man jail.conf" files could be *.local AND *.conf # *.conf files parsed first. Changes in *.local overrides configuration in *.conf if jail_conf: jail_local.extend([ conf for conf in jail_conf if conf[:-5] not in [local[:-6] for local in jail_local] ]) jails_list = list() for conf in jail_local: with open(conf, 'rt') as f: raw_data = f.read() data = ' '.join(raw_data.split()) jails_list.extend(REGEX_JAILS.findall(data)) jails_list = list(set(jails_list)) return jails_list, 'can\'t locate any jails in %s. Default jail is [\'ssh\']' % conf_dir
def check(self): # Check "log_path" is accessible. # If NOT STOP plugin if not is_accessible(self.log_path, R_OK): self.error('Cannot access file %s' % (self.log_path)) return False # Check "conf_path" is accessible. # If "conf_path" is accesible try to parse it to find enabled jails if is_accessible(self.conf_path, R_OK): with open(self.conf_path, 'rt') as jails_conf: jails_list = regex.findall(' '.join(jails_conf.read().split())) self.jails_list = [ jail[:-1] for jail, status in jails_list if status == 'true' ] else: self.jails_list = [] self.error('Cannot access jail.local file %s.' % (self.conf_path)) # If for some reason parse failed we still can START with default jails_list. self.jails_list = [jail for jail in self.jails_list if jail not in self.exclude]\ if self.jails_list else self.default_jails self.create_dimensions() self.info('Plugin succefully started. Jails: %s' % (self.jails_list)) return True
def check(self): # Check "log_path" is accessible. # If NOT STOP plugin if not is_accessible(self.log_path, R_OK): self.error('Cannot access file %s' % self.log_path) return False jails_list = list() if self.conf_dir: dir_jails, error = parse_conf_dir(self.conf_dir) jails_list.extend(dir_jails) if not dir_jails: self.error(error) if self.conf_path: path_jails, error = parse_conf_path(self.conf_path) jails_list.extend(path_jails) if not path_jails: self.error(error) # If for some reason parse failed we still can START with default jails_list. self.jails_list = list(set(jails_list) - set(self.exclude)) or ['ssh'] self.data = dict([(jail, 0) for jail in self.jails_list]) self.data.update( dict([(jail + '_in_jail', 0) for jail in self.jails_list])) self.bans = dict([(jail, list()) for jail in self.jails_list]) self.create_dimensions() self.info('Plugin successfully started. Jails: %s' % self.jails_list) return True
def check(self): # Check "log_path" is accessible. # If NOT STOP plugin if not is_accessible(self.log_path, R_OK): self.error('Cannot access file %s' % self.log_path) return False jails_list = list() if self.conf_dir: dir_jails, error = parse_conf_dir(self.conf_dir) jails_list.extend(dir_jails) if not dir_jails: self.error(error) if self.conf_path: path_jails, error = parse_conf_path(self.conf_path) jails_list.extend(path_jails) if not path_jails: self.error(error) # If for some reason parse failed we still can START with default jails_list. self.jails_list = list(set(jails_list) - set(self.exclude)) or ['ssh'] self.data = dict([(jail, 0) for jail in self.jails_list]) self.create_dimensions() self.info('Plugin successfully started. Jails: %s' % self.jails_list) return True
def parse_configuration_files_(jails_conf_path, jails_conf_dir, print_error): """ :param jails_conf_path: <str> :param jails_conf_dir: <str> :param print_error: <function> :return: <tuple> Uses "find_jails_in_files" function to find all jails in the "jails_conf_dir" directory and in the "jails_conf_path" All files must endswith ".local" or ".conf" Return order is important. According man jail.conf it should be * jail.conf * jail.d/*.conf (in alphabetical order) * jail.local * jail.d/*.local (in alphabetical order) """ path_conf, path_local, dir_conf, dir_local = list(), list(), list(), list() # Parse files in the directory if not (isinstance(jails_conf_dir, str) and isdir(jails_conf_dir)): print_error('%s is not a directory' % jails_conf_dir) else: dir_conf = list( filter(lambda conf: is_accessible(conf, R_OK), glob(jails_conf_dir + '/*.conf'))) dir_local = list( filter(lambda local: is_accessible(local, R_OK), glob(jails_conf_dir + '/*.local'))) if not (dir_conf or dir_local): print_error('%s is empty or not readable' % jails_conf_dir) else: dir_conf, dir_local = (find_jails_in_files(dir_conf, print_error), find_jails_in_files(dir_local, print_error)) # Parse .conf and .local files if isinstance(jails_conf_path, str) and jails_conf_path.endswith( ('.local', '.conf')): path_conf, path_local = (find_jails_in_files( [jails_conf_path.split('.')[0] + '.conf'], print_error), find_jails_in_files([ jails_conf_path.split('.')[0] + '.local' ], print_error)) return path_conf, dir_conf, path_local, dir_local
def parse_conf_path(conf_path): if not is_accessible(conf_path, R_OK): return list(), '%s is not readable' % conf_path with open(conf_path, 'rt') as jails_conf: raw_data = jails_conf.read() data = raw_data.split() jails_list = REGEX_JAILS.findall(' '.join(data)) return jails_list, 'can\'t locate any jails in %s. Default jail is [\'ssh\']' % conf_path
def parse_conf_path(conf_path): if not is_accessible(conf_path, R_OK): return list(), '%s is not readable' % conf_path with open(conf_path, 'rt') as jails_conf: raw_data = jails_conf.read() data = raw_data.split() jails_list = REGEX.findall(' '.join(data)) return jails_list, 'can\'t locate any jails in %s. Default jail is [\'ssh\']' % conf_path
def check(self): """ :return: bool Check if the "log_path" is not empty and readable """ if not (is_accessible(self.log_path, R_OK) and getsize(self.log_path) != 0): self.error('%s is not readable or empty' % self.log_path) return False return True
def parse_configuration_files_(jails_conf_path, jails_conf_dir, print_error): """ :param jails_conf_path: <str> :param jails_conf_dir: <str> :param print_error: <function> :return: <tuple> Uses "find_jails_in_files" function to find all jails in the "jails_conf_dir" directory and in the "jails_conf_path" All files must endswith ".local" or ".conf" Return order is important. According man jail.conf it should be * jail.conf * jail.d/*.conf (in alphabetical order) * jail.local * jail.d/*.local (in alphabetical order) """ path_conf, path_local, dir_conf, dir_local = list(), list(), list(), list() # Parse files in the directory if not (isinstance(jails_conf_dir, str) and isdir(jails_conf_dir)): print_error('%s is not a directory' % jails_conf_dir) else: dir_conf = list(filter(lambda conf: is_accessible(conf, R_OK), glob(jails_conf_dir + '/*.conf'))) dir_local = list(filter(lambda local: is_accessible(local, R_OK), glob(jails_conf_dir + '/*.local'))) if not (dir_conf or dir_local): print_error('%s is empty or not readable' % jails_conf_dir) else: dir_conf, dir_local = (find_jails_in_files(dir_conf, print_error), find_jails_in_files(dir_local, print_error)) # Parse .conf and .local files if isinstance(jails_conf_path, str) and jails_conf_path.endswith(('.local', '.conf')): path_conf, path_local = (find_jails_in_files([jails_conf_path.split('.')[0] + '.conf'], print_error), find_jails_in_files([jails_conf_path.split('.')[0] + '.local'], print_error)) return path_conf, dir_conf, path_local, dir_local
def check(self): """ :return: bool Check if the "log_path" is not empty and readable """ if not (is_accessible(self.log_path, R_OK) and getsize(self.log_path) != 0): self.error('%s is not readable or empty' % self.log_path) return False self.jails_list, self.to_netdata, self.banned_ips = self.jails_auto_detection_() self.definitions = create_definitions_(self.jails_list) self.info('Jails: %s' % self.jails_list) return True
def check(self): # Check "log_path" is accessible. # If NOT STOP plugin if not is_accessible(self.log_path, R_OK): self.error('Cannot access file %s' % (self.log_path)) return False # Check "conf_path" is accessible. # If "conf_path" is accesible try to parse it to find enabled jails if is_accessible(self.conf_path, R_OK): with open(self.conf_path, 'rt') as jails_conf: jails_list = regex.findall(' '.join(jails_conf.read().split())) self.jails_list = [jail[:-1] for jail, status in jails_list if status == 'true'] else: self.jails_list = [] self.error('Cannot access jail.local file %s.' % (self.conf_path)) # If for some reason parse failed we still can START with default jails_list. self.jails_list = [jail for jail in self.jails_list if jail not in self.exclude]\ if self.jails_list else self.default_jails self.create_dimensions() self.info('Plugin succefully started. Jails: %s' % (self.jails_list)) return True
def parse_conf_dir(conf_dir): if not isdir(conf_dir): return list(), '%s is not a directory' % conf_dir jail_local = list(filter(lambda local: is_accessible(local, R_OK), glob(conf_dir + '/*.local'))) jail_conf = list(filter(lambda conf: is_accessible(conf, R_OK), glob(conf_dir + '/*.conf'))) if not (jail_local or jail_conf): return list(), '%s is empty or not readable' % conf_dir # According "man jail.conf" files could be *.local AND *.conf # *.conf files parsed first. Changes in *.local overrides configuration in *.conf if jail_conf: jail_local.extend([conf for conf in jail_conf if conf[:-5] not in [local[:-6] for local in jail_local]]) jails_list = list() for conf in jail_local: with open(conf, 'rt') as f: raw_data = f.read() data = ' '.join(raw_data.split()) jails_list.extend(REGEX.findall(data)) jails_list = list(set(jails_list)) return jails_list, 'can\'t locate any jails in %s. Default jail is [\'ssh\']' % conf_dir
def check(self): """ :return: bool Check if the "log_path" is not empty and readable """ if not (is_accessible(self.log_path, R_OK) and getsize(self.log_path) != 0): self.error('%s is not readable or empty' % self.log_path) return False self.jails_list, self.to_netdata, self.banned_ips = self.jails_auto_detection_( ) self.definitions = create_definitions_(self.jails_list) self.info('Jails: %s' % self.jails_list) return True
def check(self): # We cant start without 'rndc' command if not self.rndc: self.error( 'Can\'t locate \'rndc\' binary or binary is not executable by netdata' ) return False # We cant start if stats file is not exist or not readable by netdata user if not is_accessible(self.named_stats_path, R_OK): self.error('Cannot access file %s' % self.named_stats_path) return False size_before = getsize(self.named_stats_path) run_rndc = Popen([self.rndc, 'stats'], shell=False) run_rndc.wait() size_after = getsize(self.named_stats_path) # We cant start if netdata user has no permissions to run 'rndc stats' if not run_rndc.returncode: # 'rndc' was found, stats file is exist and readable and we can run 'rndc stats'. Lets go! self.create_charts() # BIND APPEND dump on every run 'rndc stats' # that is why stats file size can be VERY large if update_interval too small dump_size_24hr = round( 86400 / self.update_every * (int(size_after) - int(size_before)) / 1048576, 3) # If update_every too small we should WARN user if self.update_every < 30: self.info( 'Update_every %s is NOT recommended for use. Increase the value to > 30' % self.update_every) self.info( 'With current update_interval it will be + %s MB every 24hr. ' 'Don\'t forget to create logrotate conf file for %s' % (dump_size_24hr, self.named_stats_path)) self.info('Plugin was started successfully.') return True else: self.error('Not enough permissions to run "%s stats"' % self.rndc) return False
def find_jails_in_files(list_of_files, print_error): """ :param list_of_files: <list> :param print_error: <function> :return: <list> Open a file and parse it to find all (enabled and disabled) jails The output is a list of tuples: [('ssh', 'true'), ('apache', 'false'), ...] """ jails_list = list() for conf in list_of_files: if is_accessible(conf, R_OK): with open(conf, 'rt') as conf: raw_data = conf.read() data = ' '.join(raw_data.split()) jails_list.extend(REGEX_JAILS.findall(data)) else: print_error('%s is not readable or not exist' % conf) return jails_list
def check(self): # Check "log_path" is accessible. # If NOT STOP plugin if not is_accessible(self.log_path, R_OK): self.error('Cannot access file %s' % self.log_path) return False if self.conf_dir: jails_list, error = parse_conf_dir(self.conf_dir) else: jails_list, error = parse_conf_path(self.conf_path) if not jails_list: self.error(error) # If for some reason parse failed we still can START with default jails_list. self.jails_list = list(set(jails_list) - set(self.exclude)) or ['ssh'] self.data = dict([(jail, 0) for jail in self.jails_list]) self.create_dimensions() self.info('Plugin successfully started. Jails: %s' % self.jails_list) return True
def check(self): # We cant start without 'rndc' command if not self.rndc: self.error('Can\'t locate \'rndc\' binary or binary is not executable by netdata') return False # We cant start if stats file is not exist or not readable by netdata user if not is_accessible(self.named_stats_path, R_OK): self.error('Cannot access file %s' % self.named_stats_path) return False size_before = getsize(self.named_stats_path) run_rndc = Popen([self.rndc, 'stats'], shell=False) run_rndc.wait() size_after = getsize(self.named_stats_path) # We cant start if netdata user has no permissions to run 'rndc stats' if not run_rndc.returncode: # 'rndc' was found, stats file is exist and readable and we can run 'rndc stats'. Lets go! self.create_charts() # BIND APPEND dump on every run 'rndc stats' # that is why stats file size can be VERY large if update_interval too small dump_size_24hr = round(86400 / self.update_every * (int(size_after) - int(size_before)) / 1048576, 3) # If update_every too small we should WARN user if self.update_every < 30: self.info('Update_every %s is NOT recommended for use. Increase the value to > 30' % self.update_every) self.info('With current update_interval it will be + %s MB every 24hr. ' 'Don\'t forget to create logrotate conf file for %s' % (dump_size_24hr, self.named_stats_path)) self.info('Plugin was started successfully.') return True else: self.error('Not enough permissions to run "%s stats"' % self.rndc) return False