diff --git a/heatclient/common/http.py b/heatclient/common/http.py index 03d040a9..678081bb 100644 --- a/heatclient/common/http.py +++ b/heatclient/common/http.py @@ -26,9 +26,9 @@ import requests import six from six.moves.urllib import parse +from heatclient.common import utils from heatclient import exc from heatclient.openstack.common._i18n import _ -from heatclient.openstack.common._i18n import _LE from heatclient.openstack.common._i18n import _LW LOG = logging.getLogger(__name__) @@ -263,15 +263,7 @@ class HTTPClient(object): kwargs['data'] = jsonutils.dumps(kwargs['data']) resp = self._http_request(url, method, **kwargs) - body = resp.content - if 'application/json' in resp.headers.get('content-type', ''): - try: - body = resp.json() - except ValueError: - LOG.error(_LE('Could not decode response body as JSON')) - else: - body = None - + body = utils.get_response_body(resp) return resp, body def raw_request(self, method, url, **kwargs): diff --git a/heatclient/common/utils.py b/heatclient/common/utils.py index a64fc643..87ce0db6 100644 --- a/heatclient/common/utils.py +++ b/heatclient/common/utils.py @@ -14,6 +14,7 @@ # under the License. import base64 +import logging import os import textwrap import uuid @@ -28,8 +29,12 @@ import yaml from heatclient import exc from heatclient.openstack.common._i18n import _ +from heatclient.openstack.common._i18n import _LE from heatclient.openstack.common import cliutils +LOG = logging.getLogger(__name__) + + supported_formats = { "json": lambda x: jsonutils.dumps(x, indent=2), "yaml": yaml.safe_dump @@ -261,3 +266,15 @@ def normalise_file_path_to_url(path): return path path = os.path.abspath(path) return parse.urljoin('file:', request.pathname2url(path)) + + +def get_response_body(resp): + body = resp.content + if 'application/json' in resp.headers.get('content-type', ''): + try: + body = resp.json() + except ValueError: + LOG.error(_LE('Could not decode response body as JSON')) + else: + body = None + return body diff --git a/heatclient/tests/unit/test_actions.py b/heatclient/tests/unit/test_actions.py index 673cb876..1fcfe8a7 100644 --- a/heatclient/tests/unit/test_actions.py +++ b/heatclient/tests/unit/test_actions.py @@ -11,6 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +from heatclient.tests.unit import fakes from heatclient.v1 import actions import testtools @@ -29,7 +30,43 @@ class ActionManagerTest(testtools.TestCase): def json_request(self, *args, **kwargs): assert expect_args == args assert expect_kwargs['data'] == kwargs['data'] - return {}, {} + return fakes.FakeHTTPResponse( + '200', + '', + {'content-type': 'application/json'}, + {}), {} + + def raw_request(self, *args, **kwargs): + assert expect_args == args + return fakes.FakeHTTPResponse( + '200', + '', + {}, + {}) + + def head(self, url, **kwargs): + resp, body = self.json_request("HEAD", url, **kwargs) + return resp + + def get(self, url, **kwargs): + resp, body = self.json_request("GET", url, **kwargs) + return resp + + def post(self, url, **kwargs): + resp, body = self.json_request("POST", url, **kwargs) + return resp + + def put(self, url, **kwargs): + resp, body = self.json_request("PUT", url, **kwargs) + return resp + + def delete(self, url, **kwargs): + resp, body = self.raw_request("DELETE", url, **kwargs) + return resp + + def patch(self, url, **kwargs): + resp, body = self.json_request("PATCH", url, **kwargs) + return resp manager = actions.ActionManager(FakeAPI()) return manager diff --git a/heatclient/tests/unit/test_build_info.py b/heatclient/tests/unit/test_build_info.py index 3f2f1a9e..9ee93da1 100644 --- a/heatclient/tests/unit/test_build_info.py +++ b/heatclient/tests/unit/test_build_info.py @@ -12,10 +12,11 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. - import mock +from oslo_serialization import jsonutils import testtools +from heatclient.tests.unit import fakes from heatclient.v1 import build_info @@ -23,12 +24,17 @@ class BuildInfoManagerTest(testtools.TestCase): def setUp(self): super(BuildInfoManagerTest, self).setUp() self.client = mock.Mock() - self.client.json_request.return_value = ('resp', 'body') + self.client.get.return_value = fakes.FakeHTTPResponse( + 200, + None, + {'content-type': 'application/json'}, + jsonutils.dumps('body') + ) self.manager = build_info.BuildInfoManager(self.client) def test_build_info_makes_a_call_to_the_api(self): self.manager.build_info() - self.client.json_request.assert_called_once_with('GET', '/build_info') + self.client.get.assert_called_once_with('/build_info') def test_build_info_returns_the_response_body(self): response = self.manager.build_info() diff --git a/heatclient/tests/unit/test_common_http.py b/heatclient/tests/unit/test_common_http.py index 257d76fc..0dd106dc 100644 --- a/heatclient/tests/unit/test_common_http.py +++ b/heatclient/tests/unit/test_common_http.py @@ -293,7 +293,7 @@ class HttpClientTest(testtools.TestCase): fakes.FakeHTTPResponse( 200, 'OK', {'content-type': 'not/json'}, - '{}')) + {})) # Replay, create client, assert self.m.ReplayAll() client = http.HTTPClient('http://example.com:8004') diff --git a/heatclient/tests/unit/test_events.py b/heatclient/tests/unit/test_events.py index e94b7eb9..ec8e2d2c 100644 --- a/heatclient/tests/unit/test_events.py +++ b/heatclient/tests/unit/test_events.py @@ -111,9 +111,14 @@ class EventManagerTest(testtools.TestCase): assert args == expect return {}, {'event': []} + def get(self, *args, **kwargs): + pass + manager = events.EventManager(FakeAPI()) with mock.patch('heatclient.v1.events.Event'): self.m.StubOutWithMock(manager, '_resolve_stack_id') + self.m.StubOutWithMock(utils, 'get_response_body') + utils.get_response_body(mox.IgnoreArg()).AndReturn({'event': []}) manager._resolve_stack_id('teststack').AndReturn( 'teststack/abcd1234') self.m.ReplayAll() @@ -134,9 +139,14 @@ class EventManagerTest(testtools.TestCase): assert args == expect return {}, {'event': []} + def get(self, *args, **kwargs): + pass + manager = events.EventManager(FakeAPI()) with mock.patch('heatclient.v1.events.Event'): self.m.StubOutWithMock(manager, '_resolve_stack_id') + self.m.StubOutWithMock(utils, 'get_response_body') + utils.get_response_body(mox.IgnoreArg()).AndReturn({'event': []}) manager._resolve_stack_id('teststack').AndReturn( 'teststack/abcd1234') self.m.ReplayAll() diff --git a/heatclient/tests/unit/test_resource_types.py b/heatclient/tests/unit/test_resource_types.py index b820d553..d3153038 100644 --- a/heatclient/tests/unit/test_resource_types.py +++ b/heatclient/tests/unit/test_resource_types.py @@ -10,9 +10,10 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. - +import mock import testtools +from heatclient.common import utils from heatclient.v1 import resource_types @@ -31,6 +32,25 @@ class ResourceTypeManagerTest(testtools.TestCase): ret = key and {key: []} or {} return {}, {key: ret} + def raw_request(self, *args, **kwargs): + assert args == expect + return {} + + def head(self, url, **kwargs): + return self.json_request("HEAD", url, **kwargs) + + def post(self, url, **kwargs): + return self.json_request("POST", url, **kwargs) + + def put(self, url, **kwargs): + return self.json_request("PUT", url, **kwargs) + + def delete(self, url, **kwargs): + return self.raw_request("DELETE", url, **kwargs) + + def patch(self, url, **kwargs): + return self.json_request("PATCH", url, **kwargs) + manager = resource_types.ResourceTypeManager(FakeAPI()) return manager @@ -50,18 +70,22 @@ class ResourceTypeManagerTest(testtools.TestCase): manager = resource_types.ResourceTypeManager(FakeClient()) manager.list() - def test_get(self): + @mock.patch.object(utils, 'get_response_body') + def test_get(self, mock_utils): key = 'resource_types' resource_type = 'OS::Nova::KeyPair' expect = ('GET', '/resource_types/OS%3A%3ANova%3A%3AKeyPair') manager = self._base_test(expect, key) + mock_utils.return_value = None manager.get(resource_type) - def test_generate_template(self): + @mock.patch.object(utils, 'get_response_body') + def test_generate_template(self, mock_utils): key = 'resource_types' resource_type = 'OS::Nova::KeyPair' template_type = 'cfn' expect = ('GET', '/resource_types/OS%3A%3ANova%3A%3AKeyPair/template' '?template_type=cfn') manager = self._base_test(expect, key) + mock_utils.return_value = None manager.generate_template(resource_type, template_type) diff --git a/heatclient/tests/unit/test_resources.py b/heatclient/tests/unit/test_resources.py index e084dd65..7c139b94 100644 --- a/heatclient/tests/unit/test_resources.py +++ b/heatclient/tests/unit/test_resources.py @@ -11,6 +11,7 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. +from heatclient.common import utils from heatclient.v1 import resources @@ -39,8 +40,30 @@ class ResourceManagerTest(testtools.TestCase): ret = key and {key: []} or {} return {}, {key: ret} + def raw_request(self, *args, **kwargs): + assert args == expect + return {} + + def head(self, url, **kwargs): + return self.json_request("HEAD", url, **kwargs) + + def post(self, url, **kwargs): + return self.json_request("POST", url, **kwargs) + + def put(self, url, **kwargs): + return self.json_request("PUT", url, **kwargs) + + def delete(self, url, **kwargs): + return self.raw_request("DELETE", url, **kwargs) + + def patch(self, url, **kwargs): + return self.json_request("PATCH", url, **kwargs) + manager = resources.ResourceManager(FakeAPI()) self.m.StubOutWithMock(manager, '_resolve_stack_id') + self.m.StubOutWithMock(utils, 'get_response_body') + utils.get_response_body(mox.IgnoreArg()).AndReturn( + {key: key and {key: []} or {}}) manager._resolve_stack_id('teststack').AndReturn('teststack/abcd1234') self.m.ReplayAll() diff --git a/heatclient/tests/unit/test_shell.py b/heatclient/tests/unit/test_shell.py index 2f48177f..a4230f0c 100644 --- a/heatclient/tests/unit/test_shell.py +++ b/heatclient/tests/unit/test_shell.py @@ -992,7 +992,8 @@ class ShellTestUserPass(ShellBase): resp = fakes.FakeHTTPResponse( 200, 'OK', - {'location': 'http://no.where/v1/tenant_id/stacks/teststack2/2'}, + {'location': 'http://no.where/v1/tenant_id/stacks/teststack2/2', + 'content-type': 'application/json'}, jsonutils.dumps(resp_dict)) http.HTTPClient.json_request( 'POST', '/stacks/preview', data=mox.IgnoreArg(), @@ -1403,11 +1404,15 @@ class ShellTestUserPass(ShellBase): 'OK', {'content-type': 'application/json'}, jsonutils.dumps(resp_dict)) + abandoned_resp = fakes.FakeHTTPResponse( + 200, + 'OK', + {'content-type': 'application/json'}, + jsonutils.dumps(abandoned_stack)) http.HTTPClient.json_request( 'GET', '/stacks/teststack/1').AndReturn((resp, resp_dict)) - http.HTTPClient.json_request( - 'DELETE', - '/stacks/teststack/1/abandon').AndReturn((resp, abandoned_stack)) + http.HTTPClient.raw_request( + 'DELETE', '/stacks/teststack/1/abandon').AndReturn(abandoned_resp) self.m.ReplayAll() abandon_resp = self.shell('stack-abandon teststack/1') @@ -1445,11 +1450,15 @@ class ShellTestUserPass(ShellBase): 'OK', {'content-type': 'application/json'}, jsonutils.dumps(resp_dict)) + abandoned_resp = fakes.FakeHTTPResponse( + 200, + 'OK', + {'content-type': 'application/json'}, + jsonutils.dumps(abandoned_stack)) http.HTTPClient.json_request( 'GET', '/stacks/teststack/1').AndReturn((resp, resp_dict)) - http.HTTPClient.json_request( - 'DELETE', - '/stacks/teststack/1/abandon').AndReturn((resp, abandoned_stack)) + http.HTTPClient.raw_request( + 'DELETE', '/stacks/teststack/1/abandon').AndReturn(abandoned_resp) self.m.ReplayAll() @@ -1945,8 +1954,12 @@ class ShellTestUserPass(ShellBase): 'OK', {'content-type': 'application/json'}, jsonutils.dumps(resp_dict)) - http.HTTPClient.json_request( - 'GET', '/stacks/teststack/1').AndReturn((resp, stack_dict)) + http.HTTPClient.json_request('GET', '/stacks/teststack/1').AndReturn( + (fakes.FakeHTTPResponse( + 200, + 'OK', + {'content-type': 'application/json'}, + jsonutils.dumps(stack_dict)), stack_dict)) http.HTTPClient.json_request( 'POST', '/stacks/teststack/1/snapshots', @@ -1975,13 +1988,18 @@ class ShellTestUserPass(ShellBase): "creation_time": "2014-12-05T01:25:52Z" }]} + stack_resp = fakes.FakeHTTPResponse( + 200, + 'OK', + {'content-type': 'application/json'}, + jsonutils.dumps(stack_dict)) resp = fakes.FakeHTTPResponse( 200, 'OK', {'content-type': 'application/json'}, jsonutils.dumps(resp_dict)) http.HTTPClient.json_request( - 'GET', '/stacks/teststack/1').AndReturn((resp, stack_dict)) + 'GET', '/stacks/teststack/1').AndReturn((stack_resp, stack_dict)) http.HTTPClient.json_request( 'GET', '/stacks/teststack/1/snapshots').AndReturn((resp, resp_dict)) @@ -2024,8 +2042,12 @@ class ShellTestUserPass(ShellBase): 'OK', {'content-type': 'application/json'}, jsonutils.dumps(resp_dict)) - http.HTTPClient.json_request( - 'GET', '/stacks/teststack/1').AndReturn((resp, stack_dict)) + http.HTTPClient.json_request('GET', '/stacks/teststack/1').AndReturn(( + fakes.FakeHTTPResponse( + 200, + 'OK', + {'content-type': 'application/json'}, + jsonutils.dumps(stack_dict)), stack_dict)) http.HTTPClient.json_request( 'GET', '/stacks/teststack/1/snapshots/2').AndReturn((resp, resp_dict)) @@ -2050,15 +2072,20 @@ class ShellTestUserPass(ShellBase): }} resp = fakes.FakeHTTPResponse( + 204, + 'No Content', + {'content-type': 'application/json'}, + jsonutils.dumps(stack_dict)) + second_resp = fakes.FakeHTTPResponse( 204, 'No Content', {}, - None) + jsonutils.dumps(resp_dict)) http.HTTPClient.json_request( 'GET', '/stacks/teststack/1').AndReturn((resp, stack_dict)) - http.HTTPClient.json_request( + http.HTTPClient.raw_request( 'DELETE', - '/stacks/teststack/1/snapshots/2').AndReturn((resp, resp_dict)) + '/stacks/teststack/1/snapshots/2').AndReturn(second_resp) self.m.ReplayAll() resp = self.shell('snapshot-delete teststack/1 2') @@ -2074,16 +2101,21 @@ class ShellTestUserPass(ShellBase): "creation_time": "2012-10-25T01:58:47Z" }} - resp = fakes.FakeHTTPResponse( + stack_resp = fakes.FakeHTTPResponse( 204, 'No Content', - {}, - None) + {'content-type': 'application/json'}, + jsonutils.dumps(stack_dict)) + no_resp = fakes.FakeHTTPResponse( + 204, + 'No Content', + {'content-type': 'application/json'}, + jsonutils.dumps({})) http.HTTPClient.json_request( - 'GET', '/stacks/teststack/1').AndReturn((resp, stack_dict)) + 'GET', '/stacks/teststack/1').AndReturn((stack_resp, stack_dict)) http.HTTPClient.json_request( 'POST', - '/stacks/teststack/1/snapshots/2/restore').AndReturn((resp, {})) + '/stacks/teststack/1/snapshots/2/restore').AndReturn((no_resp, {})) self.m.ReplayAll() resp = self.shell('stack-restore teststack/1 2') diff --git a/heatclient/tests/unit/test_software_configs.py b/heatclient/tests/unit/test_software_configs.py index 9cc87e4c..936ed50b 100644 --- a/heatclient/tests/unit/test_software_configs.py +++ b/heatclient/tests/unit/test_software_configs.py @@ -13,6 +13,7 @@ import mock import testtools +from heatclient.common import utils from heatclient.v1 import software_configs @@ -46,7 +47,8 @@ class SoftwareConfigManagerTest(testtools.TestCase): super(SoftwareConfigManagerTest, self).setUp() self.manager = software_configs.SoftwareConfigManager(mock.MagicMock()) - def test_get(self): + @mock.patch.object(utils, 'get_response_body') + def test_get(self, mock_body): config_id = 'bca6871d-86c0-4aff-b792-58a1f6947b57' data = { 'id': config_id, @@ -59,14 +61,16 @@ class SoftwareConfigManagerTest(testtools.TestCase): self.manager.client.json_request.return_value = ( {}, {'software_config': data}) + mock_body.return_value = {'software_config': data} result = self.manager.get(config_id=config_id) self.assertEqual(software_configs.SoftwareConfig(self.manager, data), result) - call_args = self.manager.client.json_request.call_args + call_args = self.manager.client.get.call_args self.assertEqual( - ('GET', '/software_configs/%s' % config_id), *call_args) + ('/software_configs/%s' % config_id,), *call_args) - def test_create(self): + @mock.patch.object(utils, 'get_response_body') + def test_create(self, mock_body): config_id = 'bca6871d-86c0-4aff-b792-58a1f6947b57' body = { 'name': 'config_mysql', @@ -79,12 +83,12 @@ class SoftwareConfigManagerTest(testtools.TestCase): data['id'] = config_id self.manager.client.json_request.return_value = ( {}, {'software_config': data}) + mock_body.return_value = {'software_config': data} result = self.manager.create(**body) self.assertEqual(software_configs.SoftwareConfig(self.manager, data), result) - args, kargs = self.manager.client.json_request.call_args - self.assertEqual('POST', args[0]) - self.assertEqual('/software_configs', args[1]) + args, kargs = self.manager.client.post.call_args + self.assertEqual('/software_configs', args[0]) self.assertEqual({'data': body}, kargs) def test_delete(self): diff --git a/heatclient/tests/unit/test_software_deployments.py b/heatclient/tests/unit/test_software_deployments.py index fedb7423..47a446da 100644 --- a/heatclient/tests/unit/test_software_deployments.py +++ b/heatclient/tests/unit/test_software_deployments.py @@ -13,6 +13,7 @@ import mock import testtools +from heatclient.common import utils from heatclient.v1 import software_deployments @@ -62,23 +63,24 @@ class SoftwareDeploymentManagerTest(testtools.TestCase): ('/software_deployments?server_id=%s' % server_id,), *call_args) - def test_metadata(self): + @mock.patch.object(utils, 'get_response_body') + def test_metadata(self, mock_utils): server_id = 'fc01f89f-e151-4dc5-9c28-543c0d20ed6a' metadata = { 'group1': [{'foo': 'bar'}], 'group2': [{'foo': 'bar'}, {'bar': 'baz'}], } - self.manager.client.json_request.return_value = ( - {}, - {'metadata': metadata}) + self.manager.client.get.return_value = {} + mock_utils.return_value = {'metadata': metadata} result = self.manager.metadata(server_id=server_id) self.assertEqual(metadata, result) - call_args = self.manager.client.json_request.call_args + call_args = self.manager.client.get.call_args self.assertEqual( '/software_deployments/metadata/%s' % server_id, - call_args[0][1]) + call_args[0][0]) - def test_get(self): + @mock.patch.object(utils, 'get_response_body') + def test_get(self, mock_utils): deployment_id = 'bca6871d-86c0-4aff-b792-58a1f6947b57' config_id = 'd00ba4aa-db33-42e1-92f4-2a6469260107' server_id = 'fb322564-7927-473d-8aad-68ae7fbf2abf' @@ -99,16 +101,17 @@ class SoftwareDeploymentManagerTest(testtools.TestCase): 'outputs': [], 'options': []} - self.manager.client.json_request.return_value = ( - {}, {'software_deployment': data}) + self.manager.client.get.return_value = {} + mock_utils.return_value = {'software_deployment': data} result = self.manager.get(deployment_id=deployment_id) self.assertEqual(software_deployments.SoftwareDeployment( self.manager, data), result) - call_args = self.manager.client.json_request.call_args + call_args = self.manager.client.get.call_args self.assertEqual( - ('GET', '/software_deployments/%s' % deployment_id), *call_args) + ('/software_deployments/%s' % deployment_id,), *call_args) - def test_create(self): + @mock.patch.object(utils, 'get_response_body') + def test_create(self, mock_utils): deployment_id = 'bca6871d-86c0-4aff-b792-58a1f6947b57' config_id = 'd00ba4aa-db33-42e1-92f4-2a6469260107' server_id = 'fb322564-7927-473d-8aad-68ae7fbf2abf' @@ -122,14 +125,13 @@ class SoftwareDeploymentManagerTest(testtools.TestCase): 'config_id': config_id} data = body.copy() data['id'] = deployment_id - self.manager.client.json_request.return_value = ( - {}, {'software_deployment': data}) + self.manager.client.post.return_value = {} + mock_utils.return_value = {'software_deployment': data} result = self.manager.create(**body) self.assertEqual(software_deployments.SoftwareDeployment( self.manager, data), result) - args, kwargs = self.manager.client.json_request.call_args - self.assertEqual('POST', args[0]) - self.assertEqual('/software_deployments', args[1]) + args, kwargs = self.manager.client.post.call_args + self.assertEqual('/software_deployments', args[0]) self.assertEqual({'data': body}, kwargs) def test_delete(self): @@ -139,7 +141,8 @@ class SoftwareDeploymentManagerTest(testtools.TestCase): self.assertEqual( ('/software_deployments/%s' % deployment_id,), *call_args) - def test_update(self): + @mock.patch.object(utils, 'get_response_body') + def test_update(self, mock_utils): deployment_id = 'bca6871d-86c0-4aff-b792-58a1f6947b57' config_id = 'd00ba4aa-db33-42e1-92f4-2a6469260107' server_id = 'fb322564-7927-473d-8aad-68ae7fbf2abf' @@ -153,12 +156,11 @@ class SoftwareDeploymentManagerTest(testtools.TestCase): 'config_id': config_id} data = body.copy() data['id'] = deployment_id - self.manager.client.json_request.return_value = ( - {}, {'software_deployment': data}) + self.manager.client.put.return_value = {} + mock_utils.return_value = {'software_deployment': data} result = self.manager.update(deployment_id, **body) self.assertEqual(software_deployments.SoftwareDeployment( self.manager, data), result) - args, kwargs = self.manager.client.json_request.call_args - self.assertEqual('PUT', args[0]) - self.assertEqual('/software_deployments/%s' % deployment_id, args[1]) + args, kwargs = self.manager.client.put.call_args + self.assertEqual('/software_deployments/%s' % deployment_id, args[0]) self.assertEqual({'data': body}, kwargs) diff --git a/heatclient/v1/actions.py b/heatclient/v1/actions.py index 4ecd2b63..85a539ad 100644 --- a/heatclient/v1/actions.py +++ b/heatclient/v1/actions.py @@ -36,27 +36,19 @@ class ActionManager(stacks.StackChildManager): def suspend(self, stack_id): """Suspend a stack.""" body = {'suspend': None} - resp, body = self.client.json_request('POST', - '/stacks/%s/actions' % stack_id, - data=body) + self.client.post('/stacks/%s/actions' % stack_id, data=body) def resume(self, stack_id): """Resume a stack.""" body = {'resume': None} - resp, body = self.client.json_request('POST', - '/stacks/%s/actions' % stack_id, - data=body) + self.client.post('/stacks/%s/actions' % stack_id, data=body) def cancel_update(self, stack_id): """Cancel running update of a stack.""" body = {'cancel_update': None} - resp, body = self.client.json_request('POST', - '/stacks/%s/actions' % stack_id, - data=body) + self.client.post('/stacks/%s/actions' % stack_id, data=body) def check(self, stack_id): """Check a stack.""" body = {'check': None} - resp, body = self.client.json_request('POST', - '/stacks/%s/actions' % stack_id, - data=body) + self.client.post('/stacks/%s/actions' % stack_id, data=body) diff --git a/heatclient/v1/build_info.py b/heatclient/v1/build_info.py index 0ba94918..1a5598eb 100644 --- a/heatclient/v1/build_info.py +++ b/heatclient/v1/build_info.py @@ -13,6 +13,7 @@ # License for the specific language governing permissions and limitations # under the License. +from heatclient.common import utils from heatclient.openstack.common.apiclient import base @@ -28,5 +29,6 @@ class BuildInfoManager(base.BaseManager): resource_class = BuildInfo def build_info(self): - resp, body = self.client.json_request('GET', '/build_info') + resp = self.client.get('/build_info') + body = utils.get_response_body(resp) return body diff --git a/heatclient/v1/events.py b/heatclient/v1/events.py index e94717ac..d468a123 100644 --- a/heatclient/v1/events.py +++ b/heatclient/v1/events.py @@ -17,6 +17,7 @@ from oslo_utils import encodeutils import six from six.moves.urllib import parse +from heatclient.common import utils from heatclient.openstack.common.apiclient import base from heatclient.v1 import stacks @@ -79,5 +80,6 @@ class EventManager(stacks.StackChildManager): parse.quote(stack_id, ''), parse.quote(encodeutils.safe_encode(resource_name), ''), parse.quote(event_id, '')) - resp, body = self.client.json_request('GET', url_str) - return Event(self, body['event']) + resp = self.client.get(url_str) + body = utils.get_response_body(resp) + return Event(self, body.get('event')) diff --git a/heatclient/v1/resource_types.py b/heatclient/v1/resource_types.py index c1a8b71d..34397b93 100644 --- a/heatclient/v1/resource_types.py +++ b/heatclient/v1/resource_types.py @@ -10,6 +10,7 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. +from heatclient.common import utils from oslo_utils import encodeutils from six.moves.urllib import parse @@ -44,7 +45,8 @@ class ResourceTypeManager(base.BaseManager): """ url_str = '/resource_types/%s' % ( parse.quote(encodeutils.safe_encode(resource_type), '')) - resp, body = self.client.json_request('GET', url_str) + resp = self.client.get(url_str) + body = utils.get_response_body(resp) return body def generate_template(self, resource_type, template_type='cfn'): @@ -53,5 +55,6 @@ class ResourceTypeManager(base.BaseManager): if template_type: url_str += '?%s' % parse.urlencode( {'template_type': template_type}, True) - resp, body = self.client.json_request('GET', url_str) + resp = self.client.get(url_str) + body = utils.get_response_body(resp) return body diff --git a/heatclient/v1/resources.py b/heatclient/v1/resources.py index 5887a9da..02941f7f 100644 --- a/heatclient/v1/resources.py +++ b/heatclient/v1/resources.py @@ -12,6 +12,7 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. +from heatclient.common import utils from oslo_utils import encodeutils from six.moves.urllib import parse @@ -58,8 +59,9 @@ class ResourceManager(stacks.StackChildManager): url_str = '/stacks/%s/resources/%s' % ( parse.quote(stack_id, ''), parse.quote(encodeutils.safe_encode(resource_name), '')) - resp, body = self.client.json_request('GET', url_str) - return Resource(self, body['resource']) + resp = self.client.get(url_str) + body = utils.get_response_body(resp) + return Resource(self, body.get('resource')) def metadata(self, stack_id, resource_name): """Get the metadata for a specific resource. @@ -71,8 +73,9 @@ class ResourceManager(stacks.StackChildManager): url_str = '/stacks/%s/resources/%s/metadata' % ( parse.quote(stack_id, ''), parse.quote(encodeutils.safe_encode(resource_name), '')) - resp, body = self.client.json_request('GET', url_str) - return body['metadata'] + resp = self.client.get(url_str) + body = utils.get_response_body(resp) + return body.get('metadata') def signal(self, stack_id, resource_name, data=None): """Signal a specific resource. @@ -84,7 +87,8 @@ class ResourceManager(stacks.StackChildManager): url_str = '/stacks/%s/resources/%s/signal' % ( parse.quote(stack_id, ''), parse.quote(encodeutils.safe_encode(resource_name), '')) - resp, body = self.client.json_request('POST', url_str, data=data) + resp = self.client.post(url_str, data=data) + body = utils.get_response_body(resp) return body def generate_template(self, resource_name): @@ -93,5 +97,6 @@ class ResourceManager(stacks.StackChildManager): """ url_str = '/resource_types/%s/template' % ( parse.quote(encodeutils.safe_encode(resource_name), '')) - resp, body = self.client.json_request('GET', url_str) + resp = self.client.get(url_str) + body = utils.get_response_body(resp) return body diff --git a/heatclient/v1/software_configs.py b/heatclient/v1/software_configs.py index cf038db5..dd3264db 100644 --- a/heatclient/v1/software_configs.py +++ b/heatclient/v1/software_configs.py @@ -10,6 +10,7 @@ # License for the specific language governing permissions and limitations # under the License. +from heatclient.common import utils from heatclient.openstack.common.apiclient import base @@ -32,17 +33,16 @@ class SoftwareConfigManager(base.BaseManager): :param config_id: ID of the software config """ - resp, body = self.client.json_request( - 'GET', '/software_configs/%s' % config_id) - - return SoftwareConfig(self, body['software_config']) + resp = self.client.get('/software_configs/%s' % config_id) + body = utils.get_response_body(resp) + return SoftwareConfig(self, body.get('software_config')) def create(self, **kwargs): """Create a software config.""" - resp, body = self.client.json_request('POST', '/software_configs', - data=kwargs) - - return SoftwareConfig(self, body['software_config']) + resp = self.client.post('/software_configs', + data=kwargs) + body = utils.get_response_body(resp) + return SoftwareConfig(self, body.get('software_config')) def delete(self, config_id): """Delete a software config.""" diff --git a/heatclient/v1/software_deployments.py b/heatclient/v1/software_deployments.py index 0f685f2f..494bbce8 100644 --- a/heatclient/v1/software_deployments.py +++ b/heatclient/v1/software_deployments.py @@ -12,6 +12,7 @@ from six.moves.urllib import parse +from heatclient.common import utils from heatclient.openstack.common.apiclient import base @@ -43,30 +44,32 @@ class SoftwareDeploymentManager(base.BaseManager): """ url = '/software_deployments/metadata/%s' % parse.quote( server_id, '') - resp, body = self.client.json_request('GET', url) - return body['metadata'] + resp = self.client.get(url) + body = utils.get_response_body(resp) + return body.get('metadata') def get(self, deployment_id): """Get the details for a specific software deployment. :param deployment_id: ID of the software deployment """ - resp, body = self.client.json_request( - 'GET', '/software_deployments/%s' % deployment_id) + resp = self.client.get('/software_deployments/%s' % deployment_id) + body = utils.get_response_body(resp) - return SoftwareDeployment(self, body['software_deployment']) + return SoftwareDeployment(self, body.get('software_deployment')) def create(self, **kwargs): """Create a software deployment.""" - resp, body = self.client.json_request( - 'POST', '/software_deployments', data=kwargs) - return SoftwareDeployment(self, body['software_deployment']) + resp = self.client.post('/software_deployments', data=kwargs) + body = utils.get_response_body(resp) + return SoftwareDeployment(self, body.get('software_deployment')) def update(self, deployment_id, **kwargs): """Update a software deployment.""" - resp, body = self.client.json_request( - 'PUT', '/software_deployments/%s' % deployment_id, data=kwargs) - return SoftwareDeployment(self, body['software_deployment']) + resp = self.client.put('/software_deployments/%s' % + deployment_id, data=kwargs) + body = utils.get_response_body(resp) + return SoftwareDeployment(self, body.get('software_deployment')) def delete(self, deployment_id): """Delete a software deployment.""" diff --git a/heatclient/v1/stacks.py b/heatclient/v1/stacks.py index 0524af89..bf7a7ba3 100644 --- a/heatclient/v1/stacks.py +++ b/heatclient/v1/stacks.py @@ -12,6 +12,7 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. +from heatclient.common import utils import six from six.moves.urllib import parse @@ -123,23 +124,28 @@ class StackManager(base.BaseManager): def preview(self, **kwargs): """Preview a stack.""" headers = self.client.credentials_headers() - resp, body = self.client.json_request('POST', '/stacks/preview', - data=kwargs, headers=headers) - return Stack(self, body['stack']) + resp = self.client.post('/stacks/preview', + data=kwargs, headers=headers) + body = utils.get_response_body(resp) + return Stack(self, body.get('stack')) def create(self, **kwargs): """Create a stack.""" headers = self.client.credentials_headers() - resp, body = self.client.json_request('POST', '/stacks', - data=kwargs, headers=headers) + resp = self.client.post('/stacks', + data=kwargs, headers=headers) + body = utils.get_response_body(resp) return body def update(self, stack_id, **kwargs): """Update a stack.""" headers = self.client.credentials_headers() - method = 'PATCH' if kwargs.pop('existing', None) else 'PUT' - resp, body = self.client.json_request(method, '/stacks/%s' % stack_id, - data=kwargs, headers=headers) + if kwargs.pop('existing', None): + self.client.patch('/stacks/%s' % stack_id, data=kwargs, + headers=headers) + else: + self.client.put('/stacks/%s' % stack_id, data=kwargs, + headers=headers) def delete(self, stack_id): """Delete a stack.""" @@ -148,9 +154,8 @@ class StackManager(base.BaseManager): def abandon(self, stack_id): """Abandon a stack.""" stack = self.get(stack_id) - resp, body = self.client.json_request( - 'DELETE', - '/stacks/%s/abandon' % stack.identifier) + resp = self.client.delete('/stacks/%s/abandon' % stack.identifier) + body = utils.get_response_body(resp) return body def snapshot(self, stack_id, name=None): @@ -159,39 +164,36 @@ class StackManager(base.BaseManager): data = {} if name: data['name'] = name - resp, body = self.client.json_request( - 'POST', - '/stacks/%s/snapshots' % stack.identifier, - data=data) + resp = self.client.post('/stacks/%s/snapshots' % stack.identifier, + data=data) + body = utils.get_response_body(resp) return body def snapshot_show(self, stack_id, snapshot_id): stack = self.get(stack_id) - resp, body = self.client.json_request( - 'GET', - '/stacks/%s/snapshots/%s' % (stack.identifier, snapshot_id)) + resp = self.client.get('/stacks/%s/snapshots/%s' % (stack.identifier, + snapshot_id)) + body = utils.get_response_body(resp) return body def snapshot_delete(self, stack_id, snapshot_id): stack = self.get(stack_id) - resp, body = self.client.json_request( - 'DELETE', - '/stacks/%s/snapshots/%s' % (stack.identifier, snapshot_id)) + resp = self.client.delete('/stacks/%s/snapshots/%s' % + (stack.identifier, snapshot_id)) + body = utils.get_response_body(resp) return body def restore(self, stack_id, snapshot_id): stack = self.get(stack_id) - resp, body = self.client.json_request( - 'POST', - '/stacks/%s/snapshots/%s/restore' % (stack.identifier, - snapshot_id)) + resp = self.client.post('/stacks/%s/snapshots/%s/restore' % + (stack.identifier, snapshot_id)) + body = utils.get_response_body(resp) return body def snapshot_list(self, stack_id): stack = self.get(stack_id) - resp, body = self.client.json_request( - 'GET', - '/stacks/%s/snapshots' % stack.identifier) + resp = self.client.get('/stacks/%s/snapshots' % stack.identifier) + body = utils.get_response_body(resp) return body def get(self, stack_id): @@ -199,8 +201,9 @@ class StackManager(base.BaseManager): :param stack_id: Stack ID to lookup """ - resp, body = self.client.json_request('GET', '/stacks/%s' % stack_id) - return Stack(self, body['stack']) + resp = self.client.get('/stacks/%s' % stack_id) + body = utils.get_response_body(resp) + return Stack(self, body.get('stack')) def template(self, stack_id): """Get the template content for a specific stack as a parsed JSON @@ -208,13 +211,14 @@ class StackManager(base.BaseManager): :param stack_id: Stack ID to get the template for """ - resp, body = self.client.json_request( - 'GET', '/stacks/%s/template' % stack_id) + resp = self.client.get('/stacks/%s/template' % stack_id) + body = utils.get_response_body(resp) return body def validate(self, **kwargs): """Validate a stack template.""" - resp, body = self.client.json_request('POST', '/validate', data=kwargs) + resp = self.client.post('/validate', data=kwargs) + body = utils.get_response_body(resp) return body @@ -232,9 +236,8 @@ class StackChildManager(base.BaseManager): # since all we want is the stacks:lookup response to get the # fully qualified ID, and not all users are allowed to do the # redirected stacks:show, so pass follow_redirects=False - resp, body = self.client.json_request('GET', - '/stacks/%s' % stack_id, - follow_redirects=False) + resp = self.client.get('/stacks/%s' % stack_id, + follow_redirects=False) location = resp.headers.get('location') path = self.client.strip_endpoint(location) return path[len('/stacks/'):]