diff --git a/Dockerfile b/Dockerfile index 5c8bdb45..6be3e5b7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,7 +7,7 @@ FROM ${img_user}/${img_repo}:${img_tag} COPY . /usr/local/src_dragonfly WORKDIR /usr/local/src_dragonfly -RUN pip install docker pymodbus +RUN pip install docker pymodbus Flask RUN pip install . WORKDIR / diff --git a/dragonfly/__init__.py b/dragonfly/__init__.py index eb89dbbe..0916a2e3 100644 --- a/dragonfly/__init__.py +++ b/dragonfly/__init__.py @@ -1,19 +1,4 @@ import logging logger = logging.getLogger(__name__) -def __get_version(): - import scarab - import dragonfly - import pkg_resources - #TODO: this all needs to be populated from setup.py and gita - version = scarab.VersionSemantic() - logger.info('version should be: {}'.format(pkg_resources.get_distribution('dragonfly').version)) - version.parse(pkg_resources.get_distribution('dragonfly').version) - version.package = 'project8/dragonfly' - version.commit = 'na' - dragonfly.core.add_version('dragonfly', version) - return version -version = __get_version() -__version__ = version.version - from .watchdog import * diff --git a/dragonfly/alarm_server.py b/dragonfly/alarm_server.py new file mode 100644 index 00000000..27fc02c6 --- /dev/null +++ b/dragonfly/alarm_server.py @@ -0,0 +1,81 @@ +from flask import Flask, redirect, request, render_template, url_for +import os +import yaml + +CONFIG_FILE = "/root/AlarmSystem.yaml" + +def load_data(): + if not os.path.exists(CONFIG_FILE): + return [] + with open(CONFIG_FILE, "r") as open_file: + config = yaml.safe_load( open_file ) + return config["check_endpoints"] + +def save_data(data): + with open(CONFIG_FILE, "r") as open_file: + config = yaml.safe_load( open_file ) + config["check_endpoints"] = data + print(config, flush=True) + with open(CONFIG_FILE, "w") as open_file: + yaml.safe_dump(config, open_file) + +app = Flask(__name__) + +@app.route('/') +def index(): + data = load_data() + + return render_template("index.html", data=data) + +@app.route('/add', methods=["POST"]) +def add_row(): + data = load_data() + + + new_row = { + "enable": request.form.get("enable") == "on", + "endpoint": request.form.get("endpoint"), + "method": request.form.get("comparison"), + "reference": request.form.get("reference"), + "message": request.form.get("message"), + } + try: + new_row["reference"] = float(new_row["reference"]) + except: + pass + + data.append(new_row) + + save_data(data) + + return redirect(url_for("index")) + +@app.route("/delete/", methods=["POST"]) +def delete_row(index): + data = load_data() + + if 0 <= index < len(data): + data.pop(index) + + save_data(data) + + return redirect(url_for("index")) + +@app.route("/update", methods=["POST"]) +def update(): + data = load_data() + + for i, row in enumerate(data): + row["enable"] = request.form.get(f"enable_{i}") == "on" + row["endpoint"] = request.form.get(f"endpoint_{i}") + row["comparison"] = request.form.get(f"comparison_{i}") + row["reference"] = request.form.get(f"reference_{i}") + try: + row["reference"] = float(row["reference"]) + except: + pass + row["message"] = request.form.get(f"message_{i}") + + save_data(data) + + return redirect(url_for("index")) diff --git a/dragonfly/templates/index.html b/dragonfly/templates/index.html new file mode 100644 index 00000000..28799027 --- /dev/null +++ b/dragonfly/templates/index.html @@ -0,0 +1,97 @@ + + + + YAML Monitor Table + + + + +

Alarm System Configuration Table

+ +
+ + + + + + + + + + + {% for row in data %} + + + + + + + + + {% endfor %} +
EnableEndpointComparisonReferenceMessageAction
+ + + + + + + + + + + + + +
+ +
+ + + +
+ +

Add New Row

+ +
+ + + + + + + + + + + + + + + + + +
EnableEndpointComparisonReferenceMessageAction
+
+

Notes:

+ + + diff --git a/dragonfly/watchdog.py b/dragonfly/watchdog.py index 86091db4..efb819b5 100755 --- a/dragonfly/watchdog.py +++ b/dragonfly/watchdog.py @@ -17,6 +17,7 @@ class WatchDog(object): def __init__(self, config_path): self.config_path = config_path self.load_configuration() + self.load_slack_hook() self.setup_docker_client() self.setup_dripline_connection() signal.signal(signal.SIGINT, self.exit_gracefully) @@ -27,11 +28,21 @@ def load_configuration(self): with open(Path(args.config), "r") as open_file: self.config = yaml.safe_load( open_file.read() ) - if not "slack_hook" in self.config.keys(): - self.config["slack_hook"] = None + if not "slack_hook_file" in self.config.keys(): + self.config["slack_hook_file"] = None print("Configuration is:", flush=True) print(self.config, flush=True) + + def load_slack_hook(self): + if self.config["slack_hook_file"] is not None: + with open(Path(self.config["slack_hook_file"]), "r") as open_file: + self.hook_config = yaml.safe_load( open_file.read() ) + + if not "slack_hook" in self.hook_config.keys(): + self.hook_config["slack_hook"] = None + else: + self.hook_config = {"slack_hook": None} def setup_docker_client(self): self.client = docker.from_env() @@ -45,11 +56,11 @@ def exit_gracefully(self, signum, frame): self.send_slack_message("Stopping, received signal: %d"%signum) def send_slack_message(self, message): - if self.config["slack_hook"] is None: + if self.hook_config["slack_hook"] is None: print("Slack hook not configured. No message will be send!") return post = {"text": "{0}".format(message)} - response = requests.post(self.config["slack_hook"], headers={'Content-Type': 'application/json'}, data=json.dumps(post)) + response = requests.post(self.hook_config["slack_hook"], headers={'Content-Type': 'application/json'}, data=json.dumps(post)) if response.status_code != 200: print(f'Request to slack returned an error {response.status_code}, the response is:\n{response.text}') @@ -73,20 +84,24 @@ def compare(self, value, reference, method): raise ValueError(f"Comparison method {method} is not defined. You can use one of ['not_equal', 'equal', 'lower', 'greater'].") def run(self): - while not self.kill_now: + self.load_configuration() + if self.config["check_endpoints"] is not None: for entry in self.config["check_endpoints"]: if self.kill_now: break + if "enable" in entry.keys() and entry["enable"]==False: continue try: - value = self.get_endpoint(entry["endpoint"]) + if ":value_cal" in entry["endpoint"]: + value = self.get_endpoint(entry["endpoint"].replace(":value_cal", ""), calibrated=True) + else: + value = self.get_endpoint(entry["endpoint"]) print(entry["endpoint"], value, flush=True) if self.compare(value, entry["reference"], entry["method"]): self.send_slack_message(entry["message"].format(**locals())) except Exception as e: self.send_slack_message("Could not get endpoint %s. Got error %s."%(entry["endpoint"], str(e) )) - for container in self.client.containers.list(all=True): if self.kill_now: break if any([container.name.startswith(black) for black in self.config["blacklist_containers"]]):