Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rules loader #2030

Merged
merged 11 commits into from
Dec 17, 2018
Merged

Rules loader #2030

merged 11 commits into from
Dec 17, 2018

Conversation

pdscopes
Copy link
Contributor

This is updated version of #1802 (removing the merge conflicts).

This PR creates a means to do just that. It uses a similar methodology as Enhancements and Alerters in that there is a base class RulesLoader which is specified in the config.yaml under the rules_loader property. You can use the format module.file.ClassName to use your own loader. The default is called FileRulesLoader and this behaves exactly like the current way. If you don't make a change you will see no difference in the way that EA works.

RulesLoaders are subclasses of RulesLoader, found in elastalert/loaders.py. They are used to
gather rules for a particular source. Your RulesLoader needs to implement three member functions, and will look something like this:

class AwesomeNewRulesLoader(RulesLoader):
    def get_names(self, conf, use_rule=None):
        ...
    def get_hashes(self, conf, use_rule=None):
        ...
    def get_yaml(self, rule):
        ...

You can import loaders by specifying the type as module.file.RulesLoaderName, where module is the name of a python module, and file is the name of the python file containing a RulesLoader subclass named RulesLoaderName.

As an example loader, let's retrieve rules from a database rather than from the local file system. First, create a
modules folder for the loader in the ElastAlert directory.

    $ mkdir elastalert_modules
    $ cd elastalert_modules
    $ touch __init__.py

Now, in a file named mongo_loader.py, add

from pymongo import MongoClient
from elastalert.loaders import RulesLoader

class MongoRulesLoader(RulesLoader):
    def __init__(self, conf):
        super(MongoRulesLoader, self).__init__(conf)
        self.client = MongoClient(conf['mongo_url'])
        self.db     = client[conf['mongo_db']]

    def get_names(self, conf, use_rule=None):
        if use_rule:
            return [use_rule]

        rules = []
        self.cache = {}
        for rule in self.db.rules.find():
            self.cache[rule.name] = rule.yaml
            rules.append(rule.yaml)

        return rules


    def get_hashes(self, conf, use_rule=None):
        if use_rule:
            return [use_rule]

        hashes = {}
        self.cache = {}
        for rule in self.db.rules.find():
            self.cache[rule.name] = rule.yaml
            hashes[rule.name] = rule.hash

        return hashes

    def get_yaml(self, rule):
        if rule in self.cache:
            return self.cache[rule]

        self.cache[rule] = self.db.rules.find_one({'name': rule}).yaml
        return self.cache[rule]

Finally, you need to specify in your ElastAlert configuration file that MongoRulesLoader should be used instead of the
default FileRulesLoader, so in your elastalert.conf file:

    rules_loader: "elastalert_modules.mongo_loader.MongoRulesLoader"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants