Add SSL wrapper around restapi server socket

If config['restapi']['certfile'] is specified and not empty http server
would be wrapped into SSL and api connection string changed accordingly:
http:// => https://
This commit is contained in:
Alexander Kukushkin
2015-09-09 12:15:52 +02:00
parent e90b14cd3b
commit b5a5ea2a75
2 changed files with 23 additions and 1 deletions
+13 -1
View File
@@ -52,11 +52,23 @@ class RestApiHandler(BaseHTTPRequestHandler):
class RestApiServer(ThreadingMixIn, HTTPServer, Thread):
def __init__(self, patroni, config):
self.connection_string = 'http://{}/patroni'.format(config.get('connect_address', None) or config['listen'])
host, port = config['listen'].split(':')
HTTPServer.__init__(self, (host, int(port)), RestApiHandler)
Thread.__init__(self, target=self.serve_forever)
self._set_fd_cloexec(self.socket)
protocol = 'http'
# wrap socket with ssl if 'certfile' is defined in a config.yaml
# Sometime it's also needed to pass reference to a 'keyfile'.
options = {option: config[option] for option in ['certfile', 'keyfile'] if option in config}
if options.get('certfile', None):
import ssl
self.socket = ssl.wrap_socket(self.socket, server_side=True, **options)
protocol = 'https'
self.connection_string = '{}://{}/patroni'.format(protocol, config.get('connect_address', config['listen']))
self.patroni = patroni
self.daemon = True
+10
View File
@@ -2,6 +2,7 @@ import datetime
import patroni.zookeeper
import psycopg2
import subprocess
import ssl
import sys
import time
import unittest
@@ -32,6 +33,10 @@ def time_sleep(*args):
raise SleepException()
def ssl_wrap_socket(socket, *args, **kwargs):
return socket
class Mock_BaseServer__is_shut_down:
def set(self):
@@ -62,8 +67,10 @@ class TestPatroni(unittest.TestCase):
RestApiServer._BaseServer__is_shut_down = Mock_BaseServer__is_shut_down()
RestApiServer._BaseServer__shutdown_request = True
RestApiServer.socket = 0
ssl.wrap_socket = ssl_wrap_socket
with open('postgres0.yml', 'r') as f:
config = yaml.load(f)
config['restapi']['certfile'] = 'dump'
with patch.object(Client, 'machines') as mock_machines:
mock_machines.__get__ = Mock(return_value=['http://remotehost:2379'])
self.p = Patroni(config)
@@ -147,3 +154,6 @@ class TestPatroni(unittest.TestCase):
def test_schedule_next_run(self):
self.p.next_run = time.time() - self.p.nap_time - 1
self.p.schedule_next_run()
def test_api_connection_string(self):
self.assertTrue(self.p.api.connection_string.startswith('https://'))