Skip to content

Commit 8c7d312

Browse files
authored
feat: added possibility to specify certificate file path to verify the peer (#158)
1 parent 9fc0fe1 commit 8c7d312

File tree

5 files changed

+78
-19
lines changed

5 files changed

+78
-19
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

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

67
### API
78
1. [#151](https://github.com/influxdata/influxdb-client-python/pull/151): Default port changed from 9999 -> 8086

README.rst

+2
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ The following options are supported:
170170
- ``token`` - the token to use for the authorization
171171
- ``timeout`` - socket timeout in ms (default value is 10000)
172172
- ``verify_ssl`` - set this to false to skip verifying SSL certificate when calling API from https server
173+
- ``ssl_ca_cert`` - set this to customize the certificate file to verify the peer
173174

174175
.. code-block:: python
175176
@@ -195,6 +196,7 @@ Supported properties are:
195196
- ``INFLUXDB_V2_TOKEN`` - the token to use for the authorization
196197
- ``INFLUXDB_V2_TIMEOUT`` - socket timeout in ms (default value is 10000)
197198
- ``INFLUXDB_V2_VERIFY_SSL`` - set this to false to skip verifying SSL certificate when calling API from https server
199+
- ``INFLUXDB_V2_SSL_CA_CERT`` - set this to customize the certificate file to verify the peer
198200

199201
.. code-block:: python
200202

influxdb_client/client/influxdb_client.py

+12-3
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ def __init__(self, url, token, debug=None, timeout=10000, enable_gzip=False, org
3333
supports the Gzip compression.
3434
:param org: organization name (used as a default in query and write API)
3535
:key bool verify_ssl: Set this to false to skip verifying SSL certificate when calling API from https server.
36+
:key str ssl_ca_cert: Set this to customize the certificate file to verify the peer.
3637
:key urllib3.util.retry.Retry retries: Set the default retry strategy that is used for all HTTP requests
3738
except batching writes. As a default there is no one retry strategy.
3839
@@ -52,6 +53,7 @@ def __init__(self, url, token, debug=None, timeout=10000, enable_gzip=False, org
5253
conf.enable_gzip = enable_gzip
5354
conf.debug = debug
5455
conf.verify_ssl = kwargs.get('verify_ssl', True)
56+
conf.ssl_ca_cert = kwargs.get('ssl_ca_cert', None)
5557

5658
auth_token = self.token
5759
auth_header_name = "Authorization"
@@ -73,6 +75,7 @@ def from_config_file(cls, config_file: str = "config.ini", debug=None, enable_gz
7375
- token
7476
- timeout,
7577
- verify_ssl
78+
- ssl_ca_cert
7679
"""
7780
config = configparser.ConfigParser()
7881
config.read(config_file)
@@ -94,17 +97,21 @@ def from_config_file(cls, config_file: str = "config.ini", debug=None, enable_gz
9497
if config.has_option('influx2', 'verify_ssl'):
9598
verify_ssl = config['influx2']['verify_ssl']
9699

100+
ssl_ca_cert = None
101+
if config.has_option('influx2', 'ssl_ca_cert'):
102+
ssl_ca_cert = config['influx2']['ssl_ca_cert']
103+
97104
default_tags = None
98105

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

102109
if timeout:
103110
return cls(url, token, debug=debug, timeout=int(timeout), org=org, default_tags=default_tags,
104-
enable_gzip=enable_gzip, verify_ssl=_to_bool(verify_ssl))
111+
enable_gzip=enable_gzip, verify_ssl=_to_bool(verify_ssl), ssl_ca_cert=ssl_ca_cert)
105112

106113
return cls(url, token, debug=debug, org=org, default_tags=default_tags, enable_gzip=enable_gzip,
107-
verify_ssl=_to_bool(verify_ssl))
114+
verify_ssl=_to_bool(verify_ssl), ssl_ca_cert=ssl_ca_cert)
108115

109116
@classmethod
110117
def from_env_properties(cls, debug=None, enable_gzip=False):
@@ -117,12 +124,14 @@ def from_env_properties(cls, debug=None, enable_gzip=False):
117124
- INFLUXDB_V2_TOKEN
118125
- INFLUXDB_V2_TIMEOUT
119126
- INFLUXDB_V2_VERIFY_SSL
127+
- INFLUXDB_V2_SSL_CA_CERT
120128
"""
121129
url = os.getenv('INFLUXDB_V2_URL', "http://localhost:8086")
122130
token = os.getenv('INFLUXDB_V2_TOKEN', "my-token")
123131
timeout = os.getenv('INFLUXDB_V2_TIMEOUT', "10000")
124132
org = os.getenv('INFLUXDB_V2_ORG', "my-org")
125133
verify_ssl = os.getenv('INFLUXDB_V2_VERIFY_SSL', "True")
134+
ssl_ca_cert = os.getenv('INFLUXDB_V2_SSL_CA_CERT', None)
126135

127136
default_tags = dict()
128137

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

133142
return cls(url, token, debug=debug, timeout=int(timeout), org=org, default_tags=default_tags,
134-
enable_gzip=enable_gzip, verify_ssl=_to_bool(verify_ssl))
143+
enable_gzip=enable_gzip, verify_ssl=_to_bool(verify_ssl), ssl_ca_cert=ssl_ca_cert)
135144

136145
def write_api(self, write_options=WriteOptions(), point_settings=PointSettings()) -> WriteApi:
137146
"""

tests/config-ssl-ca-cert.ini

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[influx2]
2+
url=http://localhost:8086
3+
org=my-org
4+
token=my-token
5+
timeout=6000
6+
ssl_ca_cert=/path/to/my/cert
7+
8+
[tags]
9+
id = 132-987-655
10+
customer = California Miner
11+
data_center = ${env.data_center}

tests/test_InfluxDBClient.py

+52-16
Original file line numberDiff line numberDiff line change
@@ -25,24 +25,22 @@ def test_TrailingSlashInUrl(self):
2525
self.assertEqual('http://localhost:8086', self.client.api_client.configuration.host)
2626

2727
def test_ConnectToSelfSignedServer(self):
28-
import http.server
29-
import ssl
28+
self._start_http_server()
3029

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

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

40-
# Start server at background
41-
self.httpd_thread = threading.Thread(target=self.httpd.serve_forever)
42-
self.httpd_thread.start()
38+
def test_certificate_file(self):
39+
self._start_http_server()
4340

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

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

6260
def test_init_from_env_ssl_default(self):
63-
del os.environ["INFLUXDB_V2_VERIFY_SSL"]
61+
if os.getenv("INFLUXDB_V2_VERIFY_SSL"):
62+
del os.environ["INFLUXDB_V2_VERIFY_SSL"]
6463
self.client = InfluxDBClient.from_env_properties()
6564

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

6867
def test_init_from_env_ssl(self):
69-
os.environ["INFLUXDB_V2_VERIFY_SSL"] = "False"
68+
os.environ["INFLUXDB_V2_SSL_CA_CERT"] = "/my/custom/path"
7069
self.client = InfluxDBClient.from_env_properties()
7170

72-
self.assertFalse(self.client.api_client.configuration.verify_ssl)
71+
self.assertEqual("/my/custom/path", self.client.api_client.configuration.ssl_ca_cert)
72+
73+
def test_init_from_file_ssl_ca_cert_default(self):
74+
self.client = InfluxDBClient.from_config_file(f'{os.path.dirname(__file__)}/config.ini')
75+
76+
self.assertIsNone(self.client.api_client.configuration.ssl_ca_cert)
77+
78+
def test_init_from_file_ssl_ca_cert(self):
79+
self.client = InfluxDBClient.from_config_file(f'{os.path.dirname(__file__)}/config-ssl-ca-cert.ini')
80+
81+
self.assertEqual("/path/to/my/cert", self.client.api_client.configuration.ssl_ca_cert)
82+
83+
def test_init_from_env_ssl_ca_cert_default(self):
84+
if os.getenv("INFLUXDB_V2_SSL_CA_CERT"):
85+
del os.environ["INFLUXDB_V2_SSL_CA_CERT"]
86+
self.client = InfluxDBClient.from_env_properties()
87+
88+
self.assertIsNone(self.client.api_client.configuration.ssl_ca_cert)
89+
90+
def test_init_from_env_ssl_ca_cert(self):
91+
os.environ["INFLUXDB_V2_SSL_CA_CERT"] = "/my/custom/path/to/cert"
92+
self.client = InfluxDBClient.from_env_properties()
93+
94+
self.assertEqual("/my/custom/path/to/cert", self.client.api_client.configuration.ssl_ca_cert)
95+
96+
def _start_http_server(self):
97+
import http.server
98+
import ssl
99+
# Disable unverified HTTPS requests
100+
import urllib3
101+
urllib3.disable_warnings()
102+
# Configure HTTP server
103+
self.httpd = http.server.HTTPServer(('localhost', 0), ServerWithSelfSingedSSL)
104+
self.httpd.socket = ssl.wrap_socket(self.httpd.socket, certfile=f'{os.path.dirname(__file__)}/server.pem',
105+
server_side=True)
106+
# Start server at background
107+
self.httpd_thread = threading.Thread(target=self.httpd.serve_forever)
108+
self.httpd_thread.start()
73109

74110

75111
class ServerWithSelfSingedSSL(http.server.SimpleHTTPRequestHandler):

0 commit comments

Comments
 (0)