Fixes using SSL OVSDB connection
When creating SSL OVSDB connection it is required to set the private key, certificate, and the CA certificate in order to communicate with OVSDB. This patch configures these when an SSL connection URI is used. The settings must be provided as part of neutron.conf under [ovs] section. Closes-Bug: 1745038 Change-Id: I19fd9dd0c72260835eb91e557a6029ec9d652179 Signed-off-by: Tim Rozet <trozet@redhat.com>
This commit is contained in:
parent
c46eb76394
commit
8806477abf
@ -12,13 +12,17 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import os
|
||||
|
||||
from debtcollector import moves
|
||||
from oslo_config import cfg
|
||||
from ovs.db import idl
|
||||
from ovs.stream import Stream
|
||||
from ovsdbapp.backend.ovs_idl import connection as _connection
|
||||
from ovsdbapp.backend.ovs_idl import idlutils
|
||||
import tenacity
|
||||
|
||||
from neutron.agent.ovsdb.native import exceptions as ovsdb_exc
|
||||
from neutron.agent.ovsdb.native import helpers
|
||||
|
||||
TransactionQueue = moves.moved_class(_connection.TransactionQueue,
|
||||
@ -26,9 +30,31 @@ TransactionQueue = moves.moved_class(_connection.TransactionQueue,
|
||||
Connection = moves.moved_class(_connection.Connection, 'Connection', __name__)
|
||||
|
||||
|
||||
def configure_ssl_conn():
|
||||
"""
|
||||
Configures required settings for an SSL based OVSDB client connection
|
||||
:return: None
|
||||
"""
|
||||
|
||||
req_ssl_opts = {'ssl_key_file': cfg.CONF.OVS.ssl_key_file,
|
||||
'ssl_cert_file': cfg.CONF.OVS.ssl_cert_file,
|
||||
'ssl_ca_cert_file': cfg.CONF.OVS.ssl_ca_cert_file}
|
||||
for ssl_opt, ssl_file in req_ssl_opts.items():
|
||||
if not ssl_file:
|
||||
raise ovsdb_exc.OvsdbSslRequiredOptError(ssl_opt=ssl_opt)
|
||||
elif not os.path.exists(ssl_file):
|
||||
raise ovsdb_exc.OvsdbSslConfigNotFound(ssl_file=ssl_file)
|
||||
# TODO(ihrachys): move to ovsdbapp
|
||||
Stream.ssl_set_private_key_file(req_ssl_opts['ssl_key_file'])
|
||||
Stream.ssl_set_certificate_file(req_ssl_opts['ssl_cert_file'])
|
||||
Stream.ssl_set_ca_cert_file(req_ssl_opts['ssl_ca_cert_file'])
|
||||
|
||||
|
||||
def idl_factory():
|
||||
conn = cfg.CONF.OVS.ovsdb_connection
|
||||
schema_name = 'Open_vSwitch'
|
||||
if conn.startswith('ssl:'):
|
||||
configure_ssl_conn()
|
||||
try:
|
||||
helper = idlutils.get_schema_helper(conn, schema_name)
|
||||
except Exception:
|
||||
|
28
neutron/agent/ovsdb/native/exceptions.py
Normal file
28
neutron/agent/ovsdb/native/exceptions.py
Normal file
@ -0,0 +1,28 @@
|
||||
# Copyright 2018 Red Hat, Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from neutron_lib import exceptions as e
|
||||
|
||||
from neutron._i18n import _
|
||||
|
||||
|
||||
class OvsdbSslConfigNotFound(e.NeutronException):
|
||||
message = _("Specified SSL file %(ssl_file)s could not be found")
|
||||
|
||||
|
||||
class OvsdbSslRequiredOptError(e.NeutronException):
|
||||
message = _("Required 'ovs' group option %(ssl_opt)s not set. SSL "
|
||||
"configuration options are required when using SSL "
|
||||
"ovsdb_connection URI")
|
@ -35,7 +35,22 @@ API_OPTS = [
|
||||
'Will be used by ovsdb-client when monitoring and '
|
||||
'used for the all ovsdb commands when native '
|
||||
'ovsdb_interface is enabled'
|
||||
))
|
||||
)),
|
||||
cfg.StrOpt('ssl_key_file',
|
||||
help=_('The SSL private key file to use when interacting with '
|
||||
'OVSDB. Required when using an "ssl:" prefixed '
|
||||
'ovsdb_connection'
|
||||
)),
|
||||
cfg.StrOpt('ssl_cert_file',
|
||||
help=_('The SSL certificate file to use when interacting '
|
||||
'with OVSDB. Required when using an "ssl:" prefixed '
|
||||
'ovsdb_connection'
|
||||
)),
|
||||
cfg.StrOpt('ssl_ca_cert_file',
|
||||
help=_('The Certificate Authority (CA) certificate to use '
|
||||
'when interacting with OVSDB. Required when using an '
|
||||
'"ssl:" prefixed ovsdb_connection'
|
||||
)),
|
||||
]
|
||||
|
||||
|
||||
|
@ -18,9 +18,14 @@ from ovsdbapp.backend.ovs_idl import connection
|
||||
from ovsdbapp.backend.ovs_idl import idlutils
|
||||
|
||||
from neutron.agent.ovsdb.native import connection as native_conn
|
||||
from neutron.agent.ovsdb.native import exceptions as ovsdb_exc
|
||||
from neutron.agent.ovsdb.native import helpers
|
||||
from neutron.tests import base
|
||||
|
||||
SSL_KEY_FILE = '/tmp/dummy.pem'
|
||||
SSL_CERT_FILE = '/tmp/dummy.crt'
|
||||
SSL_CA_FILE = '/tmp/ca.crt'
|
||||
|
||||
|
||||
class TestOVSNativeConnection(base.BaseTestCase):
|
||||
@mock.patch.object(connection, 'threading')
|
||||
@ -46,3 +51,59 @@ class TestOVSNativeConnection(base.BaseTestCase):
|
||||
conn.start()
|
||||
self.assertEqual(3, len(mock_get_schema_helper.mock_calls))
|
||||
mock_helper.register_all.assert_called_once_with()
|
||||
|
||||
@mock.patch.object(native_conn, 'Stream')
|
||||
@mock.patch.object(connection, 'threading')
|
||||
@mock.patch.object(native_conn, 'idl')
|
||||
@mock.patch.object(idlutils, 'get_schema_helper')
|
||||
@mock.patch.object(native_conn, 'os')
|
||||
@mock.patch.object(native_conn, 'cfg')
|
||||
def test_ssl_connection(self, mock_cfg, mock_os, mock_get_schema_helper,
|
||||
mock_idl, mock_threading, mock_stream):
|
||||
mock_os.path.isfile.return_value = True
|
||||
mock_cfg.CONF.OVS.ovsdb_connection = 'ssl:127.0.0.1:6640'
|
||||
mock_cfg.CONF.OVS.ssl_key_file = SSL_KEY_FILE
|
||||
mock_cfg.CONF.OVS.ssl_cert_file = SSL_CERT_FILE
|
||||
mock_cfg.CONF.OVS.ssl_ca_cert_file = SSL_CA_FILE
|
||||
|
||||
conn = connection.Connection(idl=native_conn.idl_factory(),
|
||||
timeout=1)
|
||||
conn.start()
|
||||
mock_stream.ssl_set_private_key_file.assert_called_once_with(
|
||||
SSL_KEY_FILE
|
||||
)
|
||||
mock_stream.ssl_set_certificate_file.assert_called_once_with(
|
||||
SSL_CERT_FILE
|
||||
)
|
||||
mock_stream.ssl_set_ca_cert_file.assert_called_once_with(
|
||||
SSL_CA_FILE
|
||||
)
|
||||
|
||||
@mock.patch.object(native_conn, 'Stream')
|
||||
@mock.patch.object(connection, 'threading')
|
||||
@mock.patch.object(native_conn, 'idl')
|
||||
@mock.patch.object(idlutils, 'get_schema_helper')
|
||||
@mock.patch.object(native_conn, 'cfg')
|
||||
def test_ssl_conn_file_missing(self, mock_cfg, mock_get_schema_helper,
|
||||
mock_idl, mock_threading, mock_stream):
|
||||
mock_cfg.CONF.OVS.ovsdb_connection = 'ssl:127.0.0.1:6640'
|
||||
mock_cfg.CONF.OVS.ssl_key_file = SSL_KEY_FILE
|
||||
mock_cfg.CONF.OVS.ssl_cert_file = SSL_CERT_FILE
|
||||
mock_cfg.CONF.OVS.ssl_ca_cert_file = SSL_CA_FILE
|
||||
|
||||
self.assertRaises(ovsdb_exc.OvsdbSslConfigNotFound,
|
||||
native_conn.idl_factory)
|
||||
|
||||
@mock.patch.object(native_conn, 'Stream')
|
||||
@mock.patch.object(connection, 'threading')
|
||||
@mock.patch.object(native_conn, 'idl')
|
||||
@mock.patch.object(idlutils, 'get_schema_helper')
|
||||
@mock.patch.object(native_conn, 'cfg')
|
||||
def test_ssl_conn_cfg_missing(self, mock_cfg, mock_get_schema_helper,
|
||||
mock_idl, mock_threading, mock_stream):
|
||||
mock_cfg.CONF.OVS.ovsdb_connection = 'ssl:127.0.0.1:6640'
|
||||
mock_cfg.CONF.OVS.ssl_key_file = None
|
||||
mock_cfg.CONF.OVS.ssl_cert_file = None
|
||||
mock_cfg.CONF.OVS.ssl_ca_cert_file = None
|
||||
self.assertRaises(ovsdb_exc.OvsdbSslRequiredOptError,
|
||||
native_conn.idl_factory)
|
||||
|
@ -0,0 +1,8 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Neutron agents now support SSL connections to OVSDB server.
|
||||
To enable an SSL based connection, use an ``ssl`` prefixed URI for the
|
||||
``ovsdb_connection`` setting. When using SSL it is also required to set
|
||||
new ``ovs`` group options which include ``ssl_key_file``, ``ssl_cert_file``, and
|
||||
``ssl_ca_cert_file``.
|
Loading…
Reference in New Issue
Block a user