def test_minimal_yaml(self): yaml1 = '' yaml2 = ''' parameters: {} resource_registry: {} ''' tpl1 = environment_format.parse(yaml1) environment_format.default_for_missing(tpl1) tpl2 = environment_format.parse(yaml2) self.assertEqual(tpl1, tpl2)
def test_minimal_yaml(self): yaml1 = '' yaml2 = ''' parameters: {} encrypted_param_names: [] parameter_defaults: {} event_sinks: [] resource_registry: {} ''' tpl1 = environment_format.parse(yaml1) environment_format.default_for_missing(tpl1) tpl2 = environment_format.parse(yaml2) self.assertEqual(tpl1, tpl2)
def test_param_valid_strategy_section(self): yaml1 = '' yaml2 = ''' parameters: {} encrypted_param_names: [] parameter_defaults: {} parameter_merge_strategies: {} event_sinks: [] resource_registry: {} ''' tpl1 = environment_format.parse(yaml1) environment_format.default_for_missing(tpl1) tpl2 = environment_format.parse(yaml2) self.assertNotEqual(tpl1, tpl2)
def read_global_environment(env, env_dir=None): if env_dir is None: cfg.CONF.import_opt('environment_dir', 'heat.common.config') env_dir = cfg.CONF.environment_dir try: env_files = glob.glob(os.path.join(env_dir, '*')) except OSError as osex: LOG.error(_LE('Failed to read %s'), env_dir) LOG.exception(osex) return for file_path in env_files: try: with open(file_path) as env_fd: LOG.info(_LI('Loading %s'), file_path) env_body = env_fmt.parse(env_fd.read()) env_fmt.default_for_missing(env_body) env.load(env_body) except ValueError as vex: LOG.error(_LE('Failed to parse %(file_path)s'), { 'file_path': file_path}) LOG.exception(vex) except IOError as ioex: LOG.error(_LE('Failed to read %(file_path)s'), { 'file_path': file_path}) LOG.exception(ioex)
def _load_global_environment(env, env_dir=None): if env_dir is None: cfg.CONF.import_opt('environment_dir', 'heat.common.config') env_dir = cfg.CONF.environment_dir for env_name in _list_environment_files(env_dir): try: file_path = os.path.join(env_dir, env_name) with open(file_path) as env_fd: LOG.info(_('Loading %s') % file_path) env_body = environment_format.parse(env_fd.read()) environment_format.default_for_missing(env_body) env.load(env_body) except ValueError as vex: LOG.error( _('Failed to parse %(dir)s/%(name)s') % { 'dir': env_dir, 'name': env_name }) LOG.exception(vex) except IOError as ioex: LOG.error( _('Failed to read %(dir)s/%(name)s') % { 'dir': env_dir, 'name': env_name }) LOG.exception(ioex)
def merge_environments(environment_files, files, params): """Merges environment files into the stack input parameters. If a list of environment files have been specified, this call will pull the contents of each from the files dict, parse them as environments, and merge them into the stack input params. This behavior is the same as earlier versions of the Heat client that performed this params population client-side. :param environment_files: ordered names of the environment files found in the files dict :type environment_files: list or None :param files: mapping of stack filenames to contents :type files: dict :param params: parameters describing the stack :type dict: """ if not environment_files: return for filename in environment_files: raw_env = files[filename] parsed_env = env_fmt.parse(raw_env) for section_key, section_value in parsed_env.items(): if section_value: params[section_key] = merge_map(params[section_key], section_value, deep_merge=True)
def test_env_user_cant_disable_sys_resource(self): # prove a user can't disable global resources from the user environment u_env_content = """ resource_registry: "AWS::*": """ # 1. load user env u_env = environment.Environment() u_env.load(environment_format.parse(u_env_content)) # 2. assert global resources are NOT gone. self.assertEqual(instance.Instance, u_env.get_resource_info("AWS::EC2::Instance").value)
def format_parse(data, data_type): """ Parse the supplied data as JSON or YAML, raising the appropriate exception if it is in the wrong format. """ try: if data_type == 'Environment': return environment_format.parse(data) else: return template_format.parse(data) except ValueError: err_reason = _("%s not in valid format") % data_type raise exc.HTTPBadRequest(err_reason)
def test_env_user_cant_disable_sys_resource(self): # prove a user can't disable global resources from the user environment u_env_content = ''' resource_registry: "AWS::*": ''' # 1. load user env u_env = environment.Environment() u_env.load(environment_format.parse(u_env_content)) # 2. assert global resources are NOT gone. self.assertEqual(instance.Instance, u_env.get_resource_info('AWS::EC2::Instance').value)
def _load_global_environment(env_dir): for env_name in _list_environment_files(env_dir): try: file_path = os.path.join(env_dir, env_name) with open(file_path) as env_fd: LOG.info('Loading %s' % file_path) env_body = environment_format.parse(env_fd.read()) environment_format.default_for_missing(env_body) _environment.load(env_body) except ValueError as vex: LOG.error('Failed to parse %s/%s' % (env_dir, env_name)) LOG.exception(vex) except IOError as ioex: LOG.error('Failed to read %s/%s' % (env_dir, env_name)) LOG.exception(ioex)
def format_parse(data, data_type): """ Parse the supplied data as JSON or YAML, raising the appropriate exception if it is in the wrong format. """ try: if data_type == 'Environment': return environment_format.parse(data) else: return template_format.parse(data) except ValueError as parse_ex: mdict = {'type': data_type, 'error': six.text_type(parse_ex)} msg = _("%(type)s not in valid format: %(error)s") % mdict raise exc.HTTPBadRequest(msg)
def test_register_with_path(self): yaml_env = """ resource_registry: test::one: a.yaml resources: res_x: test::two: b.yaml """ env = environment.Environment(environment_format.parse(yaml_env)) self.assertEqual("a.yaml", env.get_resource_info("test::one").value) self.assertEqual("b.yaml", env.get_resource_info("test::two", "res_x").value) env2 = environment.Environment() env2.register_class("test::one", "a.yaml", path=["test::one"]) env2.register_class("test::two", "b.yaml", path=["resources", "res_x", "test::two"]) self.assertEqual(env.user_env_as_dict(), env2.user_env_as_dict())
def environment(self): """ Get the user-supplied environment for the stack in YAML format. If the user supplied Parameters then merge these into the environment global options. """ env = {} if self.PARAM_ENVIRONMENT in self.data: env_data = self.data[self.PARAM_ENVIRONMENT] if isinstance(env_data, dict): env = env_data else: with self.parse_error_check('Environment'): env = environment_format.parse(env_data) environment_format.default_for_missing(env) parameters = self.data.get(self.PARAM_USER_PARAMS, {}) env[self.PARAM_USER_PARAMS].update(parameters) return env
def merge_environments(environment_files, files, params, param_schemata): """Merges environment files into the stack input parameters. If a list of environment files have been specified, this call will pull the contents of each from the files dict, parse them as environments, and merge them into the stack input params. This behavior is the same as earlier versions of the Heat client that performed this params population client-side. :param environment_files: ordered names of the environment files found in the files dict :type environment_files: list or None :param files: mapping of stack filenames to contents :type files: dict :param params: parameters describing the stack :type dict: :param param_schemata: parameter schema dict :type param_schemata: dict """ if not environment_files: return available_strategies = {} for filename in environment_files: raw_env = files[filename] parsed_env = env_fmt.parse(raw_env) strategies_in_file = parsed_env.pop( env_fmt.PARAMETER_MERGE_STRATEGIES, {}) for section_key, section_value in parsed_env.items(): if section_value: if section_key in (env_fmt.PARAMETERS, env_fmt.PARAMETER_DEFAULTS): params[section_key], new_strategies = merge_parameters( params[section_key], section_value, param_schemata, strategies_in_file, available_strategies, filename) available_strategies.update(new_strategies) else: params[section_key] = merge_map(params[section_key], section_value)
def _load_global_environment(env, env_dir=None): if env_dir is None: cfg.CONF.import_opt('environment_dir', 'heat.common.config') env_dir = cfg.CONF.environment_dir for env_name in _list_environment_files(env_dir): try: file_path = os.path.join(env_dir, env_name) with open(file_path) as env_fd: LOG.info('Loading %s' % file_path) env_body = environment_format.parse(env_fd.read()) environment_format.default_for_missing(env_body) env.load(env_body) except ValueError as vex: LOG.error('Failed to parse %s/%s' % (env_dir, env_name)) LOG.exception(vex) except IOError as ioex: LOG.error('Failed to read %s/%s' % (env_dir, env_name)) LOG.exception(ioex)
def environment(self): """Get the user-supplied environment for the stack in YAML format. If the user supplied Parameters then merge these into the environment global options. """ env = {} # Don't use merged environment, if environment_files are supplied. if (self.PARAM_ENVIRONMENT in self.data and not self.data.get(self.PARAM_ENVIRONMENT_FILES)): env_data = self.data[self.PARAM_ENVIRONMENT] with self.parse_error_check('Environment'): if isinstance(env_data, dict): env = environment_format.validate(env_data) else: env = environment_format.parse(env_data) environment_format.default_for_missing(env) parameters = self.data.get(self.PARAM_USER_PARAMS, {}) env[self.PARAM_USER_PARAMS].update(parameters) return env
def test_register_with_path(self): yaml_env = ''' resource_registry: test::one: a.yaml resources: res_x: test::two: b.yaml ''' env = environment.Environment(environment_format.parse(yaml_env)) self.assertEqual('a.yaml', env.get_resource_info('test::one').value) self.assertEqual('b.yaml', env.get_resource_info('test::two', 'res_x').value) env2 = environment.Environment() env2.register_class('test::one', 'a.yaml', path=['test::one']) env2.register_class('test::two', 'b.yaml', path=['resources', 'res_x', 'test::two']) self.assertEqual(env.env_as_dict(), env2.env_as_dict())
def read_global_environment(env, env_dir=None): if env_dir is None: cfg.CONF.import_opt("environment_dir", "heat.common.config") env_dir = cfg.CONF.environment_dir try: env_files = glob.glob(os.path.join(env_dir, "*")) except OSError: LOG.exception(_LE("Failed to read %s"), env_dir) return for file_path in env_files: try: with open(file_path) as env_fd: LOG.info(_LI("Loading %s"), file_path) env_body = env_fmt.parse(env_fd.read()) env_fmt.default_for_missing(env_body) env.load(env_body) except ValueError: LOG.exception(_LE("Failed to parse %s"), file_path) except IOError: LOG.exception(_LE("Failed to read %s"), file_path)
def test_register_with_path(self): yaml_env = ''' resource_registry: test::one: a.yaml resources: res_x: test::two: b.yaml ''' env = environment.Environment(environment_format.parse(yaml_env)) self.assertEqual('a.yaml', env.get_resource_info('test::one').value) self.assertEqual('b.yaml', env.get_resource_info('test::two', 'res_x').value) env2 = environment.Environment() env2.register_class('test::one', 'a.yaml', path=['test::one']) env2.register_class('test::two', 'b.yaml', path=['resources', 'res_x', 'test::two']) self.assertEqual(env.user_env_as_dict(), env2.user_env_as_dict())
def test_yaml_none(self): self.assertEqual({}, environment_format.parse(None))