From 277754bf314d88239e18b93ab0c3e35b2809f1b2 Mon Sep 17 00:00:00 2001 From: Pascal Zimmermann Date: Wed, 5 Oct 2022 00:07:28 +0200 Subject: [PATCH 1/6] feat: Add first version of the MTLS feature --- CHANGELOG.md | 1 + README.rst | 6 +++++ influxdb_client/_async/rest.py | 22 +++++++++++-------- influxdb_client/_sync/rest.py | 6 +++++ influxdb_client/client/_base.py | 21 ++++++++++++++++++ influxdb_client/client/influxdb_client.py | 6 +++++ .../client/influxdb_client_async.py | 3 +++ influxdb_client/configuration.py | 5 +++++ 8 files changed, 61 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index afafbe49..45448b75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ### Features 1. [#510](https://github.com/influxdata/influxdb-client-python/pull/510): Allow to use client's optional configs for initialization from file or environment properties +2. [#509](https://github.com/influxdata/influxdb-client-python/pull/509): MTLS support for the InfluxDB Python client ### Bug Fixes 1. [#512](https://github.com/influxdata/influxdb-client-python/pull/512): Exception propagation for asynchronous `QueryApi` [async/await] diff --git a/README.rst b/README.rst index 6d4358fb..66bc2186 100644 --- a/README.rst +++ b/README.rst @@ -197,6 +197,9 @@ The following options are supported: - ``timeout`` - socket timeout in ms (default value is 10000) - ``verify_ssl`` - set this to false to skip verifying SSL certificate when calling API from https server - ``ssl_ca_cert`` - set this to customize the certificate file to verify the peer +- ``cert_file`` - set this to customize the certificate client certificate file +- ``key_file`` - set this to customize the certificate client key file +- ``key_password`` - set this to customize the certificate client key file password - ``connection_pool_maxsize`` - set the number of connections to save that can be reused by urllib3 - ``auth_basic`` - enable http basic authentication when talking to a InfluxDB 1.8.x without authentication but is accessed via reverse proxy with basic authentication (defaults to false) - ``profilers`` - set the list of enabled `Flux profilers `_ @@ -226,6 +229,9 @@ Supported properties are: - ``INFLUXDB_V2_TIMEOUT`` - socket timeout in ms (default value is 10000) - ``INFLUXDB_V2_VERIFY_SSL`` - set this to false to skip verifying SSL certificate when calling API from https server - ``INFLUXDB_V2_SSL_CA_CERT`` - set this to customize the certificate file to verify the peer +- ``INFLUXDB_V2_CERT_FILE`` - set this to customize the certificate client certificate file +- ``INFLUXDB_V2_KEY_FILE`` - set this to customize the certificate client key file +- ``INFLUXDB_V2_KEY_PASSWORD`` - set this to customize the certificate client key file password - ``INFLUXDB_V2_CONNECTION_POOL_MAXSIZE`` - set the number of connections to save that can be reused by urllib3 - ``INFLUXDB_V2_AUTH_BASIC`` - enable http basic authentication when talking to a InfluxDB 1.8.x without authentication but is accessed via reverse proxy with basic authentication (defaults to false) - ``INFLUXDB_V2_PROFILERS`` - set the list of enabled `Flux profilers `_ diff --git a/influxdb_client/_async/rest.py b/influxdb_client/_async/rest.py index dcf678d0..da6cbbc0 100644 --- a/influxdb_client/_async/rest.py +++ b/influxdb_client/_async/rest.py @@ -83,15 +83,19 @@ def __init__(self, configuration, pools_size=4, maxsize=None, **kwargs): if maxsize is None: maxsize = configuration.connection_pool_maxsize - ssl_context = ssl.create_default_context(cafile=configuration.ssl_ca_cert) - if configuration.cert_file: - ssl_context.load_cert_chain( - configuration.cert_file, keyfile=configuration.key_file - ) - - if not configuration.verify_ssl: - ssl_context.check_hostname = False - ssl_context.verify_mode = ssl.CERT_NONE + if configuration.ssl_context is None: + ssl_context = ssl.create_default_context(cafile=configuration.ssl_ca_cert) + if configuration.cert_file: + ssl_context.load_cert_chain( + certfile=configuration.cert_file, keyfile=configuration.key_file, + password=configuration.key_password + ) + + if not configuration.verify_ssl: + ssl_context.check_hostname = False + ssl_context.verify_mode = ssl.CERT_NONE + else: + ssl_context = configuration.ssl_context connector = aiohttp.TCPConnector( limit=maxsize, diff --git a/influxdb_client/_sync/rest.py b/influxdb_client/_sync/rest.py index d3ac55c6..39beb07f 100644 --- a/influxdb_client/_sync/rest.py +++ b/influxdb_client/_sync/rest.py @@ -93,6 +93,8 @@ def __init__(self, configuration, pools_size=4, maxsize=None, retries=False): else: maxsize = 4 + # TODO Test the context option + # https pool manager if configuration.proxy: self.pool_manager = urllib3.ProxyManager( @@ -102,8 +104,10 @@ def __init__(self, configuration, pools_size=4, maxsize=None, retries=False): ca_certs=ca_certs, cert_file=configuration.cert_file, key_file=configuration.key_file, + key_password=configuration.key_password, proxy_url=configuration.proxy, proxy_headers=configuration.proxy_headers, + ssl_context=configuration.ssl_context, **addition_pool_args ) else: @@ -114,6 +118,8 @@ def __init__(self, configuration, pools_size=4, maxsize=None, retries=False): ca_certs=ca_certs, cert_file=configuration.cert_file, key_file=configuration.key_file, + key_password=configuration.key_password, + ssl_context=configuration.ssl_context, **addition_pool_args ) diff --git a/influxdb_client/client/_base.py b/influxdb_client/client/_base.py index 95aef3db..2c100241 100644 --- a/influxdb_client/client/_base.py +++ b/influxdb_client/client/_base.py @@ -60,6 +60,10 @@ def __init__(self, url, token, debug=None, timeout=10_000, enable_gzip=False, or self.conf.enable_gzip = enable_gzip self.conf.verify_ssl = kwargs.get('verify_ssl', True) self.conf.ssl_ca_cert = kwargs.get('ssl_ca_cert', None) + self.conf.cert_file = kwargs.get('cert_file', None) + self.conf.key_file = kwargs.get('key_file', None) + self.conf.key_password = kwargs.get('key_password', None) + self.conf.ssl_context = kwargs.get('ssl_context', None) self.conf.proxy = kwargs.get('proxy', None) self.conf.proxy_headers = kwargs.get('proxy_headers', None) self.conf.connection_pool_maxsize = kwargs.get('connection_pool_maxsize', self.conf.connection_pool_maxsize) @@ -142,6 +146,18 @@ def _has_section(key: str): if _has_option('ssl_ca_cert'): ssl_ca_cert = _config_value('ssl_ca_cert') + cert_file = None + if _has_option('cert_file'): + cert_file = _config_value('cert_file') + + key_file = None + if _has_option('key_file'): + key_file = _config_value('key_file') + + key_password = None + if _has_option('key_password'): + key_password = _config_value('key_password') + connection_pool_maxsize = None if _has_option('connection_pool_maxsize'): connection_pool_maxsize = _config_value('connection_pool_maxsize') @@ -168,6 +184,7 @@ def _has_section(key: str): return cls(url, token, debug=debug, timeout=_to_int(timeout), org=org, default_tags=default_tags, enable_gzip=enable_gzip, verify_ssl=_to_bool(verify_ssl), ssl_ca_cert=ssl_ca_cert, + cert_file=cert_file, key_file=key_file, key_password=key_password, connection_pool_maxsize=_to_int(connection_pool_maxsize), auth_basic=_to_bool(auth_basic), profilers=profilers, proxy=proxy, **kwargs) @@ -179,6 +196,9 @@ def _from_env_properties(cls, debug=None, enable_gzip=False, **kwargs): org = os.getenv('INFLUXDB_V2_ORG', "my-org") verify_ssl = os.getenv('INFLUXDB_V2_VERIFY_SSL', "True") ssl_ca_cert = os.getenv('INFLUXDB_V2_SSL_CA_CERT', None) + cert_file = os.getenv('INFLUXDB_V2_CERT_FILE', None) + key_file = os.getenv('INFLUXDB_V2_KEY_FILE', None) + key_password = os.getenv('INFLUXDB_V2_KEY_PASSWORD', None) connection_pool_maxsize = os.getenv('INFLUXDB_V2_CONNECTION_POOL_MAXSIZE', None) auth_basic = os.getenv('INFLUXDB_V2_AUTH_BASIC', "False") @@ -195,6 +215,7 @@ def _from_env_properties(cls, debug=None, enable_gzip=False, **kwargs): return cls(url, token, debug=debug, timeout=_to_int(timeout), org=org, default_tags=default_tags, enable_gzip=enable_gzip, verify_ssl=_to_bool(verify_ssl), ssl_ca_cert=ssl_ca_cert, + cert_file=cert_file, key_file=key_file, key_password=key_password, connection_pool_maxsize=_to_int(connection_pool_maxsize), auth_basic=_to_bool(auth_basic), profilers=profilers, **kwargs) diff --git a/influxdb_client/client/influxdb_client.py b/influxdb_client/client/influxdb_client.py index 042087da..6941aedd 100644 --- a/influxdb_client/client/influxdb_client.py +++ b/influxdb_client/client/influxdb_client.py @@ -102,6 +102,9 @@ def from_config_file(cls, config_file: str = "config.ini", debug=None, enable_gz - timeout, - verify_ssl - ssl_ca_cert + - cert_file + - key_file + - key_password - connection_pool_maxsize - auth_basic - profilers @@ -185,6 +188,9 @@ def from_env_properties(cls, debug=None, enable_gzip=False, **kwargs): - INFLUXDB_V2_TIMEOUT - INFLUXDB_V2_VERIFY_SSL - INFLUXDB_V2_SSL_CA_CERT + - INFLUXDB_V2_CERT_FILE + - INFLUXDB_V2_KEY_FILE + - INFLUXDB_V2_KEY_PASSWORD - INFLUXDB_V2_CONNECTION_POOL_MAXSIZE - INFLUXDB_V2_AUTH_BASIC - INFLUXDB_V2_PROFILERS diff --git a/influxdb_client/client/influxdb_client_async.py b/influxdb_client/client/influxdb_client_async.py index cdd8eade..d7369a66 100644 --- a/influxdb_client/client/influxdb_client_async.py +++ b/influxdb_client/client/influxdb_client_async.py @@ -201,6 +201,9 @@ def from_env_properties(cls, debug=None, enable_gzip=False, **kwargs): - INFLUXDB_V2_TIMEOUT - INFLUXDB_V2_VERIFY_SSL - INFLUXDB_V2_SSL_CA_CERT + - INFLUXDB_V2_CERT_FILE + - INFLUXDB_V2_KEY_FILE + - INFLUXDB_V2_KEY_PASSWORD - INFLUXDB_V2_CONNECTION_POOL_MAXSIZE - INFLUXDB_V2_AUTH_BASIC - INFLUXDB_V2_PROFILERS diff --git a/influxdb_client/configuration.py b/influxdb_client/configuration.py index e9d95c78..aedcf17b 100644 --- a/influxdb_client/configuration.py +++ b/influxdb_client/configuration.py @@ -90,9 +90,14 @@ def __init__(self): self.cert_file = None # client key file self.key_file = None + # client key file password + self.key_password = None # Set this to True/False to enable/disable SSL hostname verification. self.assert_hostname = None + # Set this to specify a custom ssl context to inject this context inside the urllib3 connection pool. + self.ssl_context = None + # urllib3 connection pool's maximum number of connections saved # per pool. urllib3 uses 1 connection as default value, but this is # not the best value when you are making a lot of possibly parallel From cbcc7d160af1d84aef82559d704286d4faba7f48 Mon Sep 17 00:00:00 2001 From: Pascal Zimmermann Date: Fri, 7 Oct 2022 15:22:34 +0200 Subject: [PATCH 2/6] feat: Add new unittests --- tests/config-ssl-mtls-certs.ini | 14 +++++++ tests/test_InfluxDBClient.py | 69 +++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 tests/config-ssl-mtls-certs.ini diff --git a/tests/config-ssl-mtls-certs.ini b/tests/config-ssl-mtls-certs.ini new file mode 100644 index 00000000..637e2f7f --- /dev/null +++ b/tests/config-ssl-mtls-certs.ini @@ -0,0 +1,14 @@ +[influx2] +url=http://localhost:8086 +org=my-org +token=my-token +timeout=6000 +ssl_ca_cert=/path/to/my/cert +cert_file=/path/to/my/cert +key_file=/path/to/my/key +key_password=test + +[tags] +id = 132-987-655 +customer = California Miner +data_center = ${env.data_center} \ No newline at end of file diff --git a/tests/test_InfluxDBClient.py b/tests/test_InfluxDBClient.py index c4b9b2a5..d807ca4a 100644 --- a/tests/test_InfluxDBClient.py +++ b/tests/test_InfluxDBClient.py @@ -141,6 +141,75 @@ def test_init_from_env_ssl_ca_cert(self): self.assertEqual("/my/custom/path/to/cert", self.client.api_client.configuration.ssl_ca_cert) + def test_init_from_env_ssl_cert_file(self): + os.environ["INFLUXDB_V2_CERT_FILE"] = "/my/custom/path" + self.client = InfluxDBClient.from_env_properties() + + self.assertEqual("/my/custom/path", self.client.api_client.configuration.cert_file) + + def test_init_from_file_ssl_cert_file_default(self): + self.client = InfluxDBClient.from_config_file(f'{os.path.dirname(__file__)}/config.ini') + + self.assertIsNone(self.client.api_client.configuration.cert_file) + + def test_init_from_file_ssl_cert_file(self): + self.client = InfluxDBClient.from_config_file(f'{os.path.dirname(__file__)}/config-ssl-mtls-certs.ini') + + self.assertEqual("/path/to/my/cert", self.client.api_client.configuration.cert_file) + + def test_init_from_env_ssl_cert_file_default(self): + if os.getenv("INFLUXDB_V2_CERT_FILE"): + del os.environ["INFLUXDB_V2_CERT_FILE"] + self.client = InfluxDBClient.from_env_properties() + + self.assertIsNone(self.client.api_client.configuration.cert_file) + + def test_init_from_env_ssl_cert_key(self): + os.environ["INFLUXDB_V2_KEY_FILE"] = "/my/custom/path" + self.client = InfluxDBClient.from_env_properties() + + self.assertEqual("/my/custom/path", self.client.api_client.configuration.key_file) + + def test_init_from_file_ssl_cert_key_default(self): + self.client = InfluxDBClient.from_config_file(f'{os.path.dirname(__file__)}/config.ini') + + self.assertIsNone(self.client.api_client.configuration.key_file) + + def test_init_from_file_ssl_cert_key(self): + self.client = InfluxDBClient.from_config_file(f'{os.path.dirname(__file__)}/config-ssl-mtls-certs.ini') + + self.assertEqual("/path/to/my/key", self.client.api_client.configuration.key_file) + + def test_init_from_env_ssl_cert_key_default(self): + if os.getenv("INFLUXDB_V2_KEY_FILE"): + del os.environ["INFLUXDB_V2_KEY_FILE"] + self.client = InfluxDBClient.from_env_properties() + + self.assertIsNone(self.client.api_client.configuration.key_file) + + def test_init_from_env_ssl_key_password(self): + os.environ["INFLUXDB_V2_KEY_PASSWORD"] = "test" + self.client = InfluxDBClient.from_env_properties() + + self.assertEqual("test", self.client.api_client.configuration.key_password) + + def test_init_from_file_ssl_key_password_default(self): + self.client = InfluxDBClient.from_config_file(f'{os.path.dirname(__file__)}/config.ini') + + self.assertIsNone(self.client.api_client.configuration.key_password) + + def test_init_from_file_ssl_key_password(self): + self.client = InfluxDBClient.from_config_file(f'{os.path.dirname(__file__)}/config-ssl-mtls-certs.ini') + + self.assertEqual("test", self.client.api_client.configuration.key_password) + + def test_init_from_env_ssl_key_password_default(self): + if os.getenv("INFLUXDB_V2_KEY_PASSWORD"): + del os.environ["INFLUXDB_V2_KEY_PASSWORD"] + self.client = InfluxDBClient.from_env_properties() + + self.assertIsNone(self.client.api_client.configuration.key_password) + def test_init_from_env_connection_pool_maxsize(self): os.environ["INFLUXDB_V2_CONNECTION_POOL_MAXSIZE"] = "29" self.client = InfluxDBClient.from_env_properties() From 9fdf2cbb001c8d9a0a0c463dbd0157a9cc17f935 Mon Sep 17 00:00:00 2001 From: Pascal Zimmermann Date: Fri, 7 Oct 2022 15:34:40 +0200 Subject: [PATCH 3/6] feat: Add a specific tls context test case --- influxdb_client/_sync/rest.py | 2 -- tests/test_InfluxDBClient.py | 13 +++++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/influxdb_client/_sync/rest.py b/influxdb_client/_sync/rest.py index 39beb07f..c2f8de4b 100644 --- a/influxdb_client/_sync/rest.py +++ b/influxdb_client/_sync/rest.py @@ -93,8 +93,6 @@ def __init__(self, configuration, pools_size=4, maxsize=None, retries=False): else: maxsize = 4 - # TODO Test the context option - # https pool manager if configuration.proxy: self.pool_manager = urllib3.ProxyManager( diff --git a/tests/test_InfluxDBClient.py b/tests/test_InfluxDBClient.py index d807ca4a..39ed417c 100644 --- a/tests/test_InfluxDBClient.py +++ b/tests/test_InfluxDBClient.py @@ -3,6 +3,7 @@ import json import logging import os +import ssl import threading import unittest from io import StringIO @@ -57,6 +58,18 @@ def test_certificate_file(self): self.assertTrue(ping) + def test_certificate_context(self): + self._start_http_server() + + ssl_context = ssl.create_default_context(cafile=f"{os.path.dirname(__file__)}/server.pem") + + self.client = InfluxDBClient(f"https://localhost:{self.httpd.server_address[1]}", + token="my-token", verify_ssl=True, + ssl_context=ssl_context) + ping = self.client.ping() + + self.assertTrue(ping) + def test_init_from_ini_file(self): self.client = InfluxDBClient.from_config_file(f'{os.path.dirname(__file__)}/config.ini') From c7fee74269e63662dec3bb07ab5f47dca59d22ef Mon Sep 17 00:00:00 2001 From: Pascal Zimmermann Date: Tue, 11 Oct 2022 20:27:23 +0200 Subject: [PATCH 4/6] feat: Update the documentation and rename the MTLS variables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BREAKING CHANGE: Rename `key_file` to `cert_key_file` inside the central configuration class Co-authored-by: Jakub Bednář --- CHANGELOG.md | 3 ++ README.rst | 12 ++++---- influxdb_client/_async/rest.py | 4 +-- influxdb_client/_sync/rest.py | 8 ++--- influxdb_client/client/_base.py | 24 +++++++-------- influxdb_client/client/influxdb_client.py | 30 ++++++++++++++++--- .../client/influxdb_client_async.py | 30 +++++++++++++++++-- influxdb_client/configuration.py | 4 +-- tests/config-ssl-mtls-certs.ini | 4 +-- tests/test_InfluxDBClient.py | 28 ++++++++--------- 10 files changed, 99 insertions(+), 48 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 45448b75..49414822 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ ### Bug Fixes 1. [#512](https://github.com/influxdata/influxdb-client-python/pull/512): Exception propagation for asynchronous `QueryApi` [async/await] +### Breaking Changes +1. [#509](https://github.com/influxdata/influxdb-client-python/pull/509): Rename `key_file` to `cert_key_file` inside the central [configuration class](https://github.com/influxdata/influxdb-client-python/blob/d011df72b528a45d305aa8accbe879b31be3280e/influxdb_client/configuration.py#L92) + ## 1.33.0 [2022-09-29] ### Features diff --git a/README.rst b/README.rst index 66bc2186..88e05c16 100644 --- a/README.rst +++ b/README.rst @@ -197,9 +197,9 @@ The following options are supported: - ``timeout`` - socket timeout in ms (default value is 10000) - ``verify_ssl`` - set this to false to skip verifying SSL certificate when calling API from https server - ``ssl_ca_cert`` - set this to customize the certificate file to verify the peer -- ``cert_file`` - set this to customize the certificate client certificate file -- ``key_file`` - set this to customize the certificate client key file -- ``key_password`` - set this to customize the certificate client key file password +- ``cert_file`` - path to the certificate that will be used for mTLS authentication +- ``cert_key_file`` - path to the file contains private key for mTLS certificate +- ``cert_key_password`` - string or function which returns password for decrypting the mTLS private key - ``connection_pool_maxsize`` - set the number of connections to save that can be reused by urllib3 - ``auth_basic`` - enable http basic authentication when talking to a InfluxDB 1.8.x without authentication but is accessed via reverse proxy with basic authentication (defaults to false) - ``profilers`` - set the list of enabled `Flux profilers `_ @@ -229,9 +229,9 @@ Supported properties are: - ``INFLUXDB_V2_TIMEOUT`` - socket timeout in ms (default value is 10000) - ``INFLUXDB_V2_VERIFY_SSL`` - set this to false to skip verifying SSL certificate when calling API from https server - ``INFLUXDB_V2_SSL_CA_CERT`` - set this to customize the certificate file to verify the peer -- ``INFLUXDB_V2_CERT_FILE`` - set this to customize the certificate client certificate file -- ``INFLUXDB_V2_KEY_FILE`` - set this to customize the certificate client key file -- ``INFLUXDB_V2_KEY_PASSWORD`` - set this to customize the certificate client key file password +- ``INFLUXDB_V2_CERT_FILE`` - path to the certificate that will be used for mTLS authentication +- ``INFLUXDB_V2_CERT_KEY_FILE`` - path to the file contains private key for mTLS certificate +- ``INFLUXDB_V2_CERT_KEY_PASSWORD`` - string or function which returns password for decrypting the mTLS private key - ``INFLUXDB_V2_CONNECTION_POOL_MAXSIZE`` - set the number of connections to save that can be reused by urllib3 - ``INFLUXDB_V2_AUTH_BASIC`` - enable http basic authentication when talking to a InfluxDB 1.8.x without authentication but is accessed via reverse proxy with basic authentication (defaults to false) - ``INFLUXDB_V2_PROFILERS`` - set the list of enabled `Flux profilers `_ diff --git a/influxdb_client/_async/rest.py b/influxdb_client/_async/rest.py index da6cbbc0..8db95e91 100644 --- a/influxdb_client/_async/rest.py +++ b/influxdb_client/_async/rest.py @@ -87,8 +87,8 @@ def __init__(self, configuration, pools_size=4, maxsize=None, **kwargs): ssl_context = ssl.create_default_context(cafile=configuration.ssl_ca_cert) if configuration.cert_file: ssl_context.load_cert_chain( - certfile=configuration.cert_file, keyfile=configuration.key_file, - password=configuration.key_password + certfile=configuration.cert_file, keyfile=configuration.cert_key_file, + password=configuration.cert_key_password ) if not configuration.verify_ssl: diff --git a/influxdb_client/_sync/rest.py b/influxdb_client/_sync/rest.py index c2f8de4b..bac94f9e 100644 --- a/influxdb_client/_sync/rest.py +++ b/influxdb_client/_sync/rest.py @@ -101,8 +101,8 @@ def __init__(self, configuration, pools_size=4, maxsize=None, retries=False): cert_reqs=cert_reqs, ca_certs=ca_certs, cert_file=configuration.cert_file, - key_file=configuration.key_file, - key_password=configuration.key_password, + key_file=configuration.cert_key_file, + key_password=configuration.cert_key_password, proxy_url=configuration.proxy, proxy_headers=configuration.proxy_headers, ssl_context=configuration.ssl_context, @@ -115,8 +115,8 @@ def __init__(self, configuration, pools_size=4, maxsize=None, retries=False): cert_reqs=cert_reqs, ca_certs=ca_certs, cert_file=configuration.cert_file, - key_file=configuration.key_file, - key_password=configuration.key_password, + key_file=configuration.cert_key_file, + key_password=configuration.cert_key_password, ssl_context=configuration.ssl_context, **addition_pool_args ) diff --git a/influxdb_client/client/_base.py b/influxdb_client/client/_base.py index 2c100241..de2910da 100644 --- a/influxdb_client/client/_base.py +++ b/influxdb_client/client/_base.py @@ -61,8 +61,8 @@ def __init__(self, url, token, debug=None, timeout=10_000, enable_gzip=False, or self.conf.verify_ssl = kwargs.get('verify_ssl', True) self.conf.ssl_ca_cert = kwargs.get('ssl_ca_cert', None) self.conf.cert_file = kwargs.get('cert_file', None) - self.conf.key_file = kwargs.get('key_file', None) - self.conf.key_password = kwargs.get('key_password', None) + self.conf.cert_key_file = kwargs.get('cert_key_file', None) + self.conf.cert_key_password = kwargs.get('cert_key_password', None) self.conf.ssl_context = kwargs.get('ssl_context', None) self.conf.proxy = kwargs.get('proxy', None) self.conf.proxy_headers = kwargs.get('proxy_headers', None) @@ -150,13 +150,13 @@ def _has_section(key: str): if _has_option('cert_file'): cert_file = _config_value('cert_file') - key_file = None - if _has_option('key_file'): - key_file = _config_value('key_file') + cert_key_file = None + if _has_option('cert_key_file'): + cert_key_file = _config_value('cert_key_file') - key_password = None - if _has_option('key_password'): - key_password = _config_value('key_password') + cert_key_password = None + if _has_option('cert_key_password'): + cert_key_password = _config_value('cert_key_password') connection_pool_maxsize = None if _has_option('connection_pool_maxsize'): @@ -184,7 +184,7 @@ def _has_section(key: str): return cls(url, token, debug=debug, timeout=_to_int(timeout), org=org, default_tags=default_tags, enable_gzip=enable_gzip, verify_ssl=_to_bool(verify_ssl), ssl_ca_cert=ssl_ca_cert, - cert_file=cert_file, key_file=key_file, key_password=key_password, + cert_file=cert_file, cert_key_file=cert_key_file, cert_key_password=cert_key_password, connection_pool_maxsize=_to_int(connection_pool_maxsize), auth_basic=_to_bool(auth_basic), profilers=profilers, proxy=proxy, **kwargs) @@ -197,8 +197,8 @@ def _from_env_properties(cls, debug=None, enable_gzip=False, **kwargs): verify_ssl = os.getenv('INFLUXDB_V2_VERIFY_SSL', "True") ssl_ca_cert = os.getenv('INFLUXDB_V2_SSL_CA_CERT', None) cert_file = os.getenv('INFLUXDB_V2_CERT_FILE', None) - key_file = os.getenv('INFLUXDB_V2_KEY_FILE', None) - key_password = os.getenv('INFLUXDB_V2_KEY_PASSWORD', None) + cert_key_file = os.getenv('INFLUXDB_V2_CERT_KEY_FILE', None) + cert_key_password = os.getenv('INFLUXDB_V2_CERT_KEY_PASSWORD', None) connection_pool_maxsize = os.getenv('INFLUXDB_V2_CONNECTION_POOL_MAXSIZE', None) auth_basic = os.getenv('INFLUXDB_V2_AUTH_BASIC', "False") @@ -215,7 +215,7 @@ def _from_env_properties(cls, debug=None, enable_gzip=False, **kwargs): return cls(url, token, debug=debug, timeout=_to_int(timeout), org=org, default_tags=default_tags, enable_gzip=enable_gzip, verify_ssl=_to_bool(verify_ssl), ssl_ca_cert=ssl_ca_cert, - cert_file=cert_file, key_file=key_file, key_password=key_password, + cert_file=cert_file, cert_key_file=cert_key_file, cert_key_password=cert_key_password, connection_pool_maxsize=_to_int(connection_pool_maxsize), auth_basic=_to_bool(auth_basic), profilers=profilers, **kwargs) diff --git a/influxdb_client/client/influxdb_client.py b/influxdb_client/client/influxdb_client.py index 6941aedd..ff45ff73 100644 --- a/influxdb_client/client/influxdb_client.py +++ b/influxdb_client/client/influxdb_client.py @@ -40,6 +40,12 @@ def __init__(self, url, token: str = None, debug=None, timeout=10_000, enable_gz :param org: organization name (used as a default in Query, Write and Delete API) :key bool verify_ssl: Set this to false to skip verifying SSL certificate when calling API from https server. :key str ssl_ca_cert: Set this to customize the certificate file to verify the peer. + :key str cert_file: Path to the certificate that will be used for mTLS authentication. + :key str cert_key_file: Path to the file contains private key for mTLS certificate. + :key str cert_key_password: String or function which returns password for decrypting the mTLS private key. + :key ssl.SSLContext ssl_context: Specify a custom Python SSL Context for the TLS/ mTLS handshake. + Be aware that only delivered certificate/ key files or an SSL Context are + possible. :key str proxy: Set this to configure the http proxy to be used (ex. http://localhost:3128) :key str proxy_headers: A dictionary containing headers that will be sent to the proxy. Could be used for proxy authentication. @@ -89,6 +95,14 @@ def from_config_file(cls, config_file: str = "config.ini", debug=None, enable_gz authentication. :key urllib3.util.retry.Retry retries: Set the default retry strategy that is used for all HTTP requests except batching writes. As a default there is no one retry strategy. + :key bool verify_ssl: Set this to false to skip verifying SSL certificate when calling API from https server. + :key str ssl_ca_cert: Set this to customize the certificate file to verify the peer. + :key str cert_file: Path to the certificate that will be used for mTLS authentication. + :key str cert_key_file: Path to the file contains private key for mTLS certificate. + :key str cert_key_password: String or function which returns password for decrypting the mTLS private key. + :key ssl.SSLContext ssl_context: Specify a custom Python SSL Context for the TLS/ mTLS handshake. + Be aware that only delivered certificate/ key files or an SSL Context are + possible. The supported formats: - https://docs.python.org/3/library/configparser.html @@ -103,8 +117,8 @@ def from_config_file(cls, config_file: str = "config.ini", debug=None, enable_gz - verify_ssl - ssl_ca_cert - cert_file - - key_file - - key_password + - cert_key_file + - cert_key_password - connection_pool_maxsize - auth_basic - profilers @@ -180,6 +194,14 @@ def from_env_properties(cls, debug=None, enable_gzip=False, **kwargs): authentication. :key urllib3.util.retry.Retry retries: Set the default retry strategy that is used for all HTTP requests except batching writes. As a default there is no one retry strategy. + :key bool verify_ssl: Set this to false to skip verifying SSL certificate when calling API from https server. + :key str ssl_ca_cert: Set this to customize the certificate file to verify the peer. + :key str cert_file: Path to the certificate that will be used for mTLS authentication. + :key str cert_key_file: Path to the file contains private key for mTLS certificate. + :key str cert_key_password: String or function which returns password for decrypting the mTLS private key. + :key ssl.SSLContext ssl_context: Specify a custom Python SSL Context for the TLS/ mTLS handshake. + Be aware that only delivered certificate/ key files or an SSL Context are + possible. Supported environment properties: - INFLUXDB_V2_URL @@ -189,8 +211,8 @@ def from_env_properties(cls, debug=None, enable_gzip=False, **kwargs): - INFLUXDB_V2_VERIFY_SSL - INFLUXDB_V2_SSL_CA_CERT - INFLUXDB_V2_CERT_FILE - - INFLUXDB_V2_KEY_FILE - - INFLUXDB_V2_KEY_PASSWORD + - INFLUXDB_V2_CERT_KEY_FILE + - INFLUXDB_V2_CERT_KEY_PASSWORD - INFLUXDB_V2_CONNECTION_POOL_MAXSIZE - INFLUXDB_V2_AUTH_BASIC - INFLUXDB_V2_PROFILERS diff --git a/influxdb_client/client/influxdb_client_async.py b/influxdb_client/client/influxdb_client_async.py index d7369a66..ba51a7f4 100644 --- a/influxdb_client/client/influxdb_client_async.py +++ b/influxdb_client/client/influxdb_client_async.py @@ -32,6 +32,12 @@ def __init__(self, url, token: str = None, org: str = None, debug=None, timeout= supports the Gzip compression. :key bool verify_ssl: Set this to false to skip verifying SSL certificate when calling API from https server. :key str ssl_ca_cert: Set this to customize the certificate file to verify the peer. + :key str cert_file: Path to the certificate that will be used for mTLS authentication. + :key str cert_key_file: Path to the file contains private key for mTLS certificate. + :key str cert_key_password: String or function which returns password for decrypting the mTLS private key. + :key ssl.SSLContext ssl_context: Specify a custom Python SSL Context for the TLS/ mTLS handshake. + Be aware that only delivered certificate/ key files or an SSL Context are + possible. :key str proxy: Set this to configure the http proxy to be used (ex. http://localhost:3128) :key str proxy_headers: A dictionary containing headers that will be sent to the proxy. Could be used for proxy authentication. @@ -105,6 +111,14 @@ def from_config_file(cls, config_file: str = "config.ini", debug=None, enable_gz authentication. :key urllib3.util.retry.Retry retries: Set the default retry strategy that is used for all HTTP requests except batching writes. As a default there is no one retry strategy. + :key bool verify_ssl: Set this to false to skip verifying SSL certificate when calling API from https server. + :key str ssl_ca_cert: Set this to customize the certificate file to verify the peer. + :key str cert_file: Path to the certificate that will be used for mTLS authentication. + :key str cert_key_file: Path to the file contains private key for mTLS certificate. + :key str cert_key_password: String or function which returns password for decrypting the mTLS private key. + :key ssl.SSLContext ssl_context: Specify a custom Python SSL Context for the TLS/ mTLS handshake. + Be aware that only delivered certificate/ key files or an SSL Context are + possible. The supported formats: - https://docs.python.org/3/library/configparser.html @@ -118,6 +132,9 @@ def from_config_file(cls, config_file: str = "config.ini", debug=None, enable_gz - timeout, - verify_ssl - ssl_ca_cert + - cert_file + - cert_key_file + - cert_key_password - connection_pool_maxsize - auth_basic - profilers @@ -193,6 +210,15 @@ def from_env_properties(cls, debug=None, enable_gzip=False, **kwargs): authentication. :key urllib3.util.retry.Retry retries: Set the default retry strategy that is used for all HTTP requests except batching writes. As a default there is no one retry strategy. + :key bool verify_ssl: Set this to false to skip verifying SSL certificate when calling API from https server. + :key str ssl_ca_cert: Set this to customize the certificate file to verify the peer. + :key str cert_file: Path to the certificate that will be used for mTLS authentication. + :key str cert_key_file: Path to the file contains private key for mTLS certificate. + :key str cert_key_password: String or function which returns password for decrypting the mTLS private key. + :key ssl.SSLContext ssl_context: Specify a custom Python SSL Context for the TLS/ mTLS handshake. + Be aware that only delivered certificate/ key files or an SSL Context are + possible. + Supported environment properties: - INFLUXDB_V2_URL @@ -202,8 +228,8 @@ def from_env_properties(cls, debug=None, enable_gzip=False, **kwargs): - INFLUXDB_V2_VERIFY_SSL - INFLUXDB_V2_SSL_CA_CERT - INFLUXDB_V2_CERT_FILE - - INFLUXDB_V2_KEY_FILE - - INFLUXDB_V2_KEY_PASSWORD + - INFLUXDB_V2_CERT_KEY_FILE + - INFLUXDB_V2_CERT_KEY_PASSWORD - INFLUXDB_V2_CONNECTION_POOL_MAXSIZE - INFLUXDB_V2_AUTH_BASIC - INFLUXDB_V2_PROFILERS diff --git a/influxdb_client/configuration.py b/influxdb_client/configuration.py index aedcf17b..3c118565 100644 --- a/influxdb_client/configuration.py +++ b/influxdb_client/configuration.py @@ -89,9 +89,9 @@ def __init__(self): # client certificate file self.cert_file = None # client key file - self.key_file = None + self.cert_key_file = None # client key file password - self.key_password = None + self.cert_key_password = None # Set this to True/False to enable/disable SSL hostname verification. self.assert_hostname = None diff --git a/tests/config-ssl-mtls-certs.ini b/tests/config-ssl-mtls-certs.ini index 637e2f7f..0b3d6360 100644 --- a/tests/config-ssl-mtls-certs.ini +++ b/tests/config-ssl-mtls-certs.ini @@ -5,8 +5,8 @@ token=my-token timeout=6000 ssl_ca_cert=/path/to/my/cert cert_file=/path/to/my/cert -key_file=/path/to/my/key -key_password=test +cert_key_file=/path/to/my/key +cert_key_password=test [tags] id = 132-987-655 diff --git a/tests/test_InfluxDBClient.py b/tests/test_InfluxDBClient.py index 39ed417c..5202d7a9 100644 --- a/tests/test_InfluxDBClient.py +++ b/tests/test_InfluxDBClient.py @@ -178,50 +178,50 @@ def test_init_from_env_ssl_cert_file_default(self): self.assertIsNone(self.client.api_client.configuration.cert_file) def test_init_from_env_ssl_cert_key(self): - os.environ["INFLUXDB_V2_KEY_FILE"] = "/my/custom/path" + os.environ["INFLUXDB_V2_CERT_KEY_FILE"] = "/my/custom/path" self.client = InfluxDBClient.from_env_properties() - self.assertEqual("/my/custom/path", self.client.api_client.configuration.key_file) + self.assertEqual("/my/custom/path", self.client.api_client.configuration.cert_key_file) def test_init_from_file_ssl_cert_key_default(self): self.client = InfluxDBClient.from_config_file(f'{os.path.dirname(__file__)}/config.ini') - self.assertIsNone(self.client.api_client.configuration.key_file) + self.assertIsNone(self.client.api_client.configuration.cert_key_file) def test_init_from_file_ssl_cert_key(self): self.client = InfluxDBClient.from_config_file(f'{os.path.dirname(__file__)}/config-ssl-mtls-certs.ini') - self.assertEqual("/path/to/my/key", self.client.api_client.configuration.key_file) + self.assertEqual("/path/to/my/key", self.client.api_client.configuration.cert_key_file) def test_init_from_env_ssl_cert_key_default(self): - if os.getenv("INFLUXDB_V2_KEY_FILE"): - del os.environ["INFLUXDB_V2_KEY_FILE"] + if os.getenv("INFLUXDB_V2_CERT_KEY_FILE"): + del os.environ["INFLUXDB_V2_CERT_KEY_FILE"] self.client = InfluxDBClient.from_env_properties() - self.assertIsNone(self.client.api_client.configuration.key_file) + self.assertIsNone(self.client.api_client.configuration.cert_key_file) def test_init_from_env_ssl_key_password(self): - os.environ["INFLUXDB_V2_KEY_PASSWORD"] = "test" + os.environ["INFLUXDB_V2_CERT_KEY_PASSWORD"] = "test" self.client = InfluxDBClient.from_env_properties() - self.assertEqual("test", self.client.api_client.configuration.key_password) + self.assertEqual("test", self.client.api_client.configuration.cert_key_password) def test_init_from_file_ssl_key_password_default(self): self.client = InfluxDBClient.from_config_file(f'{os.path.dirname(__file__)}/config.ini') - self.assertIsNone(self.client.api_client.configuration.key_password) + self.assertIsNone(self.client.api_client.configuration.cert_key_password) def test_init_from_file_ssl_key_password(self): self.client = InfluxDBClient.from_config_file(f'{os.path.dirname(__file__)}/config-ssl-mtls-certs.ini') - self.assertEqual("test", self.client.api_client.configuration.key_password) + self.assertEqual("test", self.client.api_client.configuration.cert_key_password) def test_init_from_env_ssl_key_password_default(self): - if os.getenv("INFLUXDB_V2_KEY_PASSWORD"): - del os.environ["INFLUXDB_V2_KEY_PASSWORD"] + if os.getenv("INFLUXDB_V2_CERT_KEY_PASSWORD"): + del os.environ["INFLUXDB_V2_CERT_KEY_PASSWORD"] self.client = InfluxDBClient.from_env_properties() - self.assertIsNone(self.client.api_client.configuration.key_password) + self.assertIsNone(self.client.api_client.configuration.cert_key_password) def test_init_from_env_connection_pool_maxsize(self): os.environ["INFLUXDB_V2_CONNECTION_POOL_MAXSIZE"] = "29" From dea0a56d09efd2bdc2148658babb5d2cfda55994 Mon Sep 17 00:00:00 2001 From: Pascal Zimmermann Date: Thu, 13 Oct 2022 20:54:18 +0200 Subject: [PATCH 5/6] docs: Update the docstring documentation --- influxdb_client/client/influxdb_client.py | 10 ---------- influxdb_client/client/influxdb_client_async.py | 10 ---------- 2 files changed, 20 deletions(-) diff --git a/influxdb_client/client/influxdb_client.py b/influxdb_client/client/influxdb_client.py index ff45ff73..91030774 100644 --- a/influxdb_client/client/influxdb_client.py +++ b/influxdb_client/client/influxdb_client.py @@ -95,11 +95,6 @@ def from_config_file(cls, config_file: str = "config.ini", debug=None, enable_gz authentication. :key urllib3.util.retry.Retry retries: Set the default retry strategy that is used for all HTTP requests except batching writes. As a default there is no one retry strategy. - :key bool verify_ssl: Set this to false to skip verifying SSL certificate when calling API from https server. - :key str ssl_ca_cert: Set this to customize the certificate file to verify the peer. - :key str cert_file: Path to the certificate that will be used for mTLS authentication. - :key str cert_key_file: Path to the file contains private key for mTLS certificate. - :key str cert_key_password: String or function which returns password for decrypting the mTLS private key. :key ssl.SSLContext ssl_context: Specify a custom Python SSL Context for the TLS/ mTLS handshake. Be aware that only delivered certificate/ key files or an SSL Context are possible. @@ -194,11 +189,6 @@ def from_env_properties(cls, debug=None, enable_gzip=False, **kwargs): authentication. :key urllib3.util.retry.Retry retries: Set the default retry strategy that is used for all HTTP requests except batching writes. As a default there is no one retry strategy. - :key bool verify_ssl: Set this to false to skip verifying SSL certificate when calling API from https server. - :key str ssl_ca_cert: Set this to customize the certificate file to verify the peer. - :key str cert_file: Path to the certificate that will be used for mTLS authentication. - :key str cert_key_file: Path to the file contains private key for mTLS certificate. - :key str cert_key_password: String or function which returns password for decrypting the mTLS private key. :key ssl.SSLContext ssl_context: Specify a custom Python SSL Context for the TLS/ mTLS handshake. Be aware that only delivered certificate/ key files or an SSL Context are possible. diff --git a/influxdb_client/client/influxdb_client_async.py b/influxdb_client/client/influxdb_client_async.py index ba51a7f4..96953cb3 100644 --- a/influxdb_client/client/influxdb_client_async.py +++ b/influxdb_client/client/influxdb_client_async.py @@ -111,11 +111,6 @@ def from_config_file(cls, config_file: str = "config.ini", debug=None, enable_gz authentication. :key urllib3.util.retry.Retry retries: Set the default retry strategy that is used for all HTTP requests except batching writes. As a default there is no one retry strategy. - :key bool verify_ssl: Set this to false to skip verifying SSL certificate when calling API from https server. - :key str ssl_ca_cert: Set this to customize the certificate file to verify the peer. - :key str cert_file: Path to the certificate that will be used for mTLS authentication. - :key str cert_key_file: Path to the file contains private key for mTLS certificate. - :key str cert_key_password: String or function which returns password for decrypting the mTLS private key. :key ssl.SSLContext ssl_context: Specify a custom Python SSL Context for the TLS/ mTLS handshake. Be aware that only delivered certificate/ key files or an SSL Context are possible. @@ -210,11 +205,6 @@ def from_env_properties(cls, debug=None, enable_gzip=False, **kwargs): authentication. :key urllib3.util.retry.Retry retries: Set the default retry strategy that is used for all HTTP requests except batching writes. As a default there is no one retry strategy. - :key bool verify_ssl: Set this to false to skip verifying SSL certificate when calling API from https server. - :key str ssl_ca_cert: Set this to customize the certificate file to verify the peer. - :key str cert_file: Path to the certificate that will be used for mTLS authentication. - :key str cert_key_file: Path to the file contains private key for mTLS certificate. - :key str cert_key_password: String or function which returns password for decrypting the mTLS private key. :key ssl.SSLContext ssl_context: Specify a custom Python SSL Context for the TLS/ mTLS handshake. Be aware that only delivered certificate/ key files or an SSL Context are possible. From ab43523d275e7f7fde2f94a3b19f9c836953f18d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Bedn=C3=A1=C5=99?= Date: Fri, 14 Oct 2022 13:54:48 +0200 Subject: [PATCH 6/6] docs: update CHANGELOG.md --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 49414822..4723457e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ ## 1.34.0 [unreleased] +### Breaking Changes +1. [#509](https://github.com/influxdata/influxdb-client-python/pull/509): Rename `key_file` to `cert_key_file` inside the central [configuration class](https://github.com/influxdata/influxdb-client-python/blob/d011df72b528a45d305aa8accbe879b31be3280e/influxdb_client/configuration.py#L92) + ### Features 1. [#510](https://github.com/influxdata/influxdb-client-python/pull/510): Allow to use client's optional configs for initialization from file or environment properties 2. [#509](https://github.com/influxdata/influxdb-client-python/pull/509): MTLS support for the InfluxDB Python client @@ -7,9 +10,6 @@ ### Bug Fixes 1. [#512](https://github.com/influxdata/influxdb-client-python/pull/512): Exception propagation for asynchronous `QueryApi` [async/await] -### Breaking Changes -1. [#509](https://github.com/influxdata/influxdb-client-python/pull/509): Rename `key_file` to `cert_key_file` inside the central [configuration class](https://github.com/influxdata/influxdb-client-python/blob/d011df72b528a45d305aa8accbe879b31be3280e/influxdb_client/configuration.py#L92) - ## 1.33.0 [2022-09-29] ### Features pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy