Fix metadata agent's auth info caching

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

Cherry-pick from https://review.openstack.org/#/c/118996/

Conflicts:
	neutron/agent/metadata/agent.py
	neutron/tests/unit/test_metadata_agent.py

Change-Id: Ifc1f580185d7600b48aaf80d112fc80e0c4253f2
Closes-bug: #1365352
This commit is contained in:
Chengli XU 2014-09-03 14:52:34 +08:00
parent 2dfe6fdc3e
commit 97d622a13b
2 changed files with 73 additions and 7 deletions

View File

@ -132,6 +132,7 @@ class MetadataProxyHandler(object):
internal_ports = qclient.list_ports(
device_id=router_id,
device_owner=n_const.DEVICE_OWNER_ROUTER_INTF)['ports']
self.auth_info = qclient.get_auth_info()
return tuple(p['network_id'] for p in internal_ports)
@utils.cache_method_results
@ -145,9 +146,11 @@ class MetadataProxyHandler(object):
"""
qclient = self._get_neutron_client()
return qclient.list_ports(
all_ports = qclient.list_ports(
network_id=networks,
fixed_ips=['ip_address=%s' % remote_address])['ports']
self.auth_info = qclient.get_auth_info()
return all_ports
def _get_ports(self, remote_address, network_id=None, router_id=None):
"""Search for all ports that contain passed ip address and belongs to
@ -168,15 +171,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

View File

@ -210,6 +210,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,
@ -223,7 +225,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([
@ -231,14 +234,16 @@ class TestMetadataProxyHandlerCache(base.BaseTestCase):
mock.call().list_ports(
device_id=router_id,
device_owner=constants.DEVICE_OWNER_ROUTER_INTF
)
),
mock.call().get_auth_info()
])
expected.extend([
new_qclient_call,
mock.call().list_ports(
network_id=networks or tuple(),
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)
@ -313,6 +318,67 @@ class TestMetadataProxyHandlerCache(base.BaseTestCase):
(None, None)
)
def test_auth_info_cache(self):
router_id = 'the_id'
networks = ('net1',)
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=constants.DEVICE_OWNER_ROUTER_INTF
),
mock.call().get_auth_info(),
cached_qclient_call,
mock.call().list_ports(
network_id=networks or tuple(),
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'