def build_prepare_env(environment_files, environment_directories): '''Build the environment for container image prepare :param environment_files: List of environment files to build environment from :type environment_files: list :param environment_directories: List of environment directories to build environment from :type environment_directories: list ''' env_files = [] if environment_directories: env_files.extend(load_environment_directories(environment_directories)) if environment_files: env_files.extend(environment_files) def get_env_file(method, path): if not os.path.exists(path): return '{}' env_url = heat_utils.normalise_file_path_to_url(path) return request.urlopen(env_url).read() env_f, env = (template_utils.process_multiple_environments_and_files( env_files, env_path_is_object=lambda path: True, object_request=get_env_file)) return env
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 test_process_multiple_environments_and_files_tracker(self): # Setup self.m.StubOutWithMock(request, 'urlopen') env_file1 = '/home/my/dir/env1.yaml' env1 = b''' parameters: "param1": "value1" resource_registry: "OS::Thingy1": "file:///home/b/a.yaml" ''' request.urlopen('file://%s' % env_file1).AndReturn( six.BytesIO(env1)) request.urlopen('file:///home/b/a.yaml').AndReturn( six.BytesIO(self.template_a)) request.urlopen('file:///home/b/a.yaml').AndReturn( six.BytesIO(self.template_a)) self.m.ReplayAll() # Test env_file_list = [] files, env = template_utils.process_multiple_environments_and_files( [env_file1], env_list_tracker=env_file_list) # Verify expected_env = {'parameters': {'param1': 'value1'}, 'resource_registry': {'OS::Thingy1': 'file:///home/b/a.yaml'} } self.assertEqual(expected_env, env) self.assertEqual(self.template_a.decode('utf-8'), files['file:///home/b/a.yaml']) self.assertEqual(['file:///home/my/dir/env1.yaml'], env_file_list)
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 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, 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 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 main(): result = dict( success=False, changed=False, error=None, environment={} ) module = AnsibleModule( openstack_full_argument_spec( **yaml.safe_load(DOCUMENTATION)['options'] ), **openstack_module_kwargs() ) container = module.params.get('container') env_files = module.params.get('env_files') try: if container: _, conn = openstack_cloud_from_module(module) tripleo = tc.TripleOCommon(session=conn.session) heat = tripleo.get_orchestration_client() env = heat.environment(container) else: _, env = template_utils.process_multiple_environments_and_files( env_paths=env_files) result['environment'] = env result['changed'] = True result['success'] = True except Exception as ex: result['error'] = str(ex) result['msg'] = 'Error buiding environment: {}'.format( ex) module.fail_json(**result) module.exit_json(**result)
def take_action(self, parsed_args): self.log.debug('take_action(%s)', parsed_args) client = self.app.client_manager.orchestration env_files, env = ( template_utils.process_multiple_environments_and_files( env_paths=parsed_args.environment)) adopt_url = heat_utils.normalise_file_path_to_url( parsed_args.adopt_file) adopt_data = request.urlopen(adopt_url).read().decode('utf-8') yaml_adopt_data = yaml.safe_load(adopt_data) or {} files = yaml_adopt_data.get('files', {}) files.update(env_files) fields = { 'stack_name': parsed_args.name, 'disable_rollback': not parsed_args.enable_rollback, 'adopt_stack_data': adopt_data, 'parameters': heat_utils.format_parameters(parsed_args.parameter), 'files': files, 'environment': env, 'timeout': parsed_args.timeout } stack = client.stacks.create(**fields)['stack'] if parsed_args.wait: stack_status, msg = event_utils.poll_for_events(client, parsed_args.name, action='ADOPT') if stack_status == 'ADOPT_FAILED': raise exc.CommandError(msg) return _show_stack(client, stack['id'], format='table', short=True)
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 _validate(heat_client, args): tpl_files, template = template_utils.process_template_path( args.template, object_request=http.authenticated_fetcher(heat_client)) env_files_list = [] env_files, env = template_utils.process_multiple_environments_and_files( env_paths=args.environment, env_list_tracker=env_files_list) fields = { 'template': template, 'parameters': heat_utils.format_parameters(args.parameter), 'files': dict(list(tpl_files.items()) + list(env_files.items())), 'environment': env, } if args.ignore_errors: fields['ignore_errors'] = args.ignore_errors # If one or more environments is found, pass the listing to the server if env_files_list: fields['environment_files'] = env_files_list if args.show_nested: fields['show_nested'] = args.show_nested validation = heat_client.stacks.validate(**fields) data = list(six.itervalues(validation)) columns = list(six.iterkeys(validation)) return columns, data
def take_action(self, parsed_args): self.log.debug('take_action(%s)', parsed_args) client = self.app.client_manager.orchestration env_files, env = ( template_utils.process_multiple_environments_and_files( env_paths=parsed_args.environment)) adopt_url = heat_utils.normalise_file_path_to_url( parsed_args.adopt_file) adopt_data = request.urlopen(adopt_url).read().decode('utf-8') fields = { 'stack_name': parsed_args.name, 'disable_rollback': not parsed_args.enable_rollback, 'adopt_stack_data': adopt_data, 'parameters': heat_utils.format_parameters(parsed_args.parameter), 'files': dict(list(env_files.items())), 'environment': env, 'timeout': parsed_args.timeout } stack = client.stacks.create(**fields)['stack'] if parsed_args.wait: stack_status, msg = event_utils.poll_for_events( client, parsed_args.name, action='ADOPT') if stack_status == 'ADOPT_FAILED': raise exc.CommandError(msg) return _show_stack(client, stack['id'], format='table', short=True)
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_multiple_environments_and_files( env_paths=args.environment_file) fields = { 'stack_id': args.id, '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 } if args.timeout: fields['timeout_mins'] = args.timeout hc.stacks.update(**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 _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 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 build_service_filter(self, environment_files, roles_file): # Do not filter unless asked for it if not environment_files: return None def get_env_file(method, path): if not os.path.exists(path): return '{}' env_url = heat_utils.normalise_file_path_to_url(path) return request.urlopen(env_url).read() env_files, env = ( template_utils.process_multiple_environments_and_files( environment_files, env_path_is_object=lambda path: True, object_request=get_env_file)) enabled_services = self.get_enabled_services(env, roles_file) containerized_services = set() for service, env_path in env.get('resource_registry', {}).items(): # Use the template path to determine if it represents a # containerized service if '/docker/services/' in env_path: containerized_services.add(service) return containerized_services.intersection(enabled_services)
def test_process_multiple_environments_default_resources(self): self.m.StubOutWithMock(request, 'urlopen') env_file1 = '/home/my/dir/env1.yaml' env_file2 = '/home/my/dir/env2.yaml' env1 = b''' resource_registry: resources: resource1: "OS::Thingy1": "file:///home/b/a.yaml" resource2: "OS::Thingy2": "file:///home/b/b.yaml" ''' env2 = b''' resource_registry: resources: resource1: "OS::Thingy3": "file:///home/b/a.yaml" resource2: "OS::Thingy4": "file:///home/b/b.yaml" ''' request.urlopen('file://%s' % env_file1).AndReturn( six.BytesIO(env1)) request.urlopen('file:///home/b/a.yaml').AndReturn( six.BytesIO(self.template_a)) request.urlopen('file:///home/b/b.yaml').AndReturn( six.BytesIO(self.template_a)) request.urlopen('file://%s' % env_file2).AndReturn( six.BytesIO(env2)) request.urlopen('file:///home/b/a.yaml').AndReturn( six.BytesIO(self.template_a)) request.urlopen('file:///home/b/b.yaml').AndReturn( six.BytesIO(self.template_a)) self.m.ReplayAll() files, env = template_utils.process_multiple_environments_and_files( [env_file1, env_file2]) self.assertEqual( { 'resource_registry': { 'resources': { 'resource1': { 'OS::Thingy1': 'file:///home/b/a.yaml', 'OS::Thingy3': 'file:///home/b/a.yaml' }, 'resource2': { 'OS::Thingy2': 'file:///home/b/b.yaml', 'OS::Thingy4': 'file:///home/b/b.yaml' } } } }, env) self.assertEqual(self.template_a.decode('utf-8'), files['file:///home/b/a.yaml']) self.assertEqual(self.template_a.decode('utf-8'), files['file:///home/b/b.yaml'])
def test_process_multiple_environments_default_resources(self): self.m.StubOutWithMock(request, 'urlopen') env_file1 = '/home/my/dir/env1.yaml' env_file2 = '/home/my/dir/env2.yaml' env1 = b''' resource_registry: resources: resource1: "OS::Thingy1": "file:///home/b/a.yaml" resource2: "OS::Thingy2": "file:///home/b/b.yaml" ''' env2 = b''' resource_registry: resources: resource1: "OS::Thingy3": "file:///home/b/a.yaml" resource2: "OS::Thingy4": "file:///home/b/b.yaml" ''' request.urlopen('file://%s' % env_file1).AndReturn( six.BytesIO(env1)) request.urlopen('file:///home/b/a.yaml').InAnyOrder().AndReturn( six.BytesIO(self.template_a)) request.urlopen('file:///home/b/b.yaml').InAnyOrder().AndReturn( six.BytesIO(self.template_a)) request.urlopen('file://%s' % env_file2).AndReturn( six.BytesIO(env2)) request.urlopen('file:///home/b/a.yaml').InAnyOrder().AndReturn( six.BytesIO(self.template_a)) request.urlopen('file:///home/b/b.yaml').InAnyOrder().AndReturn( six.BytesIO(self.template_a)) self.m.ReplayAll() files, env = template_utils.process_multiple_environments_and_files( [env_file1, env_file2]) self.assertEqual( { 'resource_registry': { 'resources': { 'resource1': { 'OS::Thingy1': 'file:///home/b/a.yaml', 'OS::Thingy3': 'file:///home/b/a.yaml' }, 'resource2': { 'OS::Thingy2': 'file:///home/b/b.yaml', 'OS::Thingy4': 'file:///home/b/b.yaml' } } } }, env) self.assertEqual(self.template_a.decode('utf-8'), files['file:///home/b/a.yaml']) self.assertEqual(self.template_a.decode('utf-8'), files['file:///home/b/b.yaml'])
def _get_env_files(self, template_path, env_rel_paths): template_dir = os.path.dirname(template_path) env_abs_paths = [os.path.join(template_dir, f) for f in env_rel_paths] environment_files = [] env_map, merged_env = ( template_utils.process_multiple_environments_and_files( env_paths=env_abs_paths, env_list_tracker=environment_files)) return environment_files, env_map
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 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 pre_expand_pnda(self, node_counts): ''' Use the Openstack heatclient API to expand a stack ''' # Generate template files self._update_template_file(self._flavor, node_counts['datanodes'], node_counts['kafka_nodes']) stack_name = self._cluster heat_session = self._get_heat_session() templates_path = os.getcwd() + '/cli/' + '_resources_{}-{}'.format( self._flavor, self._cluster) template_file = templates_path + "/pnda.yaml" env_file = templates_path + "/pnda_env.yaml" env_param = [env_file] tpl_files, tpl_template = template_utils.process_template_path( template_file) env_files, env_template = template_utils.process_multiple_environments_and_files( env_paths=env_param) files_all = dict(list(tpl_files.items()) + list(env_files.items())) try: heat_session.stacks.update(stack_id=stack_name, template=tpl_template, files=files_all, environment=env_template, timeout_mins=120) stack_status_body = heat_session.stacks.get(stack_id=stack_name) stack_status = 'UPDATING' stack_status_new = None stack_id = stack_status_body.stack_name except exc.HTTPBadRequest as exp: error_state = exp.error CONSOLE.error("Bad request update stack failed: %s", error_state) sys.exit(1) while stack_status in [ 'UPDATE_IN_PROGRESS', 'UPDATING', 'UPDATE_COMPLETE_CLEANUP_IN_PROGRESS' ]: time.sleep(5) if stack_status != stack_status_new: if stack_status_new is not None: stack_status = stack_status_new CONSOLE.info('Stack is: %s', stack_status) else: CONSOLE.debug('Stack is: %s', stack_status) stack_status_body = heat_session.stacks.get(stack_id) stack_status_new = stack_status_body.stack_status if stack_status != 'UPDATE_COMPLETE': CONSOLE.error('Stack did not come up, status is: %s', stack_status) sys.exit(1) self.clear_instance_map_cache()
def process_environments_and_files(swift, env_paths): """Wrap process_multiple_environments_and_files with swift object fetch""" def _env_path_is_object(env_path): return env_path.startswith(swift.url) def _object_request(method, url, token=swift.token): return object_request(method, url, token) return template_utils.process_multiple_environments_and_files( env_paths=env_paths, env_path_is_object=_env_path_is_object, object_request=_object_request)
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 test_process_multiple_environment_files_container(self): env_list_tracker = [] env_paths = ['/home/my/dir/env.yaml'] files, env = template_utils.process_multiple_environments_and_files( env_paths, env_list_tracker=env_list_tracker, fetch_env_files=False) self.assertEqual(env_paths, env_list_tracker) self.assertEqual({}, files) self.assertEqual({}, env)
def _build_env_data(env_paths): """Merge env data from the provided paths Given a list of files in env_paths, merge the contents of all those environment files and return the results. :param env_paths: A list of env files to operate on. :returns: A dict containing the merged contents of the provided files. """ _, env_data = template_utils.process_multiple_environments_and_files( env_paths) return env_data
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 test_process_multiple_environments_and_files(self, mock_url): env_file1 = '/home/my/dir/env1.yaml' env_file2 = '/home/my/dir/env2.yaml' env1 = b''' parameters: "param1": "value1" resource_registry: "OS::Thingy1": "file:///home/b/a.yaml" ''' env2 = b''' parameters: "param2": "value2" resource_registry: "OS::Thingy2": "file:///home/b/b.yaml" ''' mock_url.side_effect = [ six.BytesIO(env1), six.BytesIO(self.template_a), six.BytesIO(self.template_a), six.BytesIO(env2), six.BytesIO(self.template_a), six.BytesIO(self.template_a) ] files, env = template_utils.process_multiple_environments_and_files( [env_file1, env_file2]) self.assertEqual( { 'resource_registry': { 'OS::Thingy1': 'file:///home/b/a.yaml', 'OS::Thingy2': 'file:///home/b/b.yaml' }, 'parameters': { 'param1': 'value1', 'param2': 'value2' } }, env) self.assertEqual(self.template_a.decode('utf-8'), files['file:///home/b/a.yaml']) self.assertEqual(self.template_a.decode('utf-8'), files['file:///home/b/b.yaml']) mock_url.assert_has_calls([ mock.call('file://%s' % env_file1), mock.call('file:///home/b/a.yaml'), mock.call('file:///home/b/a.yaml'), mock.call('file://%s' % env_file2), mock.call('file:///home/b/b.yaml'), mock.call('file:///home/b/b.yaml') ])
def _create_environment(self): tpl_files, template = template_utils.get_template_contents( self.__config.hardware.heat_conf_path) env_files_list = [] env_files, env = ( template_utils.process_multiple_environments_and_files( env_paths=[self.__config.hardware.heat_env_path], env_list_tracker=env_files_list)) fields = { 'stack_name': self.__config.hardware.heat_stack_name, 'template': template, 'files': dict(list(tpl_files.items()) + list(env_files.items())), 'environment': env, 'parameters': { 'mcp_version': settings.MCP_VERSION, 'env_name': settings.ENV_NAME, } } if env_files_list: fields['environment_files'] = env_files_list @retry(heat_exceptions.HTTPBadGateway, delay=15, tries=20) def safe_heat_stack_create(): self.__stacks.create(**fields) @retry(exceptions.EnvironmentBadStatus, delay=60, tries=3) def safe_create(): self.delete_environment() safe_heat_stack_create() self.wait_of_stack_status(EXPECTED_STACK_STATUS, tries=140) LOG.info("Stack '%s' created", self.__config.hardware.heat_stack_name) incorrect_resources = self._verify_resources_status( EXPECTED_STACK_STATUS) if incorrect_resources: LOG.info("Recreate the stack because some resources have " "incorrect status") for r in incorrect_resources: LOG.error( 'The resource %s has status %s. But it should be %s', r.resource_name, r.resource_status, EXPECTED_STACK_STATUS) st = self._current_stack.stack_status raise exceptions.EnvironmentBadStatus( self.__config.hardware.heat_stack_name, EXPECTED_STACK_STATUS, st, incorrect_resources) safe_create()
def test_process_multiple_environments_default_resources(self): self.m.StubOutWithMock(request, "urlopen") env_file1 = "/home/my/dir/env1.yaml" env_file2 = "/home/my/dir/env2.yaml" env1 = b""" resource_registry: resources: resource1: "OS::Thingy1": "file:///home/b/a.yaml" resource2: "OS::Thingy2": "file:///home/b/b.yaml" """ env2 = b""" resource_registry: resources: resource1: "OS::Thingy3": "file:///home/b/a.yaml" resource2: "OS::Thingy4": "file:///home/b/b.yaml" """ request.urlopen("file://%s" % env_file1).InAnyOrder().AndReturn(six.BytesIO(env1)) request.urlopen("file:///home/b/a.yaml").InAnyOrder().AndReturn(six.BytesIO(self.template_a)) request.urlopen("file:///home/b/b.yaml").InAnyOrder().AndReturn(six.BytesIO(self.template_a)) request.urlopen("file:///home/b/a.yaml").InAnyOrder().AndReturn(six.BytesIO(self.template_a)) request.urlopen("file:///home/b/b.yaml").InAnyOrder().AndReturn(six.BytesIO(self.template_a)) request.urlopen("file://%s" % env_file2).InAnyOrder().AndReturn(six.BytesIO(env2)) request.urlopen("file:///home/b/a.yaml").InAnyOrder().AndReturn(six.BytesIO(self.template_a)) request.urlopen("file:///home/b/b.yaml").InAnyOrder().AndReturn(six.BytesIO(self.template_a)) request.urlopen("file:///home/b/a.yaml").InAnyOrder().AndReturn(six.BytesIO(self.template_a)) request.urlopen("file:///home/b/b.yaml").InAnyOrder().AndReturn(six.BytesIO(self.template_a)) self.m.ReplayAll() files, env = template_utils.process_multiple_environments_and_files([env_file1, env_file2]) self.assertEqual( { "resource_registry": { "resources": { "resource1": {"OS::Thingy1": "file:///home/b/a.yaml", "OS::Thingy3": "file:///home/b/a.yaml"}, "resource2": {"OS::Thingy2": "file:///home/b/b.yaml", "OS::Thingy4": "file:///home/b/b.yaml"}, } } }, env, ) self.assertEqual(self.template_a.decode("utf-8"), files["file:///home/b/a.yaml"]) self.assertEqual(self.template_a.decode("utf-8"), files["file:///home/b/b.yaml"])
def test_process_multiple_environments_empty_registry(self, mock_url): # Setup env_file1 = '/home/my/dir/env1.yaml' env_file2 = '/home/my/dir/env2.yaml' env1 = b''' resource_registry: "OS::Thingy1": "file:///home/b/a.yaml" ''' env2 = b''' resource_registry: ''' mock_url.side_effect = [ six.BytesIO(env1), six.BytesIO(self.template_a), six.BytesIO(self.template_a), six.BytesIO(env2) ] # Test env_file_list = [] files, env = template_utils.process_multiple_environments_and_files( [env_file1, env_file2], env_list_tracker=env_file_list) # Verify expected_env = { 'resource_registry': { 'OS::Thingy1': 'file:///home/b/a.yaml' } } self.assertEqual(expected_env, env) self.assertEqual(self.template_a.decode('utf-8'), files['file:///home/b/a.yaml']) self.assertEqual( ['file:///home/my/dir/env1.yaml', 'file:///home/my/dir/env2.yaml'], env_file_list) self.assertIn('file:///home/my/dir/env1.yaml', files) self.assertIn('file:///home/my/dir/env2.yaml', files) self.assertEqual(expected_env, json.loads(files['file:///home/my/dir/env1.yaml'])) mock_url.assert_has_calls([ mock.call('file://%s' % env_file1), mock.call('file:///home/b/a.yaml'), mock.call('file:///home/b/a.yaml'), mock.call('file://%s' % env_file2), ])
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 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 take_action(self, parsed_args): self.log.debug('take_action(%s)', parsed_args) client = self.app.client_manager.orchestration tpl_files, template = template_utils.process_template_path( parsed_args.template, object_request=_authenticated_fetcher(client)) env_files, env = ( template_utils.process_multiple_environments_and_files( env_paths=parsed_args.environment)) parameters = heat_utils.format_all_parameters( parsed_args.parameter, parsed_args.parameter_file, parsed_args.template) if parsed_args.pre_create: template_utils.hooks_to_env(env, parsed_args.pre_create, 'pre-create') fields = { 'stack_name': parsed_args.name, 'disable_rollback': not parsed_args.enable_rollback, 'parameters': parameters, 'template': template, 'files': dict(list(tpl_files.items()) + list(env_files.items())), 'environment': env } if parsed_args.tags: fields['tags'] = parsed_args.tags if parsed_args.timeout: fields['timeout_mins'] = parsed_args.timeout stack = client.stacks.create(**fields)['stack'] if parsed_args.wait: if not utils.wait_for_status(client.stacks.get, parsed_args.name, status_field='stack_status', success_status='create_complete', error_status='create_failed'): msg = _('Stack %s failed to create.') % parsed_args.name raise exc.CommandError(msg) return _show_stack(client, stack['id'], format='table', short=True)
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, _authenticated_fetcher(hc)) env_files, env = template_utils.process_multiple_environments_and_files( env_paths=args.environment_file) if args.pre_update: hooks_to_env(env, args.pre_update, 'pre-update') fields = { 'stack_id': args.id, 'parameters': utils.format_all_parameters(args.parameters, args.parameter_file, args.template_file, args.template_url), 'existing': args.existing, 'template': template, 'files': dict(list(tpl_files.items()) + list(env_files.items())), 'environment': env } if args.timeout: fields['timeout_mins'] = args.timeout if args.clear_parameter: fields['clear_parameters'] = list(args.clear_parameter) if args.rollback is not None: try: rollback = strutils.bool_from_string(args.rollback, strict=True) except ValueError as ex: raise exc.CommandError(six.text_type(ex)) else: fields['disable_rollback'] = not(rollback) # TODO(pshchelo): remove the following 'else' clause after deprecation # period of --enable-rollback switch and assign -r shortcut to --rollback else: if args.enable_rollback: fields['disable_rollback'] = False hc.stacks.update(**fields) do_stack_list(hc)
def _deploy(stack_name, stack_template, env_path): hclient = _get_heat_client() template_files, template = template_utils.get_template_contents( stack_template) env_files, env = template_utils.process_multiple_environments_and_files( ['templates/resource-registry.yaml', env_path]) all_files = {} all_files.update(template_files) all_files.update(env_files) hclient.stacks.create(stack_name=stack_name, template=template, environment=env, files=all_files) print 'Deployment of stack "%s" started.' % stack_name
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 process_environments_and_files(swift, env_paths): """Wrap process_multiple_environments_and_files with swift object fetch""" def _env_path_is_object(env_path): return env_path.startswith(swift.url) # XXX this should belong in heatclient, but for the time being and backport # purposes, let's do that here for now. _cache = {} def _object_request(method, url, token=swift.token): if url not in _cache: _cache[url] = object_request(method, url, token) return _cache[url] return template_utils.process_multiple_environments_and_files( env_paths=env_paths, env_path_is_object=_env_path_is_object, object_request=_object_request)
def create_resource(self, kind, metadata): logger.info("Creating {} resource".format(kind)) if kind == 'heat_stack': if self.auth(): tpl_files, template = template_utils.get_template_contents( template_file=metadata['template_file'], object_request=http.authenticated_fetcher(self.api)) env_files_list = [] env_files, env = template_utils.process_multiple_environments_and_files( env_paths=[metadata['environment_file']], env_list_tracker=env_files_list) fields = { 'stack_name': metadata['name'], 'disable_rollback': True, 'parameters': metadata['parameters'], 'template': template, 'files': dict(list(tpl_files.items()) + list(env_files.items())), 'environment': env } if env_files_list: fields['environment_files'] = env_files_list response = self.api.stacks.create(**fields) logger.info(response) stack = self.api.stacks.get(response['stack']['id']) resource = stack.to_dict() stack_metadata = {resource['id']: resource} template_metadata = self.get_resource_metadata( 'heat_template', metadata['template_name']) self.process_resource_metadata('heat_template', template_metadata) self.process_resource_metadata('heat_stack', stack_metadata) self._create_relation('defined_by', resource['id'], metadata['template_name']) self.save() logger.info(stack) wait_for_resource_state_task.apply_async( (self.name, resource['id'], ['active', 'error']))
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, _authenticated_fetcher(hc)) 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 process_spec(spec): template_file = spec.get('template', None) tpl_files, template = template_utils.get_template_contents( template_file=template_file) env_files, env = template_utils.process_multiple_environments_and_files( env_paths=spec.get('environment', None)) new_spec = { '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 test_process_multiple_environments_and_files_from_object(self): env_object = 'http://no.where/path/to/env.yaml' env1 = b''' parameters: "param1": "value1" resource_registry: "OS::Thingy1": "b/a.yaml" ''' self.m.ReplayAll() self.object_requested = False def env_path_is_object(object_url): return True 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 == env_object: return env1 else: return self.template_a files, env = template_utils.process_multiple_environments_and_files( env_paths=[env_object], env_path_is_object=env_path_is_object, object_request=object_request) self.assertEqual( { 'resource_registry': { 'OS::Thingy1': 'http://no.where/path/to/b/a.yaml' }, 'parameters': { 'param1': 'value1' } }, env) self.assertEqual(self.template_a.decode('utf-8'), files['http://no.where/path/to/b/a.yaml'])
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 _deploy(stack_name, stack_template, env_paths, poll): hclient = _get_heat_client() template_files, template = template_utils.get_template_contents( stack_template) env_files, env = template_utils.process_multiple_environments_and_files( ['templates/resource-registry.yaml'] + env_paths) all_files = {} all_files.update(template_files) all_files.update(env_files) parameters = {'cloud_data': auth._cloud_json()} hclient.stacks.create(stack_name=stack_name, template=template, environment=env, files=all_files, parameters=parameters) print 'Deployment of stack "%s" started.' % stack_name if poll: _poll_stack(stack_name, hclient)
def update(self, timeout_mins=constants.STACK_TIMEOUT_DEFAULT): # time rounded to seconds timestamp = int(time.time()) stack_params = {'UpdateIdentifier': timestamp, 'StackAction': 'UPDATE'} 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)) template_utils.deep_update(env, { 'resource_registry': { 'resources': { '*': { '*': { constants.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 test_process_environment_relative_file_tracker(self, mock_url): env_file = '/home/my/dir/env.yaml' env_url = 'file:///home/my/dir/env.yaml' env = b''' resource_registry: "OS::Thingy": a.yaml ''' mock_url.side_effect = [ six.BytesIO(env), six.BytesIO(self.template_a), six.BytesIO(self.template_a) ] self.assertEqual(env_url, utils.normalise_file_path_to_url(env_file)) self.assertEqual('file:///home/my/dir', utils.base_url_for_url(env_url)) env_file_list = [] files, env = template_utils.process_multiple_environments_and_files( [env_file], env_list_tracker=env_file_list) # Verify expected_env = { 'resource_registry': { 'OS::Thingy': 'file:///home/my/dir/a.yaml' } } self.assertEqual(expected_env, env) self.assertEqual(self.template_a.decode('utf-8'), files['file:///home/my/dir/a.yaml']) self.assertEqual(['file:///home/my/dir/env.yaml'], env_file_list) self.assertEqual(json.dumps(expected_env), files['file:///home/my/dir/env.yaml']) mock_url.assert_has_calls([ mock.call(env_url), mock.call('file:///home/my/dir/a.yaml'), mock.call('file:///home/my/dir/a.yaml'), ])
def test_process_environment_relative_file_tracker(self): self.m.StubOutWithMock(request, 'urlopen') env_file = '/home/my/dir/env.yaml' env_url = 'file:///home/my/dir/env.yaml' env = b''' resource_registry: "OS::Thingy": a.yaml ''' request.urlopen(env_url).AndReturn( six.BytesIO(env)) request.urlopen('file:///home/my/dir/a.yaml').AndReturn( six.BytesIO(self.template_a)) request.urlopen('file:///home/my/dir/a.yaml').AndReturn( six.BytesIO(self.template_a)) self.m.ReplayAll() self.assertEqual( env_url, utils.normalise_file_path_to_url(env_file)) self.assertEqual( 'file:///home/my/dir', utils.base_url_for_url(env_url)) env_file_list = [] files, env = template_utils.process_multiple_environments_and_files( [env_file], env_list_tracker=env_file_list) # Verify expected_env = {'resource_registry': {'OS::Thingy': 'file:///home/my/dir/a.yaml'}} self.assertEqual(expected_env, env) self.assertEqual(self.template_a.decode('utf-8'), files['file:///home/my/dir/a.yaml']) self.assertEqual(['file:///home/my/dir/env.yaml'], env_file_list) self.assertEqual(json.dumps(expected_env), files['file:///home/my/dir/env.yaml'])
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, _authenticated_fetcher(hc)) env_files, env = template_utils.process_multiple_environments_and_files( env_paths=args.environment_file) if args.create_timeout: logger.warning(_LW('%(arg1)s is deprecated, ' 'please use %(arg2)s instead'), { 'arg1': '-c/--create-timeout', 'arg2': '-t/--timeout' }) if args.pre_create: hooks_to_env(env, args.pre_create, 'pre-create') fields = { 'stack_name': args.name, 'disable_rollback': not(args.enable_rollback), '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 } timeout = args.timeout or args.create_timeout if timeout: fields['timeout_mins'] = timeout hc.stacks.create(**fields) do_stack_list(hc)
def _create_stack(module, heat): heat.format = 'json' template_file = module.params['template'] env_file = module.params['environment_files'] tpl_files, template = template_utils.get_template_contents(template_file) env_files, env = template_utils.process_multiple_environments_and_files(env_paths=env_file) stack = heat.stacks.create(stack_name=module.params['stack_name'], template=template, environment=env, files=dict(list(tpl_files.items()) + list(env_files.items())), parameters={}) uid = stack['stack']['id'] stack = heat.stacks.get(stack_id=uid).to_dict() while stack['stack_status'] == 'CREATE_IN_PROGRESS': stack = heat.stacks.get(stack_id=uid).to_dict() sleep(5) if stack['stack_status'] == 'CREATE_COMPLETE': return stack['stack']['id'] else: module.fail_json(msg = "Failure in creating stack: ".format(stack))
def test_process_multiple_environments_and_files_from_object(self): env_object = 'http://no.where/path/to/env.yaml' env1 = b''' parameters: "param1": "value1" resource_registry: "OS::Thingy1": "b/a.yaml" ''' self.m.ReplayAll() self.object_requested = False def env_path_is_object(object_url): return True 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 == env_object: return env1 else: return self.template_a files, env = template_utils.process_multiple_environments_and_files( env_paths=[env_object], env_path_is_object=env_path_is_object, object_request=object_request) self.assertEqual( { 'resource_registry': { 'OS::Thingy1': 'http://no.where/path/to/b/a.yaml'}, 'parameters': {'param1': 'value1'} }, env) self.assertEqual(self.template_a.decode('utf-8'), files['http://no.where/path/to/b/a.yaml'])