Пример #1
0
    def __init__(self,
                 monitor_id,
                 wait_time,
                 run_interval=False,
                 custom_logger=None):
        """
        Super constructor invoked from implementing sub-classes of this class
        providing interfaces start, track_success and track_error
        """
        # set meta flags
        self.active = False
        self.finished = False
        self.started = False

        # store parameters
        self.monitor_id = monitor_id
        self.wait_time = wait_time
        self.run_interval = run_interval

        # init logger
        if custom_logger is not None:
            self.logger = custom_logger
        else:
            self.logger = Logger(self.__class__.__name__)
Пример #2
0
from flask import Flask
from pbu import Logger
from config import load_config, get_log_folder, is_debug, get_port
import api.static_api as static_api
# API endpoint modules
from frappyflaskauth import register_endpoints as register_user_endpoints, check_login_state
from frappyflaskdataset import register_endpoints as register_data_endpoints
from frappyflaskcontent import register_endpoints as register_content_endpoints
# storage modules
from frappymongouser import UserStore, UserTokenStore
from frappymongodataset import DataStore
from frappymongocontent import ContentStore

if __name__ == "__main__":
    logger = Logger("MAIN", log_folder=get_log_folder())
    logger.info("==========================================")
    logger.info("           Starting application")
    logger.info("==========================================")

    # load config from .env file
    config = load_config()

    # ---- database and stores ----

    # fetch mongo config
    from config import get_mongodb_config
    mongo_url, mongo_db = get_mongodb_config()

    # initialise stores
    stores = {
        "user":
Пример #3
0
from flask import Flask
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand
from config import load_config, get_log_folder, get_mysql_config
from pbu import Logger
from storage.shared import db
from api.cli_commands import ComputeMetricsCommand

# load config from .env file
config = load_config()

# ---- database and stores ----

host, db_name, username, password = get_mysql_config()
uri = 'mysql://{0}:{1}@{2}/{3}'.format(username, password, host, db_name)

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = uri
db.init_app(app)
migrate = Migrate()
migrate.init_app(app, db)

manager = Manager(app)
manager.add_command('db', MigrateCommand)
manager.add_command('metrics', ComputeMetricsCommand)

if __name__ == '__main__':

    logger = Logger("DB", log_folder=get_log_folder())
    manager.run()
Пример #4
0
def check_login_state(permission=None, allow_api_key=False):
    """
    Main function to be called from API endpoints to check if a user is logged in.
    This will extract the authorization token from the header, check it against the currently stored active sessions and
    handle any AuthenticationErrors that might occur by returning a 401 to the callee. If the request is authenticated,
    the associated user will be returned.
    :return: the authenticated user, if authentication was successful.
    :raise: AuthenticationError in case the login failed for whatever reason
    """
    try:
        token = extract_token()
        if token is not None and token.startswith("Token "):
            # API key auth
            if allow_api_key is False:
                logger = Logger("user_api")
                logger.error(
                    "API key access not allowed for the current endpoint.")
                abort(403)  # not enabled for this endpoint
            # check api key
            if token[6:] not in api_key_cache:
                raise AuthenticationError(
                    "Invalid authorization header")  # api key not registered
            user = api_key_cache[token[6:]]
        else:
            # fetch user the regular way
            user = perform_login_check(token)
        if permission is None or permission in user.permissions:
            return user
    except AuthenticationError as ae:
        logger = Logger("user_api")
        logger.exception(ae)
        abort(401)
        raise ae

    logger = Logger("user_api")
    logger.error("User {} doesn't have required privileges: {}".format(
        user.username, permission))
    abort(403)
    raise AuthenticationError("Insufficient privileges")
Пример #5
0
class BasicMonitor(ABC):
    """
    Abstract base class (ABC) for all monitors containing base functionality for lifecycle and meta information.
    """
    def __init__(self,
                 monitor_id,
                 wait_time,
                 run_interval=False,
                 custom_logger=None):
        """
        Super constructor invoked from implementing sub-classes of this class
        providing interfaces start, track_success and track_error
        """
        # set meta flags
        self.active = False
        self.finished = False
        self.started = False

        # store parameters
        self.monitor_id = monitor_id
        self.wait_time = wait_time
        self.run_interval = run_interval

        # init logger
        if custom_logger is not None:
            self.logger = custom_logger
        else:
            self.logger = Logger(self.__class__.__name__)

    @abstractmethod
    def running(self):
        """
        Abstract main method of each inverter. `running` needs to be implemented by every non-abstract sub-class of this
        class.
        """
        pass

    def to_json(self):
        """
        Creates a dictionary with some base meta attributes about this monitor. Sub classes should invoke this method
        when serialising to json and then add any additional parameters as necessary to the result of this methods
        invoke.
        :return: a dictionary with basic information, such as site_id and overall active status
        """
        return {
            "active": self.active,
            "started": self.started,
            "finished": self.finished,
            "id": self.monitor_id,
            "waitTime": self.wait_time,
            "runInterval": self.run_interval,
        }

    def wait(self, exec_duration=0):
        """
        Executes a wait for a certain amount of time depending on the configuration of the monitor. Additionally, it
        takes into account the execution time of the last loop, if run_interval is True.
        :param exec_duration: the execution time of the last execution loop (only relevant for run_interval=True)
        """
        if self.run_interval:
            time.sleep(max(1, self.wait_time - exec_duration))
        else:
            time.sleep(self.wait_time)

    def wait_till_midnight(self):
        """
        This method will just wait until the next midnight event. If the monitor is started at 6:30pm, this method will
        simply wait for 5h and 30min.
        """
        # localise current date
        local_date = datetime.now()
        # extract time
        local_time = local_date.time()
        # compute wait time until midnight
        wait_time = ((23 - local_time.hour) * 60 * 60) + (
            (59 - local_time.minute) * 60) + (60 - local_time.second)
        # wait till midnight
        self.logger.info(
            "Waiting {} seconds for monitor {} until midnight".format(
                wait_time, self.monitor_id))
        time.sleep(wait_time)

    def start(self):
        """
        Starts the monitor, updating a flag and triggering `running()`
        """
        if self.active:
            # already started
            return
        # start monitor
        self.active = True
        try:
            if self.started:
                # only restart if the previous thread has finished or after error
                self.logger.info("Restarting monitor for {}".format(
                    self.monitor_id))
                self.running()
            else:
                # first time start
                self.started = True
                self.logger.info("Starting monitor for {}".format(
                    self.monitor_id))
                self.running()
            self.finished = True
        except BaseException as ex:
            self.logger.exception(
                "Exception during monitor execution for monitor {}: {}".format(
                    self.monitor_id, str(ex)))
            # is currently not active due to error
            self.active = False
            # wait for one execution loop to avoid error spamming
            time.sleep(self.wait_time)
            self.start()

    def stop(self):
        """
        Sets the active flag to false, which will terminate the `running()` loop.
        """
        # set a flag, let the monitor handle this
        self.logger.info("Stopping {} for {}".format(self.__class__.__name__,
                                                     self.monitor_id))
        self.active = False
Пример #6
0
from flask import Flask, request, abort, jsonify
from pbu import Logger, JSON
from config import get_log_folder, get_port, get_auth_token, get_enabled_log_levels
from logging import LogRecord


def extract_auth_token():
    key = "Authorization"
    if key in request.headers:
        return request.headers[key]
    return None


if __name__ == '__main__':
    # initialise logger
    logger = Logger("MAIN", log_folder=get_log_folder(), enable_logger_name=True,
                    enabled_log_levels=get_enabled_log_levels())
    logger.info("==========================================")
    logger.info("           Starting Log Server")
    logger.info("==========================================")

    # create flask app
    app = Flask(__name__)

    # load from config, if required
    auth_token = get_auth_token()

    # declare API handler for incoming log messages
    @app.route("/api/log", methods=["POST"])
    def log_message():
        if auth_token is not None and auth_token != extract_auth_token():
            logger.warn("Incoming request with invalid authentication")