mirror of
https://github.com/outbackdingo/patroni.git
synced 2026-08-26 15:40:21 +00:00
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:
+13
-1
@@ -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
|
||||
|
||||
|
||||
@@ -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://'))
|
||||
|
||||
Reference in New Issue
Block a user