def test_get_config_dynamic_config_item_nested_dict(self): pack_name = "dummy_pack_schema_with_nested_object_7" loader = ContentPackConfigLoader(pack_name=pack_name) KeyValuePair.add_or_update(KeyValuePairDB(name="k0", value="v0")) KeyValuePair.add_or_update(KeyValuePairDB(name="k1", value="v1")) KeyValuePair.add_or_update(KeyValuePairDB(name="k2", value="v2")) #################### # values nested dictionaries values = { "level0_key": "{{st2kv.system.k0}}", "level0_object": { "level1_key": "{{st2kv.system.k1}}", "level1_object": {"level2_key": "{{st2kv.system.k2}}"}, }, } config_db = ConfigDB(pack=pack_name, values=values) config_db = Config.add_or_update(config_db) config_rendered = loader.get_config() self.assertEqual( config_rendered, { "level0_key": "v0", "level0_object": { "level1_key": "v1", "level1_object": {"level2_key": "v2"}, }, }, ) config_db.delete()
def test_get_config_dynamic_config_item_list(self): pack_name = 'dummy_pack_schema_with_nested_object_7' loader = ContentPackConfigLoader(pack_name=pack_name) KeyValuePair.add_or_update(KeyValuePairDB(name='k0', value='v0')) KeyValuePair.add_or_update(KeyValuePairDB(name='k1', value='v1')) #################### # values in list values = { 'level0_key': [ 'a', '{{st2kv.system.k0}}', 'b', '{{st2kv.system.k1}}', ] } config_db = ConfigDB(pack=pack_name, values=values) config_db = Config.add_or_update(config_db) config_rendered = loader.get_config() self.assertEquals(config_rendered, { 'level0_key': [ 'a', 'v0', 'b', 'v1' ] }) config_db.delete()
def test_get_config_dynamic_config_item_list(self): pack_name = 'dummy_pack_schema_with_nested_object_7' loader = ContentPackConfigLoader(pack_name=pack_name) KeyValuePair.add_or_update(KeyValuePairDB(name='k0', value='v0')) KeyValuePair.add_or_update(KeyValuePairDB(name='k1', value='v1')) #################### # values in list values = { 'level0_key': [ 'a', '{{st2kv.system.k0}}', 'b', '{{st2kv.system.k1}}', ] } config_db = ConfigDB(pack=pack_name, values=values) config_db = Config.add_or_update(config_db) config_rendered = loader.get_config() self.assertEqual(config_rendered, {'level0_key': ['a', 'v0', 'b', 'v1']}) config_db.delete()
def test_get_config_dynamic_config_item_list(self): pack_name = "dummy_pack_schema_with_nested_object_7" loader = ContentPackConfigLoader(pack_name=pack_name) KeyValuePair.add_or_update(KeyValuePairDB(name="k0", value="v0")) KeyValuePair.add_or_update(KeyValuePairDB(name="k1", value="v1")) #################### # values in list values = { "level0_key": [ "a", "{{st2kv.system.k0}}", "b", "{{st2kv.system.k1}}", ] } config_db = ConfigDB(pack=pack_name, values=values) config_db = Config.add_or_update(config_db) config_rendered = loader.get_config() self.assertEqual(config_rendered, {"level0_key": ["a", "v0", "b", "v1"]}) config_db.delete()
def test_get_config_dynamic_config_item_nested_list(self): pack_name = "dummy_pack_schema_with_nested_object_8" loader = ContentPackConfigLoader(pack_name=pack_name) KeyValuePair.add_or_update(KeyValuePairDB(name="k0", value="v0")) KeyValuePair.add_or_update(KeyValuePairDB(name="k1", value="v1")) KeyValuePair.add_or_update(KeyValuePairDB(name="k2", value="v2")) #################### # values in objects embedded in lists and nested lists values = { "level0_key": [ { "level1_key0": "{{st2kv.system.k0}}" }, "{{st2kv.system.k1}}", [ "{{st2kv.system.k0}}", "{{st2kv.system.k1}}", "{{st2kv.system.k2}}", ], { "level1_key2": [ "{{st2kv.system.k2}}", ] }, ] } config_db = ConfigDB(pack=pack_name, values=values) config_db = Config.add_or_update(config_db) config_rendered = loader.get_config() self.assertEqual( config_rendered, { "level0_key": [ { "level1_key0": "v0" }, "v1", [ "v0", "v1", "v2", ], { "level1_key2": [ "v2", ] }, ] }, ) config_db.delete()
def test_get_config_dynamic_config_item_under_additional_properties(self): pack_name = "dummy_pack_schema_with_additional_properties_1" loader = ContentPackConfigLoader(pack_name=pack_name) encrypted_value = crypto.symmetric_encrypt(KeyValuePairAPI.crypto_key, "v1_encrypted") KeyValuePair.add_or_update( KeyValuePairDB(name="k1_encrypted", value=encrypted_value, secret=True)) #################### # values in objects under an object with additionalProperties values = { "profiles": { "dev": { # no host or port to test default value "token": "hard-coded-secret", }, "prod": { "host": "127.1.2.7", "port": 8282, # encrypted in datastore "token": "{{st2kv.system.k1_encrypted}}", # schema declares `secret: true` which triggers auto-decryption. # If this were not encrypted, it would try to decrypt it and fail. }, } } config_db = ConfigDB(pack=pack_name, values=values) config_db = Config.add_or_update(config_db) config_rendered = loader.get_config() self.assertEqual( config_rendered, { "region": "us-east-1", "profiles": { "dev": { "host": "127.0.0.3", "port": 8080, "token": "hard-coded-secret", }, "prod": { "host": "127.1.2.7", "port": 8282, "token": "v1_encrypted", }, }, }, ) config_db.delete()
def test_get_config_dynamic_config_item_nested_list(self): pack_name = 'dummy_pack_schema_with_nested_object_8' loader = ContentPackConfigLoader(pack_name=pack_name) KeyValuePair.add_or_update(KeyValuePairDB(name='k0', value='v0')) KeyValuePair.add_or_update(KeyValuePairDB(name='k1', value='v1')) KeyValuePair.add_or_update(KeyValuePairDB(name='k2', value='v2')) #################### # values in objects embedded in lists and nested lists values = { 'level0_key': [ { 'level1_key0': '{{st2kv.system.k0}}' }, '{{st2kv.system.k1}}', [ '{{st2kv.system.k0}}', '{{st2kv.system.k1}}', '{{st2kv.system.k2}}', ], { 'level1_key2': [ '{{st2kv.system.k2}}', ] } ] } config_db = ConfigDB(pack=pack_name, values=values) config_db = Config.add_or_update(config_db) config_rendered = loader.get_config() self.assertEquals(config_rendered, { 'level0_key': [ { 'level1_key0': 'v0' }, 'v1', [ 'v0', 'v1', 'v2', ], { 'level1_key2': [ 'v2', ] } ] }) config_db.delete()
def test_get_config_dynamic_config_item(self): pack_name = "dummy_pack_schema_with_nested_object_6" loader = ContentPackConfigLoader(pack_name=pack_name) #################### # value in top level item KeyValuePair.add_or_update(KeyValuePairDB(name="k1", value="v1")) values = {"level0_key": "{{st2kv.system.k1}}"} config_db = ConfigDB(pack=pack_name, values=values) config_db = Config.add_or_update(config_db) config_rendered = loader.get_config() self.assertEqual(config_rendered, {"level0_key": "v1"}) config_db.delete()
def get_config(self): result = {} # Retrieve corresponding ConfigDB and ConfigSchemaDB object # Note: ConfigSchemaDB is optional right now. If it doesn't exist, we assume every value # is of a type string try: config_db = Config.get_by_pack(value=self.pack_name) except StackStormDBObjectNotFoundError: # Corresponding pack config doesn't exist. We set config_db to an empty config so # that the default values from config schema are still correctly applied even if # pack doesn't contain a config. config_db = ConfigDB(pack=self.pack_name, values={}) try: config_schema_db = ConfigSchema.get_by_pack(value=self.pack_name) except StackStormDBObjectNotFoundError: config_schema_db = None # 2. Retrieve values from "global" pack config file (if available) and resolve them if # necessary config = self._get_values_for_config( config_schema_db=config_schema_db, config_db=config_db ) result.update(config) return result
def test_get_config_dynamic_config_item(self): pack_name = 'dummy_pack_schema_with_nested_object_6' loader = ContentPackConfigLoader(pack_name=pack_name) #################### # value in top level item KeyValuePair.add_or_update(KeyValuePairDB(name='k1', value='v1')) values = {'level0_key': '{{st2kv.system.k1}}'} config_db = ConfigDB(pack=pack_name, values=values) config_db = Config.add_or_update(config_db) config_rendered = loader.get_config() self.assertEqual(config_rendered, {'level0_key': 'v1'}) config_db.delete()
def test_get_config_dynamic_config_item(self): pack_name = 'dummy_pack_schema_with_nested_object_6' loader = ContentPackConfigLoader(pack_name=pack_name) #################### # value in top level item KeyValuePair.add_or_update(KeyValuePairDB(name='k1', value='v1')) values = { 'level0_key': '{{st2kv.system.k1}}' } config_db = ConfigDB(pack=pack_name, values=values) config_db = Config.add_or_update(config_db) config_rendered = loader.get_config() self.assertEquals(config_rendered, {'level0_key': 'v1'}) config_db.delete()
def test_empty_config_object_in_the_database(self): pack_name = 'dummy_pack_empty_config' config_db = ConfigDB(pack=pack_name) config_db = Config.add_or_update(config_db) loader = ContentPackConfigLoader(pack_name=pack_name) config = loader.get_config() self.assertEqual(config, {})
def test_get_config_dynamic_config_item_render_fails_user_friendly_exception_is_thrown(self): pack_name = 'dummy_pack_schema_with_nested_object_5' loader = ContentPackConfigLoader(pack_name=pack_name) # Render fails on top-level item values = { 'level0_key': '{{st2kvXX.invalid}}' } config_db = ConfigDB(pack=pack_name, values=values) config_db = Config.add_or_update(config_db) expected_msg = ('Failed to render dynamic configuration value for key "level0_key" with ' 'value "{{st2kvXX.invalid}}" for pack ".*?" config: ' '\'st2kvXX\' is undefined') self.assertRaisesRegexp(Exception, expected_msg, loader.get_config) config_db.delete() # Renders fails on fist level item values = { 'level0_object': { 'level1_key': '{{st2kvXX.invalid}}' } } config_db = ConfigDB(pack=pack_name, values=values) Config.add_or_update(config_db) expected_msg = ('Failed to render dynamic configuration value for key ' '"level0_object.level1_key" with value "{{st2kvXX.invalid}}"' ' for pack ".*?" config: \'st2kvXX\' is undefined') self.assertRaisesRegexp(Exception, expected_msg, loader.get_config) config_db.delete() # Renders fails on second level item values = { 'level0_object': { 'level1_object': { 'level2_key': '{{st2kvXX.invalid}}' } } } config_db = ConfigDB(pack=pack_name, values=values) Config.add_or_update(config_db) expected_msg = ('Failed to render dynamic configuration value for key ' '"level0_object.level1_object.level2_key" with value "{{st2kvXX.invalid}}"' ' for pack ".*?" config: \'st2kvXX\' is undefined') self.assertRaisesRegexp(Exception, expected_msg, loader.get_config) config_db.delete()
def test_get_config_dynamic_config_item_nested_dict(self): pack_name = 'dummy_pack_schema_with_nested_object_7' loader = ContentPackConfigLoader(pack_name=pack_name) KeyValuePair.add_or_update(KeyValuePairDB(name='k0', value='v0')) KeyValuePair.add_or_update(KeyValuePairDB(name='k1', value='v1')) KeyValuePair.add_or_update(KeyValuePairDB(name='k2', value='v2')) #################### # values nested dictionaries values = { 'level0_key': '{{st2kv.system.k0}}', 'level0_object': { 'level1_key': '{{st2kv.system.k1}}', 'level1_object': { 'level2_key': '{{st2kv.system.k2}}' } } } config_db = ConfigDB(pack=pack_name, values=values) config_db = Config.add_or_update(config_db) config_rendered = loader.get_config() self.assertEquals(config_rendered, { 'level0_key': 'v0', 'level0_object': { 'level1_key': 'v1', 'level1_object': { 'level2_key': 'v2' } } }) config_db.delete()
def test_get_config_dynamic_config_item_nested_dict(self): pack_name = 'dummy_pack_schema_with_nested_object_7' loader = ContentPackConfigLoader(pack_name=pack_name) KeyValuePair.add_or_update(KeyValuePairDB(name='k0', value='v0')) KeyValuePair.add_or_update(KeyValuePairDB(name='k1', value='v1')) KeyValuePair.add_or_update(KeyValuePairDB(name='k2', value='v2')) #################### # values nested dictionaries values = { 'level0_key': '{{st2kv.system.k0}}', 'level0_object': { 'level1_key': '{{st2kv.system.k1}}', 'level1_object': { 'level2_key': '{{st2kv.system.k2}}' } } } config_db = ConfigDB(pack=pack_name, values=values) config_db = Config.add_or_update(config_db) config_rendered = loader.get_config() self.assertEqual( config_rendered, { 'level0_key': 'v0', 'level0_object': { 'level1_key': 'v1', 'level1_object': { 'level2_key': 'v2' } } }) config_db.delete()
def test_default_values_are_used_when_default_values_are_falsey(self): pack_name = 'dummy_pack_17' loader = ContentPackConfigLoader(pack_name=pack_name) config = loader.get_config() # 1. Default values are used self.assertEqual(config['key_with_default_falsy_value_1'], False) self.assertEqual(config['key_with_default_falsy_value_2'], None) self.assertEqual(config['key_with_default_falsy_value_3'], {}) self.assertEqual(config['key_with_default_falsy_value_4'], '') self.assertEqual(config['key_with_default_falsy_value_5'], 0) self.assertEqual(config['key_with_default_falsy_value_6']['key_1'], False) self.assertEqual(config['key_with_default_falsy_value_6']['key_2'], 0) # 2. Default values are overwrriten with config values which are also falsey values = { 'key_with_default_falsy_value_1': 0, 'key_with_default_falsy_value_2': '', 'key_with_default_falsy_value_3': False, 'key_with_default_falsy_value_4': None, 'key_with_default_falsy_value_5': {}, 'key_with_default_falsy_value_6': { 'key_2': False } } config_db = ConfigDB(pack=pack_name, values=values) config_db = Config.add_or_update(config_db) loader = ContentPackConfigLoader(pack_name=pack_name) config = loader.get_config() self.assertEqual(config['key_with_default_falsy_value_1'], 0) self.assertEqual(config['key_with_default_falsy_value_2'], '') self.assertEqual(config['key_with_default_falsy_value_3'], False) self.assertEqual(config['key_with_default_falsy_value_4'], None) self.assertEqual(config['key_with_default_falsy_value_5'], {}) self.assertEqual(config['key_with_default_falsy_value_6']['key_1'], False) self.assertEqual(config['key_with_default_falsy_value_6']['key_2'], False)
def test_default_values_are_used_when_default_values_are_falsey(self): pack_name = "dummy_pack_17" loader = ContentPackConfigLoader(pack_name=pack_name) config = loader.get_config() # 1. Default values are used self.assertEqual(config["key_with_default_falsy_value_1"], False) self.assertEqual(config["key_with_default_falsy_value_2"], None) self.assertEqual(config["key_with_default_falsy_value_3"], {}) self.assertEqual(config["key_with_default_falsy_value_4"], "") self.assertEqual(config["key_with_default_falsy_value_5"], 0) self.assertEqual(config["key_with_default_falsy_value_6"]["key_1"], False) self.assertEqual(config["key_with_default_falsy_value_6"]["key_2"], 0) # 2. Default values are overwrriten with config values which are also falsey values = { "key_with_default_falsy_value_1": 0, "key_with_default_falsy_value_2": "", "key_with_default_falsy_value_3": False, "key_with_default_falsy_value_4": None, "key_with_default_falsy_value_5": {}, "key_with_default_falsy_value_6": { "key_2": False }, } config_db = ConfigDB(pack=pack_name, values=values) config_db = Config.add_or_update(config_db) loader = ContentPackConfigLoader(pack_name=pack_name) config = loader.get_config() self.assertEqual(config["key_with_default_falsy_value_1"], 0) self.assertEqual(config["key_with_default_falsy_value_2"], "") self.assertEqual(config["key_with_default_falsy_value_3"], False) self.assertEqual(config["key_with_default_falsy_value_4"], None) self.assertEqual(config["key_with_default_falsy_value_5"], {}) self.assertEqual(config["key_with_default_falsy_value_6"]["key_1"], False) self.assertEqual(config["key_with_default_falsy_value_6"]["key_2"], False)
def test_get_config_dynamic_config_item_render_fails_user_friendly_exception_is_thrown(self): pack_name = 'dummy_pack_schema_with_nested_object_5' loader = ContentPackConfigLoader(pack_name=pack_name) # Render fails on top-level item values = { 'level0_key': '{{st2kvXX.invalid}}' } config_db = ConfigDB(pack=pack_name, values=values) config_db = Config.add_or_update(config_db) expected_msg = ('Failed to render dynamic configuration value for key "level0_key" with ' 'value "{{st2kvXX.invalid}}" for pack ".*?" config: ' '<class \'jinja2.exceptions.UndefinedError\'> ' '\'st2kvXX\' is undefined') self.assertRaisesRegexp(RuntimeError, expected_msg, loader.get_config) config_db.delete() # Renders fails on fist level item values = { 'level0_object': { 'level1_key': '{{st2kvXX.invalid}}' } } config_db = ConfigDB(pack=pack_name, values=values) Config.add_or_update(config_db) expected_msg = ('Failed to render dynamic configuration value for key ' '"level0_object.level1_key" with value "{{st2kvXX.invalid}}"' ' for pack ".*?" config: <class \'jinja2.exceptions.UndefinedError\'>' ' \'st2kvXX\' is undefined') self.assertRaisesRegexp(RuntimeError, expected_msg, loader.get_config) config_db.delete() # Renders fails on second level item values = { 'level0_object': { 'level1_object': { 'level2_key': '{{st2kvXX.invalid}}' } } } config_db = ConfigDB(pack=pack_name, values=values) Config.add_or_update(config_db) expected_msg = ('Failed to render dynamic configuration value for key ' '"level0_object.level1_object.level2_key" with value "{{st2kvXX.invalid}}"' ' for pack ".*?" config: <class \'jinja2.exceptions.UndefinedError\'>' ' \'st2kvXX\' is undefined') self.assertRaisesRegexp(RuntimeError, expected_msg, loader.get_config) config_db.delete() # Renders fails on list item values = { 'level0_object': [ 'abc', '{{st2kvXX.invalid}}' ] } config_db = ConfigDB(pack=pack_name, values=values) Config.add_or_update(config_db) expected_msg = ('Failed to render dynamic configuration value for key ' '"level0_object.1" with value "{{st2kvXX.invalid}}"' ' for pack ".*?" config: <class \'jinja2.exceptions.UndefinedError\'>' ' \'st2kvXX\' is undefined') self.assertRaisesRegexp(RuntimeError, expected_msg, loader.get_config) config_db.delete() # Renders fails on nested object in list item values = { 'level0_object': [ {'level2_key': '{{st2kvXX.invalid}}'} ] } config_db = ConfigDB(pack=pack_name, values=values) Config.add_or_update(config_db) expected_msg = ('Failed to render dynamic configuration value for key ' '"level0_object.0.level2_key" with value "{{st2kvXX.invalid}}"' ' for pack ".*?" config: <class \'jinja2.exceptions.UndefinedError\'>' ' \'st2kvXX\' is undefined') self.assertRaisesRegexp(RuntimeError, expected_msg, loader.get_config) config_db.delete() # Renders fails on invalid syntax values = { 'level0_key': '{{ this is some invalid Jinja }}' } config_db = ConfigDB(pack=pack_name, values=values) Config.add_or_update(config_db) expected_msg = ('Failed to render dynamic configuration value for key ' '"level0_key" with value "{{ this is some invalid Jinja }}"' ' for pack ".*?" config: <class \'jinja2.exceptions.TemplateSyntaxError\'>' ' expected token \'end of print statement\', got \'Jinja\'') self.assertRaisesRegexp(RuntimeError, expected_msg, loader.get_config) config_db.delete()
def test_get_config_dynamic_config_item_render_fails_user_friendly_exception_is_thrown( self): pack_name = 'dummy_pack_schema_with_nested_object_5' loader = ContentPackConfigLoader(pack_name=pack_name) # Render fails on top-level item values = {'level0_key': '{{st2kvXX.invalid}}'} config_db = ConfigDB(pack=pack_name, values=values) config_db = Config.add_or_update(config_db) expected_msg = ( 'Failed to render dynamic configuration value for key "level0_key" with ' 'value "{{st2kvXX.invalid}}" for pack ".*?" config: ' '<class \'jinja2.exceptions.UndefinedError\'> ' '\'st2kvXX\' is undefined') self.assertRaisesRegexp(RuntimeError, expected_msg, loader.get_config) config_db.delete() # Renders fails on fist level item values = {'level0_object': {'level1_key': '{{st2kvXX.invalid}}'}} config_db = ConfigDB(pack=pack_name, values=values) Config.add_or_update(config_db) expected_msg = ( 'Failed to render dynamic configuration value for key ' '"level0_object.level1_key" with value "{{st2kvXX.invalid}}"' ' for pack ".*?" config: <class \'jinja2.exceptions.UndefinedError\'>' ' \'st2kvXX\' is undefined') self.assertRaisesRegexp(RuntimeError, expected_msg, loader.get_config) config_db.delete() # Renders fails on second level item values = { 'level0_object': { 'level1_object': { 'level2_key': '{{st2kvXX.invalid}}' } } } config_db = ConfigDB(pack=pack_name, values=values) Config.add_or_update(config_db) expected_msg = ( 'Failed to render dynamic configuration value for key ' '"level0_object.level1_object.level2_key" with value "{{st2kvXX.invalid}}"' ' for pack ".*?" config: <class \'jinja2.exceptions.UndefinedError\'>' ' \'st2kvXX\' is undefined') self.assertRaisesRegexp(RuntimeError, expected_msg, loader.get_config) config_db.delete() # Renders fails on list item values = {'level0_object': ['abc', '{{st2kvXX.invalid}}']} config_db = ConfigDB(pack=pack_name, values=values) Config.add_or_update(config_db) expected_msg = ( 'Failed to render dynamic configuration value for key ' '"level0_object.1" with value "{{st2kvXX.invalid}}"' ' for pack ".*?" config: <class \'jinja2.exceptions.UndefinedError\'>' ' \'st2kvXX\' is undefined') self.assertRaisesRegexp(RuntimeError, expected_msg, loader.get_config) config_db.delete() # Renders fails on nested object in list item values = {'level0_object': [{'level2_key': '{{st2kvXX.invalid}}'}]} config_db = ConfigDB(pack=pack_name, values=values) Config.add_or_update(config_db) expected_msg = ( 'Failed to render dynamic configuration value for key ' '"level0_object.0.level2_key" with value "{{st2kvXX.invalid}}"' ' for pack ".*?" config: <class \'jinja2.exceptions.UndefinedError\'>' ' \'st2kvXX\' is undefined') self.assertRaisesRegexp(RuntimeError, expected_msg, loader.get_config) config_db.delete() # Renders fails on invalid syntax values = {'level0_key': '{{ this is some invalid Jinja }}'} config_db = ConfigDB(pack=pack_name, values=values) Config.add_or_update(config_db) expected_msg = ( 'Failed to render dynamic configuration value for key ' '"level0_key" with value "{{ this is some invalid Jinja }}"' ' for pack ".*?" config: <class \'jinja2.exceptions.TemplateSyntaxError\'>' ' expected token \'end of print statement\', got \'Jinja\'') self.assertRaisesRegexp(RuntimeError, expected_msg, loader.get_config) config_db.delete()
def test_get_config_dynamic_config_item_render_fails_user_friendly_exception_is_thrown( self): pack_name = 'dummy_pack_schema_with_nested_object_5' loader = ContentPackConfigLoader(pack_name=pack_name) # Render fails on top-level item values = {'level0_key': '{{st2kvXX.invalid}}'} config_db = ConfigDB(pack=pack_name, values=values) config_db = Config.add_or_update(config_db) expected_msg = ( 'Failed to render dynamic configuration value for key "level0_key" with ' 'value "{{st2kvXX.invalid}}" for pack ".*?" config: ' '\'st2kvXX\' is undefined') self.assertRaisesRegexp(Exception, expected_msg, loader.get_config) config_db.delete() # Renders fails on fist level item values = {'level0_object': {'level1_key': '{{st2kvXX.invalid}}'}} config_db = ConfigDB(pack=pack_name, values=values) Config.add_or_update(config_db) expected_msg = ( 'Failed to render dynamic configuration value for key ' '"level0_object.level1_key" with value "{{st2kvXX.invalid}}"' ' for pack ".*?" config: \'st2kvXX\' is undefined') self.assertRaisesRegexp(Exception, expected_msg, loader.get_config) config_db.delete() # Renders fails on second level item values = { 'level0_object': { 'level1_object': { 'level2_key': '{{st2kvXX.invalid}}' } } } config_db = ConfigDB(pack=pack_name, values=values) Config.add_or_update(config_db) expected_msg = ( 'Failed to render dynamic configuration value for key ' '"level0_object.level1_object.level2_key" with value "{{st2kvXX.invalid}}"' ' for pack ".*?" config: \'st2kvXX\' is undefined') self.assertRaisesRegexp(Exception, expected_msg, loader.get_config) config_db.delete()
def test_get_config_dynamic_config_item_render_fails_user_friendly_exception_is_thrown( self, ): pack_name = "dummy_pack_schema_with_nested_object_5" loader = ContentPackConfigLoader(pack_name=pack_name) # Render fails on top-level item values = {"level0_key": "{{st2kvXX.invalid}}"} config_db = ConfigDB(pack=pack_name, values=values) config_db = Config.add_or_update(config_db) expected_msg = ( 'Failed to render dynamic configuration value for key "level0_key" with ' 'value "{{st2kvXX.invalid}}" for pack ".*?" config: ' "<class 'jinja2.exceptions.UndefinedError'> " "'st2kvXX' is undefined") self.assertRaisesRegexp(RuntimeError, expected_msg, loader.get_config) config_db.delete() # Renders fails on fist level item values = {"level0_object": {"level1_key": "{{st2kvXX.invalid}}"}} config_db = ConfigDB(pack=pack_name, values=values) Config.add_or_update(config_db) expected_msg = ( "Failed to render dynamic configuration value for key " '"level0_object.level1_key" with value "{{st2kvXX.invalid}}"' " for pack \".*?\" config: <class 'jinja2.exceptions.UndefinedError'>" " 'st2kvXX' is undefined") self.assertRaisesRegexp(RuntimeError, expected_msg, loader.get_config) config_db.delete() # Renders fails on second level item values = { "level0_object": { "level1_object": { "level2_key": "{{st2kvXX.invalid}}" } } } config_db = ConfigDB(pack=pack_name, values=values) Config.add_or_update(config_db) expected_msg = ( "Failed to render dynamic configuration value for key " '"level0_object.level1_object.level2_key" with value "{{st2kvXX.invalid}}"' " for pack \".*?\" config: <class 'jinja2.exceptions.UndefinedError'>" " 'st2kvXX' is undefined") self.assertRaisesRegexp(RuntimeError, expected_msg, loader.get_config) config_db.delete() # Renders fails on list item values = {"level0_object": ["abc", "{{st2kvXX.invalid}}"]} config_db = ConfigDB(pack=pack_name, values=values) Config.add_or_update(config_db) expected_msg = ( "Failed to render dynamic configuration value for key " '"level0_object.1" with value "{{st2kvXX.invalid}}"' " for pack \".*?\" config: <class 'jinja2.exceptions.UndefinedError'>" " 'st2kvXX' is undefined") self.assertRaisesRegexp(RuntimeError, expected_msg, loader.get_config) config_db.delete() # Renders fails on nested object in list item values = {"level0_object": [{"level2_key": "{{st2kvXX.invalid}}"}]} config_db = ConfigDB(pack=pack_name, values=values) Config.add_or_update(config_db) expected_msg = ( "Failed to render dynamic configuration value for key " '"level0_object.0.level2_key" with value "{{st2kvXX.invalid}}"' " for pack \".*?\" config: <class 'jinja2.exceptions.UndefinedError'>" " 'st2kvXX' is undefined") self.assertRaisesRegexp(RuntimeError, expected_msg, loader.get_config) config_db.delete() # Renders fails on invalid syntax values = {"level0_key": "{{ this is some invalid Jinja }}"} config_db = ConfigDB(pack=pack_name, values=values) Config.add_or_update(config_db) expected_msg = ( "Failed to render dynamic configuration value for key " '"level0_key" with value "{{ this is some invalid Jinja }}"' " for pack \".*?\" config: <class 'jinja2.exceptions.TemplateSyntaxError'>" " expected token 'end of print statement', got 'Jinja'") self.assertRaisesRegexp(RuntimeError, expected_msg, loader.get_config) config_db.delete()