Add CA Cert file config option to validate against SSL endpoints
Currently Octavia cannot validate against SSL service endpoints, which would be keystone, neutron, nova and glance in this case. This patch adds a config option under nova, neutron and glance sections to read the specified CA certificate files for validation. It's slightly different in the case of glance, because glance session method invocations depend on the endpoint URL whether it starts with HTTP or HTTPS. Also added is the "insecure" option for these services in case the cert validation needs to be skipped. For keystone, we read config params from keystone middleware. Thus, instead of defining a new config option, we can make use of it's pre-defined "cafile". Barbican is not added because we do not yet have a barbican endpoint override in it's config. This could be added in the future as a separate patch, if needed. Lastly, unrelated to the above, fixes the amphora REST api default bind_port in octavia.conf Change-Id: Id57672a3dc7c962b8ee07db0cb7a743041082c66 Closes-Bug: #1552987
This commit is contained in:
parent
79669c925c
commit
f4da51c27d
|
@ -50,11 +50,14 @@
|
|||
|
||||
|
||||
[keystone_authtoken]
|
||||
# This group of config options are imported from keystone middleware. Thus the
|
||||
# option names should match the names declared in the middleware.
|
||||
# auth_uri = https://localhost:5000/v3
|
||||
# admin_user = octavia
|
||||
# admin_password = password
|
||||
# admin_tenant_name = service
|
||||
# insecure = False
|
||||
# cafile =
|
||||
|
||||
[keystone_authtoken_v3]
|
||||
# If using Keystone v3
|
||||
|
@ -113,7 +116,7 @@
|
|||
|
||||
# REST Driver specific
|
||||
# bind_host = 0.0.0.0
|
||||
# bind_port = 9191
|
||||
# bind_port = 9443
|
||||
# haproxy_cmd = /usr/sbin/haproxy
|
||||
# respawn_count = 2
|
||||
# respawn_interval = 2
|
||||
|
@ -230,6 +233,10 @@
|
|||
# the OpenStack services.
|
||||
# endpoint_type = publicURL
|
||||
|
||||
# CA certificates file to verify glance connections when TLS is enabled
|
||||
# insecure = False
|
||||
# ca_certificates_file =
|
||||
|
||||
[nova]
|
||||
# The name of the nova service in the keystone catalog
|
||||
# service_name =
|
||||
|
@ -243,6 +250,10 @@
|
|||
# the OpenStack services.
|
||||
# endpoint_type = publicURL
|
||||
|
||||
# CA certificates file to verify nova connections when TLS is enabled
|
||||
# insecure = False
|
||||
# ca_certificates_file =
|
||||
|
||||
# Flag to enable nova anti-affinity capabilities to place amphorae on
|
||||
# different hosts
|
||||
# enable_anti_affinity = False
|
||||
|
@ -259,3 +270,7 @@
|
|||
# Endpoint type in Identity service catalog to use for communication with
|
||||
# the OpenStack services.
|
||||
# endpoint_type = publicURL
|
||||
|
||||
# CA certificates file to verify neutron connections when TLS is enabled
|
||||
# insecure = False
|
||||
# ca_certificates_file =
|
|
@ -30,24 +30,30 @@ class NovaAuth(object):
|
|||
|
||||
@classmethod
|
||||
def get_nova_client(cls, region, service_name=None, endpoint=None,
|
||||
endpoint_type='publicURL'):
|
||||
endpoint_type='publicURL', insecure=False,
|
||||
cacert=None):
|
||||
"""Create nova client object.
|
||||
|
||||
:param region: The region of the service
|
||||
:param service_name: The name of the nova service in the catalog
|
||||
:param endpoint: The endpoint of the service
|
||||
:param endpoint_type: The type of the endpoint
|
||||
:param insecure: Turn off certificate validation
|
||||
:param cacert: CA Cert file path
|
||||
:return: a Nova Client object.
|
||||
:raises Exception: if the client cannot be created
|
||||
"""
|
||||
if not cls.nova_client:
|
||||
kwargs = {'region_name': region,
|
||||
'session': keystone.get_session(),
|
||||
'endpoint_type': endpoint_type}
|
||||
'endpoint_type': endpoint_type,
|
||||
'insecure': insecure}
|
||||
if service_name:
|
||||
kwargs['service_name'] = service_name
|
||||
if endpoint:
|
||||
kwargs['endpoint_override'] = endpoint
|
||||
if cacert:
|
||||
kwargs['cacert'] = cacert
|
||||
try:
|
||||
cls.nova_client = nova_client.Client(
|
||||
NOVA_VERSION, **kwargs)
|
||||
|
@ -62,24 +68,30 @@ class NeutronAuth(object):
|
|||
|
||||
@classmethod
|
||||
def get_neutron_client(cls, region, service_name=None, endpoint=None,
|
||||
endpoint_type='publicURL'):
|
||||
endpoint_type='publicURL', insecure=False,
|
||||
ca_cert=None):
|
||||
"""Create neutron client object.
|
||||
|
||||
:param region: The region of the service
|
||||
:param service_name: The name of the neutron service in the catalog
|
||||
:param endpoint: The endpoint of the service
|
||||
:param endpoint_type: The endpoint_type of the service
|
||||
:param insecure: Turn off certificate validation
|
||||
:param ca_cert: CA Cert file path
|
||||
:return: a Neutron Client object.
|
||||
:raises Exception: if the client cannot be created
|
||||
"""
|
||||
if not cls.neutron_client:
|
||||
kwargs = {'region_name': region,
|
||||
'session': keystone.get_session(),
|
||||
'endpoint_type': endpoint_type}
|
||||
'endpoint_type': endpoint_type,
|
||||
'insecure': insecure}
|
||||
if service_name:
|
||||
kwargs['service_name'] = service_name
|
||||
if endpoint:
|
||||
kwargs['endpoint_override'] = endpoint
|
||||
if ca_cert:
|
||||
kwargs['ca_cert'] = ca_cert
|
||||
try:
|
||||
cls.neutron_client = neutron_client.Client(
|
||||
NEUTRON_VERSION, **kwargs)
|
||||
|
@ -94,13 +106,16 @@ class GlanceAuth(object):
|
|||
|
||||
@classmethod
|
||||
def get_glance_client(cls, region, service_name=None, endpoint=None,
|
||||
endpoint_type='publicURL'):
|
||||
endpoint_type='publicURL', insecure=False,
|
||||
cacert=None):
|
||||
"""Create glance client object.
|
||||
|
||||
:param region: The region of the service
|
||||
:param service_name: The name of the glance service in the catalog
|
||||
:param endpoint: The endpoint of the service
|
||||
:param endpoint_type: The endpoint_type of the service
|
||||
:param insecure: Turn off certificate validation
|
||||
:param cacert: CA Cert file path
|
||||
:return: a Glance Client object.
|
||||
:raises Exception: if the client cannot be created
|
||||
"""
|
||||
|
@ -112,6 +127,9 @@ class GlanceAuth(object):
|
|||
kwargs['service_name'] = service_name
|
||||
if endpoint:
|
||||
kwargs['endpoint'] = endpoint
|
||||
if endpoint.startswith("https"):
|
||||
kwargs['insecure'] = insecure
|
||||
kwargs['cacert'] = cacert
|
||||
try:
|
||||
cls.glance_client = glance_client.Client(
|
||||
GLANCE_VERSION, **kwargs)
|
||||
|
|
|
@ -360,6 +360,11 @@ nova_opts = [
|
|||
'communication with the OpenStack services.')),
|
||||
cfg.StrOpt('endpoint_type', default='publicURL',
|
||||
help=_('Endpoint interface in identity service to use')),
|
||||
cfg.StrOpt('ca_certificates_file',
|
||||
help=_('CA certificates file path')),
|
||||
cfg.BoolOpt('insecure',
|
||||
default=False,
|
||||
help=_('Disable certificate validation on SSL connections ')),
|
||||
cfg.BoolOpt('enable_anti_affinity', default=False,
|
||||
help=_('Flag to indicate if nova anti-affinity feature is '
|
||||
'turned on.'))
|
||||
|
@ -376,6 +381,11 @@ neutron_opts = [
|
|||
'communication with the OpenStack services.')),
|
||||
cfg.StrOpt('endpoint_type', default='publicURL',
|
||||
help=_('Endpoint interface in identity service to use')),
|
||||
cfg.StrOpt('ca_certificates_file',
|
||||
help=_('CA certificates file path')),
|
||||
cfg.BoolOpt('insecure',
|
||||
default=False,
|
||||
help=_('Disable certificate validation on SSL connections ')),
|
||||
]
|
||||
|
||||
glance_opts = [
|
||||
|
@ -389,6 +399,11 @@ glance_opts = [
|
|||
'communication with the OpenStack services.')),
|
||||
cfg.StrOpt('endpoint_type', default='publicURL',
|
||||
help=_('Endpoint interface in identity service to use')),
|
||||
cfg.StrOpt('ca_certificates_file',
|
||||
help=_('CA certificates file path')),
|
||||
cfg.BoolOpt('insecure',
|
||||
default=False,
|
||||
help=_('Disable certificate validation on SSL connections ')),
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -61,7 +61,8 @@ def get_session():
|
|||
try:
|
||||
kc = client.Password(**kwargs)
|
||||
_SESSION = session.Session(
|
||||
auth=kc, verify=not cfg.CONF.keystone_authtoken.insecure)
|
||||
auth=kc, verify=(cfg.CONF.keystone_authtoken.cafile or
|
||||
not cfg.CONF.keystone_authtoken.insecure))
|
||||
except Exception:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(_LE("Error creating Keystone session."))
|
||||
|
|
|
@ -69,12 +69,16 @@ class VirtualMachineManager(compute_base.ComputeBase):
|
|||
self._nova_client = clients.NovaAuth.get_nova_client(
|
||||
endpoint=CONF.nova.endpoint,
|
||||
region=CONF.nova.region_name,
|
||||
endpoint_type=CONF.nova.endpoint_type)
|
||||
endpoint_type=CONF.nova.endpoint_type,
|
||||
insecure=CONF.nova.insecure,
|
||||
cacert=CONF.nova.ca_certificates_file)
|
||||
self._glance_client = clients.GlanceAuth.get_glance_client(
|
||||
service_name=CONF.glance.service_name,
|
||||
endpoint=CONF.glance.endpoint,
|
||||
region=CONF.glance.region_name,
|
||||
endpoint_type=CONF.glance.endpoint_type)
|
||||
endpoint_type=CONF.glance.endpoint_type,
|
||||
insecure=CONF.glance.insecure,
|
||||
cacert=CONF.glance.ca_certificates_file)
|
||||
self.manager = self._nova_client.servers
|
||||
self.server_groups = self._nova_client.server_groups
|
||||
|
||||
|
|
|
@ -50,6 +50,8 @@ class AllowedAddressPairsDriver(neutron_base.BaseNeutronDriver):
|
|||
region=CONF.nova.region_name,
|
||||
endpoint_type=CONF.nova.endpoint_type,
|
||||
service_name=CONF.nova.service_name,
|
||||
insecure=CONF.nova.insecure,
|
||||
cacert=CONF.nova.ca_certificates_file
|
||||
)
|
||||
|
||||
def _check_aap_loaded(self):
|
||||
|
|
|
@ -39,7 +39,9 @@ class BaseNeutronDriver(base.AbstractNetworkDriver):
|
|||
endpoint=CONF.neutron.endpoint,
|
||||
region=CONF.neutron.region_name,
|
||||
endpoint_type=CONF.neutron.endpoint_type,
|
||||
service_name=CONF.neutron.service_name
|
||||
service_name=CONF.neutron.service_name,
|
||||
insecure=CONF.neutron.insecure,
|
||||
ca_cert=CONF.neutron.ca_certificates_file
|
||||
)
|
||||
extensions = self.neutron_client.list_extensions()
|
||||
self._extensions = extensions.get('extensions')
|
||||
|
|
|
@ -58,7 +58,7 @@ class TestNovaAuth(base.TestCase):
|
|||
# Getting the session again should return the same object
|
||||
bc2 = clients.NovaAuth.get_nova_client(
|
||||
region="test-region", service_name='novaEndpoint1',
|
||||
endpoint="test-endpoint", endpoint_type='adminURL')
|
||||
endpoint="test-endpoint", endpoint_type='adminURL', insecure=True)
|
||||
self.assertIs(bc1, bc2)
|
||||
|
||||
|
||||
|
@ -97,7 +97,7 @@ class TestNeutronAuth(base.TestCase):
|
|||
# Getting the session again should return the same object
|
||||
bc2 = clients.NeutronAuth.get_neutron_client(
|
||||
region="test-region", service_name="neutronEndpoint1",
|
||||
endpoint="test-endpoint", endpoint_type='publicURL')
|
||||
endpoint="test-endpoint", endpoint_type='publicURL', insecure=True)
|
||||
self.assertIs(bc1, bc2)
|
||||
|
||||
|
||||
|
@ -121,7 +121,7 @@ class TestGlanceAuth(base.TestCase):
|
|||
# Mock out the keystone session and get the client
|
||||
keystone._SESSION = mock.MagicMock()
|
||||
bc1 = clients.GlanceAuth.get_glance_client(
|
||||
region=None, endpoint_type='publicURL')
|
||||
region=None, endpoint_type='publicURL', insecure=True)
|
||||
|
||||
# Our returned client should also be the saved client
|
||||
self.assertIsInstance(
|
||||
|
@ -136,5 +136,5 @@ class TestGlanceAuth(base.TestCase):
|
|||
# Getting the session again should return the same object
|
||||
bc2 = clients.GlanceAuth.get_glance_client(
|
||||
region="test-region", service_name="glanceEndpoint1",
|
||||
endpoint="test-endpoint", endpoint_type='publicURL')
|
||||
endpoint="test-endpoint", endpoint_type='publicURL', insecure=True)
|
||||
self.assertIs(bc1, bc2)
|
||||
|
|
Loading…
Reference in New Issue