DRY'ed keystone session creation and retrieval

Also corrected importing of keystone config options

Change-Id: Icf4ea584bb199d36f848104254a529e19a6cf8ef
This commit is contained in:
Brandon Logan 2015-03-29 15:25:43 -05:00
parent ccecb6ea26
commit 98792dd462
10 changed files with 106 additions and 136 deletions

View File

@ -18,20 +18,18 @@ Common classes for Barbican certificate handling
"""
from barbicanclient import client as barbican_client
from keystoneclient.auth.identity import v3 as keystone_client
from keystoneclient import session
from oslo_config import cfg
from oslo_log import log as logging
from oslo_utils import excutils
from octavia.certificates.common import cert
from octavia.common import keystone
from octavia.i18n import _LE
LOG = logging.getLogger(__name__)
CONF = cfg.CONF
CONF.import_group('keystone_authtoken', 'octavia.common.config')
class BarbicanCert(cert.Cert):
@ -57,32 +55,9 @@ class BarbicanCert(cert.Cert):
return self._cert_container.private_key_passphrase.payload
class BarbicanKeystoneAuth(object):
_keystone_session = None
class BarbicanAuth(object):
_barbican_client = None
@classmethod
def _get_keystone_session(cls):
"""Initializes a Keystone session.
:return: a Keystone Session object
:raises Exception: if the session cannot be established
"""
if not cls._keystone_session:
try:
kc = keystone_client.Password(
auth_url=CONF.keystone_authtoken.auth_uri,
username=CONF.keystone_authtoken.admin_user,
password=CONF.keystone_authtoken.admin_password,
project_id=CONF.keystone_authtoken.admin_project_id
)
cls._keystone_session = session.Session(auth=kc)
except Exception as e:
with excutils.save_and_reraise_exception():
LOG.error(_LE(
"Error creating Keystone session: %s"), e)
return cls._keystone_session
@classmethod
def get_barbican_client(cls):
"""Creates a Barbican client object.
@ -93,7 +68,7 @@ class BarbicanKeystoneAuth(object):
if not cls._barbican_client:
try:
cls._barbican_client = barbican_client.Client(
session=cls._get_keystone_session()
session=keystone.get_session()
)
except Exception as e:
with excutils.save_and_reraise_exception():

View File

@ -56,7 +56,7 @@ class BarbicanCertGenerator(cert_gen.CertGenerator):
:return: PEM encoded private key
:raises Exception: If private key generation fails
"""
connection = barbican_common.BarbicanKeystoneAuth.get_barbican_client()
connection = barbican_common.BarbicanAuth.get_barbican_client()
order = connection.orders.create_asymmetric(
bit_length=bit_length,
algorithm='rsa',

View File

@ -48,7 +48,7 @@ class BarbicanCertManager(cert_mgr.CertManager):
:returns: the container_ref of the stored cert
:raises Exception: if certificate storage fails
"""
connection = barbican_common.BarbicanKeystoneAuth.get_barbican_client()
connection = barbican_common.BarbicanAuth.get_barbican_client()
LOG.info(_LI(
"Storing certificate container '{0}' in Barbican."
@ -126,7 +126,7 @@ class BarbicanCertManager(cert_mgr.CertManager):
certificate data
:raises Exception: if certificate retrieval fails
"""
connection = barbican_common.BarbicanKeystoneAuth.get_barbican_client()
connection = barbican_common.BarbicanAuth.get_barbican_client()
LOG.info(_LI(
"Loading certificate container {0} from Barbican."
@ -160,7 +160,7 @@ class BarbicanCertManager(cert_mgr.CertManager):
:raises Exception: if deregistration fails
"""
connection = barbican_common.BarbicanKeystoneAuth.get_barbican_client()
connection = barbican_common.BarbicanAuth.get_barbican_client()
LOG.info(_LI(
"Deregistering as a consumer of {0} in Barbican."
@ -184,7 +184,7 @@ class BarbicanCertManager(cert_mgr.CertManager):
:param cert_ref: the UUID of the cert to delete
:raises Exception: if certificate deletion fails
"""
connection = barbican_common.BarbicanKeystoneAuth.get_barbican_client()
connection = barbican_common.BarbicanAuth.get_barbican_client()
LOG.info(_LI(
"Recursively deleting certificate container {0} from Barbican."

View File

@ -75,13 +75,6 @@ core_opts = [
' more than one region.')),
]
keystone_authtoken_opts = [
cfg.StrOpt('auth_uri'),
cfg.StrOpt('admin_user'),
cfg.StrOpt('admin_password'),
cfg.StrOpt('admin_project_id'),
]
networking_opts = [
cfg.StrOpt('lb_network_name', help=_('Name of amphora internal network')),
]
@ -90,9 +83,9 @@ core_cli_opts = []
# Register the configuration options
cfg.CONF.register_opts(core_opts)
cfg.CONF.register_opts(keystone_authtoken_opts, group='keystone_authtoken')
cfg.CONF.register_opts(networking_opts, group='networking')
cfg.CONF.register_cli_opts(core_cli_opts)
cfg.CONF.import_group('keystone_authtoken', 'keystonemiddleware.auth_token')
# Ensure that the control exchange is set correctly
messaging.set_transport_defaults(control_exchange='octavia')

View File

@ -0,0 +1,57 @@
# Copyright 2015 Rackspace
#
# 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 keystoneclient.auth.identity import v2 as v2_client
from keystoneclient.auth.identity import v3 as v3_client
from keystoneclient import session
from oslo_config import cfg
from oslo_log import log as logging
from oslo_utils import excutils
from octavia.i18n import _LE
LOG = logging.getLogger(__name__)
cfg.CONF.import_group('keystone_authtoken', 'keystonemiddleware.auth_token')
_SESSION = None
def get_session():
"""Initializes a Keystone session.
:return: a Keystone Session object
:raises Exception: if the session cannot be established
"""
global _SESSION
if not _SESSION:
if cfg.CONF.keystone_authtoken.auth_version == '2':
client = v2_client
elif cfg.CONF.keystone_authtoken.auth_version == '3':
client = v3_client
else:
raise Exception('Unknown keystone version!')
try:
kc = client.Password(
auth_url=cfg.CONF.keystone_authtoken.auth_uri,
username=cfg.CONF.keystone_authtoken.admin_user,
password=cfg.CONF.keystone_authtoken.admin_password,
tenant_name=cfg.CONF.keystone_authtoken.admin_tenant_name
)
_SESSION = session.Session(auth=kc)
except Exception:
with excutils.save_and_reraise_exception():
LOG.exception(_LE("Error creating Keystone session."))
return _SESSION

View File

@ -12,8 +12,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from keystoneclient.auth.identity import v3 as keystone_client
from keystoneclient import session
from novaclient import client as nova_client
from oslo_config import cfg
from oslo_log import log as logging
@ -22,6 +20,7 @@ from oslo_utils import excutils
from octavia.common import constants
from octavia.common import data_models as models
from octavia.common import exceptions
from octavia.common import keystone
from octavia.compute import compute_base
from octavia.i18n import _LE
@ -38,7 +37,7 @@ class VirtualMachineManager(compute_base.ComputeBase):
def __init__(self, region=None):
super(VirtualMachineManager, self).__init__()
# Must initialize nova api
self._nova_client = NovaKeystoneAuth.get_nova_client(region)
self._nova_client = NovaAuth.get_nova_client(region)
self.manager = self._nova_client.servers
def get_logger(self):
@ -150,32 +149,9 @@ class VirtualMachineManager(compute_base.ComputeBase):
return response
class NovaKeystoneAuth(object):
_keystone_session = None
class NovaAuth(object):
_nova_client = None
# TODO(rm_you): refactor for common availability
@classmethod
def _get_keystone_session(cls):
"""Initializes a Keystone session.
:return: a Keystone Session object
:raises Exception: if the session cannot be established
"""
if not cls._keystone_session:
try:
kc = keystone_client.Password(
auth_url=CONF.keystone_authtoken.auth_uri,
username=CONF.keystone_authtoken.admin_user,
password=CONF.keystone_authtoken.admin_password,
project_id=CONF.keystone_authtoken.admin_project_id
)
cls._keystone_session = session.Session(auth=kc)
except Exception:
with excutils.save_and_reraise_exception():
LOG.exception(_LE("Error creating Keystone session."))
return cls._keystone_session
@classmethod
def get_nova_client(cls, region):
"""Create nova client object.
@ -187,7 +163,7 @@ class NovaKeystoneAuth(object):
if not cls._nova_client:
try:
cls._nova_client = nova_client.Client(
constants.NOVA_2, session=cls._get_keystone_session(),
constants.NOVA_2, session=keystone.get_session(),
region_name=region
)
except Exception:

View File

@ -11,70 +11,44 @@
# 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 barbicanclient import client as barbican_client
from keystoneclient import session
import mock
import octavia.certificates.common.barbican as barbican_common
from octavia.common import keystone
import octavia.tests.unit.base as base
class TestBarbicanAuth(base.TestCase):
def setUp(self):
# Reset the session and client
barbican_common.BarbicanKeystoneAuth._keystone_session = None
barbican_common.BarbicanKeystoneAuth._barbican_client = None
# Reset the client
barbican_common.BarbicanAuth._barbican_client = None
keystone._SESSION = None
super(TestBarbicanAuth, self).setUp()
def test_get_keystone_client(self):
# There should be no existing session
self.assertIsNone(
barbican_common.BarbicanKeystoneAuth._keystone_session
)
# Get us a session
ks1 = barbican_common.BarbicanKeystoneAuth._get_keystone_session()
# Our returned session should also be the saved session
self.assertIsInstance(
barbican_common.BarbicanKeystoneAuth._keystone_session,
session.Session
)
self.assertIs(
barbican_common.BarbicanKeystoneAuth._keystone_session,
ks1
)
# Getting the session again should return the same object
ks2 = barbican_common.BarbicanKeystoneAuth._get_keystone_session()
self.assertIs(ks1, ks2)
def test_get_barbican_client(self):
# There should be no existing client
self.assertIsNone(
barbican_common.BarbicanKeystoneAuth._barbican_client
)
self.assertIsNone(keystone._SESSION)
# Mock out the keystone session and get the client
barbican_common.BarbicanKeystoneAuth._keystone_session = (
mock.MagicMock()
)
bc1 = barbican_common.BarbicanKeystoneAuth.get_barbican_client()
keystone._SESSION = mock.MagicMock()
bc1 = barbican_common.BarbicanAuth.get_barbican_client()
# Our returned client should also be the saved client
self.assertIsInstance(
barbican_common.BarbicanKeystoneAuth._barbican_client,
barbican_common.BarbicanAuth._barbican_client,
barbican_client.Client
)
self.assertIs(
barbican_common.BarbicanKeystoneAuth._barbican_client,
barbican_common.BarbicanAuth._barbican_client,
bc1
)
# Getting the session again should return the same object
bc2 = barbican_common.BarbicanKeystoneAuth.get_barbican_client()
bc2 = barbican_common.BarbicanAuth.get_barbican_client()
self.assertIs(bc1, bc2)

View File

@ -62,7 +62,7 @@ class TestBarbicanManager(base.TestCase):
# Mock out the client
bc = mock.MagicMock()
bc.containers.create_certificate.return_value = self.empty_container
barbican_common.BarbicanKeystoneAuth._barbican_client = bc
barbican_common.BarbicanAuth._barbican_client = bc
# Attempt to store a cert
barbican_cert_mgr.BarbicanCertManager.store_cert(
@ -104,7 +104,7 @@ class TestBarbicanManager(base.TestCase):
]
bc.secrets.create.side_effect = test_secrets
self.empty_container.store.side_effect = ValueError()
barbican_common.BarbicanKeystoneAuth._barbican_client = bc
barbican_common.BarbicanAuth._barbican_client = bc
# Attempt to store a cert
self.assertRaises(
@ -144,7 +144,7 @@ class TestBarbicanManager(base.TestCase):
# Mock out the client
bc = mock.MagicMock()
bc.containers.register_consumer.return_value = self.container
barbican_common.BarbicanKeystoneAuth._barbican_client = bc
barbican_common.BarbicanAuth._barbican_client = bc
# Get the container data
data = barbican_cert_mgr.BarbicanCertManager.get_cert(
@ -175,7 +175,7 @@ class TestBarbicanManager(base.TestCase):
# Mock out the client
bc = mock.MagicMock()
bc.containers.get.return_value = self.container
barbican_common.BarbicanKeystoneAuth._barbican_client = bc
barbican_common.BarbicanAuth._barbican_client = bc
# Get the container data
data = barbican_cert_mgr.BarbicanCertManager.get_cert(
@ -201,7 +201,7 @@ class TestBarbicanManager(base.TestCase):
def test_delete_cert(self):
# Mock out the client
bc = mock.MagicMock()
barbican_common.BarbicanKeystoneAuth._barbican_client = bc
barbican_common.BarbicanAuth._barbican_client = bc
# Attempt to deregister as a consumer
barbican_cert_mgr.BarbicanCertManager.delete_cert(
@ -221,7 +221,7 @@ class TestBarbicanManager(base.TestCase):
# Mock out the client
bc = mock.MagicMock()
bc.containers.get.return_value = self.container
barbican_common.BarbicanKeystoneAuth._barbican_client = bc
barbican_common.BarbicanAuth._barbican_client = bc
# Attempt to store a cert
barbican_cert_mgr.BarbicanCertManager._actually_delete_cert(

View File

@ -21,12 +21,12 @@ from oslo_utils import uuidutils
from octavia.common import constants
from octavia.common import data_models as models
from octavia.common import exceptions
from octavia.common import keystone
import octavia.compute.drivers.nova_driver as nova_common
import octavia.tests.unit.base as base
CONF = cfg.CONF
CONF.import_group('networking', 'octavia.common.config')
class TestNovaClient(base.TestCase):
@ -35,6 +35,8 @@ class TestNovaClient(base.TestCase):
net_name = uuidutils.generate_uuid()
CONF.set_override(group='networking', name='lb_network_name',
override=net_name)
CONF.set_override(group='keystone_authtoken', name='auth_version',
override='2')
self.amphora = models.Amphora(
compute_id=uuidutils.generate_uuid(),
status='ACTIVE',
@ -116,58 +118,50 @@ class TestNovaClient(base.TestCase):
class TestNovaAuth(base.TestCase):
def setUp(self):
CONF.set_override(group='keystone_authtoken', name='auth_version',
override='2')
# Reset the session and client
nova_common.NovaKeystoneAuth._keystone_session = None
nova_common.NovaKeystoneAuth._nova_client = None
nova_common.NovaAuth._nova_client = None
keystone._SESSION = None
super(TestNovaAuth, self).setUp()
def test_get_keystone_client(self):
# There should be no existing session
self.assertIsNone(
nova_common.NovaKeystoneAuth._keystone_session
)
self.assertIsNone(keystone._SESSION)
# Get us a session
ks1 = nova_common.NovaKeystoneAuth._get_keystone_session()
ks1 = keystone.get_session()
# Our returned session should also be the saved session
self.assertIsInstance(
nova_common.NovaKeystoneAuth._keystone_session,
session.Session
)
self.assertIs(
nova_common.NovaKeystoneAuth._keystone_session,
ks1
)
self.assertIsInstance(keystone._SESSION, session.Session)
self.assertIs(keystone._SESSION, ks1)
# Getting the session again should return the same object
ks2 = nova_common.NovaKeystoneAuth._get_keystone_session()
ks2 = keystone.get_session()
self.assertIs(ks1, ks2)
def test_get_nova_client(self):
# There should be no existing client
self.assertIsNone(
nova_common.NovaKeystoneAuth._nova_client
nova_common.NovaAuth._nova_client
)
# Mock out the keystone session and get the client
nova_common.NovaKeystoneAuth._keystone_session = (
mock.MagicMock()
)
bc1 = nova_common.NovaKeystoneAuth.get_nova_client(region=None)
keystone._SESSION = mock.MagicMock()
bc1 = nova_common.NovaAuth.get_nova_client(region=None)
# Our returned client should also be the saved client
self.assertIsInstance(
nova_common.NovaKeystoneAuth._nova_client,
nova_common.NovaAuth._nova_client,
novaclient.v2.client.Client
)
self.assertIs(
nova_common.NovaKeystoneAuth._nova_client,
nova_common.NovaAuth._nova_client,
bc1
)
# Getting the session again should return the same object
bc2 = nova_common.NovaKeystoneAuth.get_nova_client(
bc2 = nova_common.NovaAuth.get_nova_client(
region="test-region")
self.assertIs(bc1, bc2)

View File

@ -10,6 +10,7 @@ Babel>=1.3
eventlet>=0.16.1,!=0.17.0
requests>=2.2.0,!=2.4.0
jsonrpclib
keystonemiddleware>=1.5.0
netaddr>=0.7.12
python-neutronclient>=2.3.11,<3
WebOb>=1.2.3