Add support for TLS-enabled etcd

This requires /etc/ccp/ca.pem to be present in a pod

Change-Id: I574d64082e77f49024f49aa7b30c4f2f6cc044ac
This commit is contained in:
Aleksandr Mogylchenko 2017-01-18 17:23:01 +01:00
parent ff6efca2c8
commit 4bee4293ca
2 changed files with 31 additions and 5 deletions

View File

@ -24,6 +24,7 @@ import six
VARIABLES = {} VARIABLES = {}
GLOBALS_PATH = '/etc/ccp/globals/globals.json' GLOBALS_PATH = '/etc/ccp/globals/globals.json'
META_FILE = "/etc/ccp/meta/meta.json" META_FILE = "/etc/ccp/meta/meta.json"
CACERT = "/etc/ccp/ca.pem"
WORKFLOW_PATH_TEMPLATE = '/etc/ccp/role/%s.json' WORKFLOW_PATH_TEMPLATE = '/etc/ccp/role/%s.json'
FILES_DIR = '/etc/ccp/files' FILES_DIR = '/etc/ccp/files'
EXPORTS_DIR = '/etc/ccp/exports' EXPORTS_DIR = '/etc/ccp/exports'
@ -292,24 +293,39 @@ def create_files(files):
@retry @retry
def get_etcd_client(): 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 = [] etcd_machines = []
# if it's etcd container use local address because container is not # if it's etcd container use local address because container is not
# accessible via service due failed readiness check # accessible via service due failed readiness check
if VARIABLES["role_name"] in ["etcd", "etcd-leader-elector", if VARIABLES["role_name"] in ["etcd", "etcd-leader-elector",
"etcd-watcher"]: "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( etcd_machines.append(
(VARIABLES["network_topology"]["private"]["address"], (etcd_address, VARIABLES["etcd"]["client_port"]['cont']))
VARIABLES["etcd"]["client_port"]['cont']))
else: else:
etcd_machines.append( etcd_machines.append(
(address('etcd'), VARIABLES["etcd"]["client_port"]['cont']) (address('etcd'), VARIABLES["etcd"]["client_port"]['cont'])
) )
etcd_machines_str = " ".join(["%s:%d" % (h, p) for h, p in etcd_machines]) 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) LOG.debug("Using the following etcd urls: \"%s\"", etcd_machines_str)
return etcd.Client(host=tuple(etcd_machines), allow_reconnect=True, 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): def check_dependence(dep, etcd_client):

View File

@ -142,6 +142,11 @@ class TestGetETCDClient(base.TestCase):
"private": { "private": {
"address": "192.0.2.1" "address": "192.0.2.1"
} }
},
"security": {
"tls": {
"enabled": False
}
} }
} }
with mock.patch("etcd.Client") as m_etcd: with mock.patch("etcd.Client") as m_etcd:
@ -166,7 +171,12 @@ class TestGetETCDClient(base.TestCase):
"connection_attempts": 3, "connection_attempts": 3,
"connection_delay": 0, "connection_delay": 0,
}, },
} "security": {
"tls": {
"enabled": False
}
}
}
with mock.patch("etcd.Client") as m_etcd: with mock.patch("etcd.Client") as m_etcd:
expected_value = object() expected_value = object()
m_etcd.return_value = expected_value m_etcd.return_value = expected_value