Merge "Move usage methods *_request to get/post/etc"

This commit is contained in:
Jenkins 2015-06-16 05:10:08 +00:00 committed by Gerrit Code Review
commit 150aaf7f05
19 changed files with 303 additions and 146 deletions

View File

@ -26,9 +26,9 @@ import requests
import six import six
from six.moves.urllib import parse from six.moves.urllib import parse
from heatclient.common import utils
from heatclient import exc from heatclient import exc
from heatclient.openstack.common._i18n import _ from heatclient.openstack.common._i18n import _
from heatclient.openstack.common._i18n import _LE
from heatclient.openstack.common._i18n import _LW from heatclient.openstack.common._i18n import _LW
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -263,15 +263,7 @@ class HTTPClient(object):
kwargs['data'] = jsonutils.dumps(kwargs['data']) kwargs['data'] = jsonutils.dumps(kwargs['data'])
resp = self._http_request(url, method, **kwargs) resp = self._http_request(url, method, **kwargs)
body = resp.content body = utils.get_response_body(resp)
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 resp, body return resp, body
def raw_request(self, method, url, **kwargs): def raw_request(self, method, url, **kwargs):

View File

@ -14,6 +14,7 @@
# under the License. # under the License.
import base64 import base64
import logging
import os import os
import textwrap import textwrap
import uuid import uuid
@ -28,8 +29,12 @@ import yaml
from heatclient import exc from heatclient import exc
from heatclient.openstack.common._i18n import _ from heatclient.openstack.common._i18n import _
from heatclient.openstack.common._i18n import _LE
from heatclient.openstack.common import cliutils from heatclient.openstack.common import cliutils
LOG = logging.getLogger(__name__)
supported_formats = { supported_formats = {
"json": lambda x: jsonutils.dumps(x, indent=2), "json": lambda x: jsonutils.dumps(x, indent=2),
"yaml": yaml.safe_dump "yaml": yaml.safe_dump
@ -261,3 +266,15 @@ def normalise_file_path_to_url(path):
return path return path
path = os.path.abspath(path) path = os.path.abspath(path)
return parse.urljoin('file:', request.pathname2url(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

View File

@ -11,6 +11,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
from heatclient.tests.unit import fakes
from heatclient.v1 import actions from heatclient.v1 import actions
import testtools import testtools
@ -29,7 +30,43 @@ class ActionManagerTest(testtools.TestCase):
def json_request(self, *args, **kwargs): def json_request(self, *args, **kwargs):
assert expect_args == args assert expect_args == args
assert expect_kwargs['data'] == kwargs['data'] 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()) manager = actions.ActionManager(FakeAPI())
return manager return manager

View File

@ -12,10 +12,11 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import mock import mock
from oslo_serialization import jsonutils
import testtools import testtools
from heatclient.tests.unit import fakes
from heatclient.v1 import build_info from heatclient.v1 import build_info
@ -23,12 +24,17 @@ class BuildInfoManagerTest(testtools.TestCase):
def setUp(self): def setUp(self):
super(BuildInfoManagerTest, self).setUp() super(BuildInfoManagerTest, self).setUp()
self.client = mock.Mock() 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) self.manager = build_info.BuildInfoManager(self.client)
def test_build_info_makes_a_call_to_the_api(self): def test_build_info_makes_a_call_to_the_api(self):
self.manager.build_info() 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): def test_build_info_returns_the_response_body(self):
response = self.manager.build_info() response = self.manager.build_info()

View File

@ -293,7 +293,7 @@ class HttpClientTest(testtools.TestCase):
fakes.FakeHTTPResponse( fakes.FakeHTTPResponse(
200, 'OK', 200, 'OK',
{'content-type': 'not/json'}, {'content-type': 'not/json'},
'{}')) {}))
# Replay, create client, assert # Replay, create client, assert
self.m.ReplayAll() self.m.ReplayAll()
client = http.HTTPClient('http://example.com:8004') client = http.HTTPClient('http://example.com:8004')

View File

@ -111,9 +111,14 @@ class EventManagerTest(testtools.TestCase):
assert args == expect assert args == expect
return {}, {'event': []} return {}, {'event': []}
def get(self, *args, **kwargs):
pass
manager = events.EventManager(FakeAPI()) manager = events.EventManager(FakeAPI())
with mock.patch('heatclient.v1.events.Event'): with mock.patch('heatclient.v1.events.Event'):
self.m.StubOutWithMock(manager, '_resolve_stack_id') 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( manager._resolve_stack_id('teststack').AndReturn(
'teststack/abcd1234') 'teststack/abcd1234')
self.m.ReplayAll() self.m.ReplayAll()
@ -134,9 +139,14 @@ class EventManagerTest(testtools.TestCase):
assert args == expect assert args == expect
return {}, {'event': []} return {}, {'event': []}
def get(self, *args, **kwargs):
pass
manager = events.EventManager(FakeAPI()) manager = events.EventManager(FakeAPI())
with mock.patch('heatclient.v1.events.Event'): with mock.patch('heatclient.v1.events.Event'):
self.m.StubOutWithMock(manager, '_resolve_stack_id') 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( manager._resolve_stack_id('teststack').AndReturn(
'teststack/abcd1234') 'teststack/abcd1234')
self.m.ReplayAll() self.m.ReplayAll()

View File

@ -10,9 +10,10 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import mock
import testtools import testtools
from heatclient.common import utils
from heatclient.v1 import resource_types from heatclient.v1 import resource_types
@ -31,6 +32,25 @@ class ResourceTypeManagerTest(testtools.TestCase):
ret = key and {key: []} or {} ret = key and {key: []} or {}
return {}, {key: ret} 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()) manager = resource_types.ResourceTypeManager(FakeAPI())
return manager return manager
@ -50,18 +70,22 @@ class ResourceTypeManagerTest(testtools.TestCase):
manager = resource_types.ResourceTypeManager(FakeClient()) manager = resource_types.ResourceTypeManager(FakeClient())
manager.list() manager.list()
def test_get(self): @mock.patch.object(utils, 'get_response_body')
def test_get(self, mock_utils):
key = 'resource_types' key = 'resource_types'
resource_type = 'OS::Nova::KeyPair' resource_type = 'OS::Nova::KeyPair'
expect = ('GET', '/resource_types/OS%3A%3ANova%3A%3AKeyPair') expect = ('GET', '/resource_types/OS%3A%3ANova%3A%3AKeyPair')
manager = self._base_test(expect, key) manager = self._base_test(expect, key)
mock_utils.return_value = None
manager.get(resource_type) 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' key = 'resource_types'
resource_type = 'OS::Nova::KeyPair' resource_type = 'OS::Nova::KeyPair'
template_type = 'cfn' template_type = 'cfn'
expect = ('GET', '/resource_types/OS%3A%3ANova%3A%3AKeyPair/template' expect = ('GET', '/resource_types/OS%3A%3ANova%3A%3AKeyPair/template'
'?template_type=cfn') '?template_type=cfn')
manager = self._base_test(expect, key) manager = self._base_test(expect, key)
mock_utils.return_value = None
manager.generate_template(resource_type, template_type) manager.generate_template(resource_type, template_type)

View File

@ -11,6 +11,7 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from heatclient.common import utils
from heatclient.v1 import resources from heatclient.v1 import resources
@ -39,8 +40,30 @@ class ResourceManagerTest(testtools.TestCase):
ret = key and {key: []} or {} ret = key and {key: []} or {}
return {}, {key: ret} 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()) manager = resources.ResourceManager(FakeAPI())
self.m.StubOutWithMock(manager, '_resolve_stack_id') 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') manager._resolve_stack_id('teststack').AndReturn('teststack/abcd1234')
self.m.ReplayAll() self.m.ReplayAll()

View File

@ -992,7 +992,8 @@ class ShellTestUserPass(ShellBase):
resp = fakes.FakeHTTPResponse( resp = fakes.FakeHTTPResponse(
200, 200,
'OK', '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)) jsonutils.dumps(resp_dict))
http.HTTPClient.json_request( http.HTTPClient.json_request(
'POST', '/stacks/preview', data=mox.IgnoreArg(), 'POST', '/stacks/preview', data=mox.IgnoreArg(),
@ -1403,11 +1404,15 @@ class ShellTestUserPass(ShellBase):
'OK', 'OK',
{'content-type': 'application/json'}, {'content-type': 'application/json'},
jsonutils.dumps(resp_dict)) jsonutils.dumps(resp_dict))
abandoned_resp = fakes.FakeHTTPResponse(
200,
'OK',
{'content-type': 'application/json'},
jsonutils.dumps(abandoned_stack))
http.HTTPClient.json_request( http.HTTPClient.json_request(
'GET', '/stacks/teststack/1').AndReturn((resp, resp_dict)) 'GET', '/stacks/teststack/1').AndReturn((resp, resp_dict))
http.HTTPClient.json_request( http.HTTPClient.raw_request(
'DELETE', 'DELETE', '/stacks/teststack/1/abandon').AndReturn(abandoned_resp)
'/stacks/teststack/1/abandon').AndReturn((resp, abandoned_stack))
self.m.ReplayAll() self.m.ReplayAll()
abandon_resp = self.shell('stack-abandon teststack/1') abandon_resp = self.shell('stack-abandon teststack/1')
@ -1445,11 +1450,15 @@ class ShellTestUserPass(ShellBase):
'OK', 'OK',
{'content-type': 'application/json'}, {'content-type': 'application/json'},
jsonutils.dumps(resp_dict)) jsonutils.dumps(resp_dict))
abandoned_resp = fakes.FakeHTTPResponse(
200,
'OK',
{'content-type': 'application/json'},
jsonutils.dumps(abandoned_stack))
http.HTTPClient.json_request( http.HTTPClient.json_request(
'GET', '/stacks/teststack/1').AndReturn((resp, resp_dict)) 'GET', '/stacks/teststack/1').AndReturn((resp, resp_dict))
http.HTTPClient.json_request( http.HTTPClient.raw_request(
'DELETE', 'DELETE', '/stacks/teststack/1/abandon').AndReturn(abandoned_resp)
'/stacks/teststack/1/abandon').AndReturn((resp, abandoned_stack))
self.m.ReplayAll() self.m.ReplayAll()
@ -1945,8 +1954,12 @@ class ShellTestUserPass(ShellBase):
'OK', 'OK',
{'content-type': 'application/json'}, {'content-type': 'application/json'},
jsonutils.dumps(resp_dict)) jsonutils.dumps(resp_dict))
http.HTTPClient.json_request( http.HTTPClient.json_request('GET', '/stacks/teststack/1').AndReturn(
'GET', '/stacks/teststack/1').AndReturn((resp, stack_dict)) (fakes.FakeHTTPResponse(
200,
'OK',
{'content-type': 'application/json'},
jsonutils.dumps(stack_dict)), stack_dict))
http.HTTPClient.json_request( http.HTTPClient.json_request(
'POST', 'POST',
'/stacks/teststack/1/snapshots', '/stacks/teststack/1/snapshots',
@ -1975,13 +1988,18 @@ class ShellTestUserPass(ShellBase):
"creation_time": "2014-12-05T01:25:52Z" "creation_time": "2014-12-05T01:25:52Z"
}]} }]}
stack_resp = fakes.FakeHTTPResponse(
200,
'OK',
{'content-type': 'application/json'},
jsonutils.dumps(stack_dict))
resp = fakes.FakeHTTPResponse( resp = fakes.FakeHTTPResponse(
200, 200,
'OK', 'OK',
{'content-type': 'application/json'}, {'content-type': 'application/json'},
jsonutils.dumps(resp_dict)) jsonutils.dumps(resp_dict))
http.HTTPClient.json_request( 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( http.HTTPClient.json_request(
'GET', 'GET',
'/stacks/teststack/1/snapshots').AndReturn((resp, resp_dict)) '/stacks/teststack/1/snapshots').AndReturn((resp, resp_dict))
@ -2024,8 +2042,12 @@ class ShellTestUserPass(ShellBase):
'OK', 'OK',
{'content-type': 'application/json'}, {'content-type': 'application/json'},
jsonutils.dumps(resp_dict)) jsonutils.dumps(resp_dict))
http.HTTPClient.json_request( http.HTTPClient.json_request('GET', '/stacks/teststack/1').AndReturn((
'GET', '/stacks/teststack/1').AndReturn((resp, stack_dict)) fakes.FakeHTTPResponse(
200,
'OK',
{'content-type': 'application/json'},
jsonutils.dumps(stack_dict)), stack_dict))
http.HTTPClient.json_request( http.HTTPClient.json_request(
'GET', 'GET',
'/stacks/teststack/1/snapshots/2').AndReturn((resp, resp_dict)) '/stacks/teststack/1/snapshots/2').AndReturn((resp, resp_dict))
@ -2050,15 +2072,20 @@ class ShellTestUserPass(ShellBase):
}} }}
resp = fakes.FakeHTTPResponse( resp = fakes.FakeHTTPResponse(
204,
'No Content',
{'content-type': 'application/json'},
jsonutils.dumps(stack_dict))
second_resp = fakes.FakeHTTPResponse(
204, 204,
'No Content', 'No Content',
{}, {},
None) jsonutils.dumps(resp_dict))
http.HTTPClient.json_request( http.HTTPClient.json_request(
'GET', '/stacks/teststack/1').AndReturn((resp, stack_dict)) 'GET', '/stacks/teststack/1').AndReturn((resp, stack_dict))
http.HTTPClient.json_request( http.HTTPClient.raw_request(
'DELETE', 'DELETE',
'/stacks/teststack/1/snapshots/2').AndReturn((resp, resp_dict)) '/stacks/teststack/1/snapshots/2').AndReturn(second_resp)
self.m.ReplayAll() self.m.ReplayAll()
resp = self.shell('snapshot-delete teststack/1 2') resp = self.shell('snapshot-delete teststack/1 2')
@ -2074,16 +2101,21 @@ class ShellTestUserPass(ShellBase):
"creation_time": "2012-10-25T01:58:47Z" "creation_time": "2012-10-25T01:58:47Z"
}} }}
resp = fakes.FakeHTTPResponse( stack_resp = fakes.FakeHTTPResponse(
204, 204,
'No Content', 'No Content',
{}, {'content-type': 'application/json'},
None) jsonutils.dumps(stack_dict))
no_resp = fakes.FakeHTTPResponse(
204,
'No Content',
{'content-type': 'application/json'},
jsonutils.dumps({}))
http.HTTPClient.json_request( 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( http.HTTPClient.json_request(
'POST', 'POST',
'/stacks/teststack/1/snapshots/2/restore').AndReturn((resp, {})) '/stacks/teststack/1/snapshots/2/restore').AndReturn((no_resp, {}))
self.m.ReplayAll() self.m.ReplayAll()
resp = self.shell('stack-restore teststack/1 2') resp = self.shell('stack-restore teststack/1 2')

View File

@ -13,6 +13,7 @@
import mock import mock
import testtools import testtools
from heatclient.common import utils
from heatclient.v1 import software_configs from heatclient.v1 import software_configs
@ -46,7 +47,8 @@ class SoftwareConfigManagerTest(testtools.TestCase):
super(SoftwareConfigManagerTest, self).setUp() super(SoftwareConfigManagerTest, self).setUp()
self.manager = software_configs.SoftwareConfigManager(mock.MagicMock()) 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' config_id = 'bca6871d-86c0-4aff-b792-58a1f6947b57'
data = { data = {
'id': config_id, 'id': config_id,
@ -59,14 +61,16 @@ class SoftwareConfigManagerTest(testtools.TestCase):
self.manager.client.json_request.return_value = ( self.manager.client.json_request.return_value = (
{}, {'software_config': data}) {}, {'software_config': data})
mock_body.return_value = {'software_config': data}
result = self.manager.get(config_id=config_id) result = self.manager.get(config_id=config_id)
self.assertEqual(software_configs.SoftwareConfig(self.manager, data), self.assertEqual(software_configs.SoftwareConfig(self.manager, data),
result) result)
call_args = self.manager.client.json_request.call_args call_args = self.manager.client.get.call_args
self.assertEqual( 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' config_id = 'bca6871d-86c0-4aff-b792-58a1f6947b57'
body = { body = {
'name': 'config_mysql', 'name': 'config_mysql',
@ -79,12 +83,12 @@ class SoftwareConfigManagerTest(testtools.TestCase):
data['id'] = config_id data['id'] = config_id
self.manager.client.json_request.return_value = ( self.manager.client.json_request.return_value = (
{}, {'software_config': data}) {}, {'software_config': data})
mock_body.return_value = {'software_config': data}
result = self.manager.create(**body) result = self.manager.create(**body)
self.assertEqual(software_configs.SoftwareConfig(self.manager, data), self.assertEqual(software_configs.SoftwareConfig(self.manager, data),
result) result)
args, kargs = self.manager.client.json_request.call_args args, kargs = self.manager.client.post.call_args
self.assertEqual('POST', args[0]) self.assertEqual('/software_configs', args[0])
self.assertEqual('/software_configs', args[1])
self.assertEqual({'data': body}, kargs) self.assertEqual({'data': body}, kargs)
def test_delete(self): def test_delete(self):

View File

@ -13,6 +13,7 @@
import mock import mock
import testtools import testtools
from heatclient.common import utils
from heatclient.v1 import software_deployments from heatclient.v1 import software_deployments
@ -62,23 +63,24 @@ class SoftwareDeploymentManagerTest(testtools.TestCase):
('/software_deployments?server_id=%s' % server_id,), ('/software_deployments?server_id=%s' % server_id,),
*call_args) *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' server_id = 'fc01f89f-e151-4dc5-9c28-543c0d20ed6a'
metadata = { metadata = {
'group1': [{'foo': 'bar'}], 'group1': [{'foo': 'bar'}],
'group2': [{'foo': 'bar'}, {'bar': 'baz'}], 'group2': [{'foo': 'bar'}, {'bar': 'baz'}],
} }
self.manager.client.json_request.return_value = ( self.manager.client.get.return_value = {}
{}, mock_utils.return_value = {'metadata': metadata}
{'metadata': metadata})
result = self.manager.metadata(server_id=server_id) result = self.manager.metadata(server_id=server_id)
self.assertEqual(metadata, result) self.assertEqual(metadata, result)
call_args = self.manager.client.json_request.call_args call_args = self.manager.client.get.call_args
self.assertEqual( self.assertEqual(
'/software_deployments/metadata/%s' % server_id, '/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' deployment_id = 'bca6871d-86c0-4aff-b792-58a1f6947b57'
config_id = 'd00ba4aa-db33-42e1-92f4-2a6469260107' config_id = 'd00ba4aa-db33-42e1-92f4-2a6469260107'
server_id = 'fb322564-7927-473d-8aad-68ae7fbf2abf' server_id = 'fb322564-7927-473d-8aad-68ae7fbf2abf'
@ -99,16 +101,17 @@ class SoftwareDeploymentManagerTest(testtools.TestCase):
'outputs': [], 'outputs': [],
'options': []} 'options': []}
self.manager.client.json_request.return_value = ( self.manager.client.get.return_value = {}
{}, {'software_deployment': data}) mock_utils.return_value = {'software_deployment': data}
result = self.manager.get(deployment_id=deployment_id) result = self.manager.get(deployment_id=deployment_id)
self.assertEqual(software_deployments.SoftwareDeployment( self.assertEqual(software_deployments.SoftwareDeployment(
self.manager, data), result) self.manager, data), result)
call_args = self.manager.client.json_request.call_args call_args = self.manager.client.get.call_args
self.assertEqual( 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' deployment_id = 'bca6871d-86c0-4aff-b792-58a1f6947b57'
config_id = 'd00ba4aa-db33-42e1-92f4-2a6469260107' config_id = 'd00ba4aa-db33-42e1-92f4-2a6469260107'
server_id = 'fb322564-7927-473d-8aad-68ae7fbf2abf' server_id = 'fb322564-7927-473d-8aad-68ae7fbf2abf'
@ -122,14 +125,13 @@ class SoftwareDeploymentManagerTest(testtools.TestCase):
'config_id': config_id} 'config_id': config_id}
data = body.copy() data = body.copy()
data['id'] = deployment_id data['id'] = deployment_id
self.manager.client.json_request.return_value = ( self.manager.client.post.return_value = {}
{}, {'software_deployment': data}) mock_utils.return_value = {'software_deployment': data}
result = self.manager.create(**body) result = self.manager.create(**body)
self.assertEqual(software_deployments.SoftwareDeployment( self.assertEqual(software_deployments.SoftwareDeployment(
self.manager, data), result) self.manager, data), result)
args, kwargs = self.manager.client.json_request.call_args args, kwargs = self.manager.client.post.call_args
self.assertEqual('POST', args[0]) self.assertEqual('/software_deployments', args[0])
self.assertEqual('/software_deployments', args[1])
self.assertEqual({'data': body}, kwargs) self.assertEqual({'data': body}, kwargs)
def test_delete(self): def test_delete(self):
@ -139,7 +141,8 @@ class SoftwareDeploymentManagerTest(testtools.TestCase):
self.assertEqual( self.assertEqual(
('/software_deployments/%s' % deployment_id,), *call_args) ('/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' deployment_id = 'bca6871d-86c0-4aff-b792-58a1f6947b57'
config_id = 'd00ba4aa-db33-42e1-92f4-2a6469260107' config_id = 'd00ba4aa-db33-42e1-92f4-2a6469260107'
server_id = 'fb322564-7927-473d-8aad-68ae7fbf2abf' server_id = 'fb322564-7927-473d-8aad-68ae7fbf2abf'
@ -153,12 +156,11 @@ class SoftwareDeploymentManagerTest(testtools.TestCase):
'config_id': config_id} 'config_id': config_id}
data = body.copy() data = body.copy()
data['id'] = deployment_id data['id'] = deployment_id
self.manager.client.json_request.return_value = ( self.manager.client.put.return_value = {}
{}, {'software_deployment': data}) mock_utils.return_value = {'software_deployment': data}
result = self.manager.update(deployment_id, **body) result = self.manager.update(deployment_id, **body)
self.assertEqual(software_deployments.SoftwareDeployment( self.assertEqual(software_deployments.SoftwareDeployment(
self.manager, data), result) self.manager, data), result)
args, kwargs = self.manager.client.json_request.call_args args, kwargs = self.manager.client.put.call_args
self.assertEqual('PUT', args[0]) self.assertEqual('/software_deployments/%s' % deployment_id, args[0])
self.assertEqual('/software_deployments/%s' % deployment_id, args[1])
self.assertEqual({'data': body}, kwargs) self.assertEqual({'data': body}, kwargs)

View File

@ -36,27 +36,19 @@ class ActionManager(stacks.StackChildManager):
def suspend(self, stack_id): def suspend(self, stack_id):
"""Suspend a stack.""" """Suspend a stack."""
body = {'suspend': None} body = {'suspend': None}
resp, body = self.client.json_request('POST', self.client.post('/stacks/%s/actions' % stack_id, data=body)
'/stacks/%s/actions' % stack_id,
data=body)
def resume(self, stack_id): def resume(self, stack_id):
"""Resume a stack.""" """Resume a stack."""
body = {'resume': None} body = {'resume': None}
resp, body = self.client.json_request('POST', self.client.post('/stacks/%s/actions' % stack_id, data=body)
'/stacks/%s/actions' % stack_id,
data=body)
def cancel_update(self, stack_id): def cancel_update(self, stack_id):
"""Cancel running update of a stack.""" """Cancel running update of a stack."""
body = {'cancel_update': None} body = {'cancel_update': None}
resp, body = self.client.json_request('POST', self.client.post('/stacks/%s/actions' % stack_id, data=body)
'/stacks/%s/actions' % stack_id,
data=body)
def check(self, stack_id): def check(self, stack_id):
"""Check a stack.""" """Check a stack."""
body = {'check': None} body = {'check': None}
resp, body = self.client.json_request('POST', self.client.post('/stacks/%s/actions' % stack_id, data=body)
'/stacks/%s/actions' % stack_id,
data=body)

View File

@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from heatclient.common import utils
from heatclient.openstack.common.apiclient import base from heatclient.openstack.common.apiclient import base
@ -28,5 +29,6 @@ class BuildInfoManager(base.BaseManager):
resource_class = BuildInfo resource_class = BuildInfo
def build_info(self): 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 return body

View File

@ -17,6 +17,7 @@ from oslo_utils import encodeutils
import six import six
from six.moves.urllib import parse from six.moves.urllib import parse
from heatclient.common import utils
from heatclient.openstack.common.apiclient import base from heatclient.openstack.common.apiclient import base
from heatclient.v1 import stacks from heatclient.v1 import stacks
@ -79,5 +80,6 @@ class EventManager(stacks.StackChildManager):
parse.quote(stack_id, ''), parse.quote(stack_id, ''),
parse.quote(encodeutils.safe_encode(resource_name), ''), parse.quote(encodeutils.safe_encode(resource_name), ''),
parse.quote(event_id, '')) parse.quote(event_id, ''))
resp, body = self.client.json_request('GET', url_str) resp = self.client.get(url_str)
return Event(self, body['event']) body = utils.get_response_body(resp)
return Event(self, body.get('event'))

View File

@ -10,6 +10,7 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from heatclient.common import utils
from oslo_utils import encodeutils from oslo_utils import encodeutils
from six.moves.urllib import parse from six.moves.urllib import parse
@ -44,7 +45,8 @@ class ResourceTypeManager(base.BaseManager):
""" """
url_str = '/resource_types/%s' % ( url_str = '/resource_types/%s' % (
parse.quote(encodeutils.safe_encode(resource_type), '')) 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 return body
def generate_template(self, resource_type, template_type='cfn'): def generate_template(self, resource_type, template_type='cfn'):
@ -53,5 +55,6 @@ class ResourceTypeManager(base.BaseManager):
if template_type: if template_type:
url_str += '?%s' % parse.urlencode( url_str += '?%s' % parse.urlencode(
{'template_type': template_type}, True) {'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 return body

View File

@ -12,6 +12,7 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from heatclient.common import utils
from oslo_utils import encodeutils from oslo_utils import encodeutils
from six.moves.urllib import parse from six.moves.urllib import parse
@ -58,8 +59,9 @@ class ResourceManager(stacks.StackChildManager):
url_str = '/stacks/%s/resources/%s' % ( url_str = '/stacks/%s/resources/%s' % (
parse.quote(stack_id, ''), parse.quote(stack_id, ''),
parse.quote(encodeutils.safe_encode(resource_name), '')) parse.quote(encodeutils.safe_encode(resource_name), ''))
resp, body = self.client.json_request('GET', url_str) resp = self.client.get(url_str)
return Resource(self, body['resource']) body = utils.get_response_body(resp)
return Resource(self, body.get('resource'))
def metadata(self, stack_id, resource_name): def metadata(self, stack_id, resource_name):
"""Get the metadata for a specific resource. """Get the metadata for a specific resource.
@ -71,8 +73,9 @@ class ResourceManager(stacks.StackChildManager):
url_str = '/stacks/%s/resources/%s/metadata' % ( url_str = '/stacks/%s/resources/%s/metadata' % (
parse.quote(stack_id, ''), parse.quote(stack_id, ''),
parse.quote(encodeutils.safe_encode(resource_name), '')) parse.quote(encodeutils.safe_encode(resource_name), ''))
resp, body = self.client.json_request('GET', url_str) resp = self.client.get(url_str)
return body['metadata'] body = utils.get_response_body(resp)
return body.get('metadata')
def signal(self, stack_id, resource_name, data=None): def signal(self, stack_id, resource_name, data=None):
"""Signal a specific resource. """Signal a specific resource.
@ -84,7 +87,8 @@ class ResourceManager(stacks.StackChildManager):
url_str = '/stacks/%s/resources/%s/signal' % ( url_str = '/stacks/%s/resources/%s/signal' % (
parse.quote(stack_id, ''), parse.quote(stack_id, ''),
parse.quote(encodeutils.safe_encode(resource_name), '')) 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 return body
def generate_template(self, resource_name): def generate_template(self, resource_name):
@ -93,5 +97,6 @@ class ResourceManager(stacks.StackChildManager):
""" """
url_str = '/resource_types/%s/template' % ( url_str = '/resource_types/%s/template' % (
parse.quote(encodeutils.safe_encode(resource_name), '')) 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 return body

View File

@ -10,6 +10,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from heatclient.common import utils
from heatclient.openstack.common.apiclient import base from heatclient.openstack.common.apiclient import base
@ -32,17 +33,16 @@ class SoftwareConfigManager(base.BaseManager):
:param config_id: ID of the software config :param config_id: ID of the software config
""" """
resp, body = self.client.json_request( resp = self.client.get('/software_configs/%s' % config_id)
'GET', '/software_configs/%s' % config_id) body = utils.get_response_body(resp)
return SoftwareConfig(self, body.get('software_config'))
return SoftwareConfig(self, body['software_config'])
def create(self, **kwargs): def create(self, **kwargs):
"""Create a software config.""" """Create a software config."""
resp, body = self.client.json_request('POST', '/software_configs', resp = self.client.post('/software_configs',
data=kwargs) data=kwargs)
body = utils.get_response_body(resp)
return SoftwareConfig(self, body['software_config']) return SoftwareConfig(self, body.get('software_config'))
def delete(self, config_id): def delete(self, config_id):
"""Delete a software config.""" """Delete a software config."""

View File

@ -12,6 +12,7 @@
from six.moves.urllib import parse from six.moves.urllib import parse
from heatclient.common import utils
from heatclient.openstack.common.apiclient import base from heatclient.openstack.common.apiclient import base
@ -43,30 +44,32 @@ class SoftwareDeploymentManager(base.BaseManager):
""" """
url = '/software_deployments/metadata/%s' % parse.quote( url = '/software_deployments/metadata/%s' % parse.quote(
server_id, '') server_id, '')
resp, body = self.client.json_request('GET', url) resp = self.client.get(url)
return body['metadata'] body = utils.get_response_body(resp)
return body.get('metadata')
def get(self, deployment_id): def get(self, deployment_id):
"""Get the details for a specific software deployment. """Get the details for a specific software deployment.
:param deployment_id: ID of the software deployment :param deployment_id: ID of the software deployment
""" """
resp, body = self.client.json_request( resp = self.client.get('/software_deployments/%s' % deployment_id)
'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): def create(self, **kwargs):
"""Create a software deployment.""" """Create a software deployment."""
resp, body = self.client.json_request( resp = self.client.post('/software_deployments', data=kwargs)
'POST', '/software_deployments', data=kwargs) body = utils.get_response_body(resp)
return SoftwareDeployment(self, body['software_deployment']) return SoftwareDeployment(self, body.get('software_deployment'))
def update(self, deployment_id, **kwargs): def update(self, deployment_id, **kwargs):
"""Update a software deployment.""" """Update a software deployment."""
resp, body = self.client.json_request( resp = self.client.put('/software_deployments/%s' %
'PUT', '/software_deployments/%s' % deployment_id, data=kwargs) deployment_id, data=kwargs)
return SoftwareDeployment(self, body['software_deployment']) body = utils.get_response_body(resp)
return SoftwareDeployment(self, body.get('software_deployment'))
def delete(self, deployment_id): def delete(self, deployment_id):
"""Delete a software deployment.""" """Delete a software deployment."""

View File

@ -12,6 +12,7 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from heatclient.common import utils
import six import six
from six.moves.urllib import parse from six.moves.urllib import parse
@ -123,23 +124,28 @@ class StackManager(base.BaseManager):
def preview(self, **kwargs): def preview(self, **kwargs):
"""Preview a stack.""" """Preview a stack."""
headers = self.client.credentials_headers() headers = self.client.credentials_headers()
resp, body = self.client.json_request('POST', '/stacks/preview', resp = self.client.post('/stacks/preview',
data=kwargs, headers=headers) data=kwargs, headers=headers)
return Stack(self, body['stack']) body = utils.get_response_body(resp)
return Stack(self, body.get('stack'))
def create(self, **kwargs): def create(self, **kwargs):
"""Create a stack.""" """Create a stack."""
headers = self.client.credentials_headers() headers = self.client.credentials_headers()
resp, body = self.client.json_request('POST', '/stacks', resp = self.client.post('/stacks',
data=kwargs, headers=headers) data=kwargs, headers=headers)
body = utils.get_response_body(resp)
return body return body
def update(self, stack_id, **kwargs): def update(self, stack_id, **kwargs):
"""Update a stack.""" """Update a stack."""
headers = self.client.credentials_headers() headers = self.client.credentials_headers()
method = 'PATCH' if kwargs.pop('existing', None) else 'PUT' if kwargs.pop('existing', None):
resp, body = self.client.json_request(method, '/stacks/%s' % stack_id, self.client.patch('/stacks/%s' % stack_id, data=kwargs,
data=kwargs, headers=headers) headers=headers)
else:
self.client.put('/stacks/%s' % stack_id, data=kwargs,
headers=headers)
def delete(self, stack_id): def delete(self, stack_id):
"""Delete a stack.""" """Delete a stack."""
@ -148,9 +154,8 @@ class StackManager(base.BaseManager):
def abandon(self, stack_id): def abandon(self, stack_id):
"""Abandon a stack.""" """Abandon a stack."""
stack = self.get(stack_id) stack = self.get(stack_id)
resp, body = self.client.json_request( resp = self.client.delete('/stacks/%s/abandon' % stack.identifier)
'DELETE', body = utils.get_response_body(resp)
'/stacks/%s/abandon' % stack.identifier)
return body return body
def snapshot(self, stack_id, name=None): def snapshot(self, stack_id, name=None):
@ -159,39 +164,36 @@ class StackManager(base.BaseManager):
data = {} data = {}
if name: if name:
data['name'] = name data['name'] = name
resp, body = self.client.json_request( resp = self.client.post('/stacks/%s/snapshots' % stack.identifier,
'POST', data=data)
'/stacks/%s/snapshots' % stack.identifier, body = utils.get_response_body(resp)
data=data)
return body return body
def snapshot_show(self, stack_id, snapshot_id): def snapshot_show(self, stack_id, snapshot_id):
stack = self.get(stack_id) stack = self.get(stack_id)
resp, body = self.client.json_request( resp = self.client.get('/stacks/%s/snapshots/%s' % (stack.identifier,
'GET', snapshot_id))
'/stacks/%s/snapshots/%s' % (stack.identifier, snapshot_id)) body = utils.get_response_body(resp)
return body return body
def snapshot_delete(self, stack_id, snapshot_id): def snapshot_delete(self, stack_id, snapshot_id):
stack = self.get(stack_id) stack = self.get(stack_id)
resp, body = self.client.json_request( resp = self.client.delete('/stacks/%s/snapshots/%s' %
'DELETE', (stack.identifier, snapshot_id))
'/stacks/%s/snapshots/%s' % (stack.identifier, snapshot_id)) body = utils.get_response_body(resp)
return body return body
def restore(self, stack_id, snapshot_id): def restore(self, stack_id, snapshot_id):
stack = self.get(stack_id) stack = self.get(stack_id)
resp, body = self.client.json_request( resp = self.client.post('/stacks/%s/snapshots/%s/restore' %
'POST', (stack.identifier, snapshot_id))
'/stacks/%s/snapshots/%s/restore' % (stack.identifier, body = utils.get_response_body(resp)
snapshot_id))
return body return body
def snapshot_list(self, stack_id): def snapshot_list(self, stack_id):
stack = self.get(stack_id) stack = self.get(stack_id)
resp, body = self.client.json_request( resp = self.client.get('/stacks/%s/snapshots' % stack.identifier)
'GET', body = utils.get_response_body(resp)
'/stacks/%s/snapshots' % stack.identifier)
return body return body
def get(self, stack_id): def get(self, stack_id):
@ -199,8 +201,9 @@ class StackManager(base.BaseManager):
:param stack_id: Stack ID to lookup :param stack_id: Stack ID to lookup
""" """
resp, body = self.client.json_request('GET', '/stacks/%s' % stack_id) resp = self.client.get('/stacks/%s' % stack_id)
return Stack(self, body['stack']) body = utils.get_response_body(resp)
return Stack(self, body.get('stack'))
def template(self, stack_id): def template(self, stack_id):
"""Get the template content for a specific stack as a parsed JSON """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 :param stack_id: Stack ID to get the template for
""" """
resp, body = self.client.json_request( resp = self.client.get('/stacks/%s/template' % stack_id)
'GET', '/stacks/%s/template' % stack_id) body = utils.get_response_body(resp)
return body return body
def validate(self, **kwargs): def validate(self, **kwargs):
"""Validate a stack template.""" """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 return body
@ -232,9 +236,8 @@ class StackChildManager(base.BaseManager):
# since all we want is the stacks:lookup response to get the # since all we want is the stacks:lookup response to get the
# fully qualified ID, and not all users are allowed to do the # fully qualified ID, and not all users are allowed to do the
# redirected stacks:show, so pass follow_redirects=False # redirected stacks:show, so pass follow_redirects=False
resp, body = self.client.json_request('GET', resp = self.client.get('/stacks/%s' % stack_id,
'/stacks/%s' % stack_id, follow_redirects=False)
follow_redirects=False)
location = resp.headers.get('location') location = resp.headers.get('location')
path = self.client.strip_endpoint(location) path = self.client.strip_endpoint(location)
return path[len('/stacks/'):] return path[len('/stacks/'):]