]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Adds POST method support in the metadata service
authorAlessandro Pilotti <ap@pilotti.it>
Wed, 1 May 2013 04:14:59 +0000 (07:14 +0300)
committerAlessandro Pilotti <ap@pilotti.it>
Wed, 1 May 2013 22:28:04 +0000 (01:28 +0300)
Fixes bug: #1092311

The password generation feature introduced in Grizzly requires POST
support in the metadata service.

Support has been added to both the metadata agent and namespace proxy.
Tests have been added and updated accordingly.

Change-Id: If7ef6bede1775ad682822cb868518ec732b90805

quantum/agent/metadata/agent.py
quantum/agent/metadata/namespace_proxy.py
quantum/tests/unit/test_metadata_agent.py
quantum/tests/unit/test_metadata_namespace_proxy.py

index d04231b26a36e2ee539f625bf3aa3e027c45456f..9e37251d1d41dc5b9bbaad2874d1394ba8f283f5 100644 (file)
@@ -139,7 +139,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))
@@ -153,6 +154,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.'
index 0a9a317bed7fc64f33db1bfe50aeba33b9c3d8bc..f6282e8b4284a207effa2c471a15eff75ab077df 100644 (file)
@@ -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)
+                                       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.'
index 1b0af7fc24dbe15320f9078e789be69ab4a26b20..c50543ff8fbccca517e2169718018034bb189d28 100644 (file)
@@ -180,9 +180,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'
@@ -193,16 +196,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))
 
@@ -214,6 +223,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)
index dc9e0ee5422f8639b42be02fd2ed55fbc3fa2310..ba1e72cb45883a4fc9e2ff1c2640c959b160d3f2 100644 (file)
@@ -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=''
                 )]
             )