diff options
author | nicolargo <nicolashennion@gmail.com> | 2016-06-13 18:06:14 +0200 |
---|---|---|
committer | nicolargo <nicolashennion@gmail.com> | 2016-06-13 18:06:14 +0200 |
commit | a38b6b48cbb0bdb99cdc6fd0311dc873c234608c (patch) | |
tree | 64860194a5a9e95f5706cce3a6ab944b2023db34 | |
parent | 18100648525f0e14a6ea1efe686bb45166d33874 (diff) |
First release for the TCP ports scanner plugin. TODO: test and doc
-rw-r--r-- | conf/glances.conf | 23 | ||||
-rw-r--r-- | glances/main.py | 2 | ||||
-rw-r--r-- | glances/outputs/glances_curses.py | 10 | ||||
-rw-r--r-- | glances/ports_list.py | 92 | ||||
-rw-r--r-- | glances/static_list.py | 8 | ||||
-rw-r--r-- | glances/stats.py | 2 | ||||
-rw-r--r-- | glances/timer.py | 17 |
7 files changed, 147 insertions, 7 deletions
diff --git a/conf/glances.conf b/conf/glances.conf index 4fb8b8c4..a85f606f 100644 --- a/conf/glances.conf +++ b/conf/glances.conf @@ -179,6 +179,27 @@ mem_careful=50 mem_warning=70 mem_critical=90 +[ports] +# TCP Ports scanner plugin configuration +# Interval in second between scan +refresh=30 +# Set the timeout for a scan +timeout=3 +# Define the scan list +# host (name or IP) and port (TCP) are mandatory +# description is optinal (set to host:port) +port_1_host=www.google.com +port_1_port=443 +port_1_description=Internet +port_2_host=www.free.fr +port_2_port=80 +port_2_description=ISP +port_3_host=192.168.0.1 +port_3_port=80 +port_3_description=Home Box +port_4_host=192.168.5.1 +port_4_port=80 + ############################################################################## # Client/server ############################################################################## @@ -202,7 +223,7 @@ mem_critical=90 # Where: host is the hostname # password is the clear password # Additionally (and optionally) a default password could be defined -#xps=abc +#localhost=abc #default=defaultpassword ############################################################################## diff --git a/glances/main.py b/glances/main.py index 5a3f021e..8b3f2dec 100644 --- a/glances/main.py +++ b/glances/main.py @@ -114,6 +114,8 @@ Start the client browser (browser mode):\n\ dest='disable_load', help='disable load module') parser.add_argument('--disable-network', action='store_true', default=False, dest='disable_network', help='disable network module') + parser.add_argument('--disable-ports', action='store_true', default=False, + dest='disable_ports', help='disable ports scanner module') parser.add_argument('--disable-ip', action='store_true', default=False, dest='disable_ip', help='disable IP module') parser.add_argument('--disable-diskio', action='store_true', default=False, diff --git a/glances/outputs/glances_curses.py b/glances/outputs/glances_curses.py index b5ba6e14..e462cc4f 100644 --- a/glances/outputs/glances_curses.py +++ b/glances/outputs/glances_curses.py @@ -412,6 +412,9 @@ class _GlancesCurses(object): # 'p' > Sort processes by name glances_processes.auto_sort = False glances_processes.sort_key = 'name' + elif self.pressedkey == ord('P'): + # 'P' > Disable ports scan plugins + self.args.disable_ports = not self.args.disable_ports elif self.pressedkey == ord('r'): # 'r' > Reset history self.reset_history_tag = not self.reset_history_tag @@ -548,6 +551,8 @@ class _GlancesCurses(object): args=self.args) stats_sensors = stats.get_plugin( 'sensors').get_stats_display(args=self.args) + stats_ports = stats.get_plugin( + 'ports').get_stats_display(args=self.args) stats_now = stats.get_plugin('now').get_stats_display() stats_docker = stats.get_plugin('docker').get_stats_display( args=self.args) @@ -704,10 +709,11 @@ class _GlancesCurses(object): self.saved_line = self.next_line # ================================================================== - # Display left sidebar (NETWORK+DISKIO+FS+SENSORS+Current time) + # Display left sidebar (NETWORK+PORTS+DISKIO+FS+SENSORS+Current time) # ================================================================== self.init_column() if not (self.args.disable_network and + self.args.disable_ports and self.args.disable_diskio and self.args.disable_fs and self.args.disable_folder and @@ -716,6 +722,8 @@ class _GlancesCurses(object): self.new_line() self.display_plugin(stats_network) self.new_line() + self.display_plugin(stats_ports) + self.new_line() self.display_plugin(stats_diskio) self.new_line() self.display_plugin(stats_fs) diff --git a/glances/ports_list.py b/glances/ports_list.py new file mode 100644 index 00000000..172743c1 --- /dev/null +++ b/glances/ports_list.py @@ -0,0 +1,92 @@ +# -*- coding: utf-8 -*- +# +# This file is part of Glances. +# +# Copyright (C) 2016 Nicolargo <nicolas@nicolargo.com> +# +# Glances is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Glances is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +"""Manage the Glances ports list (Ports plugin).""" + +from glances.compat import range +from glances.logger import logger + + +class GlancesPortsList(object): + + """Manage the ports list for the ports plugin.""" + + _section = "ports" + _default_refresh = 60 + _default_timeout = 3 + + def __init__(self, config=None, args=None): + # ports_list is a list of dict (JSON compliant) + # [ {'host': 'www.google.fr', 'port': 443, 'refresh': 30, 'description': Internet, 'status': True} ... ] + # Load the configuration file + self._ports_list = self.load(config) + + def load(self, config): + """Load the ports list from the configuration file.""" + ports_list = [] + + if config is None: + logger.debug("No configuration file available. Cannot load ports list.") + elif not config.has_section(self._section): + logger.warning("No [%s] section in the configuration file. Cannot load ports list." % self._section) + else: + logger.debug("Start reading the [%s] section in the configuration file" % self._section) + refresh = config.get_value(self._section, 'refresh', default=self._default_refresh) + timeout = config.get_value(self._section, 'timeout', default=self._default_timeout) + for i in range(1, 256): + new_port = {} + postfix = 'port_%s_' % str(i) + + # Read mandatories configuration keys: host and port + for s in ['host', 'port']: + new_port[s] = config.get_value(self._section, '%s%s' % (postfix, s)) + + if new_port['host'] is None or new_port['port'] is None: + continue + + # Read optionals configuration keys + new_port['description'] = config.get_value(self._section, + '%sdescription' % postfix, + default="%s:%s" % (new_port['host'], new_port['port'])) + + # Default status + new_port['status'] = None + + # Refresh rate in second + new_port['refresh'] = refresh + + # Timeout in second + new_port['timeout'] = timeout + + # Add the server to the list + logger.debug("Add port %s:%s to the static list" % (new_port['host'], new_port['port'])) + ports_list.append(new_port) + + # Ports list loaded + logger.debug("Ports list loaded: %s" % ports_list) + + return ports_list + + def get_ports_list(self): + """Return the current server list (dict of dict).""" + return self._ports_list + + def set_server(self, pos, key, value): + """Set the key to the value for the pos (position in the list).""" + self._ports_list[pos][key] = value diff --git a/glances/static_list.py b/glances/static_list.py index 2fdcd60b..197623d9 100644 --- a/glances/static_list.py +++ b/glances/static_list.py @@ -2,7 +2,7 @@ # # This file is part of Glances. # -# Copyright (C) 2015 Nicolargo <nicolas@nicolargo.com> +# Copyright (C) 2016 Nicolargo <nicolas@nicolargo.com> # # Glances is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by @@ -32,7 +32,7 @@ class GlancesStaticServer(object): _section = "serverlist" def __init__(self, config=None, args=None): - # server_dict is a list of dict (JSON compliant) + # server_list is a list of dict (JSON compliant) # [ {'key': 'zeroconf name', ip': '172.1.2.3', 'port': 61209, 'cpu': 3, 'mem': 34 ...} ... ] # Load the configuration file self._server_list = self.load(config) @@ -42,7 +42,7 @@ class GlancesStaticServer(object): server_list = [] if config is None: - logger.warning("No configuration file available. Cannot load server list.") + logger.debug("No configuration file available. Cannot load server list.") elif not config.has_section(self._section): logger.warning("No [%s] section in the configuration file. Cannot load server list." % self._section) else: @@ -84,7 +84,7 @@ class GlancesStaticServer(object): return server_list def get_servers_list(self): - """Return the current server list (dict of dict).""" + """Return the current server list (list of dict).""" return self._server_list def set_server(self, server_pos, key, value): diff --git a/glances/stats.py b/glances/stats.py index d00b52d0..206c2788 100644 --- a/glances/stats.py +++ b/glances/stats.py @@ -97,7 +97,7 @@ class GlancesStats(object): # for example, the file glances_xxx.py # generate self._plugins_list["xxx"] = ... plugin_name = os.path.basename(item)[len(header):-3].lower() - if plugin_name in ('help', 'amps'): + if plugin_name in ('help', 'amps', 'ports'): self._plugins[plugin_name] = plugin.Plugin(args=args, config=self.config) else: self._plugins[plugin_name] = plugin.Plugin(args=args) diff --git a/glances/timer.py b/glances/timer.py index 896a053e..5ba4ede7 100644 --- a/glances/timer.py +++ b/glances/timer.py @@ -61,3 +61,20 @@ class Timer(object): def finished(self): return time() > self.target + + +class Counter(object): + + """The counter class.""" + + def __init__(self): + self.start() + + def start(self): + self.target = time() + + def reset(self): + self.start() + + def get(self): + return time() - self.target |