diff --git a/etc/octavia.conf b/etc/octavia.conf index 785f9a17c2..d815ea81a8 100644 --- a/etc/octavia.conf +++ b/etc/octavia.conf @@ -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 = \ No newline at end of file diff --git a/octavia/common/clients.py b/octavia/common/clients.py index 307a262613..fd52eb4f41 100644 --- a/octavia/common/clients.py +++ b/octavia/common/clients.py @@ -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) diff --git a/octavia/common/config.py b/octavia/common/config.py index ab92691325..b7aa32a829 100644 --- a/octavia/common/config.py +++ b/octavia/common/config.py @@ -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 ')), ] diff --git a/octavia/common/keystone.py b/octavia/common/keystone.py index 42c3a6b837..f215d68d2f 100644 --- a/octavia/common/keystone.py +++ b/octavia/common/keystone.py @@ -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.")) diff --git a/octavia/compute/drivers/nova_driver.py b/octavia/compute/drivers/nova_driver.py index e7cd0a7759..7e204d4016 100644 --- a/octavia/compute/drivers/nova_driver.py +++ b/octavia/compute/drivers/nova_driver.py @@ -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 diff --git a/octavia/network/drivers/neutron/allowed_address_pairs.py b/octavia/network/drivers/neutron/allowed_address_pairs.py index b69c632b8f..7b2d087640 100644 --- a/octavia/network/drivers/neutron/allowed_address_pairs.py +++ b/octavia/network/drivers/neutron/allowed_address_pairs.py @@ -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): diff --git a/octavia/network/drivers/neutron/base.py b/octavia/network/drivers/neutron/base.py index 839114b6e1..55d72cd127 100644 --- a/octavia/network/drivers/neutron/base.py +++ b/octavia/network/drivers/neutron/base.py @@ -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') diff --git a/octavia/tests/unit/common/test_clients.py b/octavia/tests/unit/common/test_clients.py index 6a7b48e0d8..b22853433e 100644 --- a/octavia/tests/unit/common/test_clients.py +++ b/octavia/tests/unit/common/test_clients.py @@ -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)