def keystone_request_callback(request, uri, headers): response_headers = {"content-type": "application/json"} token_id = TOKENID if uri == BASE_URL: return (200, headers, V3_VERSION_LIST) elif uri == BASE_URL + "/v2.0": v2_token = ks_v2_fixture.Token(token_id) return (200, response_headers, jsonutils.dumps(v2_token)) elif uri == BASE_URL + "/v3": v3_token = ks_v3_fixture.Token() response_headers["X-Subject-Token"] = token_id return (201, response_headers, jsonutils.dumps(v3_token))
def get_file_contents(from_data, files, base_url=None, ignore_if=None, recurse_if=None, file_is_template=False): if recurse_if and recurse_if(from_data): if isinstance(from_data, dict): recurse_data = six.itervalues(from_data) else: recurse_data = from_data for value in recurse_data: get_file_contents(value, files, base_url, ignore_if, recurse_if, file_is_template=file_is_template) if isinstance(from_data, dict): for key, value in iter(from_data.items()): if ignore_if and ignore_if(key, value): continue if base_url and not base_url.endswith('/'): base_url = base_url + '/' str_url = parse.urljoin(base_url, value) if str_url not in files: if file_is_template: template = get_template_contents( template_url=str_url, files=files)[1] file_content = jsonutils.dumps(template) else: file_content = read_url_content(str_url) files[str_url] = file_content # replace the data value with the normalised absolute URL from_data[key] = str_url
def script_heat_list(url=None, show_nested=False): if url is None: url = '/stacks?' resp_dict = { "stacks": [{ "id": "1", "stack_name": "teststack", "stack_owner": "testowner", "project": "testproject", "stack_status": 'CREATE_COMPLETE', "creation_time": "2012-10-25T01:58:47Z" }, { "id": "2", "stack_name": "teststack2", "stack_owner": "testowner", "project": "testproject", "stack_status": 'IN_PROGRESS', "creation_time": "2012-10-25T01:58:47Z" }] } if show_nested: nested = { "id": "3", "stack_name": "teststack_nested", "stack_status": 'IN_PROGRESS', "creation_time": "2012-10-25T01:58:47Z", "parent": "theparentof3" } resp_dict["stacks"].append(nested) resp = FakeHTTPResponse(200, 'success, you', {'content-type': 'application/json'}, jsonutils.dumps(resp_dict)) http.HTTPClient.json_request('GET', url).AndReturn((resp, resp_dict))
def test_parsable_verbose(self): message = "The Stack (bad) could not be found." resp_dict = { "explanation": "The resource could not be found.", "code": 404, "error": { "message": message, "type": "StackNotFound", "traceback": "<TRACEBACK>", }, "title": "Not Found" } self._script_keystone_client() fakes.script_heat_error(jsonutils.dumps(resp_dict)) self.m.ReplayAll() exc.verbose = 1 try: self.shell("stack-show bad") except exc.HTTPException as e: expect = 'ERROR: The Stack (bad) could not be found.\n<TRACEBACK>' self.assertEqual(expect, str(e))
def test_template_show_hot(self): self._script_keystone_client() resp_dict = {"heat_template_version": "2013-05-23", "parameters": {}, "resources": {}, "outputs": {}} resp = fakes.FakeHTTPResponse( 200, 'OK', {'content-type': 'application/json'}, jsonutils.dumps(resp_dict)) http.HTTPClient.json_request( 'GET', '/stacks/teststack/template').AndReturn((resp, resp_dict)) self.m.ReplayAll() show_text = self.shell('template-show teststack') required = [ "heat_template_version: '2013-05-23'", "outputs: {}", "parameters: {}", "resources: {}" ] for r in required: self.assertRegexpMatches(show_text, r)
def test_stack_show(self): self._script_keystone_client() resp_dict = {"stack": { "id": "1", "stack_name": "teststack", "stack_status": 'CREATE_COMPLETE', "creation_time": "2012-10-25T01:58:47Z" }} resp = fakes.FakeHTTPResponse( 200, 'OK', {'content-type': 'application/json'}, jsonutils.dumps(resp_dict)) http.HTTPClient.json_request( 'GET', '/stacks/teststack/1').AndReturn((resp, resp_dict)) self.m.ReplayAll() list_text = self.shell('stack-show teststack/1') required = [ 'id', 'stack_name', 'stack_status', 'creation_time', 'teststack', 'CREATE_COMPLETE', '2012-10-25T01:58:47Z' ] for r in required: self.assertRegexpMatches(list_text, r)
def test_build_info(self): self._script_keystone_client() resp_dict = { 'build_info': { 'api': {'revision': 'api_revision'}, 'engine': {'revision': 'engine_revision'} } } resp_string = jsonutils.dumps(resp_dict) headers = {'content-type': 'application/json'} http_resp = fakes.FakeHTTPResponse(200, 'OK', headers, resp_string) response = (http_resp, resp_dict) http.HTTPClient.json_request('GET', '/build_info').AndReturn(response) self.m.ReplayAll() build_info_text = self.shell('build-info') required = [ 'api', 'engine', 'revision', 'api_revision', 'engine_revision', ] for r in required: self.assertRegexpMatches(build_info_text, r)
def test_resource_show(self): self._script_keystone_client() resp_dict = {"resource": {"description": "", "links": [{"href": "http://heat.example.com:8004/foo", "rel": "self"}, {"href": "http://heat.example.com:8004/foo2", "rel": "resource"}], "logical_resource_id": "aResource", "physical_resource_id": "43b68bae-ed5d-4aed-a99f-0b3d39c2418a", "required_by": [], "resource_name": "aResource", "resource_status": "CREATE_COMPLETE", "resource_status_reason": "state changed", "resource_type": "OS::Nova::Server", "updated_time": "2014-01-06T16:14:26Z"}} resp = fakes.FakeHTTPResponse( 200, 'OK', {'content-type': 'application/json'}, jsonutils.dumps(resp_dict)) stack_id = 'teststack/1' resource_name = 'aResource' http.HTTPClient.json_request( 'GET', '/stacks/%s/resources/%s' % ( urlutils.quote(stack_id, ''), urlutils.quote(strutils.safe_encode( resource_name), '') )).AndReturn((resp, resp_dict)) self.m.ReplayAll() resource_show_text = self.shell('resource-show {0} {1}'.format( stack_id, resource_name)) required = [ 'description', 'links', 'http://heat.example.com:8004/foo[0-9]', 'logical_resource_id', 'aResource', 'physical_resource_id', '43b68bae-ed5d-4aed-a99f-0b3d39c2418a', 'required_by', 'resource_name', 'aResource', 'resource_status', 'CREATE_COMPLETE', 'resource_status_reason', 'state changed', 'resource_type', 'OS::Nova::Server', 'updated_time', '2014-01-06T16:14:26Z', ] for r in required: self.assertRegexpMatches(resource_show_text, r)
def do_template_validate(hc, args): '''Validate a template with parameters.''' fields = {'parameters': utils.format_parameters(args.parameters)} _set_template_fields(hc, args, fields) _process_environment_and_files(args, fields) validation = hc.stacks.validate(**fields) print(jsonutils.dumps(validation, indent=2))
def do_resource_type_show(hc, args={}): """Show the resource type.""" try: resource_type = hc.resource_types.get(args.resource_type) except exc.HTTPNotFound: raise exc.CommandError("Resource Type not found: %s" % args.resource_type) else: print(jsonutils.dumps(resource_type, indent=2))
def script_heat_normal_error(): resp_dict = { "explanation": "The resource could not be found.", "code": 404, "error": { "message": "The Stack (bad) could not be found.", "type": "StackNotFound", "traceback": "", }, "title": "Not Found" } resp = FakeHTTPResponse(400, 'The resource could not be found', {'content-type': 'application/json'}, jsonutils.dumps(resp_dict)) http.HTTPClient.json_request('GET', '/stacks/bad').AndRaise( exc.from_response(resp, jsonutils.dumps(resp_dict)))
def do_stack_abandon(hc, args): '''Abandon the stack.''' fields = {'stack_id': args.id} try: stack = hc.stacks.abandon(**fields) except exc.HTTPNotFound: raise exc.CommandError('Stack not found: %s' % args.id) else: print(jsonutils.dumps(stack, indent=2))
def do_resource_type_show(hc, args): '''Show the resource type.''' try: resource_type = hc.resource_types.get(args.resource_type) except exc.HTTPNotFound: raise exc.CommandError('Resource Type not found: %s' % args.resource_type) else: print(jsonutils.dumps(resource_type, indent=2))
def do_resource_metadata(hc, args): """List resource metadata.""" fields = {"stack_id": args.id, "resource_name": args.resource} try: metadata = hc.resources.metadata(**fields) except exc.HTTPNotFound: raise exc.CommandError("Stack or resource not found: %s %s" % (args.id, args.resource)) else: print(jsonutils.dumps(metadata, indent=2))
def do_resource_metadata(hc, args): '''List resource metadata.''' fields = {'stack_id': args.id, 'resource_name': args.resource} try: metadata = hc.resources.metadata(**fields) except exc.HTTPNotFound: raise exc.CommandError('Stack or resource not found: %s %s' % (args.id, args.resource)) else: print(jsonutils.dumps(metadata, indent=2))
def do_template_show(hc, args): """Get the template for the specified stack.""" fields = {"stack_id": args.id} try: template = hc.stacks.template(**fields) except exc.HTTPNotFound: raise exc.CommandError("Stack not found: %s" % args.id) else: if "heat_template_version" in template: print(yaml.safe_dump(template, indent=2)) else: print(jsonutils.dumps(template, indent=2))
def do_template_show(hc, args): '''Get the template for the specified stack.''' fields = {'stack_id': args.id} try: template = hc.stacks.template(**fields) except exc.HTTPNotFound: raise exc.CommandError('Stack not found: %s' % args.id) else: if 'heat_template_version' in template: print(yaml.safe_dump(template, indent=2)) else: print(jsonutils.dumps(template, indent=2, ensure_ascii=False))
def do_template_show(hc, args): '''Get the template for the specified stack.''' fields = {'stack_id': args.id} try: template = hc.stacks.template(**fields) except exc.HTTPNotFound: raise exc.CommandError('Stack not found: %s' % args.id) else: if 'heat_template_version' in template: print(yaml.safe_dump(template, indent=2)) else: print(jsonutils.dumps(template, indent=2))
def do_stack_abandon(hc, args): '''Abandon the stack. This will delete the record of the stack from Heat, but will not delete any of the underlying resources. Prints an adoptable JSON representation of the stack to stdout on success. ''' fields = {'stack_id': args.id} try: stack = hc.stacks.abandon(**fields) except exc.HTTPNotFound: raise exc.CommandError('Stack not found: %s' % args.id) else: print(jsonutils.dumps(stack, indent=2))
def do_output_show(hc, args): """Show a specific stack output.""" try: stack = hc.stacks.get(stack_id=args.id) except exc.HTTPNotFound: raise exc.CommandError("Stack not found: %s" % args.id) else: for output in stack.to_dict().get("outputs", []): if output["output_key"] == args.output: value = output["output_value"] break else: return print(jsonutils.dumps(value, indent=2))
def do_output_show(hc, args): '''Show a specific stack output.''' try: stack = hc.stacks.get(stack_id=args.id) except exc.HTTPNotFound: raise exc.CommandError('Stack not found: %s' % args.id) else: for output in stack.to_dict().get('outputs', []): if output['output_key'] == args.output: value = output['output_value'] break else: return print (jsonutils.dumps(value, indent=2))
def script_heat_normal_error(): resp_dict = { "explanation": "The resource could not be found.", "code": 404, "error": { "message": "The Stack (bad) could not be found.", "type": "StackNotFound", "traceback": "", }, "title": "Not Found" } resp = FakeHTTPResponse(400, 'The resource could not be found', {'content-type': 'application/json'}, jsonutils.dumps(resp_dict)) http.HTTPClient.json_request('GET', '/stacks/bad').AndRaise( exc.from_response(resp))
def do_template_validate(hc, args): '''Validate a template with parameters.''' tpl_files, template = template_utils.get_template_contents( args.template_file, args.template_url, args.template_object, hc.http_client.raw_request) env_files, env = template_utils.process_multiple_environments_and_files( env_paths=args.environment_file) fields = { 'template': template, 'files': dict(list(tpl_files.items()) + list(env_files.items())), 'environment': env } validation = hc.stacks.validate(**fields) print(jsonutils.dumps(validation, indent=2, ensure_ascii=False))
def do_template_validate(hc, args): """Validate a template with parameters.""" tpl_files, template = template_utils.get_template_contents( args.template_file, args.template_url, args.template_object, hc.http_client.raw_request ) env_files, env = template_utils.process_environment_and_files(env_path=args.environment_file) fields = { "parameters": utils.format_parameters(args.parameters), "template": template, "files": dict(list(tpl_files.items()) + list(env_files.items())), "environment": env, } validation = hc.stacks.validate(**fields) print(jsonutils.dumps(validation, indent=2))
def script_heat_list(): resp_dict = {"stacks": [{ "id": "1", "stack_name": "teststack", "stack_status": 'CREATE_COMPLETE', "creation_time": "2012-10-25T01:58:47Z"}, { "id": "2", "stack_name": "teststack2", "stack_status": 'IN_PROGRESS', "creation_time": "2012-10-25T01:58:47Z" }] } resp = FakeHTTPResponse(200, 'success, you', {'content-type': 'application/json'}, jsonutils.dumps(resp_dict)) http.HTTPClient.json_request('GET', '/stacks?').AndReturn( (resp, resp_dict))
def json_request(self, method, url, **kwargs): kwargs.setdefault('headers', {}) kwargs['headers'].setdefault('Content-Type', 'application/json') kwargs['headers'].setdefault('Accept', 'application/json') if 'data' in kwargs: 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('Could not decode response body as JSON') else: body = None return resp, body
def test_parsable_malformed_error_missing_message(self): missing_message = { "explanation": "The resource could not be found.", "code": 404, "error": { "type": "StackNotFound", "traceback": "", }, "title": "Not Found" } self._script_keystone_client() fakes.script_heat_error(jsonutils.dumps(missing_message)) self.m.ReplayAll() try: self.shell("stack-show bad") except exc.HTTPException as e: self.assertEqual("ERROR: Internal Error", str(e))
def json_request(self, method, url, **kwargs): kwargs.setdefault('headers', {}) kwargs['headers'].setdefault('Content-Type', 'application/json') kwargs['headers'].setdefault('Accept', 'application/json') if 'body' in kwargs: kwargs['body'] = jsonutils.dumps(kwargs['body']) resp, body_str = self._http_request(url, method, **kwargs) if 'application/json' in resp.getheader('content-type', None): body = body_str try: body = jsonutils.loads(body) except ValueError: LOG.error('Could not decode response body as JSON') else: body = None return resp, body
def do_template_validate(hc, args): '''Validate a template with parameters.''' tpl_files, template = template_utils.get_template_contents( args.template_file, args.template_url, args.template_object, hc.http_client.raw_request) env_files, env = template_utils.process_environment_and_files( env_path=args.environment_file) fields = { 'parameters': utils.format_parameters(args.parameters), 'template': template, 'files': dict(tpl_files.items() + env_files.items()), 'environment': env } validation = hc.stacks.validate(**fields) print(jsonutils.dumps(validation, indent=2))
def test_stack_abandon(self): self._script_keystone_client() resp_dict = {"stack": { "id": "1", "stack_name": "teststack", "stack_status": 'CREATE_COMPLETE', "creation_time": "2012-10-25T01:58:47Z" }} abandoned_stack = { "action": "CREATE", "status": "COMPLETE", "name": "teststack", "id": "1", "resources": { "foo": { "name": "foo", "resource_id": "test-res-id", "action": "CREATE", "status": "COMPLETE", "resource_data": {}, "metadata": {}, } } } resp = fakes.FakeHTTPResponse( 200, 'OK', {'content-type': 'application/json'}, jsonutils.dumps(resp_dict)) 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)) self.m.ReplayAll() abandon_resp = self.shell('stack-abandon teststack/1') self.assertEqual(abandoned_stack, jsonutils.loads(abandon_resp))
def script_heat_list(url=None): if url is None: url = '/stacks?' resp_dict = { "stacks": [{ "id": "1", "stack_name": "teststack", "stack_status": 'CREATE_COMPLETE', "creation_time": "2012-10-25T01:58:47Z" }, { "id": "2", "stack_name": "teststack2", "stack_status": 'IN_PROGRESS', "creation_time": "2012-10-25T01:58:47Z" }] } resp = FakeHTTPResponse(200, 'success, you', {'content-type': 'application/json'}, jsonutils.dumps(resp_dict)) http.HTTPClient.json_request('GET', url).AndReturn((resp, resp_dict))
def get_file_contents(from_data, files, base_url=None, ignore_if=None, recurse_if=None, file_is_template=False): if recurse_if and recurse_if(from_data): if isinstance(from_data, dict): recurse_data = six.itervalues(from_data) else: recurse_data = from_data for value in recurse_data: get_file_contents(value, files, base_url, ignore_if, recurse_if, file_is_template=file_is_template) if isinstance(from_data, dict): for key, value in iter(from_data.items()): if ignore_if and ignore_if(key, value): continue if base_url and not base_url.endswith('/'): base_url = base_url + '/' str_url = parse.urljoin(base_url, value) if str_url not in files: if file_is_template: template = get_template_contents(template_url=str_url, files=files)[1] file_content = jsonutils.dumps(template) else: file_content = read_url_content(str_url) files[str_url] = file_content # replace the data value with the normalised absolute URL from_data[key] = str_url
def do_stack_abandon(hc, args): '''Abandon the stack. This will delete the record of the stack from Heat, but will not delete any of the underlying resources. Prints an adoptable JSON representation of the stack to stdout or a file on success. ''' fields = {'stack_id': args.id} try: stack = hc.stacks.abandon(**fields) except exc.HTTPNotFound: raise exc.CommandError('Stack not found: %s' % args.id) else: result = jsonutils.dumps(stack, indent=2) if args.output_file is not None: try: with open(args.output_file, "w") as f: f.write(result) except IOError as err: print(result) raise exc.CommandError(str(err)) else: print(result)
def script_heat_list(url=None, show_nested=False): if url is None: url = '/stacks?' resp_dict = {"stacks": [ { "id": "1", "stack_name": "teststack", "stack_owner": "testowner", "project": "testproject", "stack_status": 'CREATE_COMPLETE', "creation_time": "2012-10-25T01:58:47Z" }, { "id": "2", "stack_name": "teststack2", "stack_owner": "testowner", "project": "testproject", "stack_status": 'IN_PROGRESS', "creation_time": "2012-10-25T01:58:47Z" }] } if show_nested: nested = { "id": "3", "stack_name": "teststack_nested", "stack_status": 'IN_PROGRESS', "creation_time": "2012-10-25T01:58:47Z", "parent": "theparentof3" } resp_dict["stacks"].append(nested) resp = FakeHTTPResponse(200, 'success, you', {'content-type': 'application/json'}, jsonutils.dumps(resp_dict)) http.HTTPClient.json_request('GET', url).AndReturn((resp, resp_dict))
def json_formatter(js): return jsonutils.dumps(js, indent=2)
def _create_single_version(version): return jsonutils.dumps({'version': version})
def _create_version_list(versions): return jsonutils.dumps({'versions': {'values': versions}})
def json_formatter(js): return jsonutils.dumps(js, indent=2, ensure_ascii=False)
# under the License. from __future__ import print_function import prettytable import sys import textwrap import uuid import yaml from heatclient import exc from heatclient.openstack.common import cliutils from heatclient.openstack.common import importutils from heatclient.openstack.common import jsonutils supported_formats = { "json": lambda x: jsonutils.dumps(x, indent=2), "yaml": yaml.safe_dump } # Using common methods from oslo cliutils arg = cliutils.arg env = cliutils.env print_list = cliutils.print_list def link_formatter(links): return '\n'.join([l.get('href', '') for l in links or []]) def json_formatter(js): return jsonutils.dumps(js, indent=2, ensure_ascii=False)
def test_event_list(self): self._script_keystone_client() resp_dict = {"events": [ {"event_time": "2013-12-05T14:14:30Z", "id": self.event_id_one, "links": [{"href": "http://heat.example.com:8004/foo", "rel": "self"}, {"href": "http://heat.example.com:8004/foo2", "rel": "resource"}, {"href": "http://heat.example.com:8004/foo3", "rel": "stack"}], "logical_resource_id": "aResource", "physical_resource_id": None, "resource_name": "aResource", "resource_status": "CREATE_IN_PROGRESS", "resource_status_reason": "state changed"}, {"event_time": "2013-12-05T14:14:30Z", "id": self.event_id_two, "links": [{"href": "http://heat.example.com:8004/foo", "rel": "self"}, {"href": "http://heat.example.com:8004/foo2", "rel": "resource"}, {"href": "http://heat.example.com:8004/foo3", "rel": "stack"}], "logical_resource_id": "aResource", "physical_resource_id": "bce15ec4-8919-4a02-8a90-680960fb3731", "resource_name": "aResource", "resource_status": "CREATE_COMPLETE", "resource_status_reason": "state changed"}]} resp = fakes.FakeHTTPResponse( 200, 'OK', {'content-type': 'application/json'}, jsonutils.dumps(resp_dict)) stack_id = 'teststack/1' resource_name = 'testresource/1' http.HTTPClient.json_request( 'GET', '/stacks/%s/resources/%s/events' % ( urlutils.quote(stack_id, ''), urlutils.quote(strutils.safe_encode( resource_name), ''))).AndReturn((resp, resp_dict)) self.m.ReplayAll() event_list_text = self.shell('event-list {0} --resource {1}'.format( stack_id, resource_name)) required = [ 'resource_name', 'id', 'resource_status_reason', 'resource_status', 'event_time', 'aResource', self.event_id_one, self.event_id_two, 'state changed', 'CREATE_IN_PROGRESS', 'CREATE_COMPLETE', '2013-12-05T14:14:30Z', '2013-12-05T14:14:30Z', ] for r in required: self.assertRegexpMatches(event_list_text, r)
def test_event_show(self): self._script_keystone_client() resp_dict = {"event": {"event_time": "2013-12-05T14:14:30Z", "id": self.event_id_one, "links": [{"href": "http://heat.example.com:8004/foo", "rel": "self"}, {"href": "http://heat.example.com:8004/foo2", "rel": "resource"}, {"href": "http://heat.example.com:8004/foo3", "rel": "stack"}], "logical_resource_id": "aResource", "physical_resource_id": None, "resource_name": "aResource", "resource_properties": {"admin_user": "******", "availability_zone": "nova"}, "resource_status": "CREATE_IN_PROGRESS", "resource_status_reason": "state changed", "resource_type": "OS::Nova::Server" }} resp = fakes.FakeHTTPResponse( 200, 'OK', {'content-type': 'application/json'}, jsonutils.dumps(resp_dict)) stack_id = 'teststack/1' resource_name = 'testresource/1' http.HTTPClient.json_request( 'GET', '/stacks/%s/resources/%s/events/%s' % ( urlutils.quote(stack_id, ''), urlutils.quote(strutils.safe_encode( resource_name), ''), urlutils.quote(self.event_id_one, '') )).AndReturn((resp, resp_dict)) self.m.ReplayAll() event_list_text = self.shell('event-show {0} {1} {2}'.format( stack_id, resource_name, self.event_id_one)) required = [ 'Property', 'Value', 'event_time', '2013-12-05T14:14:30Z', 'id', self.event_id_one, 'links', 'http://heat.example.com:8004/foo[0-9]', 'logical_resource_id', 'physical_resource_id', 'resource_name', 'aResource', 'resource_properties', 'admin_user', 'availability_zone', 'resource_status', 'CREATE_IN_PROGRESS', 'resource_status_reason', 'state changed', 'resource_type', 'OS::Nova::Server', ] for r in required: self.assertRegexpMatches(event_list_text, r)