From 3c503adcf703db7b772208389b43ee09cee66185 Mon Sep 17 00:00:00 2001 From: Chengli XU Date: Wed, 3 Sep 2014 14:52:34 +0800 Subject: [PATCH] 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 --- neutron/agent/metadata/agent.py | 5 +- neutron/tests/unit/test_metadata_agent.py | 69 ++++++++++++++++++++++- 2 files changed, 68 insertions(+), 6 deletions(-) diff --git a/neutron/agent/metadata/agent.py b/neutron/agent/metadata/agent.py index 3381f1492..569a99171 100644 --- a/neutron/agent/metadata/agent.py +++ b/neutron/agent/metadata/agent.py @@ -146,6 +146,7 @@ class MetadataProxyHandler(object): device_id=router_id, device_owner=[n_const.DEVICE_OWNER_ROUTER_INTF, n_const.DEVICE_OWNER_DVR_INTERFACE])['ports'] + self.auth_info = qclient.get_auth_info() return tuple(p['network_id'] for p in internal_ports) @utils.cache_method_results @@ -161,6 +162,7 @@ class MetadataProxyHandler(object): all_ports = qclient.list_ports( fixed_ips=['ip_address=%s' % remote_address])['ports'] + self.auth_info = qclient.get_auth_info() networks = set(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) def _get_instance_and_tenant_id(self, req): - qclient = self._get_neutron_client() - remote_address = req.headers.get('X-Forwarded-For') network_id = req.headers.get('X-Neutron-Network-ID') router_id = req.headers.get('X-Neutron-Router-ID') ports = self._get_ports(remote_address, network_id, router_id) - self.auth_info = qclient.get_auth_info() if len(ports) == 1: return ports[0]['device_id'], ports[0]['tenant_id'] return None, None diff --git a/neutron/tests/unit/test_metadata_agent.py b/neutron/tests/unit/test_metadata_agent.py index 6a1e51cac..dbb3e1230 100644 --- a/neutron/tests/unit/test_metadata_agent.py +++ b/neutron/tests/unit/test_metadata_agent.py @@ -218,6 +218,8 @@ class TestMetadataProxyHandlerCache(base.BaseTestCase): return {'ports': list_ports_retval.pop(0)} 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) new_qclient_call = mock.call( username=FakeConf.admin_user, @@ -231,7 +233,8 @@ class TestMetadataProxyHandlerCache(base.BaseTestCase): ca_cert=FakeConf.auth_ca_cert, endpoint_url=None, endpoint_type=FakeConf.endpoint_type) - expected = [new_qclient_call] + + expected = [] if router_id: expected.extend([ @@ -239,13 +242,15 @@ class TestMetadataProxyHandlerCache(base.BaseTestCase): mock.call().list_ports( device_id=router_id, device_owner=EXPECTED_OWNER_ROUTERS - ) + ), + mock.call().get_auth_info() ]) expected.extend([ new_qclient_call, 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) @@ -322,6 +327,64 @@ class TestMetadataProxyHandlerCache(base.BaseTestCase): (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'): hdrs = {'X-Forwarded-For': '8.8.8.8'} body = 'body' -- 2.45.2