Fix metadata agent's auth info caching

metadata agent does not implement auth info cache correctly but
retrieves from keystone every time

Change-Id: Ifc1f580185d7600b48aaf80d112fc80e0c4253f2
Closes-bug: #1365352
This commit is contained in:
Chengli XU 2014-09-03 14:52:34 +08:00 committed by Chengli Xu
parent eef2b10c88
commit 565eccfadd
2 changed files with 68 additions and 6 deletions

View File

@ -146,6 +146,7 @@ class MetadataProxyHandler(object):
device_id=router_id, device_id=router_id,
device_owner=[n_const.DEVICE_OWNER_ROUTER_INTF, device_owner=[n_const.DEVICE_OWNER_ROUTER_INTF,
n_const.DEVICE_OWNER_DVR_INTERFACE])['ports'] n_const.DEVICE_OWNER_DVR_INTERFACE])['ports']
self.auth_info = qclient.get_auth_info()
return tuple(p['network_id'] for p in internal_ports) return tuple(p['network_id'] for p in internal_ports)
@utils.cache_method_results @utils.cache_method_results
@ -161,6 +162,7 @@ class MetadataProxyHandler(object):
all_ports = qclient.list_ports( all_ports = qclient.list_ports(
fixed_ips=['ip_address=%s' % remote_address])['ports'] fixed_ips=['ip_address=%s' % remote_address])['ports']
self.auth_info = qclient.get_auth_info()
networks = set(networks) networks = set(networks)
return [p for p in all_ports if p['network_id'] in networks] return [p for p in all_ports if p['network_id'] in networks]
@ -183,15 +185,12 @@ class MetadataProxyHandler(object):
return self._get_ports_for_remote_address(remote_address, networks) return self._get_ports_for_remote_address(remote_address, networks)
def _get_instance_and_tenant_id(self, req): def _get_instance_and_tenant_id(self, req):
qclient = self._get_neutron_client()
remote_address = req.headers.get('X-Forwarded-For') remote_address = req.headers.get('X-Forwarded-For')
network_id = req.headers.get('X-Neutron-Network-ID') network_id = req.headers.get('X-Neutron-Network-ID')
router_id = req.headers.get('X-Neutron-Router-ID') router_id = req.headers.get('X-Neutron-Router-ID')
ports = self._get_ports(remote_address, network_id, router_id) ports = self._get_ports(remote_address, network_id, router_id)
self.auth_info = qclient.get_auth_info()
if len(ports) == 1: if len(ports) == 1:
return ports[0]['device_id'], ports[0]['tenant_id'] return ports[0]['device_id'], ports[0]['tenant_id']
return None, None return None, None

View File

@ -218,6 +218,8 @@ class TestMetadataProxyHandlerCache(base.BaseTestCase):
return {'ports': list_ports_retval.pop(0)} return {'ports': list_ports_retval.pop(0)}
self.qclient.return_value.list_ports.side_effect = mock_list_ports self.qclient.return_value.list_ports.side_effect = mock_list_ports
self.qclient.return_value.get_auth_info.return_value = {
'auth_token': None, 'endpoint_url': None}
instance_id, tenant_id = self.handler._get_instance_and_tenant_id(req) instance_id, tenant_id = self.handler._get_instance_and_tenant_id(req)
new_qclient_call = mock.call( new_qclient_call = mock.call(
username=FakeConf.admin_user, username=FakeConf.admin_user,
@ -231,7 +233,8 @@ class TestMetadataProxyHandlerCache(base.BaseTestCase):
ca_cert=FakeConf.auth_ca_cert, ca_cert=FakeConf.auth_ca_cert,
endpoint_url=None, endpoint_url=None,
endpoint_type=FakeConf.endpoint_type) endpoint_type=FakeConf.endpoint_type)
expected = [new_qclient_call]
expected = []
if router_id: if router_id:
expected.extend([ expected.extend([
@ -239,13 +242,15 @@ class TestMetadataProxyHandlerCache(base.BaseTestCase):
mock.call().list_ports( mock.call().list_ports(
device_id=router_id, device_id=router_id,
device_owner=EXPECTED_OWNER_ROUTERS device_owner=EXPECTED_OWNER_ROUTERS
) ),
mock.call().get_auth_info()
]) ])
expected.extend([ expected.extend([
new_qclient_call, new_qclient_call,
mock.call().list_ports( mock.call().list_ports(
fixed_ips=['ip_address=192.168.1.1']) fixed_ips=['ip_address=192.168.1.1']),
mock.call().get_auth_info()
]) ])
self.qclient.assert_has_calls(expected) self.qclient.assert_has_calls(expected)
@ -322,6 +327,64 @@ class TestMetadataProxyHandlerCache(base.BaseTestCase):
(None, None) (None, None)
) )
def test_auth_info_cache(self):
router_id = 'the_id'
list_ports = [
[{'network_id': 'net1'}],
[{'device_id': 'did', 'tenant_id': 'tid', 'network_id': 'net1'}]]
def update_get_auth_info(*args, **kwargs):
self.qclient.return_value.get_auth_info.return_value = {
'auth_token': 'token', 'endpoint_url': 'uri'}
return {'ports': list_ports.pop(0)}
self.qclient.return_value.list_ports.side_effect = update_get_auth_info
new_qclient_call = mock.call(
username=FakeConf.admin_user,
tenant_name=FakeConf.admin_tenant_name,
region_name=FakeConf.auth_region,
auth_url=FakeConf.auth_url,
password=FakeConf.admin_password,
auth_strategy=FakeConf.auth_strategy,
token=None,
insecure=FakeConf.auth_insecure,
ca_cert=FakeConf.auth_ca_cert,
endpoint_url=None,
endpoint_type=FakeConf.endpoint_type)
cached_qclient_call = mock.call(
username=FakeConf.admin_user,
tenant_name=FakeConf.admin_tenant_name,
region_name=FakeConf.auth_region,
auth_url=FakeConf.auth_url,
password=FakeConf.admin_password,
auth_strategy=FakeConf.auth_strategy,
token='token',
insecure=FakeConf.auth_insecure,
ca_cert=FakeConf.auth_ca_cert,
endpoint_url='uri',
endpoint_type=FakeConf.endpoint_type)
headers = {'X-Forwarded-For': '192.168.1.10',
'X-Neutron-Router-ID': router_id}
req = mock.Mock(headers=headers)
self.handler._get_instance_and_tenant_id(req)
expected = [
new_qclient_call,
mock.call().list_ports(
device_id=router_id,
device_owner=EXPECTED_OWNER_ROUTERS
),
mock.call().get_auth_info(),
cached_qclient_call,
mock.call().list_ports(fixed_ips=['ip_address=192.168.1.10']),
mock.call().get_auth_info(),
]
self.qclient.assert_has_calls(expected)
def _proxy_request_test_helper(self, response_code=200, method='GET'): def _proxy_request_test_helper(self, response_code=200, method='GET'):
hdrs = {'X-Forwarded-For': '8.8.8.8'} hdrs = {'X-Forwarded-For': '8.8.8.8'}
body = 'body' body = 'body'