diff --git a/Authors b/Authors index 6fe9a836..cf4b4056 100644 --- a/Authors +++ b/Authors @@ -91,6 +91,7 @@ Joseph W. Breu Josh Durgin Josh Kearney Josh Kleinpeter +Joshua Harlow Joshua McKenty Juan G. Hernando Rivero Julien Danjou diff --git a/nova/rpc/impl_kombu.py b/nova/rpc/impl_kombu.py index 99402f6b..82103b38 100644 --- a/nova/rpc/impl_kombu.py +++ b/nova/rpc/impl_kombu.py @@ -16,6 +16,7 @@ import itertools import socket +import ssl import sys import time import uuid @@ -28,11 +29,28 @@ import kombu.messaging import kombu.connection from nova import flags -from nova.rpc import common as rpc_common +from nova.openstack.common import cfg from nova.rpc import amqp as rpc_amqp +from nova.rpc import common as rpc_common +kombu_opts = [ + cfg.StrOpt('kombu_ssl_version', + default='', + help='SSL version to use (valid only if SSL enabled)'), + cfg.StrOpt('kombu_ssl_keyfile', + default='', + help='SSL key file (valid only if SSL enabled)'), + cfg.StrOpt('kombu_ssl_certfile', + default='', + help='SSL cert file (valid only if SSL enabled)'), + cfg.StrOpt('kombu_ssl_ca_certs', + default='', + help=('SSL certification authority file ' + '(valid only if SSL enabled)')), + ] FLAGS = flags.FLAGS +FLAGS.register_opts(kombu_opts) LOG = rpc_common.LOG @@ -345,9 +363,38 @@ class Connection(object): self.memory_transport = True else: self.memory_transport = False + + if FLAGS.rabbit_use_ssl: + self.params['ssl'] = self._fetch_ssl_params() + self.connection = None self.reconnect() + def _fetch_ssl_params(self): + """Handles fetching what ssl params + should be used for the connection (if any)""" + ssl_params = dict() + + # http://docs.python.org/library/ssl.html - ssl.wrap_socket + if FLAGS.kombu_ssl_version: + ssl_params['ssl_version'] = FLAGS.kombu_ssl_version + if FLAGS.kombu_ssl_keyfile: + ssl_params['keyfile'] = FLAGS.kombu_ssl_keyfile + if FLAGS.kombu_ssl_certfile: + ssl_params['certfile'] = FLAGS.kombu_ssl_certfile + if FLAGS.kombu_ssl_ca_certs: + ssl_params['ca_certs'] = FLAGS.kombu_ssl_ca_certs + # We might want to allow variations in the + # future with this? + ssl_params['cert_reqs'] = ssl.CERT_REQUIRED + + if not ssl_params: + # Just have the default behavior + return True + else: + # Return the extended behavior + return ssl_params + def _connect(self): """Connect to rabbit. Re-establish any queues that may have been declared before if we are reconnecting. Exceptions should diff --git a/nova/tests/rpc/test_kombu_ssl.py b/nova/tests/rpc/test_kombu_ssl.py new file mode 100644 index 00000000..246968b1 --- /dev/null +++ b/nova/tests/rpc/test_kombu_ssl.py @@ -0,0 +1,54 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 United States Government as represented by the +# Administrator of the National Aeronautics and Space Administration. +# 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. +""" +Unit Tests for remote procedure calls using kombu + ssl +""" + +from nova import test +from nova.rpc import impl_kombu + +# Flag settings we will ensure get passed to amqplib +SSL_VERSION = "SSLv2" +SSL_CERT = "/tmp/cert.blah.blah" +SSL_CA_CERT = "/tmp/cert.ca.blah.blah" +SSL_KEYFILE = "/tmp/keyfile.blah.blah" + + +class RpcKombuSslTestCase(test.TestCase): + + def setUp(self): + test.TestCase.setUp(self) + self.flags(kombu_ssl_keyfile=SSL_KEYFILE, + kombu_ssl_ca_certs=SSL_CA_CERT, + kombu_ssl_certfile=SSL_CERT, + kombu_ssl_version=SSL_VERSION, + rabbit_use_ssl=True) + + def test_ssl_on_extended(self): + rpc = impl_kombu + conn = rpc.create_connection(True) + c = conn.connection + #This might be kombu version dependent... + #Since we are now peaking into the internals of kombu... + self.assertTrue(isinstance(c.connection.ssl, dict)) + self.assertEqual(SSL_VERSION, c.connection.ssl.get("ssl_version")) + self.assertEqual(SSL_CERT, c.connection.ssl.get("certfile")) + self.assertEqual(SSL_CA_CERT, c.connection.ssl.get("ca_certs")) + self.assertEqual(SSL_KEYFILE, c.connection.ssl.get("keyfile")) + #That hash then goes into amqplib which then goes + #Into python ssl creation...