diff --git a/synapse_topology/controller/cli/cli.py b/synapse_topology/controller/cli/cli.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/synapse_topology/controller/server/__init__.py b/synapse_topology/controller/server/__init__.py new file mode 100644 index 0000000000..18f39c0c07 --- /dev/null +++ b/synapse_topology/controller/server/__init__.py @@ -0,0 +1,4 @@ +from . import server + +app = server.app + diff --git a/synapse_topology/controller/server/api.rst b/synapse_topology/controller/server/api.rst new file mode 100644 index 0000000000..e69de29bb2 diff --git a/synapse_topology/controller/server/error_handlers.py b/synapse_topology/controller/server/error_handlers.py new file mode 100644 index 0000000000..7356ec756c --- /dev/null +++ b/synapse_topology/controller/server/error_handlers.py @@ -0,0 +1,47 @@ +from jsonschema import ValidationError +from simplejson.errors import JSONDecodeError +from synapse_topology.model.errors import ( + BasConfigInUseError, + BaseConfigNotFoundError, + ConfigNotFoundError, +) + +from . import server + +app = server.app + + +@app.handle_errors(ValidationError) +def validation_error(request, failure): + request.setResponseCode(400) + return "Invalid post schema {}".format(failure.getErrorMessage()) + + +@app.handle_errors(JSONDecodeError) +def json_decode_error(request, failure): + request.setResponseCode(400) + return "Invalid post json" + + +@app.handle_errors(BaseConfigNotFoundError) +def base_config_not_found(request, failure): + request.setResponseCode(500) + return "Config file not setup, please initialise it using the /servername endpoint" + + +@app.handle_errors(ConfigNotFoundError) +def config_not_found(request, failure): + request.setResponseCode(404) + return "The config does not exist" + + +@app.handle_errors(BasConfigInUseError) +def base_config_in_use(request, failure): + request.setResponseCode(409) + return "Sever name and keys already configured" + + +@app.handle_errors(Exception) +def handle_generic_error(request, failure): + request.setResponseCode(500) + return "Internal server error\n{}".format(failure) diff --git a/synapse_topology/controller/server/schemas.py b/synapse_topology/controller/server/schemas.py new file mode 100644 index 0000000000..b841b18a84 --- /dev/null +++ b/synapse_topology/controller/server/schemas.py @@ -0,0 +1,17 @@ +SERVERNAME_SCHEMA = { + "type": "object", + "properties": { + "server_name": {"type": "string", "minlength": 1}, + "report_stats": {"type": "boolean"}, + }, + "required": ["server_name", "report_stats"], +} + +BASE_CONFIG_SCHEMA = { + "type": "object", + "properties": { + "server_name": {"type": "string", "minlength": 1}, + "report_stats": {"type": "boolean"}, + }, + "required": ["server_name", "report_stats"], +} diff --git a/synapse_topology/controller/server/server.py b/synapse_topology/controller/server/server.py new file mode 100644 index 0000000000..b5a79fba00 --- /dev/null +++ b/synapse_topology/controller/server/server.py @@ -0,0 +1,48 @@ +from canonicaljson import json +from klein import Klein +from synapse_topology import model + +from .schemas import BASE_CONFIG_SCHEMA, SERVERNAME_SCHEMA +from .utils import validate_schema + +app = Klein() +from . import error_handlers + + +@app.route("/servername", methods=["GET"]) +def get_server_name(request): + return model.get_server_name() + + +@app.route("/servername", methods=["POST"]) +@validate_schema(SERVERNAME_SCHEMA) +def set_server_name(request, body): + model.generate_base_config(**body) + + +@app.route("/secretkey", methods=["GET"]) +def get_secret_key(request): + return model.get_secret_key() + + +@app.route("/config", methods=["GET"]) +def get_config(request): + return str(model.get_config()) + + +@app.route("/config", methods=["POST"]) +@validate_schema(BASE_CONFIG_SCHEMA) +def set_config(request, body): + model.set_config(body) + + +with app.subroute("/config") as app: + for config in model.constants.CONFIGS: + + @app.route("/config/{}".format(config), methods=["GET"]) + def get_sub_config(request, sub_config): + return model.get_config(sub_config=config) + + @app.route("/config/{}".format(config), methods=["POST"]) + def set_sub_config(request, sub_config): + model.set_config(json.loads(request.content.read()), sub_config=config) diff --git a/synapse_topology/controller/server/utils.py b/synapse_topology/controller/server/utils.py new file mode 100644 index 0000000000..009a1a1c79 --- /dev/null +++ b/synapse_topology/controller/server/utils.py @@ -0,0 +1,17 @@ +from functools import wraps + +from canonicaljson import json +from jsonschema import validate + + +def validate_schema(schema): + def _wrap_validate(func): + @wraps(func) + def _do_validate(request): + body = json.loads(request.content.read()) + validate(instance=body, schema=schema) + return func(request, body) + + return _do_validate + + return _wrap_validate