summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornicolargo <nicolashennion@gmail.com>2016-06-13 18:06:14 +0200
committernicolargo <nicolashennion@gmail.com>2016-06-13 18:06:14 +0200
commita38b6b48cbb0bdb99cdc6fd0311dc873c234608c (patch)
tree64860194a5a9e95f5706cce3a6ab944b2023db34
parent18100648525f0e14a6ea1efe686bb45166d33874 (diff)
First release for the TCP ports scanner plugin. TODO: test and doc
-rw-r--r--conf/glances.conf23
-rw-r--r--glances/main.py2
-rw-r--r--glances/outputs/glances_curses.py10
-rw-r--r--glances/ports_list.py92
-rw-r--r--glances/static_list.py8
-rw-r--r--glances/stats.py2
-rw-r--r--glances/timer.py17
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