コード例 #1
0
    - 200: The configuration as JSON is returned

The Status Get Node Configuration provides the ability to see the
configuration of the current Node. After the configuration is loaded
(which is one of the first things that the application does) it is in
dictionary form and is easily serializable to JSON and returned.
"""
from flask import make_response, jsonify
from flask_restplus import Resource

from redirectory.libs_int.metrics import REQUESTS_DURATION_SECONDS
from redirectory.libs_int.config import Configuration
from redirectory.libs_int.service import NamespaceManager

# Metrics
STATUS_CONFIG_REQUEST_DURATION_SECONDS = REQUESTS_DURATION_SECONDS.labels("management")

# Api Namespace
api = NamespaceManager().get_namespace("status")


@api.route("/get_node_configuration")
class ServiceGetConfiguration(Resource):

    @api.doc(description="Get the configuration of the service")
    @STATUS_CONFIG_REQUEST_DURATION_SECONDS.time()
    def get(self):
        config = Configuration().values

        return make_response(jsonify({
            "configuration": config
コード例 #2
0
ファイル: get_page.py プロジェクト: kumina/k8s-redirectory
The endpoint also accepts filters (optional) which will be applied and the result
of the filtered query will be paginated after that.
If no items are found with the specified filters then an api_error with error code 404
will be returned.
"""
from time import time
from flask import make_response, jsonify, request
from flask_restplus import Resource, fields

from redirectory.libs_int.metrics import REQUESTS_DURATION_SECONDS, metric_update_rules_total
from redirectory.models import RedirectRule, DomainRule, PathRule, DestinationRule
from redirectory.libs_int.database import DatabaseManager, db_encode_model, paginate, Page, db_sanitize_like_query
from redirectory.libs_int.service import NamespaceManager, api_error

# Metrics
RULES_GET_PAGE_REQUEST_DURATION_SECONDS = REQUESTS_DURATION_SECONDS.labels(
    "management")

# Api Namespace
api = NamespaceManager().get_namespace("management")

# All possible filters to apply to the page selection
filter_args = api.model(
    "filter", {
        "redirect_rule_id":
        fields.Integer(required=False, default=None),
        "domain_rule_id":
        fields.Integer(required=False, default=None),
        "path_rule_id":
        fields.Integer(required=False, default=None),
        "destination_rule_id":
        fields.Integer(required=False, default=None),
コード例 #3
0
ファイル: ui.py プロジェクト: kumina/k8s-redirectory
are the UI itself. The path is the path to the file which the frontend requires.
If the path is None then the index.html will be served.
The UI static files are located in a folder specified in the Configuration of the node itself.
The endpoint serves files only from the specified folder.
If a file doesn't exists then a 404 is returned.
"""
import os
from flask import send_from_directory
from flask_restplus import Resource

from redirectory.libs_int.metrics import REQUESTS_DURATION_SECONDS
from redirectory.libs_int.config import Configuration
from redirectory.libs_int.service import api_error

# Metrics
UI_REQUEST_DURATION_SECONDS = REQUESTS_DURATION_SECONDS.labels("management")


class ManagementUI(Resource):
    @UI_REQUEST_DURATION_SECONDS.time()
    def get(self, path=None):
        if path is None:
            path = "index.html"

        ui_directory = Configuration().values.directories.ui
        does_file_exist = os.path.isfile(os.path.join(ui_directory, path))

        if does_file_exist:
            return send_from_directory(ui_directory, path)
        else:
            return api_error(message="Something went wrong!",
コード例 #4
0
Method: GET

RESPONSES:
    - 200: Service is up and running

A really simple endpoint that just returns a status OK.
Useful for Kubernetes to know if the service has started and it's
running. For more in depth check see the Status Readiness.
The endpoint returns the same no matter the Node Configuration.
"""
from flask import make_response, jsonify
from flask_restplus import Resource

from redirectory.libs_int.metrics import REQUESTS_DURATION_SECONDS
from redirectory.libs_int.service import NamespaceManager

# Metrics
STATUS_HEALTH_REQUEST_DURATION_SECONDS = REQUESTS_DURATION_SECONDS.labels(
    "management")

# Api Namespace
api = NamespaceManager().get_namespace("status")


@api.route("/health_check")
class ServiceHealth(Resource):
    @api.doc(description="Get the status of the service")
    @STATUS_HEALTH_REQUEST_DURATION_SECONDS.time()
    def get(self):
        return make_response(jsonify({"status": "ok"}))
コード例 #5
0
ファイル: list.py プロジェクト: kumina/k8s-redirectory
RESPONSES:
    - 200: A list of all ambiguous request entries
    - 404: No ambiguous entries in the SQL database

The List Ambiguous endpoint provides the ability to list all
currently stored ambiguous request entries in the SQL database.
"""
from flask import make_response, jsonify
from flask_restplus import Resource

from redirectory.libs_int.metrics import REQUESTS_DURATION_SECONDS
from redirectory.libs_int.database import DatabaseManager, list_ambiguous_requests
from redirectory.libs_int.service import NamespaceManager, api_error

AMBIGUOUS_LIST_REQUEST_DURATION_SECONDS = REQUESTS_DURATION_SECONDS.labels(
    "management")
api = NamespaceManager().get_namespace("management")


@api.route("/ambiguous/list")
class ManagementListAmbiguous(Resource):
    @api.doc(description="List all ambiguous request entries")
    @AMBIGUOUS_LIST_REQUEST_DURATION_SECONDS.time()
    def get(self):
        db_session = DatabaseManager().get_session()

        data = list_ambiguous_requests(db_session)

        DatabaseManager().return_session(db_session)
        if len(data) > 0:
            return make_response(
コード例 #6
0
Before sending an update worker request to the worker the endpoint checks if
the worker actually exists by making a health status request.
If the health status request fails then the worker is considered unreachable and a 400 is returned.
If the health status request succeeds then a second reload worker hs db request is send.
If the reload worker hs db requests returns 200 then the worker has started updating itself.
"""
from flask import make_response, jsonify, request
from flask_restplus import Resource, fields
from kubi_ecs_logger import Logger, Severity

from redirectory.libs_int.metrics import REQUESTS_DURATION_SECONDS
from redirectory.libs_int.sync import Synchronizer
from redirectory.libs_int.kubernetes import WorkerPod
from redirectory.libs_int.service import NamespaceManager, api_error

DATABASE_RELOAD_WORKER_REQUEST_DURATION_SECONDS = REQUESTS_DURATION_SECONDS.labels(
    "management")
api = NamespaceManager().get_namespace("management")

endpoint_args = api.model(
    "update_worker", {
        "name": fields.String(required=True, example="redirectory-worker"),
        "ip": fields.String(required=True, example="127.0.0.1"),
        "port": fields.Integer(required=True, example=8001),
    })


@api.route("/database/reload_worker")
class ManagementReloadWorkerHsDb(Resource):
    @api.expect(endpoint_args, validate=True)
    @api.doc(description=
             "With the help of kubernetes api update every worker with new db."
コード例 #7
0
from the database. It will not take effect for the Hyperscan database. That
must be recompiled. The endpoint takes one argument which is the id of the Redirect Rule.
If the rule is found it's delete() method will be executed. The delete is custom
and it will delete Domain Rules, Path Rules and Destination Rules if they are not
used by any other Redirect Rule. For more insights on the topic take a look at delete_redirect_rule() function.
If no Redirect Rule with the given id exists then a 404 will be returned.
"""
from flask import make_response, jsonify, request
from flask_restplus import Resource, fields

from redirectory.libs_int.metrics import REQUESTS_DURATION_SECONDS, metric_update_rules_total
from redirectory.libs_int.database import DatabaseManager, delete_redirect_rule
from redirectory.libs_int.service import NamespaceManager, api_error

# Metrics
RULES_DELETE_REQUEST_DURATION_SECONDS = REQUESTS_DURATION_SECONDS.labels("management")

# Api Namespace
api = NamespaceManager().get_namespace("management")

endpoint_args = api.model("del_rule", {
    "rule_id": fields.Integer(required=True, example=1, min=1)
})


@api.route("/rules/delete")
class ManagementDeleteRule(Resource):

    @api.expect(endpoint_args, validate=True)
    @api.doc(description="Delete an already existing rule from the database")
    @RULES_DELETE_REQUEST_DURATION_SECONDS.time()
コード例 #8
0
1. If duplicate Redirect Rules are encountered in the CSV file they will be ignored/skipped.
2. If there is a parsing error somewhere in the file then the whole import process fails
   and all of the so far added Redirect Rules to the DB are rolled back like nothing happened.
3. At the moment there is no way of telling if an import is finished.
"""
import threading
from flask import make_response, jsonify
from flask_restplus import Resource, reqparse
from werkzeug.datastructures import FileStorage

from redirectory.libs_int.metrics import REQUESTS_DURATION_SECONDS, metric_update_rules_total
from redirectory.libs_int.importers import CSVImporter
from redirectory.libs_int.service import NamespaceManager, api_error

# Metrics
RULES_BULK_IMPORT_REQUEST_DURATION_SECONDS = REQUESTS_DURATION_SECONDS.labels("management")

# Api Namespace
api = NamespaceManager().get_namespace("management")

file_upload_args = reqparse.RequestParser()
file_upload_args.add_argument("csv_file", type=FileStorage, location='files', required=True, help="CSV FILE")


@api.route("/rules/bulk_import")
class ManagementBulkImportRules(Resource):

    @api.expect(file_upload_args, validate=True)
    @api.doc(description="Adds a rule to the database from the given args in the post data")
    @RULES_BULK_IMPORT_REQUEST_DURATION_SECONDS.time()
    def post(self):
コード例 #9
0
RESPONSES:
    - 200: Returns information about the management pod
    - 400: Unable to get management pod. Not running in a cluster

This endpoint provides the management pod with the ability to get
information about itself. This is done with the use of the Kubernetes API.
"""
from flask import make_response, jsonify
from flask_restplus import Resource

from redirectory.libs_int.metrics import REQUESTS_DURATION_SECONDS
from redirectory.libs_int.kubernetes import K8sManager
from redirectory.libs_int.service import NamespaceManager, api_error

K8S_GET_MANAGEMENT_REQUEST_DURATION_SECONDS = REQUESTS_DURATION_SECONDS.labels(
    "management")
api = NamespaceManager().get_namespace("management")


@api.route("/kubernetes/get_management")
class ManagementKubernetesGetManagement(Resource):
    @api.doc(description="Get data about the management pod!")
    @K8S_GET_MANAGEMENT_REQUEST_DURATION_SECONDS.time()
    def get(self):
        try:
            management_pod = K8sManager().get_management_pod()
        except AssertionError as e:
            return api_error(message="Unable to get management pod",
                             errors=str(e),
                             status_code=400)
コード例 #10
0
    - 200: Returns the current Hyperscan DB version that the worker is using
    - 400: The worker has not Hyperscan DB loaded at the moment

The Get Hyperscan DB Version endpoint provides with the ability to retrieve
the current Hyperscan DB Version that the HsManager() has loaded and is using to run queries.
If the worker still has not Hyperscan DB loaded then a 400 is returned.
"""
from flask import make_response, jsonify
from flask_restplus import Resource

from redirectory.libs_int.metrics import REQUESTS_TOTAL, REQUESTS_DURATION_SECONDS
from redirectory.libs_int.hyperscan import HsManager
from redirectory.libs_int.service import NamespaceManager, api_error

# Metrics
WORKER_GET_HS_DB_VERSION_REQUEST_DURATION_SECONDS = REQUESTS_DURATION_SECONDS.labels(
    "worker")

# Api Namespace
api = NamespaceManager().get_namespace("worker")


@api.route("/get_hs_db_version")
class WorkerGetHsDbVersion(Resource):
    @api.doc(
        description=
        "Get the current hyperscan database version that the worker is using")
    @WORKER_GET_HS_DB_VERSION_REQUEST_DURATION_SECONDS.time()
    def get(self):
        hs_db_version = HsManager().database.db_version
        if hs_db_version:
            return make_response(jsonify({"hs_db_version": hs_db_version}))
コード例 #11
0
Files in zip:

1. sqlite database
2. hyperscan domain database
3. hyperscan rule database
"""
from flask import send_file
from flask_restplus import Resource
from kubi_ecs_logger import Logger, Severity

from redirectory.libs_int.metrics import REQUESTS_DURATION_SECONDS
from redirectory.libs_int.sync import Synchronizer
from redirectory.libs_int.service import NamespaceManager, api_error

# Metrics
SYNC_DOWNLOAD_REQUEST_DURATION_SECONDS = REQUESTS_DURATION_SECONDS.labels(
    "management")

# Api Namespace
api = NamespaceManager().get_namespace("management")


@api.route("/sync/download")
class ManagementSyncDownload(Resource):
    @api.doc(description="Download all of the needed files in one as a zip")
    @SYNC_DOWNLOAD_REQUEST_DURATION_SECONDS.time()
    def get(self):
        sync = Synchronizer()

        try:
            zip_sync_file = sync.util_get_sync_files_as_zip()
        except FileNotFoundError as e:
コード例 #12
0
also the SQL database is reloaded as well. When the thread starts it find the management
pod with the help of the Kubernetes API and downloads a zip file from it containing all
the needed file to reload itself. The zip file is then extracted and first the SQL manager
is reloaded and after that the Hyperscan database
"""
from threading import Thread

from flask import make_response, jsonify
from flask_restplus import Resource

from redirectory.libs_int.metrics import REQUESTS_DURATION_SECONDS
from redirectory.libs_int.sync import Synchronizer
from redirectory.libs_int.service import NamespaceManager

# Metrics
WORKER_RELOAD_HS_DB_REQUEST_DURATION_SECONDS = REQUESTS_DURATION_SECONDS.labels(
    "worker")

# Api Namespace
api = NamespaceManager().get_namespace("worker")


@api.route("/reload_hs_db")
class WorkerReloadHsDb(Resource):
    @api.doc(
        description=
        "Tells the current worker to update itself. Runs in a separate thread")
    @WORKER_RELOAD_HS_DB_REQUEST_DURATION_SECONDS.time()
    def get(self):
        sync = Synchronizer()

        sync_thread = Thread(name="sync worker thread",
コード例 #13
0
Method: GET

RESPONSES:
    - 200: The Hyperscan Database has been reloaded

This endpoint provides the management pod with the ability to reload it's
hyperscan database that it uses for testing purposes.
"""
from flask import make_response, jsonify
from flask_restplus import Resource

from redirectory.libs_int.metrics import REQUESTS_DURATION_SECONDS
from redirectory.libs_int.hyperscan import HsManager
from redirectory.libs_int.service import NamespaceManager

DATABASE_RELOAD_MANAGEMENT_REQUEST_DURATION_SECONDS = REQUESTS_DURATION_SECONDS.labels(
    "management")
api = NamespaceManager().get_namespace("management")


@api.route("/database/reload_management")
class ManagementReloadManagementHsDb(Resource):
    @api.doc(description="Reload Management Hyperscan Test Database")
    @DATABASE_RELOAD_MANAGEMENT_REQUEST_DURATION_SECONDS.time()
    def get(self):
        hs_manager = HsManager()
        hs_manager.database.reload_database()
        new_db_version = hs_manager.database.db_version

        return make_response(
            jsonify({
                "new_hs_db_version": new_db_version,
コード例 #14
0
configured correctly then a 404 page will be returned and the request will be also
added to the Ambiguous Table for later checking by a person.
"""
from typing import Optional

from flask import request, redirect
from flask_restplus import Resource
from kubi_ecs_logger import Logger, Severity

from redirectory.libs_int.hyperscan import HsManager
from redirectory.libs_int.database import DatabaseManager
from redirectory.libs_int.metrics import REQUESTS_DURATION_SECONDS, REQUESTS_REDIRECTED_DURATION_SECONDS, \
    REQUESTS_REDIRECTED_TOTAL

# Metrics
REDIRECT_REQUEST_DURATION_SECONDS = REQUESTS_DURATION_SECONDS.labels("worker")
TOTAL_REQUESTS_REDIRECTED_DURATION_SECONDS = REQUESTS_REDIRECTED_DURATION_SECONDS.labels(
    "worker", "total")
HYPERSCAN_REQUESTS_REDIRECTED_DURATION_SECONDS = REQUESTS_REDIRECTED_DURATION_SECONDS.labels(
    "worker", "hyperscan")
DB_LOOKUP_REQUESTS_REDIRECTED_DURATION_SECONDS = REQUESTS_REDIRECTED_DURATION_SECONDS.labels(
    "worker", "db_lookup")


class WorkerRedirect(Resource):
    @REDIRECT_REQUEST_DURATION_SECONDS.time()
    @TOTAL_REQUESTS_REDIRECTED_DURATION_SECONDS.time()
    def get(self, content=None):
        del content
        host = request.host.split(":")[0]
        path = request.path
コード例 #15
0
the Redirect Rules.
When you call this endpoint only the management pod is reloaded with the new DB in order to test!
All of the workers are untouched and will continue running the old version!
"""
from threading import Thread
from flask import make_response, jsonify
from flask_restplus import Resource

from redirectory.models import RedirectRule
from redirectory.runnables import CompilerJob
from redirectory.libs_int.metrics import REQUESTS_DURATION_SECONDS, metric_update_rules_total
from redirectory.libs_int.database import DatabaseManager, db_get_table_row_count
from redirectory.libs_int.sync import Synchronizer
from redirectory.libs_int.service import NamespaceManager, api_error

DATABASE_COMPILE_REQUEST_DURATION_SECONDS = REQUESTS_DURATION_SECONDS.labels(
    "management")
api = NamespaceManager().get_namespace("management")


@api.route("/database/compile_test")
class ManagementCompileNewDbTest(Resource):
    @api.doc(
        description=
        "Compile a new version of HS databases based on the sqlite DB only for testing"
    )
    @DATABASE_COMPILE_REQUEST_DURATION_SECONDS.time()
    def get(self):
        db_session = DatabaseManager().get_session()
        sync = Synchronizer()

        # Check if sqlite DB is empty.
コード例 #16
0
ファイル: get_workers.py プロジェクト: kumina/k8s-redirectory
    - 200: Returns a list of worker pods information
    - 400: Unable to get workers. Not running in a cluster

This endpoint provides the management pod with the ability to get
information about all of the worker pods. This is done with the use
of the Kubernetes API. It returns an array with every worker as an object.
If the application is not running in a Kubernetes environment then a 400 will be returned.
"""
from flask import make_response, jsonify
from flask_restplus import Resource

from redirectory.libs_int.metrics import REQUESTS_DURATION_SECONDS
from redirectory.libs_int.kubernetes import K8sManager
from redirectory.libs_int.service import NamespaceManager, api_error

K8S_GET_WORKERS_REQUEST_DURATION_SECONDS = REQUESTS_DURATION_SECONDS.labels(
    "management")
api = NamespaceManager().get_namespace("management")


@api.route("/kubernetes/get_workers")
class ManagementKubernetesGetWorkers(Resource):
    @api.doc(
        description="Get a list of all worker nodes currently up and running!")
    @K8S_GET_WORKERS_REQUEST_DURATION_SECONDS.time()
    def get(self):
        try:
            workers = K8sManager().get_worker_pods()
        except AssertionError as e:
            return api_error(message="Unable to get worker pods",
                             errors=str(e),
                             status_code=400)
コード例 #17
0
RESPONSES:
    - 200: Returns the old_version and the current_version. If not versions are yet available then None

The Get Hyperscan DB Version endpoint provides with the ability to retrieve
the previous and the current Hyperscan DB Version which are stored in the database.
It will return None for both if there is still no entry about versions in the database.
"""
from flask import make_response, jsonify
from flask_restplus import Resource

from redirectory.libs_int.metrics import REQUESTS_DURATION_SECONDS
from redirectory.libs_int.hyperscan import get_hs_db_version, HsManager
from redirectory.libs_int.service import NamespaceManager

DATABASE_GET_VERSION_REQUEST_DURATION_SECONDS = REQUESTS_DURATION_SECONDS.labels(
    "management")
api = NamespaceManager().get_namespace("management")


@api.route("/database/version")
class ManagementGetDBVersion(Resource):
    @api.doc(
        description="Returns the previous and current Hyperscan database version"
    )
    @DATABASE_GET_VERSION_REQUEST_DURATION_SECONDS.time()
    def get(self):
        old_version, current_version = get_hs_db_version()
        hs_db_version = HsManager().database.db_version

        return make_response(
            jsonify({