mirror of https://github.com/nicolargo/glances.git
Only work for the first refresh...
This commit is contained in:
parent
712cd67581
commit
296c3fd2a0
|
|
@ -175,6 +175,17 @@ tx_critical=90
|
|||
|
||||
[ip]
|
||||
disable=False
|
||||
public_refresh_interval=300
|
||||
public_ip_disabled=False
|
||||
# Configuration for the Censys online service
|
||||
# Need to create an aacount: https://censys.io/login
|
||||
censys_url=https://search.censys.io/api
|
||||
# Get your own credential here: https://search.censys.io/account/api
|
||||
# Enter and uncomment the following lines to use your credentials
|
||||
censys_username=13718bd6-b0c4-4c21-ae63-2d13da0b2dd8
|
||||
censys_password=hnjdSOukHM84tgx1Oo9Zzv4Pmz2E5bXH
|
||||
# List of fields to be displayed in user interface (comma separated)
|
||||
censys_fields=location:continent,location:country,autonomous_system:name
|
||||
|
||||
[connections]
|
||||
# Display additional information about TCP connections
|
||||
|
|
|
|||
|
|
@ -17,12 +17,29 @@ file under the ``[ip]`` section:
|
|||
|
||||
.. code-block:: ini
|
||||
[ip]
|
||||
public_refresh_interval=240
|
||||
public_refresh_interval=300
|
||||
public_ip_disabled=True
|
||||
|
||||
|
||||
**NOTE:** Setting low values for `public_refresh_interval` will result in frequent
|
||||
HTTP requests to the IP detection servers. Recommended range: 120-600 seconds
|
||||
|
||||
If the Censys options are configured, the public IP address is also analysed (with the same interval)
|
||||
and additional information is displayed.
|
||||
|
||||
.. code-block:: ini
|
||||
[ip]
|
||||
public_refresh_interval=300
|
||||
public_ip_disabled=True
|
||||
censys_url=https://search.censys.io/api
|
||||
# Get your own credential here: https://search.censys.io/account/api
|
||||
censys_username=CENSYS_API_ID
|
||||
censys_password=CENSYS_API_SECRET
|
||||
# List of fields to be displayed in user interface (comma separated)
|
||||
censys_fields=location:continent,location:country,autonomous_system:name
|
||||
|
||||
**Note:** Access to the Censys Search API need an account (https://censys.io/login).
|
||||
|
||||
**Connected**:
|
||||
|
||||
.. image:: ../_static/connected.png
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ if PY3:
|
|||
from statistics import mean
|
||||
from xmlrpc.client import Fault, ProtocolError, ServerProxy, Transport, Server
|
||||
from xmlrpc.server import SimpleXMLRPCRequestHandler, SimpleXMLRPCServer
|
||||
from urllib.request import urlopen
|
||||
from urllib.request import Request, urlopen, base64
|
||||
from urllib.error import HTTPError, URLError
|
||||
from urllib.parse import urlparse
|
||||
|
||||
|
|
@ -126,7 +126,7 @@ else:
|
|||
from ConfigParser import SafeConfigParser as ConfigParser, NoOptionError, NoSectionError
|
||||
from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler, SimpleXMLRPCServer
|
||||
from xmlrpclib import Fault, ProtocolError, ServerProxy, Transport, Server
|
||||
from urllib2 import urlopen, HTTPError, URLError
|
||||
from urllib2 import Request, urlopen, HTTPError, URLError, base64
|
||||
from urlparse import urlparse
|
||||
|
||||
# Correct issue #1025 by monkey path the xmlrpc lib
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
"""IP plugin."""
|
||||
|
||||
import threading
|
||||
import urllib
|
||||
from json import loads
|
||||
|
||||
from glances.compat import iterkeys, urlopen, queue
|
||||
|
|
@ -65,6 +66,13 @@ class Plugin(GlancesPlugin):
|
|||
public_ip_disabled = self.get_conf_value("public_ip_disabled", default=self._default_public_ip_disabled)
|
||||
self.public_ip_disabled = True if public_ip_disabled == ["True"] else False
|
||||
|
||||
# For the Censys options (see issue #2105)
|
||||
self.public_info = ""
|
||||
self.censys_url = self.get_conf_value("censys_url", default=[None])[0]
|
||||
self.censys_username = self.get_conf_value("censys_username", default=[None])[0]
|
||||
self.censys_password = self.get_conf_value("censys_password", default=[None])[0]
|
||||
self.censys_fields = self.get_conf_value("censys_fields", default=[None])
|
||||
|
||||
@GlancesPlugin._check_decorator
|
||||
@GlancesPlugin._log_result_decorator
|
||||
def update(self):
|
||||
|
|
@ -77,30 +85,53 @@ class Plugin(GlancesPlugin):
|
|||
|
||||
if self.input_method == 'local' and not import_error_tag:
|
||||
# Update stats using the netifaces lib
|
||||
# Start with the default IP gateway
|
||||
try:
|
||||
default_gw = netifaces.gateways()['default'][netifaces.AF_INET]
|
||||
except (KeyError, AttributeError) as e:
|
||||
logger.debug("Cannot grab the default gateway ({})".format(e))
|
||||
logger.debug("Cannot grab default gateway IP address ({})".format(e))
|
||||
return {}
|
||||
else:
|
||||
stats['gateway'] = default_gw[0]
|
||||
|
||||
# Then the private IP address
|
||||
try:
|
||||
address = netifaces.ifaddresses(default_gw[1])[netifaces.AF_INET][0]['addr']
|
||||
mask = netifaces.ifaddresses(default_gw[1])[netifaces.AF_INET][0]['netmask']
|
||||
|
||||
time_since_update = getTimeSinceLastUpdate('public-ip')
|
||||
if not self.public_ip_disabled and (
|
||||
self.stats.get('address') != address or time_since_update > self.public_address_refresh_interval
|
||||
):
|
||||
self.public_address = PublicIpAddress().get()
|
||||
except (KeyError, AttributeError) as e:
|
||||
logger.debug("Cannot grab IP information: {}".format(e))
|
||||
logger.debug("Cannot grab private IP address ({})".format(e))
|
||||
return {}
|
||||
else:
|
||||
stats['address'] = address
|
||||
stats['mask'] = mask
|
||||
stats['mask_cidr'] = self.ip_to_cidr(stats['mask'])
|
||||
stats['gateway'] = default_gw[0]
|
||||
|
||||
# Continue with the public IP address
|
||||
time_since_update = getTimeSinceLastUpdate('public-ip')
|
||||
try:
|
||||
if not self.public_ip_disabled and (
|
||||
self.stats.get('address') != address
|
||||
or time_since_update > self.public_address_refresh_interval
|
||||
):
|
||||
self.public_address = PublicIpAddress().get()
|
||||
except (KeyError, AttributeError) as e:
|
||||
logger.debug("Cannot grab public IP address ({})".format(e))
|
||||
else:
|
||||
stats['public_address'] = self.public_address
|
||||
|
||||
# Finally the Censys information
|
||||
if (
|
||||
self.public_address
|
||||
and not self.public_ip_disabled
|
||||
and (self.stats.get('address') != address
|
||||
or time_since_update > self.public_address_refresh_interval)
|
||||
):
|
||||
self.public_info = PublicIpInfo(self.public_address,
|
||||
self.censys_url,
|
||||
self.censys_username,
|
||||
self.censys_password).get()
|
||||
stats['public_info'] = self.public_info
|
||||
|
||||
elif self.input_method == 'snmp':
|
||||
# Not implemented yet
|
||||
pass
|
||||
|
|
@ -151,6 +182,14 @@ class Plugin(GlancesPlugin):
|
|||
msg = ' Pub '
|
||||
ret.append(self.curse_add_line(msg, 'TITLE'))
|
||||
ret.append(self.curse_add_line(msg_pub))
|
||||
if 'public_info' in self.stats:
|
||||
for f in self.censys_fields:
|
||||
field = f.split(':')
|
||||
if len(field) == 1 and field[0] in self.stats['public_info']:
|
||||
msg = '{}'.format(self.stats['public_info'][field[0]])
|
||||
elif len(field) == 2 and field[0] in self.stats['public_info'] and field[1] in self.stats['public_info'][field[0]]:
|
||||
msg = '{}'.format(self.stats['public_info'][field[0]][field[1]])
|
||||
ret.append(self.curse_add_line(msg))
|
||||
|
||||
return ret
|
||||
|
||||
|
|
@ -211,3 +250,59 @@ class PublicIpAddress(object):
|
|||
queue_target.put(loads(response)[key])
|
||||
except ValueError:
|
||||
queue_target.put(None)
|
||||
|
||||
|
||||
class PublicIpInfo(object):
|
||||
"""Get public IP information from Censys online service."""
|
||||
|
||||
def __init__(self, ip, url, username, password, timeout=2):
|
||||
"""Init the class."""
|
||||
self.ip = ip
|
||||
self.url = url
|
||||
self.username = username
|
||||
self.password = password
|
||||
self.timeout = timeout
|
||||
|
||||
def get(self):
|
||||
"""Return the public IP information returned by one of the online service."""
|
||||
q = queue.Queue()
|
||||
|
||||
t = threading.Thread(target=self._get_ip_public_info, args=(q,
|
||||
self.ip,
|
||||
self.url,
|
||||
self.username,
|
||||
self.password))
|
||||
t.daemon = True
|
||||
t.start()
|
||||
|
||||
timer = Timer(self.timeout)
|
||||
info = None
|
||||
while not timer.finished() and info is None:
|
||||
if q.qsize() > 0:
|
||||
info = q.get()
|
||||
|
||||
if info is None:
|
||||
return None
|
||||
|
||||
return info
|
||||
|
||||
def _get_ip_public_info(self, queue_target, ip, url, username, password):
|
||||
"""Request the url service and put the result in the queue_target."""
|
||||
request_url = "{}/v2/hosts/{}".format(url, ip)
|
||||
try:
|
||||
# Python 3 code only
|
||||
# https://stackoverflow.com/questions/24635064/how-to-use-urllib-with-username-password-authentication-in-python-3/24648149#24648149
|
||||
request = urllib.request.Request(request_url)
|
||||
base64string = urllib.request.base64.b64encode(bytes('%s:%s' % (username, password), 'ascii'))
|
||||
request.add_header("Authorization", "Basic %s" % base64string.decode('utf-8'))
|
||||
result = urllib.request.urlopen(request)
|
||||
response = result.read()
|
||||
except Exception as e:
|
||||
logger.debug("IP plugin - Cannot open URL {} ({})".format(request_url, e))
|
||||
queue_target.put(None)
|
||||
else:
|
||||
try:
|
||||
queue_target.put(loads(response)['result'])
|
||||
except (ValueError, KeyError) as e:
|
||||
logger.debug("IP plugin - Cannot get result field from {} ({})".format(request_url, e))
|
||||
queue_target.put(None)
|
||||
|
|
|
|||
Loading…
Reference in New Issue