Skip to content

Commit

Permalink
Merge "Cache Neutron Client for Admin Scenarios"
Browse files Browse the repository at this point in the history
  • Loading branch information
Jenkins authored and openstack-gerrit committed Nov 14, 2013
2 parents e5ca566 + 8533201 commit 706c690
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 5 deletions.
23 changes: 18 additions & 5 deletions nova/network/neutronv2/__init__.py
Expand Up @@ -19,6 +19,7 @@
from neutronclient.v2_0 import client as clientv20
from oslo.config import cfg

from nova.openstack.common import local
from nova.openstack.common import log as logging

CONF = cfg.CONF
Expand Down Expand Up @@ -46,11 +47,23 @@ def _get_client(token=None):


def get_client(context, admin=False):
# NOTE(dims): We need to use admin token, let us cache a
# thread local copy for re-using this client
# multiple times and to avoid excessive calls
# to neutron to fetch tokens. Some of the hackiness in this code
# will go away once BP auth-plugins is implemented.
# That blue print will ensure that tokens can be shared
# across clients as well
if admin or context.is_admin:
token = None
elif not context.auth_token:
raise exceptions.Unauthorized()
else:
if not hasattr(local.strong_store, 'neutron_client'):
local.strong_store.neutron_client = _get_client(token=None)
return local.strong_store.neutron_client

# We got a user token that we can use that as-is
if context.auth_token:
token = context.auth_token
return _get_client(token=token)

return _get_client(token=token)
# We did not get a user token and we should not be using
# an admin token so log an error
raise exceptions.Unauthorized()
47 changes: 47 additions & 0 deletions nova/tests/network/test_neutronv2.py
Expand Up @@ -31,6 +31,7 @@
from nova.network.neutronv2 import api as neutronapi
from nova.network.neutronv2 import constants
from nova.openstack.common import jsonutils
from nova.openstack.common import local
from nova import test
from nova import utils

Expand Down Expand Up @@ -1814,3 +1815,49 @@ def test_allocate_for_instance_extradhcpopts(self):

self._allocate_for_instance(1, dhcp_options=dhcp_opts)
CONF.set_override('dhcp_options_enabled', False)


class TestNeutronClientForAdminScenarios(test.TestCase):
def test_get_cached_neutron_client_for_admin(self):
self.flags(neutron_url='http://anyhost/')
self.flags(neutron_url_timeout=30)
my_context = context.RequestContext('userid',
'my_tenantid',
auth_token='token')

# Make multiple calls and ensure we get the same
# client back again and again
client = neutronv2.get_client(my_context, True)
client2 = neutronv2.get_client(my_context, True)
client3 = neutronv2.get_client(my_context, True)
self.assertEqual(client, client2)
self.assertEqual(client, client3)

# clear the cache
local.strong_store.neutron_client = None

# A new client should be created now
client4 = neutronv2.get_client(my_context, True)
self.assertNotEqual(client, client4)

def test_get_neutron_client_for_non_admin(self):
self.flags(neutron_url='http://anyhost/')
self.flags(neutron_url_timeout=30)
my_context = context.RequestContext('userid',
'my_tenantid',
auth_token='token')

# Multiple calls should return different clients
client = neutronv2.get_client(my_context)
client2 = neutronv2.get_client(my_context)
self.assertNotEqual(client, client2)

def test_get_neutron_client_for_non_admin_and_no_token(self):
self.flags(neutron_url='http://anyhost/')
self.flags(neutron_url_timeout=30)
my_context = context.RequestContext('userid',
'my_tenantid')

self.assertRaises(exceptions.Unauthorized,
neutronv2.get_client,
my_context)

0 comments on commit 706c690

Please sign in to comment.