Skip to content

Commit

Permalink
feat: added possibility to specify certificate file path to verify th…
Browse files Browse the repository at this point in the history
…e peer (#158)
  • Loading branch information
bednar authored Sep 24, 2020
1 parent 9fc0fe1 commit 8c7d312
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 19 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

### Features
1. [#152](https://github.com/influxdata/influxdb-client-python/pull/152): WriteApi supports generic Iterable type
1. [#158](https://github.com/influxdata/influxdb-client-python/pull/158): Added possibility to specify certificate file path to verify the peer

### API
1. [#151](https://github.com/influxdata/influxdb-client-python/pull/151): Default port changed from 9999 -> 8086
Expand Down
2 changes: 2 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ The following options are supported:
- ``token`` - the token to use for the authorization
- ``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

.. code-block:: python
Expand All @@ -195,6 +196,7 @@ Supported properties are:
- ``INFLUXDB_V2_TOKEN`` - the token to use for the authorization
- ``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

.. code-block:: python
Expand Down
15 changes: 12 additions & 3 deletions influxdb_client/client/influxdb_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ def __init__(self, url, token, debug=None, timeout=10000, enable_gzip=False, org
supports the Gzip compression.
:param org: organization name (used as a default in query and write 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 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.
Expand All @@ -52,6 +53,7 @@ def __init__(self, url, token, debug=None, timeout=10000, enable_gzip=False, org
conf.enable_gzip = enable_gzip
conf.debug = debug
conf.verify_ssl = kwargs.get('verify_ssl', True)
conf.ssl_ca_cert = kwargs.get('ssl_ca_cert', None)

auth_token = self.token
auth_header_name = "Authorization"
Expand All @@ -73,6 +75,7 @@ def from_config_file(cls, config_file: str = "config.ini", debug=None, enable_gz
- token
- timeout,
- verify_ssl
- ssl_ca_cert
"""
config = configparser.ConfigParser()
config.read(config_file)
Expand All @@ -94,17 +97,21 @@ def from_config_file(cls, config_file: str = "config.ini", debug=None, enable_gz
if config.has_option('influx2', 'verify_ssl'):
verify_ssl = config['influx2']['verify_ssl']

ssl_ca_cert = None
if config.has_option('influx2', 'ssl_ca_cert'):
ssl_ca_cert = config['influx2']['ssl_ca_cert']

default_tags = None

if config.has_section('tags'):
default_tags = dict(config.items('tags'))

if timeout:
return cls(url, token, debug=debug, timeout=int(timeout), org=org, default_tags=default_tags,
enable_gzip=enable_gzip, verify_ssl=_to_bool(verify_ssl))
enable_gzip=enable_gzip, verify_ssl=_to_bool(verify_ssl), ssl_ca_cert=ssl_ca_cert)

return cls(url, token, debug=debug, org=org, default_tags=default_tags, enable_gzip=enable_gzip,
verify_ssl=_to_bool(verify_ssl))
verify_ssl=_to_bool(verify_ssl), ssl_ca_cert=ssl_ca_cert)

@classmethod
def from_env_properties(cls, debug=None, enable_gzip=False):
Expand All @@ -117,12 +124,14 @@ def from_env_properties(cls, debug=None, enable_gzip=False):
- INFLUXDB_V2_TOKEN
- INFLUXDB_V2_TIMEOUT
- INFLUXDB_V2_VERIFY_SSL
- INFLUXDB_V2_SSL_CA_CERT
"""
url = os.getenv('INFLUXDB_V2_URL', "http://localhost:8086")
token = os.getenv('INFLUXDB_V2_TOKEN', "my-token")
timeout = os.getenv('INFLUXDB_V2_TIMEOUT', "10000")
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)

default_tags = dict()

Expand All @@ -131,7 +140,7 @@ def from_env_properties(cls, debug=None, enable_gzip=False):
default_tags[key[16:].lower()] = value

return cls(url, token, debug=debug, timeout=int(timeout), org=org, default_tags=default_tags,
enable_gzip=enable_gzip, verify_ssl=_to_bool(verify_ssl))
enable_gzip=enable_gzip, verify_ssl=_to_bool(verify_ssl), ssl_ca_cert=ssl_ca_cert)

def write_api(self, write_options=WriteOptions(), point_settings=PointSettings()) -> WriteApi:
"""
Expand Down
11 changes: 11 additions & 0 deletions tests/config-ssl-ca-cert.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[influx2]
url=http://localhost:8086
org=my-org
token=my-token
timeout=6000
ssl_ca_cert=/path/to/my/cert

[tags]
id = 132-987-655
customer = California Miner
data_center = ${env.data_center}
68 changes: 52 additions & 16 deletions tests/test_InfluxDBClient.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,24 +25,22 @@ def test_TrailingSlashInUrl(self):
self.assertEqual('http://localhost:8086', self.client.api_client.configuration.host)

def test_ConnectToSelfSignedServer(self):
import http.server
import ssl
self._start_http_server()

# Disable unverified HTTPS requests
import urllib3
urllib3.disable_warnings()
self.client = InfluxDBClient(f"https://localhost:{self.httpd.server_address[1]}",
token="my-token", verify_ssl=False)
health = self.client.health()

# Configure HTTP server
self.httpd = http.server.HTTPServer(('localhost', 0), ServerWithSelfSingedSSL)
self.httpd.socket = ssl.wrap_socket(self.httpd.socket, certfile=f'{os.path.dirname(__file__)}/server.pem',
server_side=True)
self.assertEqual(health.message, 'ready for queries and writes')
self.assertEqual(health.status, "pass")
self.assertEqual(health.name, "influxdb")

# Start server at background
self.httpd_thread = threading.Thread(target=self.httpd.serve_forever)
self.httpd_thread.start()
def test_certificate_file(self):
self._start_http_server()

self.client = InfluxDBClient(f"https://localhost:{self.httpd.server_address[1]}",
token="my-token", verify_ssl=False)
token="my-token", verify_ssl=True,
ssl_ca_cert=f'{os.path.dirname(__file__)}/server.pem')
health = self.client.health()

self.assertEqual(health.message, 'ready for queries and writes')
Expand All @@ -60,16 +58,54 @@ def test_init_from_file_ssl(self):
self.assertFalse(self.client.api_client.configuration.verify_ssl)

def test_init_from_env_ssl_default(self):
del os.environ["INFLUXDB_V2_VERIFY_SSL"]
if os.getenv("INFLUXDB_V2_VERIFY_SSL"):
del os.environ["INFLUXDB_V2_VERIFY_SSL"]
self.client = InfluxDBClient.from_env_properties()

self.assertTrue(self.client.api_client.configuration.verify_ssl)

def test_init_from_env_ssl(self):
os.environ["INFLUXDB_V2_VERIFY_SSL"] = "False"
os.environ["INFLUXDB_V2_SSL_CA_CERT"] = "/my/custom/path"
self.client = InfluxDBClient.from_env_properties()

self.assertFalse(self.client.api_client.configuration.verify_ssl)
self.assertEqual("/my/custom/path", self.client.api_client.configuration.ssl_ca_cert)

def test_init_from_file_ssl_ca_cert_default(self):
self.client = InfluxDBClient.from_config_file(f'{os.path.dirname(__file__)}/config.ini')

self.assertIsNone(self.client.api_client.configuration.ssl_ca_cert)

def test_init_from_file_ssl_ca_cert(self):
self.client = InfluxDBClient.from_config_file(f'{os.path.dirname(__file__)}/config-ssl-ca-cert.ini')

self.assertEqual("/path/to/my/cert", self.client.api_client.configuration.ssl_ca_cert)

def test_init_from_env_ssl_ca_cert_default(self):
if os.getenv("INFLUXDB_V2_SSL_CA_CERT"):
del os.environ["INFLUXDB_V2_SSL_CA_CERT"]
self.client = InfluxDBClient.from_env_properties()

self.assertIsNone(self.client.api_client.configuration.ssl_ca_cert)

def test_init_from_env_ssl_ca_cert(self):
os.environ["INFLUXDB_V2_SSL_CA_CERT"] = "/my/custom/path/to/cert"
self.client = InfluxDBClient.from_env_properties()

self.assertEqual("/my/custom/path/to/cert", self.client.api_client.configuration.ssl_ca_cert)

def _start_http_server(self):
import http.server
import ssl
# Disable unverified HTTPS requests
import urllib3
urllib3.disable_warnings()
# Configure HTTP server
self.httpd = http.server.HTTPServer(('localhost', 0), ServerWithSelfSingedSSL)
self.httpd.socket = ssl.wrap_socket(self.httpd.socket, certfile=f'{os.path.dirname(__file__)}/server.pem',
server_side=True)
# Start server at background
self.httpd_thread = threading.Thread(target=self.httpd.serve_forever)
self.httpd_thread.start()


class ServerWithSelfSingedSSL(http.server.SimpleHTTPRequestHandler):
Expand Down

0 comments on commit 8c7d312

Please sign in to comment.