예제 #1
0
    def test_register_configs_for_all_packs(self):
        # Verify DB is empty
        pack_dbs = Pack.get_all()
        config_dbs = Config.get_all()

        self.assertEqual(len(pack_dbs), 0)
        self.assertEqual(len(config_dbs), 0)

        registrar = ConfigsRegistrar(use_pack_cache=False)
        registrar._pack_loader.get_packs = mock.Mock()
        registrar._pack_loader.get_packs.return_value = {"dummy_pack_1": PACK_PATH}
        packs_base_paths = content_utils.get_packs_base_paths()
        registrar.register_configs_for_all_packs(base_dirs=packs_base_paths)

        # Verify pack and schema have been registered
        pack_dbs = Pack.get_all()
        config_dbs = Config.get_all()

        self.assertEqual(len(pack_dbs), 1)
        self.assertEqual(len(config_dbs), 1)

        config_db = config_dbs[0]
        self.assertEqual(config_db.values["api_key"], "{{user.api_key}}")
        self.assertEqual(config_db.values["api_secret"], "{{user.api_secret}}")
        self.assertEqual(config_db.values["region"], "us-west-1")
예제 #2
0
    def _register_config_for_pack(self, pack, config_path):
        content = {}
        values = self._meta_loader.load(config_path)

        content['pack'] = pack
        content['values'] = values

        config_api = ConfigAPI(**content)
        config_api.validate(validate_against_schema=self._validate_configs)
        config_db = ConfigAPI.to_model(config_api)

        try:
            config_db.id = Config.get_by_pack(config_api.pack).id
        except StackStormDBObjectNotFoundError:
            LOG.debug('Config for pack "%s" not found. Creating new entry.', pack)

        try:
            config_db = Config.add_or_update(config_db)
            extra = {'config_db': config_db}
            LOG.audit('Config for pack "%s" is updated.', config_db.pack, extra=extra)
        except Exception:
            LOG.exception('Failed to config for pack %s.', pack)
            raise

        return config_db
예제 #3
0
    def test_get_config_default_value_from_config_schema_is_used(self):
        # No value is provided for "region" in the config, default value from config schema
        # should be used
        loader = ContentPackConfigLoader(pack_name='dummy_pack_5')
        config = loader.get_config()
        self.assertEqual(config['region'], 'default-region-value')

        # Here a default value is specified in schema but an explicit value is provided in the
        # config
        loader = ContentPackConfigLoader(pack_name='dummy_pack_1')
        config = loader.get_config()
        self.assertEqual(config['region'], 'us-west-1')

        # Config item attribute has required: false
        # Value is provided in the config - it should be used as provided
        pack_name = 'dummy_pack_5'

        loader = ContentPackConfigLoader(pack_name=pack_name)
        config = loader.get_config()
        self.assertEqual(config['non_required_with_default_value'], 'config value')

        config_db = Config.get_by_pack(pack_name)
        del config_db['values']['non_required_with_default_value']
        Config.add_or_update(config_db)

        # No value in the config - default value should be used
        config_db = Config.get_by_pack(pack_name)
        config_db.delete()

        # No config exists for that pack - default value should be used
        loader = ContentPackConfigLoader(pack_name=pack_name)
        config = loader.get_config()
        self.assertEqual(config['non_required_with_default_value'], 'some default value')
예제 #4
0
    def test_register_configs_for_all_packs(self):
        # Verify DB is empty
        pack_dbs = Pack.get_all()
        config_dbs = Config.get_all()

        self.assertEqual(len(pack_dbs), 0)
        self.assertEqual(len(config_dbs), 0)

        registrar = ConfigsRegistrar(use_pack_cache=False)
        registrar._pack_loader.get_packs = mock.Mock()
        registrar._pack_loader.get_packs.return_value = {'dummy_pack_1': PACK_1_PATH}
        packs_base_paths = content_utils.get_packs_base_paths()
        registrar.register_from_packs(base_dirs=packs_base_paths)

        # Verify pack and schema have been registered
        pack_dbs = Pack.get_all()
        config_dbs = Config.get_all()

        self.assertEqual(len(pack_dbs), 1)
        self.assertEqual(len(config_dbs), 1)

        config_db = config_dbs[0]
        self.assertEqual(config_db.values['api_key'], '{{st2kv.user.api_key}}')
        self.assertEqual(config_db.values['api_secret'], SUPER_SECRET_PARAMETER)
        self.assertEqual(config_db.values['region'], 'us-west-1')
예제 #5
0
    def test_run(self):
        pack = 'dummy_pack_1'
        # Verify all the resources are there

        pack_dbs = Pack.query(ref=pack)
        action_dbs = Action.query(pack=pack)
        alias_dbs = ActionAlias.query(pack=pack)
        rule_dbs = Rule.query(pack=pack)
        sensor_dbs = Sensor.query(pack=pack)
        trigger_type_dbs = TriggerType.query(pack=pack)
        policy_dbs = Policy.query(pack=pack)

        config_schema_dbs = ConfigSchema.query(pack=pack)
        config_dbs = Config.query(pack=pack)

        self.assertEqual(len(pack_dbs), 1)
        self.assertEqual(len(action_dbs), 1)
        self.assertEqual(len(alias_dbs), 2)
        self.assertEqual(len(rule_dbs), 1)
        self.assertEqual(len(sensor_dbs), 3)
        self.assertEqual(len(trigger_type_dbs), 4)
        self.assertEqual(len(policy_dbs), 2)

        self.assertEqual(len(config_schema_dbs), 1)
        self.assertEqual(len(config_dbs), 1)

        # Run action
        action = self.get_action_instance()
        action.run(packs=[pack])

        # Make sure all resources have been removed from the db
        pack_dbs = Pack.query(ref=pack)
        action_dbs = Action.query(pack=pack)
        alias_dbs = ActionAlias.query(pack=pack)
        rule_dbs = Rule.query(pack=pack)
        sensor_dbs = Sensor.query(pack=pack)
        trigger_type_dbs = TriggerType.query(pack=pack)
        policy_dbs = Policy.query(pack=pack)

        config_schema_dbs = ConfigSchema.query(pack=pack)
        config_dbs = Config.query(pack=pack)

        self.assertEqual(len(pack_dbs), 0)
        self.assertEqual(len(action_dbs), 0)
        self.assertEqual(len(alias_dbs), 0)
        self.assertEqual(len(rule_dbs), 0)
        self.assertEqual(len(sensor_dbs), 0)
        self.assertEqual(len(trigger_type_dbs), 0)
        self.assertEqual(len(policy_dbs), 0)

        self.assertEqual(len(config_schema_dbs), 0)
        self.assertEqual(len(config_dbs), 0)
예제 #6
0
    def test_default_values_from_schema_are_used_when_no_config_exists(self):
        pack_name = 'dummy_pack_5'
        config_db = Config.get_by_pack(pack_name)

        # Delete the existing config loaded in setUp
        config_db = Config.get_by_pack(pack_name)
        config_db.delete()

        # Verify config has been deleted from the database
        self.assertRaises(StackStormDBObjectNotFoundError, Config.get_by_pack, pack_name)

        loader = ContentPackConfigLoader(pack_name=pack_name)
        config = loader.get_config()
        self.assertEqual(config['region'], 'default-region-value')
예제 #7
0
    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()
예제 #8
0
파일: config_loader.py 프로젝트: Plexxi/st2
    def get_config(self):
        result = {}

        # 1. Retrieve values from pack local config.yaml file
        config = self._config_parser.get_config()

        if config:
            config = config.config or {}
            result.update(config)

        # 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, return early
            return result

        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
예제 #9
0
    def test_register_all_configs_with_config_schema_validation_validation_failure_1(self):
        # Verify DB is empty
        pack_dbs = Pack.get_all()
        config_dbs = Config.get_all()

        self.assertEqual(len(pack_dbs), 0)
        self.assertEqual(len(config_dbs), 0)

        registrar = ConfigsRegistrar(use_pack_cache=False, fail_on_failure=True,
                                     validate_configs=True)
        registrar._pack_loader.get_packs = mock.Mock()
        registrar._pack_loader.get_packs.return_value = {'dummy_pack_6': PACK_6_PATH}

        # Register ConfigSchema for pack
        registrar._register_pack_db = mock.Mock()
        registrar._register_pack(pack_name='dummy_pack_5', pack_dir=PACK_6_PATH)
        packs_base_paths = content_utils.get_packs_base_paths()

        if six.PY3:
            expected_msg = ('Failed validating attribute "regions" in config for pack '
                            '"dummy_pack_6" (.*?): 1000 is not of type \'array\'')
        else:
            expected_msg = ('Failed validating attribute "regions" in config for pack '
                            '"dummy_pack_6" (.*?): 1000 is not of type u\'array\'')

        self.assertRaisesRegexp(ValueError, expected_msg,
                                registrar.register_from_packs,
                                base_dirs=packs_base_paths)
예제 #10
0
    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()
예제 #11
0
    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
예제 #12
0
    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, {})
예제 #13
0
    def save_model(config_api):
        pack = config_api.pack
        config_db = ConfigAPI.to_model(config_api)

        try:
            config_db.id = Config.get_by_pack(pack).id
        except StackStormDBObjectNotFoundError:
            LOG.debug('Config for pack "%s" not found. Creating new entry.', pack)

        try:
            config_db = Config.add_or_update(config_db)
            extra = {'config_db': config_db}
            LOG.audit('Config for pack "%s" is updated.', config_db.pack, extra=extra)
        except Exception:
            LOG.exception('Failed to save config for pack %s.', pack)
            raise

        return config_db
예제 #14
0
    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()
예제 #15
0
    def test_register_all_configs_invalid_config_no_config_schema(self):
        # verify_ configs is on, but ConfigSchema for the pack doesn't exist so
        # validation should proceed normally

        # Verify DB is empty
        pack_dbs = Pack.get_all()
        config_dbs = Config.get_all()

        self.assertEqual(len(pack_dbs), 0)
        self.assertEqual(len(config_dbs), 0)

        registrar = ConfigsRegistrar(use_pack_cache=False, validate_configs=False)
        registrar._pack_loader.get_packs = mock.Mock()
        registrar._pack_loader.get_packs.return_value = {'dummy_pack_6': PACK_6_PATH}
        packs_base_paths = content_utils.get_packs_base_paths()
        registrar.register_from_packs(base_dirs=packs_base_paths)

        # Verify pack and schema have been registered
        pack_dbs = Pack.get_all()
        config_dbs = Config.get_all()

        self.assertEqual(len(pack_dbs), 1)
        self.assertEqual(len(config_dbs), 1)
예제 #16
0
    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()
예제 #17
0
    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()
예제 #18
0
    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()
예제 #19
0
    def setUp(self):
        super(UnloadActionTestCase, self).setUp()

        # Register mock pack
        # Verify DB is empty
        pack_dbs = Pack.get_all()
        config_schema_dbs = ConfigSchema.get_all()
        config_dbs = Config.get_all()

        self.assertEqual(len(pack_dbs), 0)
        self.assertEqual(len(config_schema_dbs), 0)
        self.assertEqual(len(config_dbs), 0)

        # Register the pack with all the content
        # TODO: Don't use pack cache
        cfg.CONF.set_override(name='all', override=True, group='register')
        cfg.CONF.set_override(name='pack', override=PACK_PATH_1, group='register')
        cfg.CONF.set_override(name='no_fail_on_failure', override=True, group='register')
        register_content()
예제 #20
0
    def setUp(self):
        super(UnloadActionTestCase, self).setUp()

        # Register mock pack
        # Verify DB is empty
        pack_dbs = Pack.get_all()
        config_schema_dbs = ConfigSchema.get_all()
        config_dbs = Config.get_all()

        self.assertEqual(len(pack_dbs), 0)
        self.assertEqual(len(config_schema_dbs), 0)
        self.assertEqual(len(config_dbs), 0)

        # Register the pack with all the content
        # TODO: Don't use pack cache
        cfg.CONF.set_override(name='all', override=True, group='register')
        cfg.CONF.set_override(name='pack', override=PACK_PATH_1, group='register')
        cfg.CONF.set_override(name='no_fail_on_failure', override=True, group='register')
        register_content()
예제 #21
0
    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)
예제 #22
0
    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)
예제 #23
0
    def test_register_all_configs_with_config_schema_validation_validation_failure_2(
        self, ):
        # Verify DB is empty
        pack_dbs = Pack.get_all()
        config_dbs = Config.get_all()

        self.assertEqual(len(pack_dbs), 0)
        self.assertEqual(len(config_dbs), 0)

        registrar = ConfigsRegistrar(use_pack_cache=False,
                                     fail_on_failure=True,
                                     validate_configs=True)
        registrar._pack_loader.get_packs = mock.Mock()
        registrar._pack_loader.get_packs.return_value = {
            "dummy_pack_19": PACK_19_PATH
        }

        # Register ConfigSchema for pack
        registrar._register_pack_db = mock.Mock()
        registrar._register_pack(pack_name="dummy_pack_19",
                                 pack_dir=PACK_19_PATH)
        packs_base_paths = content_utils.get_packs_base_paths()

        if six.PY3:
            expected_msg = (
                'Failed validating attribute "instances.0.alias" in config for pack '
                "\"dummy_pack_19\" (.*?): {'not': 'string'} is not of type "
                "'string'")
        else:
            expected_msg = (
                'Failed validating attribute "instances.0.alias" in config for pack '
                "\"dummy_pack_19\" (.*?): {'not': 'string'} is not of type "
                "u'string'")

        self.assertRaisesRegexp(
            ValueError,
            expected_msg,
            registrar.register_from_packs,
            base_dirs=packs_base_paths,
        )
예제 #24
0
    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)
예제 #25
0
    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()
예제 #26
0
    def test_register_all_configs_with_config_schema_validation_validation_failure_4(
        self, ):
        # This test checks for default values containing "decrypt_kv" jinja filter for
        # keys which have "secret: True" set.

        # Verify DB is empty
        pack_dbs = Pack.get_all()
        config_dbs = Config.get_all()

        self.assertEqual(len(pack_dbs), 0)
        self.assertEqual(len(config_dbs), 0)

        registrar = ConfigsRegistrar(use_pack_cache=False,
                                     fail_on_failure=True,
                                     validate_configs=True)
        registrar._pack_loader.get_packs = mock.Mock()
        registrar._pack_loader.get_packs.return_value = {
            "dummy_pack_22": PACK_22_PATH
        }

        # Register ConfigSchema for pack
        registrar._register_pack_db = mock.Mock()
        registrar._register_pack(pack_name="dummy_pack_22",
                                 pack_dir=PACK_22_PATH)
        packs_base_paths = content_utils.get_packs_base_paths()

        expected_msg = (
            'Values specified as "secret: True" in config schema are automatically '
            'decrypted by default. Use of "decrypt_kv" jinja filter is not allowed '
            "for such values. Please check the specified values in the config or "
            "the default values in the schema.")

        self.assertRaisesRegexp(
            ValueError,
            expected_msg,
            registrar.register_from_packs,
            base_dirs=packs_base_paths,
        )
예제 #27
0
    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()
예제 #28
0
    def test_register_all_configs_with_config_schema_validation_validation_failure_1(
            self):
        # Verify DB is empty
        pack_dbs = Pack.get_all()
        config_dbs = Config.get_all()

        self.assertEqual(len(pack_dbs), 0)
        self.assertEqual(len(config_dbs), 0)

        registrar = ConfigsRegistrar(use_pack_cache=False,
                                     fail_on_failure=True,
                                     validate_configs=True)
        registrar._pack_loader.get_packs = mock.Mock()
        registrar._pack_loader.get_packs.return_value = {
            'dummy_pack_6': PACK_6_PATH
        }

        # Register ConfigSchema for pack
        registrar._register_pack_db = mock.Mock()
        registrar._register_pack(pack_name='dummy_pack_5',
                                 pack_dir=PACK_6_PATH)
        packs_base_paths = content_utils.get_packs_base_paths()

        if six.PY3:
            expected_msg = (
                'Failed validating attribute "regions" in config for pack '
                '"dummy_pack_6" (.*?): 1000 is not of type \'array\'')
        else:
            expected_msg = (
                'Failed validating attribute "regions" in config for pack '
                '"dummy_pack_6" (.*?): 1000 is not of type u\'array\'')

        self.assertRaisesRegexp(ValueError,
                                expected_msg,
                                registrar.register_from_packs,
                                base_dirs=packs_base_paths)
예제 #29
0
    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()
예제 #30
0
    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()
예제 #31
0
    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()
예제 #32
0
    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()