def do_stack_preview(hc, args): '''Preview the stack.''' 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 = { 'stack_name': args.name, 'disable_rollback': not (args.enable_rollback), 'timeout_mins': args.timeout, 'parameters': utils.format_parameters(args.parameters), 'template': template, 'files': dict(list(tpl_files.items()) + list(env_files.items())), 'environment': env } stack = hc.stacks.preview(**fields) formatters = { 'description': utils.text_wrap_formatter, 'template_description': utils.text_wrap_formatter, 'stack_status_reason': utils.text_wrap_formatter, 'parameters': utils.json_formatter, 'outputs': utils.json_formatter, 'resources': utils.json_formatter, 'links': utils.link_formatter, } utils.print_dict(stack.to_dict(), formatters=formatters)
def do_stack_create(hc, args): '''Create the stack.''' 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) if args.create_timeout: logger.warning('-c/--create-timeout is deprecated, ' 'please use -t/--timeout instead') fields = { 'stack_name': args.name, 'disable_rollback': not(args.enable_rollback), 'parameters': utils.format_parameters(args.parameters), 'template': template, 'files': dict(list(tpl_files.items()) + list(env_files.items())), 'environment': env } timeout = args.timeout or args.create_timeout if timeout: fields['timeout_mins'] = timeout hc.stacks.create(**fields) do_stack_list(hc)
def test_hot_template(self): self.m.StubOutWithMock(request, 'urlopen') tmpl_file = '/home/my/dir/template.yaml' url = 'file:///home/my/dir/template.yaml' request.urlopen(url).AndReturn( six.BytesIO(self.hot_template)) request.urlopen( 'http://localhost/bar.yaml').InAnyOrder().AndReturn( six.BytesIO(b'bar contents')) request.urlopen( 'file:///home/my/dir/foo.yaml').InAnyOrder().AndReturn( six.BytesIO(b'foo contents')) request.urlopen( 'file:///home/my/dir/baz/baz1.yaml').InAnyOrder().AndReturn( six.BytesIO(b'baz1 contents')) request.urlopen( 'file:///home/my/dir/baz/baz2.yaml').InAnyOrder().AndReturn( six.BytesIO(b'baz2 contents')) request.urlopen( 'file:///home/my/dir/baz/baz3.yaml').InAnyOrder().AndReturn( six.BytesIO(b'baz3 contents')) self.m.ReplayAll() files, tmpl_parsed = template_utils.get_template_contents( template_file=tmpl_file) self.assertEqual({ 'http://localhost/bar.yaml': b'bar contents', 'file:///home/my/dir/foo.yaml': b'foo contents', 'file:///home/my/dir/baz/baz1.yaml': b'baz1 contents', 'file:///home/my/dir/baz/baz2.yaml': b'baz2 contents', 'file:///home/my/dir/baz/baz3.yaml': b'baz3 contents', }, files) self.assertEqual({ 'heat_template_version': '2013-05-23', 'resources': { 'resource1': { 'type': 'OS::type1', 'properties': { 'bar': {'get_file': 'http://localhost/bar.yaml'}, 'foo': {'get_file': 'file:///home/my/dir/foo.yaml'}, }, }, 'resource2': { 'type': 'OS::type1', 'properties': { 'baz': [ {'get_file': 'file:///home/my/dir/baz/baz1.yaml'}, {'get_file': 'file:///home/my/dir/baz/baz2.yaml'}, {'get_file': 'file:///home/my/dir/baz/baz3.yaml'}, ], 'ignored_list': {'get_file': ['ignore', 'me']}, 'ignored_dict': {'get_file': {'ignore': 'me'}}, 'ignored_none': {'get_file': None}, }, } } }, tmpl_parsed)
def do_stack_adopt(hc, args): '''Adopt a stack.''' 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) if not args.adopt_file: raise exc.CommandError('Need to specify --adopt-file') adopt_url = template_utils.normalise_file_path_to_url(args.adopt_file) adopt_data = request.urlopen(adopt_url).read() if args.create_timeout: logger.warning('-c/--create-timeout is deprecated, ' 'please use -t/--timeout instead') fields = { 'stack_name': args.name, 'disable_rollback': not (args.enable_rollback), 'adopt_stack_data': adopt_data, 'parameters': utils.format_parameters(args.parameters), 'template': template, 'files': dict(list(tpl_files.items()) + list(env_files.items())), 'environment': env } timeout = args.timeout or args.create_timeout if timeout: fields['timeout_mins'] = timeout hc.stacks.create(**fields) do_stack_list(hc)
def _load_template(self, base_file, file_name, sub_dir=None, files=None): sub_dir = sub_dir or '' filepath = os.path.join(os.path.dirname(os.path.realpath(base_file)), sub_dir, file_name) _files, template = template_utils.get_template_contents(filepath, files=files) return yaml.safe_dump(template)
def _update_stack(self, context, osc, cluster, scale_manager=None, rollback=False): template_path, heat_params, env_files = ( self._extract_template_definition(context, cluster, scale_manager=scale_manager)) tpl_files, template = template_utils.get_template_contents( template_path) environment_files, env_map = self._get_env_files( template_path, env_files) tpl_files.update(env_map) fields = { 'parameters': heat_params, 'environment_files': environment_files, 'template': template, 'files': tpl_files, 'disable_rollback': not rollback } osc.heat().stacks.update(cluster.stack_id, **fields)
def do_stack_preview(hc, args): '''Preview the stack.''' tpl_files, template = template_utils.get_template_contents( args.template_file, args.template_url, args.template_object, _authenticated_fetcher(hc)) env_files, env = template_utils.process_multiple_environments_and_files( env_paths=args.environment_file) fields = { 'stack_name': args.name, 'disable_rollback': not(args.enable_rollback), 'timeout_mins': args.timeout, 'parameters': utils.format_all_parameters(args.parameters, args.parameter_file, args.template_file, args.template_url), 'template': template, 'files': dict(list(tpl_files.items()) + list(env_files.items())), 'environment': env } stack = hc.stacks.preview(**fields) formatters = { 'description': utils.text_wrap_formatter, 'template_description': utils.text_wrap_formatter, 'stack_status_reason': utils.text_wrap_formatter, 'parameters': utils.json_formatter, 'outputs': utils.json_formatter, 'resources': utils.json_formatter, 'links': utils.link_formatter, } utils.print_dict(stack.to_dict(), formatters=formatters)
def do_stack_preview(hc, args): '''Preview the stack.''' 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 = { 'stack_name': args.name, 'parameters': utils.format_parameters(args.parameters), 'template': template, 'files': dict(list(tpl_files.items()) + list(env_files.items())), 'environment': env } stack = hc.stacks.preview(**fields) formatters = { 'description': utils.text_wrap_formatter, 'template_description': utils.text_wrap_formatter, 'stack_status_reason': utils.text_wrap_formatter, 'parameters': utils.json_formatter, 'outputs': utils.json_formatter, 'resources': utils.json_formatter, 'links': utils.link_formatter, } utils.print_dict(stack.to_dict(), formatters=formatters)
def do_stack_adopt(hc, args): """Adopt a stack.""" 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) if not args.adopt_file: raise exc.CommandError("Need to specify --adopt-file") adopt_url = template_utils.normalise_file_path_to_url(args.adopt_file) adopt_data = request.urlopen(adopt_url).read() if args.create_timeout: logger.warning("-c/--create-timeout is deprecated, " "please use -t/--timeout instead") fields = { "stack_name": args.name, "disable_rollback": not (args.enable_rollback), "adopt_stack_data": adopt_data, "parameters": utils.format_parameters(args.parameters), "template": template, "files": dict(list(tpl_files.items()) + list(env_files.items())), "environment": env, } timeout = args.timeout or args.create_timeout if timeout: fields["timeout_mins"] = timeout hc.stacks.create(**fields) do_stack_list(hc)
def get_template_contents(swift, template_object): """Wrap get_template_contents with swift object fetch""" def _object_request(method, url, token=swift.token): return object_request(method, url, token) return template_utils.get_template_contents( template_object=template_object, object_request=_object_request)
def do_stack_update(hc, args): '''Update the stack.''' 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 = { 'stack_id': args.id, 'parameters': utils.format_parameters(args.parameters), 'template': template, 'files': dict(list(tpl_files.items()) + list(env_files.items())), 'environment': env } if args.timeout: fields['timeout_mins'] = args.timeout hc.stacks.update(**fields) do_stack_list(hc)
def process_stack_spec(spec): # Heat stack is a headache, because it demands for client side file # content processing try: tmplfile = spec.get('template', None) except AttributeError as ex: raise exc.FileFormatError(_('The specified file is not a valid ' 'YAML file: %s') % six.text_type(ex)) if not tmplfile: raise exc.FileFormatError(_('No template found in the given ' 'spec file')) tpl_files, template = template_utils.get_template_contents( template_file=tmplfile) env_files, env = template_utils.process_multiple_environments_and_files( env_paths=spec.get('environment', None)) new_spec = { # TODO(Qiming): add context support 'disable_rollback': spec.get('disable_rollback', True), 'context': spec.get('context', {}), 'parameters': spec.get('parameters', {}), 'timeout': spec.get('timeout', 60), 'template': template, 'files': dict(list(tpl_files.items()) + list(env_files.items())), 'environment': env } return new_spec
def _update_stack(self, parameters={}, timeout_mins=constants.STACK_TIMEOUT_DEFAULT): tpl_files, template = template_utils.get_template_contents( template_file=os.path.join(self.tht_dir, constants.TEMPLATE_NAME)) env_paths = [] if self.environment_files: env_paths.extend(self.environment_files) env_files, env = ( template_utils.process_multiple_environments_and_files( env_paths=env_paths)) update.add_breakpoints_cleanup_into_env(env) fields = { 'existing': True, 'stack_id': self.stack_id, 'template': template, 'files': dict(list(tpl_files.items()) + list(env_files.items())), 'environment': env, 'parameters': parameters, 'timeout_mins': timeout_mins } LOG.debug('stack update params: %s', fields) self.heatclient.stacks.update(**fields)
def test_hot_template(self): self.m.StubOutWithMock(request, "urlopen") tmpl_file = "/home/my/dir/template.yaml" url = "file:///home/my/dir/template.yaml" request.urlopen("file:///home/my/dir/foo.yaml").InAnyOrder().AndReturn(six.BytesIO(self.foo_template)) request.urlopen("file:///home/my/dir/foo.yaml").InAnyOrder().AndReturn(six.BytesIO(self.foo_template)) request.urlopen(url).InAnyOrder().AndReturn(six.BytesIO(self.hot_template)) request.urlopen("file:///home/my/dir/spam/egg.yaml").InAnyOrder().AndReturn(six.BytesIO(self.egg_template)) request.urlopen("file:///home/my/dir/spam/egg.yaml").InAnyOrder().AndReturn(six.BytesIO(self.egg_template)) self.m.ReplayAll() files, tmpl_parsed = template_utils.get_template_contents(template_file=tmpl_file) self.assertEqual( yaml.load(self.foo_template.decode("utf-8")), json.loads(files.get("file:///home/my/dir/foo.yaml")) ) self.assertEqual( yaml.load(self.egg_template.decode("utf-8")), json.loads(files.get("file:///home/my/dir/spam/egg.yaml")) ) self.assertEqual( { u"heat_template_version": u"2013-05-23", u"parameters": {u"param1": {u"type": u"string"}}, u"resources": { u"resource1": {u"type": u"file:///home/my/dir/foo.yaml", u"properties": {u"foo": u"bar"}}, u"resource2": { u"type": u"OS::Heat::ResourceGroup", u"properties": {u"resource_def": {u"type": u"file:///home/my/dir/spam/egg.yaml"}}, }, }, }, tmpl_parsed, )
def _update_stack(self, parameters={}, timeout_mins=240): tpl_files, template = template_utils.get_template_contents( template_file=os.path.join(self.tht_dir, TEMPLATE_NAME)) env_paths = [] if self.environment_files: env_paths.extend(self.environment_files) env_files, env = ( template_utils.process_multiple_environments_and_files( env_paths=env_paths)) update.add_breakpoints_cleanup_into_env(env) fields = { 'existing': True, 'stack_id': self.stack_id, 'template': template, 'files': dict(list(tpl_files.items()) + list(env_files.items())), 'environment': env, 'parameters': parameters, 'timeout_mins': timeout_mins } LOG.debug('stack update params: %s', fields) self.heatclient.stacks.update(**fields)
def test_get_nested_stack_template_contents_object(self): tmpl = ('{"heat_template_version": "2016-04-08",' '"resources": {' '"FooBar": {' '"type": "foo/bar.yaml"}}}') url = 'http://no.where/path/to/a.yaml' self.m.ReplayAll() self.object_requested = False def object_request(method, object_url): self.object_requested = True self.assertEqual('GET', method) self.assertTrue(object_url.startswith("http://no.where/path/to/")) if object_url == url: return tmpl else: return '{"heat_template_version": "2016-04-08"}' files, tmpl_parsed = template_utils.get_template_contents( template_object=url, object_request=object_request) self.assertEqual(files['http://no.where/path/to/foo/bar.yaml'], '{"heat_template_version": "2016-04-08"}') self.assertTrue(self.object_requested)
def _update_stack(context, osc, bay): template_path, heat_params = _extract_template_definition(context, bay) tpl_files, template = template_utils.get_template_contents(template_path) fields = {"parameters": heat_params, "template": template, "files": dict(list(tpl_files.items()))} return osc.heat().stacks.update(bay.stack_id, **fields)
def create_stack(self, context, osc, cluster, cluster_create_timeout): template_path, heat_params, env_files = (_extract_template_definition( context, cluster)) tpl_files, template = template_utils.get_template_contents( template_path) environment_files, env_map = _get_env_files(template_path, env_files) tpl_files.update(env_map) # Make sure no duplicate stack name stack_name = '%s-%s' % (cluster.name, short_id.generate_id()) if cluster_create_timeout: heat_timeout = cluster_create_timeout else: # no cluster_create_timeout value was passed in to the request # so falling back on configuration file value heat_timeout = cfg.CONF.cluster_heat.create_timeout fields = { 'stack_name': stack_name, 'parameters': heat_params, 'environment_files': environment_files, 'template': template, 'files': tpl_files, 'timeout_mins': heat_timeout } created_stack = osc.heat().stacks.create(**fields) return created_stack
def do_stack_create(hc, args): """Create the stack.""" 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) if args.create_timeout: logger.warning("-c/--create-timeout is deprecated, " "please use -t/--timeout instead") fields = { "stack_name": args.name, "disable_rollback": not (args.enable_rollback), "parameters": utils.format_parameters(args.parameters), "template": template, "files": dict(list(tpl_files.items()) + list(env_files.items())), "environment": env, } timeout = args.timeout or args.create_timeout if timeout: fields["timeout_mins"] = timeout hc.stacks.create(**fields) do_stack_list(hc)
def do_stack_preview(hc, args): """Preview the stack.""" 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 = { "stack_name": args.name, "disable_rollback": not (args.enable_rollback), "timeout_mins": args.timeout, "parameters": utils.format_parameters(args.parameters), "template": template, "files": dict(list(tpl_files.items()) + list(env_files.items())), "environment": env, } stack = hc.stacks.preview(**fields) formatters = { "description": utils.text_wrap_formatter, "template_description": utils.text_wrap_formatter, "stack_status_reason": utils.text_wrap_formatter, "parameters": utils.json_formatter, "outputs": utils.json_formatter, "resources": utils.json_formatter, "links": utils.link_formatter, } utils.print_dict(stack.to_dict(), formatters=formatters)
def _update_stack(self, timeout_mins, stage_env): stack_params = {} tpl_files, template = template_utils.get_template_contents( template_file=os.path.join(self.tht_dir, constants.TEMPLATE_NAME)) env_paths = [] if self.environment_files: env_paths.extend(self.environment_files) env_paths.append(os.path.join(self.tht_dir, 'environments', stage_env)) env_files, env = ( template_utils.process_multiple_environments_and_files( env_paths=env_paths)) fields = { 'existing': True, 'stack_id': self.stack.id, 'template': template, 'files': dict(list(tpl_files.items()) + list(env_files.items())), 'environment': env, 'parameters': stack_params, 'timeout_mins': timeout_mins, } LOG.debug('stack update params: %s', fields) self.heatclient.stacks.update(**fields)
def update(self, timeout_mins=240): # time rounded to seconds timestamp = int(time.time()) stack_params = {"UpdateIdentifier": timestamp} tpl_files, template = template_utils.get_template_contents( template_file=os.path.join(self.tht_dir, TEMPLATE_NAME) ) env_paths = [] if self.environment_files: env_paths.extend(self.environment_files) env_files, env = template_utils.process_multiple_environments_and_files(env_paths=env_paths) template_utils.deep_update( env, {"resource_registry": {"resources": {"*": {"*": {UPDATE_RESOURCE_NAME: {"hooks": "pre-update"}}}}}} ) fields = { "existing": True, "stack_id": self.stack.id, "template": template, "files": dict(list(tpl_files.items()) + list(env_files.items())), "environment": env, "parameters": stack_params, "timeout_mins": timeout_mins, } LOG.info("updating stack: %s", self.stack.stack_name) LOG.debug("stack update params: %s", fields) self.heatclient.stacks.update(**fields)
def do_stack_create(hc, args): '''Create the stack.''' 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) if args.create_timeout: logger.warning('-c/--create-timeout is deprecated, ' 'please use -t/--timeout instead') fields = { 'stack_name': args.name, 'disable_rollback': not (args.enable_rollback), 'parameters': utils.format_parameters(args.parameters), 'template': template, 'files': dict(list(tpl_files.items()) + list(env_files.items())), 'environment': env } timeout = args.timeout or args.create_timeout if timeout: fields['timeout_mins'] = timeout hc.stacks.create(**fields) do_stack_list(hc)
def process_stack_spec(spec): # Heat stack is a headache, because it demands for client side file # content processing try: tmplfile = spec.get('template', None) except AttributeError as ex: raise exc.FileFormatError( _('The specified file is not a valid ' 'YAML file: %s') % six.text_type(ex)) if not tmplfile: raise exc.FileFormatError( _('No template found in the given ' 'spec file')) tpl_files, template = template_utils.get_template_contents( template_file=tmplfile) env_files, env = template_utils.process_multiple_environments_and_files( env_paths=spec.get('environment', None)) new_spec = { # TODO(Qiming): add context support 'disable_rollback': spec.get('disable_rollback', True), 'context': spec.get('context', {}), 'parameters': spec.get('parameters', {}), 'timeout': spec.get('timeout', 60), 'template': template, 'files': dict(list(tpl_files.items()) + list(env_files.items())), 'environment': env } return new_spec
def _create_stack(self, context, osc, cluster, cluster_create_timeout): template_path, heat_params, env_files = ( self._extract_template_definition(context, cluster)) tpl_files, template = template_utils.get_template_contents( template_path) environment_files, env_map = self._get_env_files(template_path, env_files) tpl_files.update(env_map) # Make sure no duplicate stack name stack_name = '%s-%s' % (cluster.name, short_id.generate_id()) if cluster_create_timeout: heat_timeout = cluster_create_timeout else: # no cluster_create_timeout value was passed in to the request # so falling back on configuration file value heat_timeout = cfg.CONF.cluster_heat.create_timeout fields = { 'stack_name': stack_name, 'parameters': heat_params, 'environment_files': environment_files, 'template': template, 'files': tpl_files, 'timeout_mins': heat_timeout } created_stack = osc.heat().stacks.create(**fields) return created_stack
def do_stack_adopt(hc, args): '''Adopt a stack.''' 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) if not args.adopt_file: raise exc.CommandError('Need to specify --adopt-file') adopt_url = template_utils.normalise_file_path_to_url(args.adopt_file) adopt_data = request.urlopen(adopt_url).read() if args.create_timeout: logger.warning('-c/--create-timeout is deprecated, ' 'please use -t/--timeout instead') fields = { 'stack_name': args.name, 'timeout_mins': args.timeout or args.create_timeout, 'disable_rollback': not(args.enable_rollback), 'adopt_stack_data': adopt_data, 'parameters': utils.format_parameters(args.parameters), 'template': template, 'files': dict(list(tpl_files.items()) + list(env_files.items())), 'environment': env } hc.stacks.create(**fields) do_stack_list(hc)
def test_hot_template(self, mock_url): tmpl_file = '/home/my/dir/template.yaml' url = 'file:///home/my/dir/template.yaml' foo_url = 'file:///home/my/dir/foo.yaml' bar_url = 'file:///home/my/dir/bar.yaml' def side_effect(args): if url == args: return six.BytesIO(self.hot_template) if foo_url == args: return six.BytesIO(self.foo_template) if bar_url == args: return six.BytesIO(self.bar_template) mock_url.side_effect = side_effect files, tmpl_parsed = template_utils.get_template_contents( template_file=tmpl_file) self.assertEqual(yaml.safe_load(self.bar_template.decode('utf-8')), json.loads(files.get('file:///home/my/dir/bar.yaml'))) self.assertEqual( { u'heat_template_version': u'2013-05-23', u'resources': { u'foo': { u'type': u'OS::Type1', u'properties': { u'config': { u'get_file': u'file:///home/my/dir/bar.yaml' } } } } }, json.loads(files.get('file:///home/my/dir/foo.yaml'))) self.assertEqual( { u'heat_template_version': u'2013-05-23', u'resources': { u'resource1': { u'type': u'OS::Heat::Stack', u'properties': { u'template': { u'get_file': u'file:///home/my/dir/foo.yaml' } } } } }, tmpl_parsed) mock_url.assert_has_calls([ mock.call(foo_url), mock.call(url), mock.call(bar_url), ], any_order=True)
def _heat_deploy(self, stack, stack_name, template_path, parameters, env_files, timeout, tht_root, env, update_plan_only, run_validations, skip_deploy_identifier, plan_env_file, deployment_options=None): """Verify the Baremetal nodes are available and do a stack update""" if stack: self.log.debug( "Checking compatibilities of neutron drivers for {0}".format( stack_name)) msg = update.check_neutron_mechanism_drivers( env, stack, self.object_client, stack_name) if msg: raise oscexc.CommandError(msg) self.log.debug("Getting template contents from plan %s" % stack_name) # We need to reference the plan here, not the local # tht root, as we need template_object to refer to # the rendered overcloud.yaml, not the tht_root overcloud.j2.yaml # FIXME(shardy) we need to move more of this into mistral actions plan_yaml_path = os.path.relpath(template_path, tht_root) # heatclient template_utils needs a function that can # retrieve objects from a container by name/path def do_object_request(method='GET', object_path=None): obj = self.object_client.get_object(stack_name, object_path) return obj and obj[1] template_files, template = template_utils.get_template_contents( template_object=plan_yaml_path, object_request=do_object_request) files = dict(list(template_files.items()) + list(env_files.items())) moved_files = self._upload_missing_files( stack_name, files, tht_root) self._process_and_upload_environment( stack_name, env, moved_files, tht_root) # Invokes the workflows specified in plan environment file if plan_env_file: workflow_params.invoke_plan_env_workflows(self.clients, stack_name, plan_env_file) workflow_params.check_deprecated_parameters(self.clients, stack_name) if not update_plan_only: print("Deploying templates in the directory {0}".format( os.path.abspath(tht_root))) deployment.deploy_and_wait( self.log, self.clients, stack, stack_name, self.app_args.verbose_level, timeout=timeout, run_validations=run_validations, skip_deploy_identifier=skip_deploy_identifier, deployment_options=deployment_options)
def get_fields(template_file, params): tpl_files, template = template_utils.get_template_contents(template_file = template_file) fields = { 'stack_name': 'teste', 'parameters': params, 'template': template, 'files': dict(list(tpl_files.items())), } return fields
def test_get_template_contents_file(self): with tempfile.NamedTemporaryFile() as tmpl_file: tmpl = b'{"AWSTemplateFormatVersion" : "2010-09-09",' b' "foo": "bar"}' tmpl_file.write(tmpl) tmpl_file.flush() files, tmpl_parsed = template_utils.get_template_contents(tmpl_file.name) self.assertEqual({"AWSTemplateFormatVersion": "2010-09-09", "foo": "bar"}, tmpl_parsed) self.assertEqual({}, files)
def _heat_deploy(self, stack, stack_name, template_path, parameters, created_env_files, timeout, tht_root, env): """Verify the Baremetal nodes are available and do a stack update""" clients = self.app.client_manager workflow_client = clients.workflow_engine self.log.debug("Processing environment files %s" % created_env_files) env_files, localenv = ( template_utils.process_multiple_environments_and_files( created_env_files)) # Command line has more precedence than env files template_utils.deep_update(localenv, env) if stack: update.add_breakpoints_cleanup_into_env(localenv) self.log.debug("Getting template contents from plan %s" % stack_name) # We need to reference the plan here, not the local # tht root, as we need template_object to refer to # the rendered overcloud.yaml, not the tht_root overcloud.j2.yaml # FIXME(shardy) we need to move more of this into mistral actions plan_yaml_path = os.path.relpath(template_path, tht_root) # heatclient template_utils needs a function that can # retrieve objects from a container by name/path objectclient = clients.tripleoclient.object_store def do_object_request(method='GET', object_path=None): obj = objectclient.get_object(stack_name, object_path) return obj and obj[1] template_files, template = template_utils.get_template_contents( template_object=plan_yaml_path, object_request=do_object_request) files = dict(list(template_files.items()) + list(env_files.items())) number_controllers = int(parameters.get('ControllerCount', 0)) if number_controllers > 1: if not localenv.get('parameter_defaults').get('NtpServer'): raise exceptions.InvalidConfiguration( 'Specify --ntp-server as parameter or NtpServer in ' 'environments when using multiple controllers ' '(with HA).') clients = self.app.client_manager moved_files = self._upload_missing_files( stack_name, objectclient, files, tht_root) self._process_and_upload_environment( stack_name, objectclient, localenv, moved_files, tht_root, workflow_client) deployment.deploy_and_wait(self.log, clients, stack, stack_name, self.app_args.verbose_level, timeout)
def test_hot_template(self, mock_url): tmpl_file = '/home/my/dir/template.yaml' url = 'file:///home/my/dir/template.yaml' def side_effect(args): if url == args: return six.BytesIO(self.hot_template) if 'file:///home/my/dir/foo.yaml' == args: return six.BytesIO(self.foo_template) if 'file:///home/my/dir/spam/egg.yaml' == args: return six.BytesIO(self.egg_template) mock_url.side_effect = side_effect files, tmpl_parsed = template_utils.get_template_contents( template_file=tmpl_file) self.assertEqual(yaml.safe_load(self.foo_template.decode('utf-8')), json.loads(files.get('file:///home/my/dir/foo.yaml'))) self.assertEqual( yaml.safe_load(self.egg_template.decode('utf-8')), json.loads(files.get('file:///home/my/dir/spam/egg.yaml'))) self.assertEqual( { u'heat_template_version': u'2013-05-23', u'parameters': { u'param1': { u'type': u'string' } }, u'resources': { u'resource1': { u'type': u'file:///home/my/dir/foo.yaml', u'properties': { u'foo': u'bar' } }, u'resource2': { u'type': u'OS::Heat::ResourceGroup', u'properties': { u'resource_def': { u'type': u'file:///home/my/dir/spam/egg.yaml' } } } } }, tmpl_parsed) mock_url.assert_has_calls([ mock.call('file:///home/my/dir/foo.yaml'), mock.call(url), mock.call('file:///home/my/dir/spam/egg.yaml'), ], any_order=True)
def _create_stack(self, context, osc, cluster, cluster_create_timeout, nodegroup=None): nodegroups = [nodegroup] if nodegroup else None template_path, heat_params, env_files = ( self._extract_template_definition(context, cluster, nodegroups=nodegroups)) tpl_files, template = template_utils.get_template_contents( template_path) environment_files, env_map = self._get_env_files(template_path, env_files) tpl_files.update(env_map) # Make sure we end up with a valid hostname valid_chars = set(ascii_letters + digits + '-') # valid hostnames are 63 chars long, leaving enough room # to add the random id (for uniqueness) if nodegroup is None: stack_name = cluster.name[:30] else: stack_name = "%s-%s" % (cluster.name[:20], nodegroup.name[:9]) stack_name = stack_name.replace('_', '-') stack_name = stack_name.replace('.', '-') stack_name = ''.join(filter(valid_chars.__contains__, stack_name)) # Make sure no duplicate stack name stack_name = '%s-%s' % (stack_name, short_id.generate_id()) stack_name = stack_name.lower() if cluster_create_timeout: heat_timeout = cluster_create_timeout else: # no cluster_create_timeout value was passed in to the request # so falling back on configuration file value heat_timeout = cfg.CONF.cluster_heat.create_timeout heat_params['is_cluster_stack'] = nodegroup is None if nodegroup: # In case we are creating a new stack for a new nodegroup then # we need to extract more params. heat_params.update(self.get_nodegroup_extra_params(cluster, osc)) fields = { 'stack_name': stack_name, 'parameters': heat_params, 'environment_files': environment_files, 'template': template, 'files': tpl_files, 'timeout_mins': heat_timeout } created_stack = osc.heat().stacks.create(**fields) return created_stack
def setup_template(self): if self.template_dirs or not os.path.isfile(self.template_file): template_dirs = self.template_dirs or TEMPLATE_DIRS template_file = find_heat_template_file( template_file=self.template_file, template_dirs=template_dirs) template_files, template = template_utils.get_template_contents( template_file=template_file) self.template = template self.template_files = template_files super(HeatTemplateFileFixture, self).setup_template()
def test_get_template_contents_url(self): tmpl = b'{"AWSTemplateFormatVersion" : "2010-09-09", "foo": "bar"}' url = "http://no.where/path/to/a.yaml" self.m.StubOutWithMock(request, "urlopen") request.urlopen(url).AndReturn(six.BytesIO(tmpl)) self.m.ReplayAll() files, tmpl_parsed = template_utils.get_template_contents(template_url=url) self.assertEqual({"AWSTemplateFormatVersion": "2010-09-09", "foo": "bar"}, tmpl_parsed) self.assertEqual({}, files)
def test_get_template_contents_file(self): with tempfile.NamedTemporaryFile() as tmpl_file: tmpl = '{"foo": "bar"}' tmpl_file.write(tmpl) tmpl_file.flush() files, tmpl_parsed = template_utils.get_template_contents( tmpl_file.name) self.assertEqual({"foo": "bar"}, tmpl_parsed) self.assertEqual({}, files)
def update(self): # time rounded to seconds, we explicitly convert to string because of # tuskar timestamp = str(int(time.time())) if self.tuskarclient: stack_params = self._set_update_params(timestamp) self.tht_dir = libutils.save_templates( self.tuskarclient.plans.templates(self.plan.uuid)) tpl_name = 'plan.yaml' env_name = 'environment.yaml' else: tpl_name = TEMPLATE_NAME env_name = REGISTRY_NAME stack_params = {'UpdateIdentifier': timestamp} try: tpl_files, template = template_utils.get_template_contents( template_file=os.path.join(self.tht_dir, tpl_name)) env_paths = [os.path.join(self.tht_dir, env_name)] if self.environment_files: env_paths.extend(self.environment_files) env_files, env = ( template_utils.process_multiple_environments_and_files( env_paths=env_paths)) template_utils.deep_update(env, { 'resource_registry': { 'resources': { '*': { '*': { self.hook_resource: {'hooks': 'pre-update'} } } } } }) fields = { 'existing': True, 'stack_id': self.stack.id, 'template': template, 'files': dict(list(tpl_files.items()) + list(env_files.items())), 'environment': env, 'parameters': stack_params } LOG.info('updating stack: %s', self.stack.stack_name) LOG.debug('stack update params: %s', fields) self.heatclient.stacks.update(**fields) finally: if self.tuskarclient: if LOG.isEnabledFor(logging.DEBUG): LOG.debug("Tuskar templates saved in %s", self.tht_dir) else: shutil.rmtree(self.tht_dir)
def heat_stack_create(hc, env, name, params): tf, t = template_utils.get_template_contents(env['template-file']) ef, e = template_utils.process_multiple_environments_and_files(env_paths=env['env-file']) px = utils.format_all_parameters(params, None, template_file=env['template-file']) data = {'stack_name' : name, 'parameters' : px, 'template' : t, 'files' : dict(list(tf.items()) + list(ef.items())), 'environment': e} stk = hc.stacks.create(**data) return stk
def test_hot_template(self): self.m.StubOutWithMock(request, "urlopen") tmpl_file = "/home/my/dir/template.yaml" url = "file:///home/my/dir/template.yaml" request.urlopen(url).AndReturn(six.BytesIO(self.hot_template)) request.urlopen("http://localhost/bar.yaml").InAnyOrder().AndReturn(six.BytesIO(b"bar contents")) request.urlopen("file:///home/my/dir/foo.yaml").InAnyOrder().AndReturn(six.BytesIO(b"foo contents")) request.urlopen("file:///home/my/dir/baz/baz1.yaml").InAnyOrder().AndReturn(six.BytesIO(b"baz1 contents")) request.urlopen("file:///home/my/dir/baz/baz2.yaml").InAnyOrder().AndReturn(six.BytesIO(b"baz2 contents")) request.urlopen("file:///home/my/dir/baz/baz3.yaml").InAnyOrder().AndReturn(six.BytesIO(b"baz3 contents")) self.m.ReplayAll() files, tmpl_parsed = template_utils.get_template_contents(template_file=tmpl_file) self.assertEqual( { "http://localhost/bar.yaml": b"bar contents", "file:///home/my/dir/foo.yaml": b"foo contents", "file:///home/my/dir/baz/baz1.yaml": b"baz1 contents", "file:///home/my/dir/baz/baz2.yaml": b"baz2 contents", "file:///home/my/dir/baz/baz3.yaml": b"baz3 contents", }, files, ) self.assertEqual( { "heat_template_version": "2013-05-23", "resources": { "resource1": { "type": "OS::type1", "properties": { "bar": {"get_file": "http://localhost/bar.yaml"}, "foo": {"get_file": "file:///home/my/dir/foo.yaml"}, }, }, "resource2": { "type": "OS::type1", "properties": { "baz": [ {"get_file": "file:///home/my/dir/baz/baz1.yaml"}, {"get_file": "file:///home/my/dir/baz/baz2.yaml"}, {"get_file": "file:///home/my/dir/baz/baz3.yaml"}, ], "ignored_list": {"get_file": ["ignore", "me"]}, "ignored_dict": {"get_file": {"ignore": "me"}}, "ignored_none": {"get_file": None}, }, }, }, }, tmpl_parsed, )
def test_get_template_contents_url(self): tmpl = '{"foo": "bar"}' url = 'http://no.where/path/to/a.yaml' self.m.StubOutWithMock(urlutils, 'urlopen') urlutils.urlopen(url).AndReturn(six.StringIO(tmpl)) self.m.ReplayAll() files, tmpl_parsed = template_utils.get_template_contents( template_url=url) self.assertEqual({"foo": "bar"}, tmpl_parsed) self.assertEqual({}, files)
def create_stack(self, template_file, stack_name, parameters): self.init_heat() # self.print_stacks() tpl_files, template = template_utils.get_template_contents(template_file) fields = { 'template': template, 'files': dict(list(tpl_files.items())) } self.heat.stacks.create(stack_name=stack_name, files=fields['files'], template=template, parameters=parameters) self.print_stacks(stack_name)
def create_stack(self, template_file, stack_name, parameters): self.init_heat() # self.print_stacks() tpl_files, template = template_utils.get_template_contents( template_file) fields = {'template': template, 'files': dict(list(tpl_files.items()))} self.heat.stacks.create(stack_name=stack_name, files=fields['files'], template=template, parameters=parameters) self.print_stacks(stack_name)
def test_get_template_contents_file(self): with tempfile.NamedTemporaryFile() as tmpl_file: tmpl = b'{"AWSTemplateFormatVersion" : "2010-09-09",' \ b' "foo": "bar"}' tmpl_file.write(tmpl) tmpl_file.flush() files, tmpl_parsed = template_utils.get_template_contents( tmpl_file.name) self.assertEqual({"AWSTemplateFormatVersion": "2010-09-09", "foo": "bar"}, tmpl_parsed) self.assertEqual({}, files)
def test_get_template_contents_url(self): tmpl = b'{"AWSTemplateFormatVersion" : "2010-09-09", "foo": "bar"}' url = 'http://no.where/path/to/a.yaml' self.m.StubOutWithMock(request, 'urlopen') request.urlopen(url).AndReturn(six.BytesIO(tmpl)) self.m.ReplayAll() files, tmpl_parsed = template_utils.get_template_contents( template_url=url) self.assertEqual({"AWSTemplateFormatVersion": "2010-09-09", "foo": "bar"}, tmpl_parsed) self.assertEqual({}, files)
def create_stack(self): # 创建stack path = "/var/tmp/hello_world.yaml" tpl_files, template = template_utils.get_template_contents(path) create_fields = { 'stack_name': 'test_stack', 'disable_rollback': 'false', 'parameters': '', 'template': template, 'files': dict(list(tpl_files.items())) } heat.stacks.create(**create_fields)
def _update_stack(context, osc, bay, scale_manager=None): template_path, heat_params = _extract_template_definition( context, bay, scale_manager=scale_manager) tpl_files, template = template_utils.get_template_contents(template_path) fields = { 'parameters': heat_params, 'template': template, 'files': dict(list(tpl_files.items())) } return osc.heat().stacks.update(bay.stack_id, **fields)
def test_hot_template(self): self.m.StubOutWithMock(request, 'urlopen') tmpl_file = '/home/my/dir/template.yaml' url = 'file:///home/my/dir/template.yaml' foo_url = 'file:///home/my/dir/foo.yaml' bar_url = 'file:///home/my/dir/bar.yaml' request.urlopen(url).InAnyOrder().AndReturn( six.BytesIO(self.hot_template)) request.urlopen(foo_url).InAnyOrder().AndReturn( six.BytesIO(self.foo_template)) request.urlopen(foo_url).InAnyOrder().AndReturn( six.BytesIO(self.foo_template)) request.urlopen(bar_url).InAnyOrder().AndReturn( six.BytesIO(self.bar_template)) request.urlopen(bar_url).InAnyOrder().AndReturn( six.BytesIO(self.bar_template)) self.m.ReplayAll() files, tmpl_parsed = template_utils.get_template_contents( template_file=tmpl_file) self.assertEqual(yaml.safe_load(self.bar_template.decode('utf-8')), json.loads(files.get('file:///home/my/dir/bar.yaml'))) self.assertEqual( { u'heat_template_version': u'2013-05-23', u'resources': { u'foo': { u'type': u'OS::Type1', u'properties': { u'config': { u'get_file': u'file:///home/my/dir/bar.yaml' } } } } }, json.loads(files.get('file:///home/my/dir/foo.yaml'))) self.assertEqual( { u'heat_template_version': u'2013-05-23', u'resources': { u'resource1': { u'type': u'OS::Heat::Stack', u'properties': { u'template': { u'get_file': u'file:///home/my/dir/foo.yaml' } } } } }, tmpl_parsed)
def _heat_deploy(self, stack, template_path, parameters, environments, timeout): """Verify the Baremetal nodes are available and do a stack update""" self.log.debug("Processing environment files") env_files, env = ( template_utils.process_multiple_environments_and_files( environments)) self.log.debug("Getting template contents") template_files, template = template_utils.get_template_contents( template_path) files = dict(list(template_files.items()) + list(env_files.items())) clients = self.app.client_manager orchestration_client = clients.rdomanager_oscplugin.orchestration() stack_name = "overcloud" self.log.debug("Deploying stack: %s", stack_name) self.log.debug("Deploying template: %s", template) self.log.debug("Deploying parameters: %s", parameters) self.log.debug("Deploying environment: %s", env) self.log.debug("Deploying files: %s", files) stack_args = { 'stack_name': stack_name, 'template': template, 'parameters': parameters, 'environment': env, 'files': files } if timeout: stack_args['timeout_mins'] = timeout if stack is None: self.log.info("Performing Heat stack create") orchestration_client.stacks.create(**stack_args) else: self.log.info("Performing Heat stack update") # Make sure existing parameters for stack are reused stack_args['existing'] = 'true' orchestration_client.stacks.update(stack.id, **stack_args) create_result = utils.wait_for_stack_ready(orchestration_client, "overcloud") if not create_result: if stack is None: raise Exception("Heat Stack create failed.") else: raise Exception("Heat Stack update failed.")
def _heat_deploy(self, stack, template_path, parameters, environments, timeout): """Verify the Baremetal nodes are available and do a stack update""" self.log.debug("Processing environment files") env_files, env = ( template_utils.process_multiple_environments_and_files( environments)) self.log.debug("Getting template contents") template_files, template = template_utils.get_template_contents( template_path) files = dict(list(template_files.items()) + list(env_files.items())) clients = self.app.client_manager orchestration_client = clients.rdomanager_oscplugin.orchestration() stack_name = "overcloud" self.log.debug("Deploying stack: %s", stack_name) self.log.debug("Deploying template: %s", template) self.log.debug("Deploying parameters: %s", parameters) self.log.debug("Deploying environment: %s", env) self.log.debug("Deploying files: %s", files) stack_args = { 'stack_name': stack_name, 'template': template, 'parameters': parameters, 'environment': env, 'files': files } if timeout: stack_args['timeout_mins'] = timeout if stack is None: self.log.info("Performing Heat stack create") orchestration_client.stacks.create(**stack_args) else: self.log.info("Performing Heat stack update") # Make sure existing parameters for stack are reused stack_args['existing'] = 'true' orchestration_client.stacks.update(stack.id, **stack_args) create_result = utils.wait_for_stack_ready( orchestration_client, "overcloud") if not create_result: if stack is None: raise Exception("Heat Stack create failed.") else: raise Exception("Heat Stack update failed.")
def index(request): if request.method == 'POST': form = LendForm(request.POST) if form.is_valid(): project_name = form.cleaned_data['project_name'] mail = form.cleaned_data['mail'] ssh_key = form.cleaned_data['ssh_key'] validity = form.cleaned_data['validity'] description = form.cleaned_data['description'] flavor = form.cleaned_data['flavor'] template_id = form.cleaned_data['heat_template'] template_path = HeatTemplateHelper.get_full_path_from_file_name( template_id) tpl_files, template_content = template_utils.get_template_contents( template_path) kp = NovaClientHelper( **settings.OS_PARAMS).keypair_create(project_name) parameters = { 'f_name': flavor, 'kp_name': project_name, 'img_name': 'Ubuntu precise', 'subnet_id': settings.SUBNET_ID, 'net_id': settings.NET_ID, 'floating_id': settings.FLOATING_ID, 'description': description, 'mail': mail, 'validity': validity.isoformat() } fields = { 'stack_name': project_name, 'disable_rollback': True, 'template': template_content, 'parameters': parameters, } _htc = HeatClientHelper(**settings.OS_PARAMS).get_client() testor = _htc.stacks.create(**fields) from time import sleep sleep(30) fields['parameters']['mail'] = 'lolilol lol' testor.update(**fields) else: form = LendForm() return render(request, 'index.html', { 'form': form, })
def test_hot_template(self): self.m.StubOutWithMock(request, 'urlopen') tmpl_file = '/home/my/dir/template.yaml' url = 'file:///home/my/dir/template.yaml' request.urlopen('file:///home/my/dir/foo.yaml').InAnyOrder().AndReturn( six.BytesIO(self.foo_template)) request.urlopen('file:///home/my/dir/foo.yaml').InAnyOrder().AndReturn( six.BytesIO(self.foo_template)) request.urlopen(url).InAnyOrder().AndReturn( six.BytesIO(self.hot_template)) request.urlopen( 'file:///home/my/dir/spam/egg.yaml').InAnyOrder().AndReturn( six.BytesIO(self.egg_template)) request.urlopen( 'file:///home/my/dir/spam/egg.yaml').InAnyOrder().AndReturn( six.BytesIO(self.egg_template)) self.m.ReplayAll() files, tmpl_parsed = template_utils.get_template_contents( template_file=tmpl_file) self.assertEqual(yaml.safe_load(self.foo_template.decode('utf-8')), json.loads(files.get('file:///home/my/dir/foo.yaml'))) self.assertEqual( yaml.safe_load(self.egg_template.decode('utf-8')), json.loads(files.get('file:///home/my/dir/spam/egg.yaml'))) self.assertEqual( { u'heat_template_version': u'2013-05-23', u'parameters': { u'param1': { u'type': u'string' } }, u'resources': { u'resource1': { u'type': u'file:///home/my/dir/foo.yaml', u'properties': { u'foo': u'bar' } }, u'resource2': { u'type': u'OS::Heat::ResourceGroup', u'properties': { u'resource_def': { u'type': u'file:///home/my/dir/spam/egg.yaml' } } } } }, tmpl_parsed)
def create_stack(instance_info): # data = {'resources':{'my_instance':{'type':'OS::Nova::Server', 'properties':{'name':str(instance_info['name']),'image':str(instance_info['image']),'flavor':str(instance_info['flavor']),'networks':[{'network':'VM-Network01'}]}}}} data = {"resources": { "my_instance": {"type": "OS::Nova::Server", "properties": {"name": str(instance_info['name']), "image": str(instance_info['image']), "flavor": str(instance_info['flavor']), "networks": [{"port": "{get_resource: instance_port}"}]}}, "instance_port": {"type": "OS::Neutron::Port", "properties": {"network": "DevOps_Network", "security_groups": ["default"]}}, # "floating_ip": {"type": "OS::Neutron::FloatingIP", "properties": {"floating_network": "Ex-Network01"}}, # "association": {"type": "OS::Neutron::FloatingIPAssociation", # "properties": {"floatingip_id": "{get_resource: floating_ip}", # "port_id": "{get_resource: instance_port}"}} }, "outputs": {"instance_name": {"description": "Name of the instance", "value": "{get_attr:[my_instance, name]}"}, "instance_id": {"description": "UUID of the instance", "value": "{get_resource: my_instance}"}, # "instance_image_name":{"description":"Name of the image","value":"{get_attr:[my_instance, image]}"}, # "instance_flavor_name":{"description":"Name of the flavor","value":"{get_attr:[my_instance, flavor]}"}, # "instance_public_ip": {"description": "Floating IP address", # "value": "{get_attr:[floating_ip, floating_ip_address]}"} # } } stack = yaml.dump(data, default_flow_style=False) stack = stack.replace("'", "") file_path = "./%s-stack.yml" % (instance_info['name']) with open(file_path, 'w') as f: # f.write('heat_template_version: 2013-05-23\n') f.write('heat_template_version: 2016-04-08\n') f.write('description: Simple template to deploy a single compute instance\n') f.write(stack) heat = hclient.Client("1", session=sess) template_file = file_path template_url = '' template_object = '' tpl_files, template = template_utils.get_template_contents(template_file, template_url, template_object) stack_name = "%s-%s-stack" % (str(instance_info['owner']), str(instance_info['name'])) fields = { 'stack_name': stack_name, 'template': template } heat.stacks.create(**fields) return
def create_stack(token, tenant_id, heat_base_url, stack_name, template_file, params): headers = {'X-Auth-Token': token} tpl_files, template = template_utils.get_template_contents(template_file = template_file) fields = { 'tenant_id' : tenant_id, 'stack_name': stack_name, 'parameters': params, 'template': template, 'files': dict(list(tpl_files.items())), } r = requests.post(heat_base_url + "/" + tenant_id + "/stacks", data = json.dumps(fields), headers = headers) data = r.json() return data['stack']['id']
def test_get_template_contents_url(self, mock_url): tmpl = b'{"AWSTemplateFormatVersion" : "2010-09-09", "foo": "bar"}' url = 'http://no.where/path/to/a.yaml' mock_url.return_value = six.BytesIO(tmpl) files, tmpl_parsed = template_utils.get_template_contents( template_url=url) self.assertEqual( { "AWSTemplateFormatVersion": "2010-09-09", "foo": "bar" }, tmpl_parsed) self.assertEqual({}, files) mock_url.assert_called_with(url)