diff --git a/quantum/agent/metadata/agent.py b/quantum/agent/metadata/agent.py index 4ceb4d0e4..7bdfae8df 100644 --- a/quantum/agent/metadata/agent.py +++ b/quantum/agent/metadata/agent.py @@ -134,7 +134,8 @@ class MetadataProxyHandler(object): '')) h = httplib2.Http() - resp, content = h.request(url, headers=headers) + resp, content = h.request(url, method=req.method, headers=headers, + body=req.body) if resp.status == 200: LOG.debug(str(resp)) @@ -148,6 +149,8 @@ class MetadataProxyHandler(object): return webob.exc.HTTPForbidden() elif resp.status == 404: return webob.exc.HTTPNotFound() + elif resp.status == 409: + return webob.exc.HTTPConflict() elif resp.status == 500: msg = _( 'Remote metadata server experienced an internal server error.' diff --git a/quantum/agent/metadata/namespace_proxy.py b/quantum/agent/metadata/namespace_proxy.py index 47f47db52..d0c1b69da 100644 --- a/quantum/agent/metadata/namespace_proxy.py +++ b/quantum/agent/metadata/namespace_proxy.py @@ -75,15 +75,18 @@ class NetworkMetadataProxyHandler(object): LOG.debug(_("Request: %s"), req) try: return self._proxy_request(req.remote_addr, + req.method, req.path_info, - req.query_string) - except Exception, e: + req.query_string, + req.body) + except Exception: LOG.exception(_("Unexpected error.")) msg = _('An unknown error has occurred. ' 'Please try your request again.') return webob.exc.HTTPInternalServerError(explanation=unicode(msg)) - def _proxy_request(self, remote_address, path_info, query_string): + def _proxy_request(self, remote_address, method, path_info, + query_string, body): headers = { 'X-Forwarded-For': remote_address, } @@ -103,7 +106,9 @@ class NetworkMetadataProxyHandler(object): h = httplib2.Http() resp, content = h.request( url, + method=method, headers=headers, + body=body, connection_type=UnixDomainHTTPConnection) if resp.status == 200: @@ -112,6 +117,8 @@ class NetworkMetadataProxyHandler(object): return content elif resp.status == 404: return webob.exc.HTTPNotFound() + elif resp.status == 409: + return webob.exc.HTTPConflict() elif resp.status == 500: msg = _( 'Remote metadata server experienced an internal server error.' diff --git a/quantum/tests/unit/test_metadata_agent.py b/quantum/tests/unit/test_metadata_agent.py index 8a0b02d39..c81a237a7 100644 --- a/quantum/tests/unit/test_metadata_agent.py +++ b/quantum/tests/unit/test_metadata_agent.py @@ -178,9 +178,12 @@ class TestMetadataProxyHandler(base.BaseTestCase): self._get_instance_id_helper(headers, ports, networks=['the_id']) ) - def _proxy_request_test_helper(self, response_code): + def _proxy_request_test_helper(self, response_code=200, method='GET'): hdrs = {'X-Forwarded-For': '8.8.8.8'} - req = mock.Mock(path_info='/the_path', query_string='', headers=hdrs) + body = 'body' + + req = mock.Mock(path_info='/the_path', query_string='', headers=hdrs, + method=method, body=body) resp = mock.Mock(status=response_code) with mock.patch.object(self.handler, '_sign_instance_id') as sign: sign.return_value = 'signed' @@ -191,16 +194,22 @@ class TestMetadataProxyHandler(base.BaseTestCase): mock_http.assert_has_calls([ mock.call().request( 'http://9.9.9.9:8775/the_path', + method=method, headers={ 'X-Forwarded-For': '8.8.8.8', 'X-Instance-ID-Signature': 'signed', 'X-Instance-ID': 'the_id' - } + }, + body=body )] ) return retval + def test_proxy_request_post(self): + self.assertEqual('content', + self._proxy_request_test_helper(method='POST')) + def test_proxy_request_200(self): self.assertEqual('content', self._proxy_request_test_helper(200)) @@ -212,6 +221,10 @@ class TestMetadataProxyHandler(base.BaseTestCase): self.assertIsInstance(self._proxy_request_test_helper(404), webob.exc.HTTPNotFound) + def test_proxy_request_409(self): + self.assertIsInstance(self._proxy_request_test_helper(409), + webob.exc.HTTPConflict) + def test_proxy_request_500(self): self.assertIsInstance(self._proxy_request_test_helper(500), webob.exc.HTTPInternalServerError) diff --git a/quantum/tests/unit/test_metadata_namespace_proxy.py b/quantum/tests/unit/test_metadata_namespace_proxy.py index 4ad29645c..225332c27 100644 --- a/quantum/tests/unit/test_metadata_namespace_proxy.py +++ b/quantum/tests/unit/test_metadata_namespace_proxy.py @@ -74,8 +74,10 @@ class TestNetworkMetadataProxyHandler(base.BaseTestCase): retval = self.handler(req) self.assertEqual(retval, 'value') proxy_req.assert_called_once_with(req.remote_addr, + req.method, req.path_info, - req.query_string) + req.query_string, + req.body) def test_no_argument_passed_to_init(self): with testtools.ExpectedException(ValueError): @@ -98,17 +100,21 @@ class TestNetworkMetadataProxyHandler(base.BaseTestCase): mock_http.return_value.request.return_value = (resp, 'content') retval = self.handler._proxy_request('192.168.1.1', + 'GET', '/latest/meta-data', + '', '') mock_http.assert_has_calls([ mock.call().request( 'http://169.254.169.254/latest/meta-data', + method='GET', headers={ 'X-Forwarded-For': '192.168.1.1', 'X-Quantum-Router-ID': 'router_id' }, - connection_type=ns_proxy.UnixDomainHTTPConnection + connection_type=ns_proxy.UnixDomainHTTPConnection, + body='' )] ) @@ -122,17 +128,21 @@ class TestNetworkMetadataProxyHandler(base.BaseTestCase): mock_http.return_value.request.return_value = (resp, 'content') retval = self.handler._proxy_request('192.168.1.1', + 'GET', '/latest/meta-data', + '', '') mock_http.assert_has_calls([ mock.call().request( 'http://169.254.169.254/latest/meta-data', + method='GET', headers={ 'X-Forwarded-For': '192.168.1.1', 'X-Quantum-Network-ID': 'network_id' }, - connection_type=ns_proxy.UnixDomainHTTPConnection + connection_type=ns_proxy.UnixDomainHTTPConnection, + body='' )] ) @@ -146,22 +156,54 @@ class TestNetworkMetadataProxyHandler(base.BaseTestCase): mock_http.return_value.request.return_value = (resp, '') retval = self.handler._proxy_request('192.168.1.1', + 'GET', '/latest/meta-data', + '', '') mock_http.assert_has_calls([ mock.call().request( 'http://169.254.169.254/latest/meta-data', + method='GET', headers={ 'X-Forwarded-For': '192.168.1.1', 'X-Quantum-Network-ID': 'network_id' }, - connection_type=ns_proxy.UnixDomainHTTPConnection + connection_type=ns_proxy.UnixDomainHTTPConnection, + body='' )] ) self.assertIsInstance(retval, webob.exc.HTTPNotFound) + def test_proxy_request_network_409(self): + self.handler.network_id = 'network_id' + + resp = mock.Mock(status=409) + with mock.patch('httplib2.Http') as mock_http: + mock_http.return_value.request.return_value = (resp, '') + + retval = self.handler._proxy_request('192.168.1.1', + 'POST', + '/latest/meta-data', + '', + '') + + mock_http.assert_has_calls([ + mock.call().request( + 'http://169.254.169.254/latest/meta-data', + method='POST', + headers={ + 'X-Forwarded-For': '192.168.1.1', + 'X-Quantum-Network-ID': 'network_id' + }, + connection_type=ns_proxy.UnixDomainHTTPConnection, + body='' + )] + ) + + self.assertIsInstance(retval, webob.exc.HTTPConflict) + def test_proxy_request_network_500(self): self.handler.network_id = 'network_id' @@ -170,17 +212,21 @@ class TestNetworkMetadataProxyHandler(base.BaseTestCase): mock_http.return_value.request.return_value = (resp, '') retval = self.handler._proxy_request('192.168.1.1', + 'GET', '/latest/meta-data', + '', '') mock_http.assert_has_calls([ mock.call().request( 'http://169.254.169.254/latest/meta-data', + method='GET', headers={ 'X-Forwarded-For': '192.168.1.1', 'X-Quantum-Network-ID': 'network_id' }, - connection_type=ns_proxy.UnixDomainHTTPConnection + connection_type=ns_proxy.UnixDomainHTTPConnection, + body='' )] ) @@ -195,17 +241,21 @@ class TestNetworkMetadataProxyHandler(base.BaseTestCase): with testtools.ExpectedException(Exception): self.handler._proxy_request('192.168.1.1', + 'GET', '/latest/meta-data', + '', '') mock_http.assert_has_calls([ mock.call().request( 'http://169.254.169.254/latest/meta-data', + method='GET', headers={ 'X-Forwarded-For': '192.168.1.1', 'X-Quantum-Network-ID': 'network_id' }, - connection_type=ns_proxy.UnixDomainHTTPConnection + connection_type=ns_proxy.UnixDomainHTTPConnection, + body='' )] ) @@ -218,17 +268,21 @@ class TestNetworkMetadataProxyHandler(base.BaseTestCase): with testtools.ExpectedException(Exception): self.handler._proxy_request('192.168.1.1', + 'GET', '/latest/meta-data', + '', '') mock_http.assert_has_calls([ mock.call().request( 'http://169.254.169.254/latest/meta-data', + method='GET', headers={ 'X-Forwarded-For': '192.168.1.1', 'X-Quantum-Network-ID': 'network_id' }, - connection_type=ns_proxy.UnixDomainHTTPConnection + connection_type=ns_proxy.UnixDomainHTTPConnection, + body='' )] )