From 2920bdd2978ed744882226ab46a379bd03b6d221 Mon Sep 17 00:00:00 2001 From: Aleksandr Mogylchenko Date: Wed, 18 Jan 2017 17:23:01 +0100 Subject: [PATCH] Add support for TLS-enabled etcd This requires /etc/ccp/ca.pem to be present in a pod Change-Id: I574d64082e77f49024f49aa7b30c4f2f6cc044ac --- fuel_ccp_entrypoint/start_script.py | 24 +++++++++++++++---- .../tests/test_fuel_ccp_entrypoint.py | 18 ++++++++++++-- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/fuel_ccp_entrypoint/start_script.py b/fuel_ccp_entrypoint/start_script.py index 92a74e0..513b05a 100644 --- a/fuel_ccp_entrypoint/start_script.py +++ b/fuel_ccp_entrypoint/start_script.py @@ -24,6 +24,7 @@ import six VARIABLES = {} GLOBALS_PATH = '/etc/ccp/globals/globals.json' META_FILE = "/etc/ccp/meta/meta.json" +CACERT = "/etc/ccp/ca.pem" WORKFLOW_PATH_TEMPLATE = '/etc/ccp/role/%s.json' FILES_DIR = '/etc/ccp/files' EXPORTS_DIR = '/etc/ccp/exports' @@ -292,24 +293,39 @@ def create_files(files): @retry def get_etcd_client(): + if VARIABLES["security"]["tls"]["enabled"]: + LOG.debug("TLS is enabled for etcd, using encrypted connectivity") + scheme = "https" + ca_cert = CACERT + else: + scheme = "http" + ca_cert = None + etcd_machines = [] # if it's etcd container use local address because container is not # accessible via service due failed readiness check if VARIABLES["role_name"] in ["etcd", "etcd-leader-elector", "etcd-watcher"]: + if VARIABLES["security"]["tls"]["enabled"]: + # If it's etcd container, connectivity goes over IP address, thus + # TLS connection will fail. Need to reuse non-TLS + # https://github.com/coreos/etcd/issues/4311 + scheme = "http" + ca_cert = None + etcd_address = '127.0.0.1' + else: + etcd_address = VARIABLES["network_topology"]["private"]["address"] etcd_machines.append( - (VARIABLES["network_topology"]["private"]["address"], - VARIABLES["etcd"]["client_port"]['cont'])) + (etcd_address, VARIABLES["etcd"]["client_port"]['cont'])) else: etcd_machines.append( (address('etcd'), VARIABLES["etcd"]["client_port"]['cont']) ) - etcd_machines_str = " ".join(["%s:%d" % (h, p) for h, p in etcd_machines]) LOG.debug("Using the following etcd urls: \"%s\"", etcd_machines_str) return etcd.Client(host=tuple(etcd_machines), allow_reconnect=True, - read_timeout=2) + read_timeout=2, protocol=scheme, ca_cert=ca_cert) def check_dependence(dep, etcd_client): diff --git a/fuel_ccp_entrypoint/tests/test_fuel_ccp_entrypoint.py b/fuel_ccp_entrypoint/tests/test_fuel_ccp_entrypoint.py index 51d8f63..2bc47bf 100644 --- a/fuel_ccp_entrypoint/tests/test_fuel_ccp_entrypoint.py +++ b/fuel_ccp_entrypoint/tests/test_fuel_ccp_entrypoint.py @@ -142,6 +142,11 @@ class TestGetETCDClient(base.TestCase): "private": { "address": "192.0.2.1" } + }, + "security": { + "tls": { + "enabled": False + } } } with mock.patch("etcd.Client") as m_etcd: @@ -152,7 +157,9 @@ class TestGetETCDClient(base.TestCase): m_etcd.assert_called_once_with( host=(("192.0.2.1", 10042),), allow_reconnect=True, - read_timeout=2) + read_timeout=2, + protocol='http', + ca_cert=None) def test_get_etcd_client(self): start_script.VARIABLES = { @@ -166,6 +173,11 @@ class TestGetETCDClient(base.TestCase): "connection_attempts": 3, "connection_delay": 0, }, + "security": { + "tls": { + "enabled": False + } + } } with mock.patch("etcd.Client") as m_etcd: expected_value = object() @@ -175,7 +187,9 @@ class TestGetETCDClient(base.TestCase): m_etcd.assert_called_once_with( host=(('etcd.ccp.svc.cluster.local', 1234),), allow_reconnect=True, - read_timeout=2) + read_timeout=2, + protocol='http', + ca_cert=None) def test_get_etcd_client_wrong(self): start_script.VARIABLES = {