Source code for ghast.server

# -*- coding: utf-8 -*-

"""Flask server definition"""

from logging import getLogger
import subprocess

from flask import Flask, request, Blueprint, url_for
from flask_restplus import Api, Resource, fields

__log__ = getLogger(__name__)

APP = Flask(__name__)

__api_version__ = (0, 0, 0)

API_BLUEPRINT = Blueprint('ghast api', __name__)

# to be set within __main__.py
ALERT_SCRIPT_PATH = None
# to be set within __main__.py
API_HTTPS = False


[docs]class HTTPSApi(Api): @property def specs_url(self): """Monkey patch for HTTPS""" scheme = 'https' if API_HTTPS else 'http' return url_for(self.endpoint('specs'), _external=True, _scheme=scheme)
API = HTTPSApi( API_BLUEPRINT, version="{}.{}.{}".format(*__api_version__), title='Graylog HTTP Alert Script Triggerer (ghast) API', doc='/doc', description='API for the Graylog HTTP Alert Script Triggerer (ghast)', contact_email="nklapste@ualberta.ca", ) http_alert_script_triggered_model = API.model( 'http_alert_script_triggered', { 'script': fields.String( description='Path to the script that was triggered as a result ' 'of the given Graylog HTTP alert callback', ), 'script_return_code': fields.Integer( description="Return code of the script that was triggered as a " "result of the given Graylog HTTP alert callback", ) } )
[docs]@API.route("/") class AlertScriptTrigger(Resource):
[docs] @API.doc(False) def get(self): """Removing automatic/implicit support for GET requests""" API.abort(405)
[docs] @API.marshal_with(http_alert_script_triggered_model, code=200) def post(self): """Handle incoming Graylog HTTP alert callbacks and trigger the configured alert script On a POST request representing a Graylog HTTP alert callback trigger the configured alert script and return a JSON containing the path to the executed script and the return code of executing such script. """ # TODO: validate Graylog HTTP alert callback json json_data = request.json return_code = None if ALERT_SCRIPT_PATH is not None: return_code = subprocess.call(ALERT_SCRIPT_PATH) return { "script": ALERT_SCRIPT_PATH, "script_return_code": return_code }, 200
[docs]@APP.after_request def after_request(response): """log details on the request and its served response""" __log__.info('%s - "%s %s %s" %s -', request.remote_addr, request.method, request.full_path, request.environ.get('SERVER_PROTOCOL'), response.status_code) return response