summaryrefslogtreecommitdiffstats
path: root/collectors/python.d.plugin/python_modules
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2018-11-07 12:19:29 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2018-11-07 12:20:17 +0000
commita64a253794ac64cb40befee54db53bde17dd0d49 (patch)
treec1024acc5f6e508814b944d99f112259bb28b1be /collectors/python.d.plugin/python_modules
parentNew upstream version 1.10.0+dfsg (diff)
downloadnetdata-upstream/1.11.0+dfsg.tar.xz
netdata-upstream/1.11.0+dfsg.zip
New upstream version 1.11.0+dfsgupstream/1.11.0+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--collectors/python.d.plugin/python_modules/__init__.py (renamed from python.d/python_modules/third_party/__init__.py)0
-rw-r--r--collectors/python.d.plugin/python_modules/bases/FrameworkServices/ExecutableService.py (renamed from python.d/python_modules/bases/FrameworkServices/ExecutableService.py)9
-rw-r--r--collectors/python.d.plugin/python_modules/bases/FrameworkServices/LogService.py (renamed from python.d/python_modules/bases/FrameworkServices/LogService.py)2
-rw-r--r--collectors/python.d.plugin/python_modules/bases/FrameworkServices/MySQLService.py (renamed from python.d/python_modules/bases/FrameworkServices/MySQLService.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/bases/FrameworkServices/SimpleService.py (renamed from python.d/python_modules/bases/FrameworkServices/SimpleService.py)13
-rw-r--r--collectors/python.d.plugin/python_modules/bases/FrameworkServices/SocketService.py (renamed from python.d/python_modules/bases/FrameworkServices/SocketService.py)64
-rw-r--r--collectors/python.d.plugin/python_modules/bases/FrameworkServices/UrlService.py (renamed from python.d/python_modules/bases/FrameworkServices/UrlService.py)32
-rw-r--r--collectors/python.d.plugin/python_modules/bases/FrameworkServices/__init__.py (renamed from python.d/python_modules/urllib3/contrib/__init__.py)0
-rw-r--r--collectors/python.d.plugin/python_modules/bases/__init__.py (renamed from python.d/python_modules/urllib3/contrib/_securetransport/__init__.py)0
-rw-r--r--collectors/python.d.plugin/python_modules/bases/charts.py (renamed from python.d/python_modules/bases/charts.py)18
-rw-r--r--collectors/python.d.plugin/python_modules/bases/collection.py (renamed from python.d/python_modules/bases/collection.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/bases/loaders.py (renamed from python.d/python_modules/bases/loaders.py)21
-rw-r--r--collectors/python.d.plugin/python_modules/bases/loggers.py (renamed from python.d/python_modules/bases/loggers.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/pyyaml2/__init__.py (renamed from python.d/python_modules/pyyaml2/__init__.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/pyyaml2/composer.py (renamed from python.d/python_modules/pyyaml2/composer.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/pyyaml2/constructor.py (renamed from python.d/python_modules/pyyaml2/constructor.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/pyyaml2/cyaml.py (renamed from python.d/python_modules/pyyaml2/cyaml.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/pyyaml2/dumper.py (renamed from python.d/python_modules/pyyaml2/dumper.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/pyyaml2/emitter.py (renamed from python.d/python_modules/pyyaml2/emitter.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/pyyaml2/error.py (renamed from python.d/python_modules/pyyaml2/error.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/pyyaml2/events.py (renamed from python.d/python_modules/pyyaml2/events.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/pyyaml2/loader.py (renamed from python.d/python_modules/pyyaml2/loader.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/pyyaml2/nodes.py (renamed from python.d/python_modules/pyyaml2/nodes.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/pyyaml2/parser.py (renamed from python.d/python_modules/pyyaml2/parser.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/pyyaml2/reader.py (renamed from python.d/python_modules/pyyaml2/reader.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/pyyaml2/representer.py (renamed from python.d/python_modules/pyyaml2/representer.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/pyyaml2/resolver.py (renamed from python.d/python_modules/pyyaml2/resolver.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/pyyaml2/scanner.py (renamed from python.d/python_modules/pyyaml2/scanner.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/pyyaml2/serializer.py (renamed from python.d/python_modules/pyyaml2/serializer.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/pyyaml2/tokens.py (renamed from python.d/python_modules/pyyaml2/tokens.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/pyyaml3/__init__.py (renamed from python.d/python_modules/pyyaml3/__init__.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/pyyaml3/composer.py (renamed from python.d/python_modules/pyyaml3/composer.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/pyyaml3/constructor.py (renamed from python.d/python_modules/pyyaml3/constructor.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/pyyaml3/cyaml.py (renamed from python.d/python_modules/pyyaml3/cyaml.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/pyyaml3/dumper.py (renamed from python.d/python_modules/pyyaml3/dumper.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/pyyaml3/emitter.py (renamed from python.d/python_modules/pyyaml3/emitter.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/pyyaml3/error.py (renamed from python.d/python_modules/pyyaml3/error.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/pyyaml3/events.py (renamed from python.d/python_modules/pyyaml3/events.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/pyyaml3/loader.py (renamed from python.d/python_modules/pyyaml3/loader.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/pyyaml3/nodes.py (renamed from python.d/python_modules/pyyaml3/nodes.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/pyyaml3/parser.py (renamed from python.d/python_modules/pyyaml3/parser.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/pyyaml3/reader.py (renamed from python.d/python_modules/pyyaml3/reader.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/pyyaml3/representer.py (renamed from python.d/python_modules/pyyaml3/representer.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/pyyaml3/resolver.py (renamed from python.d/python_modules/pyyaml3/resolver.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/pyyaml3/scanner.py (renamed from python.d/python_modules/pyyaml3/scanner.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/pyyaml3/serializer.py (renamed from python.d/python_modules/pyyaml3/serializer.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/pyyaml3/tokens.py (renamed from python.d/python_modules/pyyaml3/tokens.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/third_party/__init__.py (renamed from python.d/python_modules/urllib3/packages/backports/__init__.py)0
-rw-r--r--collectors/python.d.plugin/python_modules/third_party/boinc_client.py515
-rw-r--r--collectors/python.d.plugin/python_modules/third_party/lm_sensors.py (renamed from python.d/python_modules/third_party/lm_sensors.py)3
-rw-r--r--collectors/python.d.plugin/python_modules/third_party/mcrcon.py74
-rw-r--r--collectors/python.d.plugin/python_modules/third_party/monotonic.py171
-rw-r--r--collectors/python.d.plugin/python_modules/third_party/ordereddict.py (renamed from python.d/python_modules/third_party/ordereddict.py)20
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/__init__.py (renamed from python.d/python_modules/urllib3/__init__.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/_collections.py (renamed from python.d/python_modules/urllib3/_collections.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/connection.py (renamed from python.d/python_modules/urllib3/connection.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/connectionpool.py (renamed from python.d/python_modules/urllib3/connectionpool.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/contrib/__init__.py (renamed from src/.keep)0
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/contrib/_securetransport/__init__.py0
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/contrib/_securetransport/bindings.py (renamed from python.d/python_modules/urllib3/contrib/_securetransport/bindings.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/contrib/_securetransport/low_level.py (renamed from python.d/python_modules/urllib3/contrib/_securetransport/low_level.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/contrib/appengine.py (renamed from python.d/python_modules/urllib3/contrib/appengine.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/contrib/ntlmpool.py (renamed from python.d/python_modules/urllib3/contrib/ntlmpool.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/contrib/pyopenssl.py (renamed from python.d/python_modules/urllib3/contrib/pyopenssl.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/contrib/securetransport.py (renamed from python.d/python_modules/urllib3/contrib/securetransport.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/contrib/socks.py (renamed from python.d/python_modules/urllib3/contrib/socks.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/exceptions.py (renamed from python.d/python_modules/urllib3/exceptions.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/fields.py (renamed from python.d/python_modules/urllib3/fields.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/filepost.py (renamed from python.d/python_modules/urllib3/filepost.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/packages/__init__.py (renamed from python.d/python_modules/urllib3/packages/__init__.py)0
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/packages/backports/__init__.py0
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/packages/backports/makefile.py (renamed from python.d/python_modules/urllib3/packages/backports/makefile.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/packages/ordered_dict.py (renamed from python.d/python_modules/urllib3/packages/ordered_dict.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/packages/six.py (renamed from python.d/python_modules/urllib3/packages/six.py)18
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/packages/ssl_match_hostname/__init__.py (renamed from python.d/python_modules/urllib3/packages/ssl_match_hostname/__init__.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/packages/ssl_match_hostname/_implementation.py (renamed from python.d/python_modules/urllib3/packages/ssl_match_hostname/_implementation.py)3
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/poolmanager.py (renamed from python.d/python_modules/urllib3/poolmanager.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/request.py (renamed from python.d/python_modules/urllib3/request.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/response.py (renamed from python.d/python_modules/urllib3/response.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/util/__init__.py (renamed from python.d/python_modules/urllib3/util/__init__.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/util/connection.py (renamed from python.d/python_modules/urllib3/util/connection.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/util/request.py (renamed from python.d/python_modules/urllib3/util/request.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/util/response.py (renamed from python.d/python_modules/urllib3/util/response.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/util/retry.py (renamed from python.d/python_modules/urllib3/util/retry.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/util/selectors.py (renamed from python.d/python_modules/urllib3/util/selectors.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/util/ssl_.py (renamed from python.d/python_modules/urllib3/util/ssl_.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/util/timeout.py (renamed from python.d/python_modules/urllib3/util/timeout.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/util/url.py (renamed from python.d/python_modules/urllib3/util/url.py)1
-rw-r--r--collectors/python.d.plugin/python_modules/urllib3/util/wait.py (renamed from python.d/python_modules/urllib3/util/wait.py)1
89 files changed, 961 insertions, 69 deletions
diff --git a/python.d/python_modules/third_party/__init__.py b/collectors/python.d.plugin/python_modules/__init__.py
index e69de29bb..e69de29bb 100644
--- a/python.d/python_modules/third_party/__init__.py
+++ b/collectors/python.d.plugin/python_modules/__init__.py
diff --git a/python.d/python_modules/bases/FrameworkServices/ExecutableService.py b/collectors/python.d.plugin/python_modules/bases/FrameworkServices/ExecutableService.py
index a71f2bfd2..72f9ff714 100644
--- a/python.d/python_modules/bases/FrameworkServices/ExecutableService.py
+++ b/collectors/python.d.plugin/python_modules/bases/FrameworkServices/ExecutableService.py
@@ -2,6 +2,7 @@
# Description:
# Author: Pawel Krupa (paulfantom)
# Author: Ilya Mashchenko (l2isbad)
+# SPDX-License-Identifier: GPL-3.0-or-later
import os
@@ -16,15 +17,15 @@ class ExecutableService(SimpleService):
SimpleService.__init__(self, configuration=configuration, name=name)
self.command = None
- def _get_raw_data(self, stderr=False):
+ def _get_raw_data(self, stderr=False, command=None):
"""
Get raw data from executed command
:return: <list>
"""
try:
- p = Popen(self.command, stdout=PIPE, stderr=PIPE)
+ p = Popen(command if command else self.command, stdout=PIPE, stderr=PIPE)
except Exception as error:
- self.error('Executing command {command} resulted in error: {error}'.format(command=self.command,
+ self.error('Executing command {command} resulted in error: {error}'.format(command=command or self.command,
error=error))
return None
data = list()
@@ -35,7 +36,7 @@ class ExecutableService(SimpleService):
except TypeError:
continue
- return data or None
+ return data
def check(self):
"""
diff --git a/python.d/python_modules/bases/FrameworkServices/LogService.py b/collectors/python.d.plugin/python_modules/bases/FrameworkServices/LogService.py
index 45daa2446..5acfd73f8 100644
--- a/python.d/python_modules/bases/FrameworkServices/LogService.py
+++ b/collectors/python.d.plugin/python_modules/bases/FrameworkServices/LogService.py
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
# Description:
# Author: Pawel Krupa (paulfantom)
+# Author: Ilya Mashchenko (l2isbad)
+# SPDX-License-Identifier: GPL-3.0-or-later
from glob import glob
import os
diff --git a/python.d/python_modules/bases/FrameworkServices/MySQLService.py b/collectors/python.d.plugin/python_modules/bases/FrameworkServices/MySQLService.py
index 3acc5b109..53807e2c4 100644
--- a/python.d/python_modules/bases/FrameworkServices/MySQLService.py
+++ b/collectors/python.d.plugin/python_modules/bases/FrameworkServices/MySQLService.py
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
# Description:
# Author: Ilya Mashchenko (l2isbad)
+# SPDX-License-Identifier: GPL-3.0-or-later
from sys import exc_info
diff --git a/python.d/python_modules/bases/FrameworkServices/SimpleService.py b/collectors/python.d.plugin/python_modules/bases/FrameworkServices/SimpleService.py
index 177332c1f..dd53fbc14 100644
--- a/python.d/python_modules/bases/FrameworkServices/SimpleService.py
+++ b/collectors/python.d.plugin/python_modules/bases/FrameworkServices/SimpleService.py
@@ -2,13 +2,12 @@
# Description:
# Author: Pawel Krupa (paulfantom)
# Author: Ilya Mashchenko (l2isbad)
+# SPDX-License-Identifier: GPL-3.0-or-later
from threading import Thread
+from time import sleep
-try:
- from time import sleep, monotonic as time
-except ImportError:
- from time import sleep, time
+from third_party.monotonic import monotonic
from bases.charts import Charts, ChartError, create_runtime_chart
from bases.collection import OldVersionCompatibility, safe_print
@@ -168,7 +167,7 @@ class SimpleService(Thread, PythonDLimitedLogger, OldVersionCompatibility, objec
'retries: {retries}'.format(freq=job.FREQ, retries=job.RETRIES_MAX - job.RETRIES))
while True:
- job.START_RUN = time()
+ job.START_RUN = monotonic()
job.NEXT_RUN = job.START_RUN - (job.START_RUN % job.FREQ) + job.FREQ + job.PENALTY
@@ -189,7 +188,7 @@ class SimpleService(Thread, PythonDLimitedLogger, OldVersionCompatibility, objec
if not self.manage_retries():
return
else:
- job.ELAPSED = int((time() - job.START_RUN) * 1e3)
+ job.ELAPSED = int((monotonic() - job.START_RUN) * 1e3)
job.PREV_UPDATE = job.START_RUN
job.RETRIES, job.PENALTY = 0, 0
safe_print(RUNTIME_CHART_UPDATE.format(job_name=self.name,
@@ -253,7 +252,7 @@ class SimpleService(Thread, PythonDLimitedLogger, OldVersionCompatibility, objec
self.debug('sleeping for {sleep_time} to reach frequency of {freq} sec'.format(sleep_time=sleep_time,
freq=job.FREQ + job.PENALTY))
sleep(sleep_time)
- job.START_RUN = time()
+ job.START_RUN = monotonic()
def get_data(self):
return self._get_data()
diff --git a/python.d/python_modules/bases/FrameworkServices/SocketService.py b/collectors/python.d.plugin/python_modules/bases/FrameworkServices/SocketService.py
index 8d27ae660..e85455307 100644
--- a/python.d/python_modules/bases/FrameworkServices/SocketService.py
+++ b/collectors/python.d.plugin/python_modules/bases/FrameworkServices/SocketService.py
@@ -1,9 +1,18 @@
# -*- coding: utf-8 -*-
# Description:
# Author: Pawel Krupa (paulfantom)
+# Author: Ilya Mashchenko (l2isbad)
+# SPDX-License-Identifier: GPL-3.0-or-later
import socket
+try:
+ import ssl
+except ImportError:
+ _TLS_SUPPORT = False
+else:
+ _TLS_SUPPORT = True
+
from bases.FrameworkServices.SimpleService import SimpleService
@@ -16,6 +25,9 @@ class SocketService(SimpleService):
self.unix_socket = None
self.dgram_socket = False
self.request = ''
+ self.tls = False
+ self.cert = None
+ self.key = None
self.__socket_config = None
self.__empty_request = "".encode()
SimpleService.__init__(self, configuration=configuration, name=name)
@@ -26,7 +38,7 @@ class SocketService(SimpleService):
message=message))
else:
if self.__socket_config is not None:
- af, sock_type, proto, canon_name, sa = self.__socket_config
+ _, _, _, _, sa = self.__socket_config
self.error('socket to "{address}" port {port}: {message}'.format(address=sa[0],
port=sa[1],
message=message))
@@ -44,7 +56,7 @@ class SocketService(SimpleService):
self.error("Cannot create socket to 'None':")
return False
- af, sock_type, proto, canon_name, sa = res
+ af, sock_type, proto, _, sa = res
try:
self.debug('Creating socket to "{address}", port {port}'.format(address=sa[0], port=sa[1]))
self._sock = socket.socket(af, sock_type, proto)
@@ -56,10 +68,24 @@ class SocketService(SimpleService):
self.__socket_config = None
return False
+ if self.tls:
+ try:
+ self.debug('Encapsulating socket with TLS')
+ self._sock = ssl.wrap_socket(self._sock,
+ keyfile=self.key,
+ certfile=self.cert,
+ server_side=False,
+ cert_reqs=ssl.CERT_NONE)
+ except (socket.error, ssl.SSLError) as error:
+ self.error('Failed to wrap socket.')
+ self._disconnect()
+ self.__socket_config = None
+ return False
+
try:
self.debug('connecting socket to "{address}", port {port}'.format(address=sa[0], port=sa[1]))
self._sock.connect(sa)
- except socket.error as error:
+ except (socket.error, ssl.SSLError) as error:
self.error('Failed to connect to "{address}", port {port}, error: {error}'.format(address=sa[0],
port=sa[1],
error=error))
@@ -147,7 +173,7 @@ class SocketService(SimpleService):
pass
self._sock = None
- def _send(self):
+ def _send(self, request=None):
"""
Send request.
:return: boolean
@@ -155,8 +181,8 @@ class SocketService(SimpleService):
# Send request if it is needed
if self.request != self.__empty_request:
try:
- self.debug('sending request: {0}'.format(self.request))
- self._sock.send(self.request)
+ self.debug('sending request: {0}'.format(request or self.request))
+ self._sock.send(request or self.request)
except Exception as error:
self._socket_error('error sending request: {0}'.format(error))
self._disconnect()
@@ -197,7 +223,7 @@ class SocketService(SimpleService):
self.debug('final response: {0}'.format(data))
return data
- def _get_raw_data(self, raw=False):
+ def _get_raw_data(self, raw=False, request=None):
"""
Get raw data with low-level "socket" module.
:param raw: set `True` to return bytes
@@ -211,7 +237,7 @@ class SocketService(SimpleService):
return None
# Send request if it is needed
- if not self._send():
+ if not self._send(request):
return None
data = self._receive(raw)
@@ -249,6 +275,28 @@ class SocketService(SimpleService):
except (KeyError, TypeError):
self.debug('No port specified. Using: "{0}"'.format(self.port))
+ self.tls = bool(self.configuration.get('tls', self.tls))
+ if self.tls and not _TLS_SUPPORT:
+ self.warning('TLS requested but no TLS module found, disabling TLS support.')
+ self.tls = False
+ if _TLS_SUPPORT and not self.tls:
+ self.debug('No TLS preference specified, not using TLS.')
+
+ if self.tls and _TLS_SUPPORT:
+ self.key = self.configuration.get('tls_key_file')
+ self.cert = self.configuration.get('tls_cert_file')
+ if not self.cert:
+ # If there's not a valid certificate, clear the key too.
+ self.debug('No valid TLS client certificate configuration found.')
+ self.key = None
+ self.cert = None
+ elif not self.key:
+ # If a key isn't listed, the config may still be
+ # valid, because there may be a key attached to the
+ # certificate.
+ self.info('No TLS client key specified, assuming it\'s attached to the certificate.')
+ self.key = None
+
try:
self.request = str(self.configuration['request'])
except (KeyError, TypeError):
diff --git a/python.d/python_modules/bases/FrameworkServices/UrlService.py b/collectors/python.d.plugin/python_modules/bases/FrameworkServices/UrlService.py
index bb340ba3b..856f38851 100644
--- a/python.d/python_modules/bases/FrameworkServices/UrlService.py
+++ b/collectors/python.d.plugin/python_modules/bases/FrameworkServices/UrlService.py
@@ -2,6 +2,7 @@
# Description:
# Author: Pawel Krupa (paulfantom)
# Author: Ilya Mashchenko (l2isbad)
+# SPDX-License-Identifier: GPL-3.0-or-later
import urllib3
@@ -22,8 +23,13 @@ class UrlService(SimpleService):
self.proxy_user = self.configuration.get('proxy_user')
self.proxy_password = self.configuration.get('proxy_pass')
self.proxy_url = self.configuration.get('proxy_url')
+ self.method = self.configuration.get('method', 'GET')
self.header = self.configuration.get('header')
self.request_timeout = self.configuration.get('timeout', 1)
+ self.tls_verify = self.configuration.get('tls_verify')
+ self.tls_ca_file = self.configuration.get('tls_ca_file')
+ self.tls_key_file = self.configuration.get('tls_key_file')
+ self.tls_cert_file = self.configuration.get('tls_cert_file')
self._manager = None
def __make_headers(self, **header_kw):
@@ -60,9 +66,21 @@ class UrlService(SimpleService):
else:
manager = urllib3.PoolManager
params = dict(headers=header)
+ tls_cert_file = self.tls_cert_file
+ if tls_cert_file:
+ params['cert_file'] = tls_cert_file
+ # NOTE: key_file is useless without cert_file, but
+ # cert_file may include the key as well.
+ tls_key_file = self.tls_key_file
+ if tls_key_file:
+ params['key_file'] = tls_key_file
+ tls_ca_file = self.tls_ca_file
+ if tls_ca_file:
+ params['ca_certs'] = tls_ca_file
try:
url = header_kw.get('url') or self.url
- if url.startswith('https'):
+ if url.startswith('https') and not self.tls_verify and not tls_ca_file:
+ params['ca_certs'] = None
return manager(assert_hostname=False, cert_reqs='CERT_NONE', **params)
return manager(**params)
except (urllib3.exceptions.ProxySchemeUnknown, TypeError) as error:
@@ -77,13 +95,13 @@ class UrlService(SimpleService):
try:
status, data = self._get_raw_data_with_status(url, manager)
except (urllib3.exceptions.HTTPError, TypeError, AttributeError) as error:
- self.error('Url: {url}. Error: {error}'.format(url=url, error=error))
+ self.error('Url: {url}. Error: {error}'.format(url=url or self.url, error=error))
return None
if status == 200:
- return data.decode()
+ return data
else:
- self.debug('Url: {url}. Http response status code: {code}'.format(url=url, code=status))
+ self.debug('Url: {url}. Http response status code: {code}'.format(url=url or self.url, code=status))
return None
def _get_raw_data_with_status(self, url=None, manager=None, retries=1, redirect=True):
@@ -93,13 +111,15 @@ class UrlService(SimpleService):
"""
url = url or self.url
manager = manager or self._manager
- response = manager.request(method='GET',
+ response = manager.request(method=self.method,
url=url,
timeout=self.request_timeout,
retries=retries,
headers=manager.headers,
redirect=redirect)
- return response.status, response.data
+ if isinstance(response.data, str):
+ return response.status, response.data
+ return response.status, response.data.decode()
def check(self):
"""
diff --git a/python.d/python_modules/urllib3/contrib/__init__.py b/collectors/python.d.plugin/python_modules/bases/FrameworkServices/__init__.py
index e69de29bb..e69de29bb 100644
--- a/python.d/python_modules/urllib3/contrib/__init__.py
+++ b/collectors/python.d.plugin/python_modules/bases/FrameworkServices/__init__.py
diff --git a/python.d/python_modules/urllib3/contrib/_securetransport/__init__.py b/collectors/python.d.plugin/python_modules/bases/__init__.py
index e69de29bb..e69de29bb 100644
--- a/python.d/python_modules/urllib3/contrib/_securetransport/__init__.py
+++ b/collectors/python.d.plugin/python_modules/bases/__init__.py
diff --git a/python.d/python_modules/bases/charts.py b/collectors/python.d.plugin/python_modules/bases/charts.py
index 5394fbf64..2963739ec 100644
--- a/python.d/python_modules/bases/charts.py
+++ b/collectors/python.d.plugin/python_modules/bases/charts.py
@@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
# Description:
# Author: Ilya Mashchenko (l2isbad)
+# SPDX-License-Identifier: GPL-3.0-or-later
from bases.collection import safe_print
-CHART_PARAMS = ['type', 'id', 'name', 'title', 'units', 'family', 'context', 'chart_type']
+CHART_PARAMS = ['type', 'id', 'name', 'title', 'units', 'family', 'context', 'chart_type', 'hidden']
DIMENSION_PARAMS = ['id', 'name', 'algorithm', 'multiplier', 'divisor', 'hidden']
VARIABLE_PARAMS = ['id', 'value']
@@ -13,9 +14,9 @@ DIMENSION_ALGORITHMS = ['absolute', 'incremental', 'percentage-of-absolute-row',
CHART_BEGIN = 'BEGIN {type}.{id} {since_last}\n'
CHART_CREATE = "CHART {type}.{id} '{name}' '{title}' '{units}' '{family}' '{context}' " \
- "{chart_type} {priority} {update_every} '' 'python.d.plugin' '{module_name}'\n"
+ "{chart_type} {priority} {update_every} '{hidden}' 'python.d.plugin' '{module_name}'\n"
CHART_OBSOLETE = "CHART {type}.{id} '{name}' '{title}' '{units}' '{family}' '{context}' " \
- "{chart_type} {priority} {update_every} 'obsolete'\n"
+ "{chart_type} {priority} {update_every} '{hidden} obsolete'\n"
DIMENSION_CREATE = "DIMENSION '{id}' '{name}' {algorithm} {multiplier} {divisor} '{hidden}'\n"
@@ -151,6 +152,8 @@ class Chart:
id=self.params['id'])
if self.params.get('chart_type') not in CHART_TYPES:
self.params['chart_type'] = 'absolute'
+ hidden = str(self.params.get('hidden', ''))
+ self.params['hidden'] = 'hidden' if hidden == 'hidden' else ''
self.dimensions = list()
self.variables = set()
@@ -304,6 +307,12 @@ class Dimension:
return self.id == other
return self.id == other.id
+ def __ne__(self, other):
+ return not self == other
+
+ def __hash__(self):
+ return hash(repr(self))
+
def create(self):
return DIMENSION_CREATE.format(**self.params)
@@ -360,6 +369,9 @@ class ChartVariable:
return self.id == other.id
return False
+ def __ne__(self, other):
+ return not self == other
+
def __hash__(self):
return hash(repr(self))
diff --git a/python.d/python_modules/bases/collection.py b/collectors/python.d.plugin/python_modules/bases/collection.py
index e03b4f58e..479a3b610 100644
--- a/python.d/python_modules/bases/collection.py
+++ b/collectors/python.d.plugin/python_modules/bases/collection.py
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
# Description:
# Author: Ilya Mashchenko (l2isbad)
+# SPDX-License-Identifier: GPL-3.0-or-later
import os
diff --git a/python.d/python_modules/bases/loaders.py b/collectors/python.d.plugin/python_modules/bases/loaders.py
index d18b9dcd0..9eb268ce7 100644
--- a/python.d/python_modules/bases/loaders.py
+++ b/collectors/python.d.plugin/python_modules/bases/loaders.py
@@ -1,18 +1,27 @@
# -*- coding: utf-8 -*-
# Description:
# Author: Ilya Mashchenko (l2isbad)
+# SPDX-License-Identifier: GPL-3.0-or-later
import types
+
from sys import version_info
PY_VERSION = version_info[:2]
+try:
+ if PY_VERSION > (3, 1):
+ from pyyaml3 import SafeLoader as YamlSafeLoader
+ else:
+ from pyyaml2 import SafeLoader as YamlSafeLoader
+except ImportError:
+ from yaml import SafeLoader as YamlSafeLoader
+
+
if PY_VERSION > (3, 1):
- from pyyaml3 import SafeLoader as YamlSafeLoader
from importlib.machinery import SourceFileLoader
DEFAULT_MAPPING_TAG = 'tag:yaml.org,2002:map'
else:
- from pyyaml2 import SafeLoader as YamlSafeLoader
from imp import load_source as SourceFileLoader
DEFAULT_MAPPING_TAG = u'tag:yaml.org,2002:map'
@@ -26,6 +35,14 @@ def dict_constructor(loader, node):
return OrderedDict(loader.construct_pairs(node))
+def safe_load(stream):
+ loader = YamlSafeLoader(stream)
+ try:
+ return loader.get_single_data()
+ finally:
+ loader.dispose()
+
+
YamlSafeLoader.add_constructor(DEFAULT_MAPPING_TAG, dict_constructor)
diff --git a/python.d/python_modules/bases/loggers.py b/collectors/python.d.plugin/python_modules/bases/loggers.py
index fc40b83d3..39be77a79 100644
--- a/python.d/python_modules/bases/loggers.py
+++ b/collectors/python.d.plugin/python_modules/bases/loggers.py
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
# Description:
# Author: Ilya Mashchenko (l2isbad)
+# SPDX-License-Identifier: GPL-3.0-or-later
import logging
import traceback
diff --git a/python.d/python_modules/pyyaml2/__init__.py b/collectors/python.d.plugin/python_modules/pyyaml2/__init__.py
index 76e19e13f..4d560e438 100644
--- a/python.d/python_modules/pyyaml2/__init__.py
+++ b/collectors/python.d.plugin/python_modules/pyyaml2/__init__.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
from error import *
diff --git a/python.d/python_modules/pyyaml2/composer.py b/collectors/python.d.plugin/python_modules/pyyaml2/composer.py
index 06e5ac782..6b41b8067 100644
--- a/python.d/python_modules/pyyaml2/composer.py
+++ b/collectors/python.d.plugin/python_modules/pyyaml2/composer.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
__all__ = ['Composer', 'ComposerError']
diff --git a/python.d/python_modules/pyyaml2/constructor.py b/collectors/python.d.plugin/python_modules/pyyaml2/constructor.py
index 635faac3e..8ad1b90a7 100644
--- a/python.d/python_modules/pyyaml2/constructor.py
+++ b/collectors/python.d.plugin/python_modules/pyyaml2/constructor.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
__all__ = ['BaseConstructor', 'SafeConstructor', 'Constructor',
'ConstructorError']
diff --git a/python.d/python_modules/pyyaml2/cyaml.py b/collectors/python.d.plugin/python_modules/pyyaml2/cyaml.py
index 68dcd7519..2858ab479 100644
--- a/python.d/python_modules/pyyaml2/cyaml.py
+++ b/collectors/python.d.plugin/python_modules/pyyaml2/cyaml.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
__all__ = ['CBaseLoader', 'CSafeLoader', 'CLoader',
'CBaseDumper', 'CSafeDumper', 'CDumper']
diff --git a/python.d/python_modules/pyyaml2/dumper.py b/collectors/python.d.plugin/python_modules/pyyaml2/dumper.py
index f811d2c91..3685cbeeb 100644
--- a/python.d/python_modules/pyyaml2/dumper.py
+++ b/collectors/python.d.plugin/python_modules/pyyaml2/dumper.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
__all__ = ['BaseDumper', 'SafeDumper', 'Dumper']
diff --git a/python.d/python_modules/pyyaml2/emitter.py b/collectors/python.d.plugin/python_modules/pyyaml2/emitter.py
index e5bcdcccb..9a460a0fd 100644
--- a/python.d/python_modules/pyyaml2/emitter.py
+++ b/collectors/python.d.plugin/python_modules/pyyaml2/emitter.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
# Emitter expects events obeying the following grammar:
# stream ::= STREAM-START document* STREAM-END
diff --git a/python.d/python_modules/pyyaml2/error.py b/collectors/python.d.plugin/python_modules/pyyaml2/error.py
index 577686db5..5466be721 100644
--- a/python.d/python_modules/pyyaml2/error.py
+++ b/collectors/python.d.plugin/python_modules/pyyaml2/error.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
__all__ = ['Mark', 'YAMLError', 'MarkedYAMLError']
diff --git a/python.d/python_modules/pyyaml2/events.py b/collectors/python.d.plugin/python_modules/pyyaml2/events.py
index f79ad389c..283452add 100644
--- a/python.d/python_modules/pyyaml2/events.py
+++ b/collectors/python.d.plugin/python_modules/pyyaml2/events.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
# Abstract classes.
diff --git a/python.d/python_modules/pyyaml2/loader.py b/collectors/python.d.plugin/python_modules/pyyaml2/loader.py
index 293ff467b..1c195531f 100644
--- a/python.d/python_modules/pyyaml2/loader.py
+++ b/collectors/python.d.plugin/python_modules/pyyaml2/loader.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
__all__ = ['BaseLoader', 'SafeLoader', 'Loader']
diff --git a/python.d/python_modules/pyyaml2/nodes.py b/collectors/python.d.plugin/python_modules/pyyaml2/nodes.py
index c4f070c41..ed2a1b43e 100644
--- a/python.d/python_modules/pyyaml2/nodes.py
+++ b/collectors/python.d.plugin/python_modules/pyyaml2/nodes.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
class Node(object):
def __init__(self, tag, value, start_mark, end_mark):
diff --git a/python.d/python_modules/pyyaml2/parser.py b/collectors/python.d.plugin/python_modules/pyyaml2/parser.py
index f9e3057f3..97ba08337 100644
--- a/python.d/python_modules/pyyaml2/parser.py
+++ b/collectors/python.d.plugin/python_modules/pyyaml2/parser.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
# The following YAML grammar is LL(1) and is parsed by a recursive descent
# parser.
diff --git a/python.d/python_modules/pyyaml2/reader.py b/collectors/python.d.plugin/python_modules/pyyaml2/reader.py
index 3249e6b9f..8d422954e 100644
--- a/python.d/python_modules/pyyaml2/reader.py
+++ b/collectors/python.d.plugin/python_modules/pyyaml2/reader.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
# This module contains abstractions for the input stream. You don't have to
# looks further, there are no pretty code.
#
diff --git a/python.d/python_modules/pyyaml2/representer.py b/collectors/python.d.plugin/python_modules/pyyaml2/representer.py
index 5f4fc70db..0a1404eca 100644
--- a/python.d/python_modules/pyyaml2/representer.py
+++ b/collectors/python.d.plugin/python_modules/pyyaml2/representer.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
__all__ = ['BaseRepresenter', 'SafeRepresenter', 'Representer',
'RepresenterError']
diff --git a/python.d/python_modules/pyyaml2/resolver.py b/collectors/python.d.plugin/python_modules/pyyaml2/resolver.py
index 6b5ab8759..49922debf 100644
--- a/python.d/python_modules/pyyaml2/resolver.py
+++ b/collectors/python.d.plugin/python_modules/pyyaml2/resolver.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
__all__ = ['BaseResolver', 'Resolver']
diff --git a/python.d/python_modules/pyyaml2/scanner.py b/collectors/python.d.plugin/python_modules/pyyaml2/scanner.py
index 5228fad65..971da6127 100644
--- a/python.d/python_modules/pyyaml2/scanner.py
+++ b/collectors/python.d.plugin/python_modules/pyyaml2/scanner.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
# Scanner produces tokens of the following types:
# STREAM-START
diff --git a/python.d/python_modules/pyyaml2/serializer.py b/collectors/python.d.plugin/python_modules/pyyaml2/serializer.py
index 0bf1e96dc..15fdbb0c0 100644
--- a/python.d/python_modules/pyyaml2/serializer.py
+++ b/collectors/python.d.plugin/python_modules/pyyaml2/serializer.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
__all__ = ['Serializer', 'SerializerError']
diff --git a/python.d/python_modules/pyyaml2/tokens.py b/collectors/python.d.plugin/python_modules/pyyaml2/tokens.py
index 4d0b48a39..c5c4fb116 100644
--- a/python.d/python_modules/pyyaml2/tokens.py
+++ b/collectors/python.d.plugin/python_modules/pyyaml2/tokens.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
class Token(object):
def __init__(self, start_mark, end_mark):
diff --git a/python.d/python_modules/pyyaml3/__init__.py b/collectors/python.d.plugin/python_modules/pyyaml3/__init__.py
index a5e20f94d..a884b33cf 100644
--- a/python.d/python_modules/pyyaml3/__init__.py
+++ b/collectors/python.d.plugin/python_modules/pyyaml3/__init__.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
from .error import *
diff --git a/python.d/python_modules/pyyaml3/composer.py b/collectors/python.d.plugin/python_modules/pyyaml3/composer.py
index d5c6a7acd..c418bba91 100644
--- a/python.d/python_modules/pyyaml3/composer.py
+++ b/collectors/python.d.plugin/python_modules/pyyaml3/composer.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
__all__ = ['Composer', 'ComposerError']
diff --git a/python.d/python_modules/pyyaml3/constructor.py b/collectors/python.d.plugin/python_modules/pyyaml3/constructor.py
index 981543aeb..ee09a7a7e 100644
--- a/python.d/python_modules/pyyaml3/constructor.py
+++ b/collectors/python.d.plugin/python_modules/pyyaml3/constructor.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
__all__ = ['BaseConstructor', 'SafeConstructor', 'Constructor',
'ConstructorError']
diff --git a/python.d/python_modules/pyyaml3/cyaml.py b/collectors/python.d.plugin/python_modules/pyyaml3/cyaml.py
index d5cb87e99..e6c16d894 100644
--- a/python.d/python_modules/pyyaml3/cyaml.py
+++ b/collectors/python.d.plugin/python_modules/pyyaml3/cyaml.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
__all__ = ['CBaseLoader', 'CSafeLoader', 'CLoader',
'CBaseDumper', 'CSafeDumper', 'CDumper']
diff --git a/python.d/python_modules/pyyaml3/dumper.py b/collectors/python.d.plugin/python_modules/pyyaml3/dumper.py
index 0b6912877..ba590c6e6 100644
--- a/python.d/python_modules/pyyaml3/dumper.py
+++ b/collectors/python.d.plugin/python_modules/pyyaml3/dumper.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
__all__ = ['BaseDumper', 'SafeDumper', 'Dumper']
diff --git a/python.d/python_modules/pyyaml3/emitter.py b/collectors/python.d.plugin/python_modules/pyyaml3/emitter.py
index 34cb145a5..d4be65a8e 100644
--- a/python.d/python_modules/pyyaml3/emitter.py
+++ b/collectors/python.d.plugin/python_modules/pyyaml3/emitter.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
# Emitter expects events obeying the following grammar:
# stream ::= STREAM-START document* STREAM-END
diff --git a/python.d/python_modules/pyyaml3/error.py b/collectors/python.d.plugin/python_modules/pyyaml3/error.py
index b796b4dc5..5fec7d449 100644
--- a/python.d/python_modules/pyyaml3/error.py
+++ b/collectors/python.d.plugin/python_modules/pyyaml3/error.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
__all__ = ['Mark', 'YAMLError', 'MarkedYAMLError']
diff --git a/python.d/python_modules/pyyaml3/events.py b/collectors/python.d.plugin/python_modules/pyyaml3/events.py
index f79ad389c..283452add 100644
--- a/python.d/python_modules/pyyaml3/events.py
+++ b/collectors/python.d.plugin/python_modules/pyyaml3/events.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
# Abstract classes.
diff --git a/python.d/python_modules/pyyaml3/loader.py b/collectors/python.d.plugin/python_modules/pyyaml3/loader.py
index 08c8f01b3..7ef6cf815 100644
--- a/python.d/python_modules/pyyaml3/loader.py
+++ b/collectors/python.d.plugin/python_modules/pyyaml3/loader.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
__all__ = ['BaseLoader', 'SafeLoader', 'Loader']
diff --git a/python.d/python_modules/pyyaml3/nodes.py b/collectors/python.d.plugin/python_modules/pyyaml3/nodes.py
index c4f070c41..ed2a1b43e 100644
--- a/python.d/python_modules/pyyaml3/nodes.py
+++ b/collectors/python.d.plugin/python_modules/pyyaml3/nodes.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
class Node(object):
def __init__(self, tag, value, start_mark, end_mark):
diff --git a/python.d/python_modules/pyyaml3/parser.py b/collectors/python.d.plugin/python_modules/pyyaml3/parser.py
index 13a5995d2..bcec7f994 100644
--- a/python.d/python_modules/pyyaml3/parser.py
+++ b/collectors/python.d.plugin/python_modules/pyyaml3/parser.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
# The following YAML grammar is LL(1) and is parsed by a recursive descent
# parser.
diff --git a/python.d/python_modules/pyyaml3/reader.py b/collectors/python.d.plugin/python_modules/pyyaml3/reader.py
index f70e920f4..0a515fd64 100644
--- a/python.d/python_modules/pyyaml3/reader.py
+++ b/collectors/python.d.plugin/python_modules/pyyaml3/reader.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
# This module contains abstractions for the input stream. You don't have to
# looks further, there are no pretty code.
#
diff --git a/python.d/python_modules/pyyaml3/representer.py b/collectors/python.d.plugin/python_modules/pyyaml3/representer.py
index 67cd6fd25..756a18dcc 100644
--- a/python.d/python_modules/pyyaml3/representer.py
+++ b/collectors/python.d.plugin/python_modules/pyyaml3/representer.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
__all__ = ['BaseRepresenter', 'SafeRepresenter', 'Representer',
'RepresenterError']
diff --git a/python.d/python_modules/pyyaml3/resolver.py b/collectors/python.d.plugin/python_modules/pyyaml3/resolver.py
index 0eece2582..50945e04d 100644
--- a/python.d/python_modules/pyyaml3/resolver.py
+++ b/collectors/python.d.plugin/python_modules/pyyaml3/resolver.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
__all__ = ['BaseResolver', 'Resolver']
diff --git a/python.d/python_modules/pyyaml3/scanner.py b/collectors/python.d.plugin/python_modules/pyyaml3/scanner.py
index 494d975ba..b55854e8b 100644
--- a/python.d/python_modules/pyyaml3/scanner.py
+++ b/collectors/python.d.plugin/python_modules/pyyaml3/scanner.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
# Scanner produces tokens of the following types:
# STREAM-START
diff --git a/python.d/python_modules/pyyaml3/serializer.py b/collectors/python.d.plugin/python_modules/pyyaml3/serializer.py
index fe911e67a..1ba2f7f9d 100644
--- a/python.d/python_modules/pyyaml3/serializer.py
+++ b/collectors/python.d.plugin/python_modules/pyyaml3/serializer.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
__all__ = ['Serializer', 'SerializerError']
diff --git a/python.d/python_modules/pyyaml3/tokens.py b/collectors/python.d.plugin/python_modules/pyyaml3/tokens.py
index 4d0b48a39..c5c4fb116 100644
--- a/python.d/python_modules/pyyaml3/tokens.py
+++ b/collectors/python.d.plugin/python_modules/pyyaml3/tokens.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
class Token(object):
def __init__(self, start_mark, end_mark):
diff --git a/python.d/python_modules/urllib3/packages/backports/__init__.py b/collectors/python.d.plugin/python_modules/third_party/__init__.py
index e69de29bb..e69de29bb 100644
--- a/python.d/python_modules/urllib3/packages/backports/__init__.py
+++ b/collectors/python.d.plugin/python_modules/third_party/__init__.py
diff --git a/collectors/python.d.plugin/python_modules/third_party/boinc_client.py b/collectors/python.d.plugin/python_modules/third_party/boinc_client.py
new file mode 100644
index 000000000..ec21779a0
--- /dev/null
+++ b/collectors/python.d.plugin/python_modules/third_party/boinc_client.py
@@ -0,0 +1,515 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# client.py - Somewhat higher-level GUI_RPC API for BOINC core client
+#
+# Copyright (C) 2013 Rodrigo Silva (MestreLion) <linux@rodrigosilva.com>
+# Copyright (C) 2017 Austin S. Hemmelgarn
+#
+# SPDX-License-Identifier: GPL-3.0
+
+# Based on client/boinc_cmd.cpp
+
+import hashlib
+import socket
+import sys
+import time
+from functools import total_ordering
+from xml.etree import ElementTree
+
+GUI_RPC_PASSWD_FILE = "/var/lib/boinc/gui_rpc_auth.cfg"
+
+GUI_RPC_HOSTNAME = None # localhost
+GUI_RPC_PORT = 31416
+GUI_RPC_TIMEOUT = 1
+
+class Rpc(object):
+ ''' Class to perform GUI RPC calls to a BOINC core client.
+ Usage in a context manager ('with' block) is recommended to ensure
+ disconnect() is called. Using the same instance for all calls is also
+ recommended so it reuses the same socket connection
+ '''
+ def __init__(self, hostname="", port=0, timeout=0, text_output=False):
+ self.hostname = hostname
+ self.port = port
+ self.timeout = timeout
+ self.sock = None
+ self.text_output = text_output
+
+ @property
+ def sockargs(self):
+ return (self.hostname, self.port, self.timeout)
+
+ def __enter__(self): self.connect(*self.sockargs); return self
+ def __exit__(self, *args): self.disconnect()
+
+ def connect(self, hostname="", port=0, timeout=0):
+ ''' Connect to (hostname, port) with timeout in seconds.
+ Hostname defaults to None (localhost), and port to 31416
+ Calling multiple times will disconnect previous connection (if any),
+ and (re-)connect to host.
+ '''
+ if self.sock:
+ self.disconnect()
+
+ self.hostname = hostname or GUI_RPC_HOSTNAME
+ self.port = port or GUI_RPC_PORT
+ self.timeout = timeout or GUI_RPC_TIMEOUT
+
+ self.sock = socket.create_connection(self.sockargs[0:2], self.sockargs[2])
+
+ def disconnect(self):
+ ''' Disconnect from host. Calling multiple times is OK (idempotent)
+ '''
+ if self.sock:
+ self.sock.close()
+ self.sock = None
+
+ def call(self, request, text_output=None):
+ ''' Do an RPC call. Pack and send the XML request and return the
+ unpacked reply. request can be either plain XML text or a
+ xml.etree.ElementTree.Element object. Return ElementTree.Element
+ or XML text according to text_output flag.
+ Will auto-connect if not connected.
+ '''
+ if text_output is None:
+ text_output = self.text_output
+
+ if not self.sock:
+ self.connect(*self.sockargs)
+
+ if not isinstance(request, ElementTree.Element):
+ request = ElementTree.fromstring(request)
+
+ # pack request
+ end = '\003'
+ if sys.version_info[0] < 3:
+ req = "<boinc_gui_rpc_request>\n{0}\n</boinc_gui_rpc_request>\n{1}".format(ElementTree.tostring(request).replace(' />', '/>'), end)
+ else:
+ req = "<boinc_gui_rpc_request>\n{0}\n</boinc_gui_rpc_request>\n{1}".format(ElementTree.tostring(request, encoding='unicode').replace(' />', '/>'), end).encode()
+
+ try:
+ self.sock.sendall(req)
+ except (socket.error, socket.herror, socket.gaierror, socket.timeout):
+ raise
+
+ req = ""
+ while True:
+ try:
+ buf = self.sock.recv(8192)
+ if not buf:
+ raise socket.error("No data from socket")
+ if sys.version_info[0] >= 3:
+ buf = buf.decode()
+ except socket.error:
+ raise
+ n = buf.find(end)
+ if not n == -1: break
+ req += buf
+ req += buf[:n]
+
+ # unpack reply (remove root tag, ie: first and last lines)
+ req = '\n'.join(req.strip().rsplit('\n')[1:-1])
+
+ if text_output:
+ return req
+ else:
+ return ElementTree.fromstring(req)
+
+def setattrs_from_xml(obj, xml, attrfuncdict={}):
+ ''' Helper to set values for attributes of a class instance by mapping
+ matching tags from a XML file.
+ attrfuncdict is a dict of functions to customize value data type of
+ each attribute. It falls back to simple int/float/bool/str detection
+ based on values defined in __init__(). This would not be needed if
+ Boinc used standard RPC protocol, which includes data type in XML.
+ '''
+ if not isinstance(xml, ElementTree.Element):
+ xml = ElementTree.fromstring(xml)
+ for e in list(xml):
+ if hasattr(obj, e.tag):
+ attr = getattr(obj, e.tag)
+ attrfunc = attrfuncdict.get(e.tag, None)
+ if attrfunc is None:
+ if isinstance(attr, bool): attrfunc = parse_bool
+ elif isinstance(attr, int): attrfunc = parse_int
+ elif isinstance(attr, float): attrfunc = parse_float
+ elif isinstance(attr, str): attrfunc = parse_str
+ elif isinstance(attr, list): attrfunc = parse_list
+ else: attrfunc = lambda x: x
+ setattr(obj, e.tag, attrfunc(e))
+ else:
+ pass
+ #print "class missing attribute '%s': %r" % (e.tag, obj)
+ return obj
+
+
+def parse_bool(e):
+ ''' Helper to convert ElementTree.Element.text to boolean.
+ Treat '<foo/>' (and '<foo>[[:blank:]]</foo>') as True
+ Treat '0' and 'false' as False
+ '''
+ if e.text is None:
+ return True
+ else:
+ return bool(e.text) and not e.text.strip().lower() in ('0', 'false')
+
+
+def parse_int(e):
+ ''' Helper to convert ElementTree.Element.text to integer.
+ Treat '<foo/>' (and '<foo></foo>') as 0
+ '''
+ # int(float()) allows casting to int a value expressed as float in XML
+ return 0 if e.text is None else int(float(e.text.strip()))
+
+
+def parse_float(e):
+ ''' Helper to convert ElementTree.Element.text to float. '''
+ return 0.0 if e.text is None else float(e.text.strip())
+
+
+def parse_str(e):
+ ''' Helper to convert ElementTree.Element.text to string. '''
+ return "" if e.text is None else e.text.strip()
+
+
+def parse_list(e):
+ ''' Helper to convert ElementTree.Element to list. For now, simply return
+ the list of root element's children
+ '''
+ return list(e)
+
+
+class Enum(object):
+ UNKNOWN = -1 # Not in original API
+
+ @classmethod
+ def name(cls, value):
+ ''' Quick-and-dirty fallback for getting the "name" of an enum item '''
+
+ # value as string, if it matches an enum attribute.
+ # Allows short usage as Enum.name("VALUE") besides Enum.name(Enum.VALUE)
+ if hasattr(cls, str(value)):
+ return cls.name(getattr(cls, value, None))
+
+ # value not handled in subclass name()
+ for k, v in cls.__dict__.items():
+ if v == value:
+ return k.lower().replace('_', ' ')
+
+ # value not found
+ return cls.name(Enum.UNKNOWN)
+
+
+class CpuSched(Enum):
+ ''' values of ACTIVE_TASK::scheduler_state and ACTIVE_TASK::next_scheduler_state
+ "SCHEDULED" is synonymous with "executing" except when CPU throttling
+ is in use.
+ '''
+ UNINITIALIZED = 0
+ PREEMPTED = 1
+ SCHEDULED = 2
+
+
+class ResultState(Enum):
+ ''' Values of RESULT::state in client.
+ THESE MUST BE IN NUMERICAL ORDER
+ (because of the > comparison in RESULT::computing_done())
+ see html/inc/common_defs.inc
+ '''
+ NEW = 0
+ #// New result
+ FILES_DOWNLOADING = 1
+ #// Input files for result (WU, app version) are being downloaded
+ FILES_DOWNLOADED = 2
+ #// Files are downloaded, result can be (or is being) computed
+ COMPUTE_ERROR = 3
+ #// computation failed; no file upload
+ FILES_UPLOADING = 4
+ #// Output files for result are being uploaded
+ FILES_UPLOADED = 5
+ #// Files are uploaded, notify scheduling server at some point
+ ABORTED = 6
+ #// result was aborted
+ UPLOAD_FAILED = 7
+ #// some output file permanent failure
+
+
+class Process(Enum):
+ ''' values of ACTIVE_TASK::task_state '''
+ UNINITIALIZED = 0
+ #// process doesn't exist yet
+ EXECUTING = 1
+ #// process is running, as far as we know
+ SUSPENDED = 9
+ #// we've sent it a "suspend" message
+ ABORT_PENDING = 5
+ #// process exceeded limits; send "abort" message, waiting to exit
+ QUIT_PENDING = 8
+ #// we've sent it a "quit" message, waiting to exit
+ COPY_PENDING = 10
+ #// waiting for async file copies to finish
+
+
+class _Struct(object):
+ ''' base helper class with common methods for all classes derived from
+ BOINC's C++ structs
+ '''
+ @classmethod
+ def parse(cls, xml):
+ return setattrs_from_xml(cls(), xml)
+
+ def __str__(self, indent=0):
+ buf = '{0}{1}:\n'.format('\t' * indent, self.__class__.__name__)
+ for attr in self.__dict__:
+ value = getattr(self, attr)
+ if isinstance(value, list):
+ buf += '{0}\t{1} [\n'.format('\t' * indent, attr)
+ for v in value: buf += '\t\t{0}\t\t,\n'.format(v)
+ buf += '\t]\n'
+ else:
+ buf += '{0}\t{1}\t{2}\n'.format('\t' * indent,
+ attr,
+ value.__str__(indent+2)
+ if isinstance(value, _Struct)
+ else repr(value))
+ return buf
+
+
+@total_ordering
+class VersionInfo(_Struct):
+ def __init__(self, major=0, minor=0, release=0):
+ self.major = major
+ self.minor = minor
+ self.release = release
+
+ @property
+ def _tuple(self):
+ return (self.major, self.minor, self.release)
+
+ def __eq__(self, other):
+ return isinstance(other, self.__class__) and self._tuple == other._tuple
+
+ def __ne__(self, other):
+ return not self.__eq__(other)
+
+ def __gt__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return self._tuple > other._tuple
+
+ def __str__(self):
+ return "{0}.{1}.{2}".format(self.major, self.minor, self.release)
+
+ def __repr__(self):
+ return "{0}{1}".format(self.__class__.__name__, self._tuple)
+
+
+class Result(_Struct):
+ ''' Also called "task" in some contexts '''
+ def __init__(self):
+ # Names and values follow lib/gui_rpc_client.h @ RESULT
+ # Order too, except when grouping contradicts client/result.cpp
+ # RESULT::write_gui(), then XML order is used.
+
+ self.name = ""
+ self.wu_name = ""
+ self.version_num = 0
+ #// identifies the app used
+ self.plan_class = ""
+ self.project_url = "" # from PROJECT.master_url
+ self.report_deadline = 0.0 # seconds since epoch
+ self.received_time = 0.0 # seconds since epoch
+ #// when we got this from server
+ self.ready_to_report = False
+ #// we're ready to report this result to the server;
+ #// either computation is done and all the files have been uploaded
+ #// or there was an error
+ self.got_server_ack = False
+ #// we've received the ack for this result from the server
+ self.final_cpu_time = 0.0
+ self.final_elapsed_time = 0.0
+ self.state = ResultState.NEW
+ self.estimated_cpu_time_remaining = 0.0
+ #// actually, estimated elapsed time remaining
+ self.exit_status = 0
+ #// return value from the application
+ self.suspended_via_gui = False
+ self.project_suspended_via_gui = False
+ self.edf_scheduled = False
+ #// temporary used to tell GUI that this result is deadline-scheduled
+ self.coproc_missing = False
+ #// a coproc needed by this job is missing
+ #// (e.g. because user removed their GPU board).
+ self.scheduler_wait = False
+ self.scheduler_wait_reason = ""
+ self.network_wait = False
+ self.resources = ""
+ #// textual description of resources used
+
+ #// the following defined if active
+ # XML is generated in client/app.cpp ACTIVE_TASK::write_gui()
+ self.active_task = False
+ self.active_task_state = Process.UNINITIALIZED
+ self.app_version_num = 0
+ self.slot = -1
+ self.pid = 0
+ self.scheduler_state = CpuSched.UNINITIALIZED
+ self.checkpoint_cpu_time = 0.0
+ self.current_cpu_time = 0.0
+ self.fraction_done = 0.0
+ self.elapsed_time = 0.0
+ self.swap_size = 0
+ self.working_set_size_smoothed = 0.0
+ self.too_large = False
+ self.needs_shmem = False
+ self.graphics_exec_path = ""
+ self.web_graphics_url = ""
+ self.remote_desktop_addr = ""
+ self.slot_path = ""
+ #// only present if graphics_exec_path is
+
+ # The following are not in original API, but are present in RPC XML reply
+ self.completed_time = 0.0
+ #// time when ready_to_report was set
+ self.report_immediately = False
+ self.working_set_size = 0
+ self.page_fault_rate = 0.0
+ #// derived by higher-level code
+
+ # The following are in API, but are NEVER in RPC XML reply. Go figure
+ self.signal = 0
+
+ self.app = None # APP*
+ self.wup = None # WORKUNIT*
+ self.project = None # PROJECT*
+ self.avp = None # APP_VERSION*
+
+ @classmethod
+ def parse(cls, xml):
+ if not isinstance(xml, ElementTree.Element):
+ xml = ElementTree.fromstring(xml)
+
+ # parse main XML
+ result = super(Result, cls).parse(xml)
+
+ # parse '<active_task>' children
+ active_task = xml.find('active_task')
+ if active_task is None:
+ result.active_task = False # already the default after __init__()
+ else:
+ result.active_task = True # already the default after main parse
+ result = setattrs_from_xml(result, active_task)
+
+ #// if CPU time is nonzero but elapsed time is zero,
+ #// we must be talking to an old client.
+ #// Set elapsed = CPU
+ #// (easier to deal with this here than in the manager)
+ if result.current_cpu_time != 0 and result.elapsed_time == 0:
+ result.elapsed_time = result.current_cpu_time
+
+ if result.final_cpu_time != 0 and result.final_elapsed_time == 0:
+ result.final_elapsed_time = result.final_cpu_time
+
+ return result
+
+ def __str__(self):
+ buf = '{0}:\n'.format(self.__class__.__name__)
+ for attr in self.__dict__:
+ value = getattr(self, attr)
+ if attr in ['received_time', 'report_deadline']:
+ value = time.ctime(value)
+ buf += '\t{0}\t{1}\n'.format(attr, value)
+ return buf
+
+
+class BoincClient(object):
+
+ def __init__(self, host="", port=0, passwd=None):
+ self.hostname = host
+ self.port = port
+ self.passwd = passwd
+ self.rpc = Rpc(text_output=False)
+ self.version = None
+ self.authorized = False
+
+ # Informative, not authoritative. Records status of *last* RPC call,
+ # but does not infer success about the *next* one.
+ # Thus, it should be read *after* an RPC call, not prior to one
+ self.connected = False
+
+ def __enter__(self): self.connect(); return self
+ def __exit__(self, *args): self.disconnect()
+
+ def connect(self):
+ try:
+ self.rpc.connect(self.hostname, self.port)
+ self.connected = True
+ except socket.error:
+ self.connected = False
+ return
+ self.authorized = self.authorize(self.passwd)
+ self.version = self.exchange_versions()
+
+ def disconnect(self):
+ self.rpc.disconnect()
+
+ def authorize(self, password):
+ ''' Request authorization. If password is None and we are connecting
+ to localhost, try to read password from the local config file
+ GUI_RPC_PASSWD_FILE. If file can't be read (not found or no
+ permission to read), try to authorize with a blank password.
+ If authorization is requested and fails, all subsequent calls
+ will be refused with socket.error 'Connection reset by peer' (104).
+ Since most local calls do no require authorization, do not attempt
+ it if you're not sure about the password.
+ '''
+ if password is None and not self.hostname:
+ password = read_gui_rpc_password() or ""
+ nonce = self.rpc.call('<auth1/>').text
+ authhash = hashlib.md5('{0}{1}'.format(nonce, password).encode()).hexdigest().lower()
+ reply = self.rpc.call('<auth2><nonce_hash>{0}</nonce_hash></auth2>'.format(authhash))
+
+ if reply.tag == 'authorized':
+ return True
+ else:
+ return False
+
+ def exchange_versions(self):
+ ''' Return VersionInfo instance with core client version info '''
+ return VersionInfo.parse(self.rpc.call('<exchange_versions/>'))
+
+ def get_tasks(self):
+ ''' Same as get_results(active_only=False) '''
+ return self.get_results(False)
+
+ def get_results(self, active_only=False):
+ ''' Get a list of results.
+ Those that are in progress will have information such as CPU time
+ and fraction done. Each result includes a name;
+ Use CC_STATE::lookup_result() to find this result in the current static state;
+ if it's not there, call get_state() again.
+ '''
+ reply = self.rpc.call("<get_results><active_only>{0}</active_only></get_results>".format(1 if active_only else 0))
+ if not reply.tag == 'results':
+ return []
+
+ results = []
+ for item in list(reply):
+ results.append(Result.parse(item))
+
+ return results
+
+
+def read_gui_rpc_password():
+ ''' Read password string from GUI_RPC_PASSWD_FILE file, trim the last CR
+ (if any), and return it
+ '''
+ try:
+ with open(GUI_RPC_PASSWD_FILE, 'r') as f:
+ buf = f.read()
+ if buf.endswith('\n'): return buf[:-1] # trim last CR
+ else: return buf
+ except IOError:
+ # Permission denied or File not found.
+ pass
diff --git a/python.d/python_modules/third_party/lm_sensors.py b/collectors/python.d.plugin/python_modules/third_party/lm_sensors.py
index 1d868f0e2..f10cd6209 100644
--- a/python.d/python_modules/third_party/lm_sensors.py
+++ b/collectors/python.d.plugin/python_modules/third_party/lm_sensors.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: LGPL-2.1
"""
@package sensors.py
Python Bindings for libsensors3
@@ -254,4 +255,4 @@ class SubFeatureIterator:
return subfeature
def next(self): # python2 compability
- return self.__next__() \ No newline at end of file
+ return self.__next__()
diff --git a/collectors/python.d.plugin/python_modules/third_party/mcrcon.py b/collectors/python.d.plugin/python_modules/third_party/mcrcon.py
new file mode 100644
index 000000000..a65a304b6
--- /dev/null
+++ b/collectors/python.d.plugin/python_modules/third_party/mcrcon.py
@@ -0,0 +1,74 @@
+# Minecraft Remote Console module.
+#
+# Copyright (C) 2015 Barnaby Gale
+#
+# SPDX-License-Identifier: MIT
+
+import socket
+import select
+import struct
+import time
+
+
+class MCRconException(Exception):
+ pass
+
+
+class MCRcon(object):
+ socket = None
+
+ def connect(self, host, port, password):
+ if self.socket is not None:
+ raise MCRconException("Already connected")
+ self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ self.socket.settimeout(0.9)
+ self.socket.connect((host, port))
+ self.send(3, password)
+
+ def disconnect(self):
+ if self.socket is None:
+ raise MCRconException("Already disconnected")
+ self.socket.close()
+ self.socket = None
+
+ def read(self, length):
+ data = b""
+ while len(data) < length:
+ data += self.socket.recv(length - len(data))
+ return data
+
+ def send(self, out_type, out_data):
+ if self.socket is None:
+ raise MCRconException("Must connect before sending data")
+
+ # Send a request packet
+ out_payload = struct.pack('<ii', 0, out_type) + out_data.encode('utf8') + b'\x00\x00'
+ out_length = struct.pack('<i', len(out_payload))
+ self.socket.send(out_length + out_payload)
+
+ # Read response packets
+ in_data = ""
+ while True:
+ # Read a packet
+ in_length, = struct.unpack('<i', self.read(4))
+ in_payload = self.read(in_length)
+ in_id = struct.unpack('<ii', in_payload[:8])
+ in_data_partial, in_padding = in_payload[8:-2], in_payload[-2:]
+
+ # Sanity checks
+ if in_padding != b'\x00\x00':
+ raise MCRconException("Incorrect padding")
+ if in_id == -1:
+ raise MCRconException("Login failed")
+
+ # Record the response
+ in_data += in_data_partial.decode('utf8')
+
+ # If there's nothing more to receive, return the response
+ if len(select.select([self.socket], [], [], 0)[0]) == 0:
+ return in_data
+
+ def command(self, command):
+ result = self.send(2, command)
+ time.sleep(0.003) # MC-72390 workaround
+ return result
diff --git a/collectors/python.d.plugin/python_modules/third_party/monotonic.py b/collectors/python.d.plugin/python_modules/third_party/monotonic.py
new file mode 100644
index 000000000..da04bb857
--- /dev/null
+++ b/collectors/python.d.plugin/python_modules/third_party/monotonic.py
@@ -0,0 +1,171 @@
+# -*- coding: utf-8 -*-
+#
+# SPDX-License-Identifier: Apache-2.0
+"""
+ monotonic
+ ~~~~~~~~~
+
+ This module provides a ``monotonic()`` function which returns the
+ value (in fractional seconds) of a clock which never goes backwards.
+
+ On Python 3.3 or newer, ``monotonic`` will be an alias of
+ ``time.monotonic`` from the standard library. On older versions,
+ it will fall back to an equivalent implementation:
+
+ +-------------+----------------------------------------+
+ | Linux, BSD | ``clock_gettime(3)`` |
+ +-------------+----------------------------------------+
+ | Windows | ``GetTickCount`` or ``GetTickCount64`` |
+ +-------------+----------------------------------------+
+ | OS X | ``mach_absolute_time`` |
+ +-------------+----------------------------------------+
+
+ If no suitable implementation exists for the current platform,
+ attempting to import this module (or to import from it) will
+ cause a ``RuntimeError`` exception to be raised.
+
+
+ Copyright 2014, 2015, 2016 Ori Livneh <ori@wikimedia.org>
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+"""
+import time
+
+
+__all__ = ('monotonic',)
+
+
+try:
+ monotonic = time.monotonic
+except AttributeError:
+ import ctypes
+ import ctypes.util
+ import os
+ import sys
+ import threading
+ try:
+ if sys.platform == 'darwin': # OS X, iOS
+ # See Technical Q&A QA1398 of the Mac Developer Library:
+ # <https://developer.apple.com/library/mac/qa/qa1398/>
+ libc = ctypes.CDLL('/usr/lib/libc.dylib', use_errno=True)
+
+ class mach_timebase_info_data_t(ctypes.Structure):
+ """System timebase info. Defined in <mach/mach_time.h>."""
+ _fields_ = (('numer', ctypes.c_uint32),
+ ('denom', ctypes.c_uint32))
+
+ mach_absolute_time = libc.mach_absolute_time
+ mach_absolute_time.restype = ctypes.c_uint64
+
+ timebase = mach_timebase_info_data_t()
+ libc.mach_timebase_info(ctypes.byref(timebase))
+ ticks_per_second = timebase.numer / timebase.denom * 1.0e9
+
+ def monotonic():
+ """Monotonic clock, cannot go backward."""
+ return mach_absolute_time() / ticks_per_second
+
+ elif sys.platform.startswith('win32') or sys.platform.startswith('cygwin'):
+ if sys.platform.startswith('cygwin'):
+ # Note: cygwin implements clock_gettime (CLOCK_MONOTONIC = 4) since
+ # version 1.7.6. Using raw WinAPI for maximum version compatibility.
+
+ # Ugly hack using the wrong calling convention (in 32-bit mode)
+ # because ctypes has no windll under cygwin (and it also seems that
+ # the code letting you select stdcall in _ctypes doesn't exist under
+ # the preprocessor definitions relevant to cygwin).
+ # This is 'safe' because:
+ # 1. The ABI of GetTickCount and GetTickCount64 is identical for
+ # both calling conventions because they both have no parameters.
+ # 2. libffi masks the problem because after making the call it doesn't
+ # touch anything through esp and epilogue code restores a correct
+ # esp from ebp afterwards.
+ try:
+ kernel32 = ctypes.cdll.kernel32
+ except OSError: # 'No such file or directory'
+ kernel32 = ctypes.cdll.LoadLibrary('kernel32.dll')
+ else:
+ kernel32 = ctypes.windll.kernel32
+
+ GetTickCount64 = getattr(kernel32, 'GetTickCount64', None)
+ if GetTickCount64:
+ # Windows Vista / Windows Server 2008 or newer.
+ GetTickCount64.restype = ctypes.c_ulonglong
+
+ def monotonic():
+ """Monotonic clock, cannot go backward."""
+ return GetTickCount64() / 1000.0
+
+ else:
+ # Before Windows Vista.
+ GetTickCount = kernel32.GetTickCount
+ GetTickCount.restype = ctypes.c_uint32
+
+ get_tick_count_lock = threading.Lock()
+ get_tick_count_last_sample = 0
+ get_tick_count_wraparounds = 0
+
+ def monotonic():
+ """Monotonic clock, cannot go backward."""
+ global get_tick_count_last_sample
+ global get_tick_count_wraparounds
+
+ with get_tick_count_lock:
+ current_sample = GetTickCount()
+ if current_sample < get_tick_count_last_sample:
+ get_tick_count_wraparounds += 1
+ get_tick_count_last_sample = current_sample
+
+ final_milliseconds = get_tick_count_wraparounds << 32
+ final_milliseconds += get_tick_count_last_sample
+ return final_milliseconds / 1000.0
+
+ else:
+ try:
+ clock_gettime = ctypes.CDLL(ctypes.util.find_library('c'),
+ use_errno=True).clock_gettime
+ except Exception:
+ clock_gettime = ctypes.CDLL(ctypes.util.find_library('rt'),
+ use_errno=True).clock_gettime
+
+ class timespec(ctypes.Structure):
+ """Time specification, as described in clock_gettime(3)."""
+ _fields_ = (('tv_sec', ctypes.c_long),
+ ('tv_nsec', ctypes.c_long))
+
+ if sys.platform.startswith('linux'):
+ CLOCK_MONOTONIC = 1
+ elif sys.platform.startswith('freebsd'):
+ CLOCK_MONOTONIC = 4
+ elif sys.platform.startswith('sunos5'):
+ CLOCK_MONOTONIC = 4
+ elif 'bsd' in sys.platform:
+ CLOCK_MONOTONIC = 3
+ elif sys.platform.startswith('aix'):
+ CLOCK_MONOTONIC = ctypes.c_longlong(10)
+
+ def monotonic():
+ """Monotonic clock, cannot go backward."""
+ ts = timespec()
+ if clock_gettime(CLOCK_MONOTONIC, ctypes.pointer(ts)):
+ errno = ctypes.get_errno()
+ raise OSError(errno, os.strerror(errno))
+ return ts.tv_sec + ts.tv_nsec / 1.0e9
+
+ # Perform a sanity-check.
+ if monotonic() - monotonic() > 0:
+ raise ValueError('monotonic() is not monotonic!')
+
+ except Exception as e:
+ raise RuntimeError('no suitable implementation for this system: ' + repr(e))
diff --git a/python.d/python_modules/third_party/ordereddict.py b/collectors/python.d.plugin/python_modules/third_party/ordereddict.py
index d0b97d47c..589401b8f 100644
--- a/python.d/python_modules/third_party/ordereddict.py
+++ b/collectors/python.d.plugin/python_modules/third_party/ordereddict.py
@@ -1,24 +1,6 @@
# Copyright (c) 2009 Raymond Hettinger
#
-# Permission is hereby granted, free of charge, to any person
-# obtaining a copy of this software and associated documentation files
-# (the "Software"), to deal in the Software without restriction,
-# including without limitation the rights to use, copy, modify, merge,
-# publish, distribute, sublicense, and/or sell copies of the Software,
-# and to permit persons to whom the Software is furnished to do so,
-# subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-# OTHER DEALINGS IN THE SOFTWARE.
+# SPDX-License-Identifier: MIT
from UserDict import DictMixin
diff --git a/python.d/python_modules/urllib3/__init__.py b/collectors/python.d.plugin/python_modules/urllib3/__init__.py
index 26493ecb9..3add84816 100644
--- a/python.d/python_modules/urllib3/__init__.py
+++ b/collectors/python.d.plugin/python_modules/urllib3/__init__.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
"""
urllib3 - Thread-safe connection pooling and re-using.
"""
diff --git a/python.d/python_modules/urllib3/_collections.py b/collectors/python.d.plugin/python_modules/urllib3/_collections.py
index 4849ddecd..c1d2fad36 100644
--- a/python.d/python_modules/urllib3/_collections.py
+++ b/collectors/python.d.plugin/python_modules/urllib3/_collections.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
from __future__ import absolute_import
from collections import Mapping, MutableMapping
try:
diff --git a/python.d/python_modules/urllib3/connection.py b/collectors/python.d.plugin/python_modules/urllib3/connection.py
index c0d832998..f757493c7 100644
--- a/python.d/python_modules/urllib3/connection.py
+++ b/collectors/python.d.plugin/python_modules/urllib3/connection.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
from __future__ import absolute_import
import datetime
import logging
diff --git a/python.d/python_modules/urllib3/connectionpool.py b/collectors/python.d.plugin/python_modules/urllib3/connectionpool.py
index b4f1166a6..90e4c86a5 100644
--- a/python.d/python_modules/urllib3/connectionpool.py
+++ b/collectors/python.d.plugin/python_modules/urllib3/connectionpool.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
from __future__ import absolute_import
import errno
import logging
diff --git a/src/.keep b/collectors/python.d.plugin/python_modules/urllib3/contrib/__init__.py
index e69de29bb..e69de29bb 100644
--- a/src/.keep
+++ b/collectors/python.d.plugin/python_modules/urllib3/contrib/__init__.py
diff --git a/collectors/python.d.plugin/python_modules/urllib3/contrib/_securetransport/__init__.py b/collectors/python.d.plugin/python_modules/urllib3/contrib/_securetransport/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/collectors/python.d.plugin/python_modules/urllib3/contrib/_securetransport/__init__.py
diff --git a/python.d/python_modules/urllib3/contrib/_securetransport/bindings.py b/collectors/python.d.plugin/python_modules/urllib3/contrib/_securetransport/bindings.py
index e26b84086..bb826673f 100644
--- a/python.d/python_modules/urllib3/contrib/_securetransport/bindings.py
+++ b/collectors/python.d.plugin/python_modules/urllib3/contrib/_securetransport/bindings.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
"""
This module uses ctypes to bind a whole bunch of functions and constants from
SecureTransport. The goal here is to provide the low-level API to
diff --git a/python.d/python_modules/urllib3/contrib/_securetransport/low_level.py b/collectors/python.d.plugin/python_modules/urllib3/contrib/_securetransport/low_level.py
index 5e3494bce..0f79a1372 100644
--- a/python.d/python_modules/urllib3/contrib/_securetransport/low_level.py
+++ b/collectors/python.d.plugin/python_modules/urllib3/contrib/_securetransport/low_level.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
"""
Low-level helpers for the SecureTransport bindings.
diff --git a/python.d/python_modules/urllib3/contrib/appengine.py b/collectors/python.d.plugin/python_modules/urllib3/contrib/appengine.py
index 814b0222d..e74589fa8 100644
--- a/python.d/python_modules/urllib3/contrib/appengine.py
+++ b/collectors/python.d.plugin/python_modules/urllib3/contrib/appengine.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
"""
This module provides a pool manager that uses Google App Engine's
`URLFetch Service <https://cloud.google.com/appengine/docs/python/urlfetch>`_.
diff --git a/python.d/python_modules/urllib3/contrib/ntlmpool.py b/collectors/python.d.plugin/python_modules/urllib3/contrib/ntlmpool.py
index 642e99ed2..3f8c9ebf5 100644
--- a/python.d/python_modules/urllib3/contrib/ntlmpool.py
+++ b/collectors/python.d.plugin/python_modules/urllib3/contrib/ntlmpool.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
"""
NTLM authenticating pool, contributed by erikcederstran
diff --git a/python.d/python_modules/urllib3/contrib/pyopenssl.py b/collectors/python.d.plugin/python_modules/urllib3/contrib/pyopenssl.py
index 6645dbaa9..8d373507d 100644
--- a/python.d/python_modules/urllib3/contrib/pyopenssl.py
+++ b/collectors/python.d.plugin/python_modules/urllib3/contrib/pyopenssl.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
"""
SSL with SNI_-support for Python 2. Follow these instructions if you would
like to verify SSL certificates in Python 2. Note, the default libraries do
diff --git a/python.d/python_modules/urllib3/contrib/securetransport.py b/collectors/python.d.plugin/python_modules/urllib3/contrib/securetransport.py
index 72b23ab1c..fcc30118c 100644
--- a/python.d/python_modules/urllib3/contrib/securetransport.py
+++ b/collectors/python.d.plugin/python_modules/urllib3/contrib/securetransport.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
"""
SecureTranport support for urllib3 via ctypes.
diff --git a/python.d/python_modules/urllib3/contrib/socks.py b/collectors/python.d.plugin/python_modules/urllib3/contrib/socks.py
index 39e92fde1..1cb79285b 100644
--- a/python.d/python_modules/urllib3/contrib/socks.py
+++ b/collectors/python.d.plugin/python_modules/urllib3/contrib/socks.py
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
+# SPDX-License-Identifier: MIT
"""
This module contains provisional support for SOCKS proxies from within
urllib3. This module supports SOCKS4 (specifically the SOCKS4A variant) and
diff --git a/python.d/python_modules/urllib3/exceptions.py b/collectors/python.d.plugin/python_modules/urllib3/exceptions.py
index 6c4be5810..a71cabe06 100644
--- a/python.d/python_modules/urllib3/exceptions.py
+++ b/collectors/python.d.plugin/python_modules/urllib3/exceptions.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
from __future__ import absolute_import
from .packages.six.moves.http_client import (
IncompleteRead as httplib_IncompleteRead
diff --git a/python.d/python_modules/urllib3/fields.py b/collectors/python.d.plugin/python_modules/urllib3/fields.py
index 19b0ae0c8..de7577b74 100644
--- a/python.d/python_modules/urllib3/fields.py
+++ b/collectors/python.d.plugin/python_modules/urllib3/fields.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
from __future__ import absolute_import
import email.utils
import mimetypes
diff --git a/python.d/python_modules/urllib3/filepost.py b/collectors/python.d.plugin/python_modules/urllib3/filepost.py
index cd11cee46..3febc9cfe 100644
--- a/python.d/python_modules/urllib3/filepost.py
+++ b/collectors/python.d.plugin/python_modules/urllib3/filepost.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
from __future__ import absolute_import
import codecs
diff --git a/python.d/python_modules/urllib3/packages/__init__.py b/collectors/python.d.plugin/python_modules/urllib3/packages/__init__.py
index 170e974c1..170e974c1 100644
--- a/python.d/python_modules/urllib3/packages/__init__.py
+++ b/collectors/python.d.plugin/python_modules/urllib3/packages/__init__.py
diff --git a/collectors/python.d.plugin/python_modules/urllib3/packages/backports/__init__.py b/collectors/python.d.plugin/python_modules/urllib3/packages/backports/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/collectors/python.d.plugin/python_modules/urllib3/packages/backports/__init__.py
diff --git a/python.d/python_modules/urllib3/packages/backports/makefile.py b/collectors/python.d.plugin/python_modules/urllib3/packages/backports/makefile.py
index 75b80dcf8..8ab122f8b 100644
--- a/python.d/python_modules/urllib3/packages/backports/makefile.py
+++ b/collectors/python.d.plugin/python_modules/urllib3/packages/backports/makefile.py
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
+# SPDX-License-Identifier: MIT
"""
backports.makefile
~~~~~~~~~~~~~~~~~~
diff --git a/python.d/python_modules/urllib3/packages/ordered_dict.py b/collectors/python.d.plugin/python_modules/urllib3/packages/ordered_dict.py
index 4479363cc..9f7c0e6b8 100644
--- a/python.d/python_modules/urllib3/packages/ordered_dict.py
+++ b/collectors/python.d.plugin/python_modules/urllib3/packages/ordered_dict.py
@@ -2,6 +2,7 @@
# Passes Python2.7's test suite and incorporates all the latest updates.
# Copyright 2009 Raymond Hettinger, released under the MIT License.
# http://code.activestate.com/recipes/576693/
+# SPDX-License-Identifier: MIT
try:
from thread import get_ident as _get_ident
except ImportError:
diff --git a/python.d/python_modules/urllib3/packages/six.py b/collectors/python.d.plugin/python_modules/urllib3/packages/six.py
index 190c0239c..31df5012b 100644
--- a/python.d/python_modules/urllib3/packages/six.py
+++ b/collectors/python.d.plugin/python_modules/urllib3/packages/six.py
@@ -2,23 +2,7 @@
# Copyright (c) 2010-2015 Benjamin Peterson
#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
+# SPDX-License-Identifier: MIT
from __future__ import absolute_import
diff --git a/python.d/python_modules/urllib3/packages/ssl_match_hostname/__init__.py b/collectors/python.d.plugin/python_modules/urllib3/packages/ssl_match_hostname/__init__.py
index d6594eb26..2aeeeff91 100644
--- a/python.d/python_modules/urllib3/packages/ssl_match_hostname/__init__.py
+++ b/collectors/python.d.plugin/python_modules/urllib3/packages/ssl_match_hostname/__init__.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
import sys
try:
diff --git a/python.d/python_modules/urllib3/packages/ssl_match_hostname/_implementation.py b/collectors/python.d.plugin/python_modules/urllib3/packages/ssl_match_hostname/_implementation.py
index 1fd42f38a..647e081da 100644
--- a/python.d/python_modules/urllib3/packages/ssl_match_hostname/_implementation.py
+++ b/collectors/python.d.plugin/python_modules/urllib3/packages/ssl_match_hostname/_implementation.py
@@ -1,7 +1,6 @@
"""The match_hostname() function from Python 3.3.3, essential when using SSL."""
-# Note: This file is under the PSF license as the code comes from the python
-# stdlib. http://docs.python.org/3/license.html
+# SPDX-License-Identifier: Python-2.0
import re
import sys
diff --git a/python.d/python_modules/urllib3/poolmanager.py b/collectors/python.d.plugin/python_modules/urllib3/poolmanager.py
index 4ae91744d..adea9bc01 100644
--- a/python.d/python_modules/urllib3/poolmanager.py
+++ b/collectors/python.d.plugin/python_modules/urllib3/poolmanager.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
from __future__ import absolute_import
import collections
import functools
diff --git a/python.d/python_modules/urllib3/request.py b/collectors/python.d.plugin/python_modules/urllib3/request.py
index c0fddff04..f78331975 100644
--- a/python.d/python_modules/urllib3/request.py
+++ b/collectors/python.d.plugin/python_modules/urllib3/request.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
from __future__ import absolute_import
from .filepost import encode_multipart_formdata
diff --git a/python.d/python_modules/urllib3/response.py b/collectors/python.d.plugin/python_modules/urllib3/response.py
index 408d9996a..cf14a3076 100644
--- a/python.d/python_modules/urllib3/response.py
+++ b/collectors/python.d.plugin/python_modules/urllib3/response.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
from __future__ import absolute_import
from contextlib import contextmanager
import zlib
diff --git a/python.d/python_modules/urllib3/util/__init__.py b/collectors/python.d.plugin/python_modules/urllib3/util/__init__.py
index 2f2770b62..bba628d98 100644
--- a/python.d/python_modules/urllib3/util/__init__.py
+++ b/collectors/python.d.plugin/python_modules/urllib3/util/__init__.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
from __future__ import absolute_import
# For backwards compatibility, provide imports that used to be here.
from .connection import is_connection_dropped
diff --git a/python.d/python_modules/urllib3/util/connection.py b/collectors/python.d.plugin/python_modules/urllib3/util/connection.py
index bf699cfd0..3bd69e8fa 100644
--- a/python.d/python_modules/urllib3/util/connection.py
+++ b/collectors/python.d.plugin/python_modules/urllib3/util/connection.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
from __future__ import absolute_import
import socket
from .wait import wait_for_read
diff --git a/python.d/python_modules/urllib3/util/request.py b/collectors/python.d.plugin/python_modules/urllib3/util/request.py
index 3ddfcd559..18f27b032 100644
--- a/python.d/python_modules/urllib3/util/request.py
+++ b/collectors/python.d.plugin/python_modules/urllib3/util/request.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
from __future__ import absolute_import
from base64 import b64encode
diff --git a/python.d/python_modules/urllib3/util/response.py b/collectors/python.d.plugin/python_modules/urllib3/util/response.py
index 67cf730ab..e4cda93d4 100644
--- a/python.d/python_modules/urllib3/util/response.py
+++ b/collectors/python.d.plugin/python_modules/urllib3/util/response.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
from __future__ import absolute_import
from ..packages.six.moves import http_client as httplib
diff --git a/python.d/python_modules/urllib3/util/retry.py b/collectors/python.d.plugin/python_modules/urllib3/util/retry.py
index c603cb490..61e63afec 100644
--- a/python.d/python_modules/urllib3/util/retry.py
+++ b/collectors/python.d.plugin/python_modules/urllib3/util/retry.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
from __future__ import absolute_import
import time
import logging
diff --git a/python.d/python_modules/urllib3/util/selectors.py b/collectors/python.d.plugin/python_modules/urllib3/util/selectors.py
index d75cb266b..c0997b1a2 100644
--- a/python.d/python_modules/urllib3/util/selectors.py
+++ b/collectors/python.d.plugin/python_modules/urllib3/util/selectors.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
# Backport of selectors.py from Python 3.5+ to support Python < 3.4
# Also has the behavior specified in PEP 475 which is to retry syscalls
# in the case of an EINTR error. This module is required because selectors34
diff --git a/python.d/python_modules/urllib3/util/ssl_.py b/collectors/python.d.plugin/python_modules/urllib3/util/ssl_.py
index 33d428ed8..ece3ec39e 100644
--- a/python.d/python_modules/urllib3/util/ssl_.py
+++ b/collectors/python.d.plugin/python_modules/urllib3/util/ssl_.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
from __future__ import absolute_import
import errno
import warnings
diff --git a/python.d/python_modules/urllib3/util/timeout.py b/collectors/python.d.plugin/python_modules/urllib3/util/timeout.py
index cec817e6e..4041cf9b9 100644
--- a/python.d/python_modules/urllib3/util/timeout.py
+++ b/collectors/python.d.plugin/python_modules/urllib3/util/timeout.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
from __future__ import absolute_import
# The default socket timeout, used by httplib to indicate that no timeout was
# specified by the user
diff --git a/python.d/python_modules/urllib3/util/url.py b/collectors/python.d.plugin/python_modules/urllib3/util/url.py
index 6b6f9968d..99fd6534a 100644
--- a/python.d/python_modules/urllib3/util/url.py
+++ b/collectors/python.d.plugin/python_modules/urllib3/util/url.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
from __future__ import absolute_import
from collections import namedtuple
diff --git a/python.d/python_modules/urllib3/util/wait.py b/collectors/python.d.plugin/python_modules/urllib3/util/wait.py
index cb396e508..21e72979c 100644
--- a/python.d/python_modules/urllib3/util/wait.py
+++ b/collectors/python.d.plugin/python_modules/urllib3/util/wait.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: MIT
from .selectors import (
HAS_SELECT,
DefaultSelector,