diff --git a/foris_controller_modules/introspect/__init__.py b/foris_controller_modules/introspect/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..bedc326b9c5293de3390a1d26601af9818e9d3e7 --- /dev/null +++ b/foris_controller_modules/introspect/__init__.py @@ -0,0 +1,39 @@ +# +# foris-controller +# Copyright (C) 2020 CZ.NIC, z.s.p.o. (http://www.nic.cz/) +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# + +import logging + +from foris_controller.module_base import BaseModule +from foris_controller.handler_base import wrap_required_functions + + +class IntrospectModule(BaseModule): + logger = logging.getLogger(__name__) + + def action_list_modules(self, data): + """ + :returns: list of loaded foris controller modules + :rtype: dict + """ + return {"modules": self.handler.list_modules()} + + +@wrap_required_functions(["list_modules"]) +class Handler: + pass diff --git a/foris_controller_modules/introspect/handlers/__init__.py b/foris_controller_modules/introspect/handlers/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..dc9a911f32591eb98f57815762bf61e5a82fe5ca --- /dev/null +++ b/foris_controller_modules/introspect/handlers/__init__.py @@ -0,0 +1,23 @@ +# +# foris-controller +# Copyright (C) 2020 CZ.NIC, z.s.p.o. (http://www.nic.cz/) +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# + +from .mock import MockIntrospectHandler +from .openwrt import OpenwrtIntrospectHandler + +__all__ = ["MockIntrospectHandler", "OpenwrtIntrospectHandler"] diff --git a/foris_controller_modules/introspect/handlers/mock.py b/foris_controller_modules/introspect/handlers/mock.py new file mode 100644 index 0000000000000000000000000000000000000000..b125e2645d2b375ef6980834f3a0a0714f8a0f1d --- /dev/null +++ b/foris_controller_modules/introspect/handlers/mock.py @@ -0,0 +1,54 @@ +# +# foris-controller +# Copyright (C) 2020 CZ.NIC, z.s.p.o. (http://www.nic.cz/) +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# + +import logging + +from foris_controller.handler_base import BaseMockHandler +from foris_controller.utils import logger_wrapper + +from .. import Handler + +logger = logging.getLogger(__name__) + +FORIS_CONTROLLER_MODULES = [ + "about", + "diagnostics", + "dns", + "guest", + "introspect", + "lan", + "maintain", + "networks", + "password", + "remote", + "router_notifications", + "storage", + "time", + "updater", + "wan", + "web", + "wifi" +] + + +class MockIntrospectHandler(Handler, BaseMockHandler): + @staticmethod + @logger_wrapper(logger) + def list_modules(): + return FORIS_CONTROLLER_MODULES diff --git a/foris_controller_modules/introspect/handlers/openwrt.py b/foris_controller_modules/introspect/handlers/openwrt.py new file mode 100644 index 0000000000000000000000000000000000000000..c049cfff83988350c1043f5f4a5e7a8069c0f9c4 --- /dev/null +++ b/foris_controller_modules/introspect/handlers/openwrt.py @@ -0,0 +1,37 @@ +# +# foris-controller +# Copyright (C) 2020 CZ.NIC, z.s.p.o. (http://www.nic.cz/) +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# + +import logging + +from foris_controller.app import app_info +from foris_controller.handler_base import BaseOpenwrtHandler +from foris_controller.utils import get_modules, logger_wrapper + +from .. import Handler + +logger = logging.getLogger(__name__) + + +class OpenwrtIntrospectHandler(Handler, BaseOpenwrtHandler): + @staticmethod + @logger_wrapper(logger) + def list_modules(): + modules = get_modules(app_info["filter_modules"], app_info["extra_module_paths"]) + + return [mod[0] for mod in modules] diff --git a/foris_controller_modules/introspect/schema/introspect.json b/foris_controller_modules/introspect/schema/introspect.json new file mode 100644 index 0000000000000000000000000000000000000000..92ad07e915b5d2e8b94f92ff20ae8ab5f7139a5c --- /dev/null +++ b/foris_controller_modules/introspect/schema/introspect.json @@ -0,0 +1,34 @@ +{ + "oneOf": [ + { + "description": "List Foris Controller modules", + "properties": { + "module": {"enum": ["introspect"]}, + "kind": {"enum": ["request"]}, + "action": {"enum": ["list_modules"]} + }, + "additionalProperties": false + }, + { + "description": "Reply to list Foris Controller modules", + "properties": { + "module": {"enum": ["introspect"]}, + "kind": {"enum": ["reply"]}, + "action": {"enum": ["list_modules"]}, + "data": { + "type": "object", + "properties": { + "modules": { + "type": "array", + "items": {"type": "string"} + } + }, + "additionalProperties": false, + "required": ["modules"] + } + }, + "additionalProperties": false, + "required": ["data"] + } + ] +} diff --git a/setup.py b/setup.py index a7c1dc9c8ea42477bf9f2eb7f53eba8fc5c0fe35..46bb41cb8d3749ca22d6afb1fcc17f035faaace3 100644 --- a/setup.py +++ b/setup.py @@ -28,7 +28,7 @@ setup( name='foris-controller', version=__version__, author='CZ.NIC, z.s.p.o. (http://www.nic.cz/)', - author_email='stepan.henek@nic.cz', + author_email='packaging@nic.cz', packages=[ 'foris_controller', 'foris_controller.controller', @@ -60,6 +60,8 @@ setup( 'foris_controller_modules.dns.handlers', 'foris_controller_modules.guest', 'foris_controller_modules.guest.handlers', + 'foris_controller_modules.introspect', + 'foris_controller_modules.introspect.handlers', 'foris_controller_modules.lan', 'foris_controller_modules.lan.handlers', 'foris_controller_modules.maintain', @@ -90,6 +92,7 @@ setup( 'foris_controller_modules.about': ['schema', 'schema/*.json'], 'foris_controller_modules.dns': ['schema', 'schema/*.json'], 'foris_controller_modules.guest': ['schema', 'schema/*.json'], + 'foris_controller_modules.introspect': ['schema', 'schema/*.json'], 'foris_controller_modules.lan': ['schema', 'schema/*.json'], 'foris_controller_modules.maintain': ['schema', 'schema/*.json'], 'foris_controller_modules.networks': ['schema', 'schema/*.json'], diff --git a/tests/blackbox/conftest.py b/tests/blackbox/conftest.py index 47c8126b76b103bd2b01b70dd45c0191a7008565..b34dfce95345a63a0e1879275842ae569e13c909 100644 --- a/tests/blackbox/conftest.py +++ b/tests/blackbox/conftest.py @@ -70,4 +70,5 @@ def controller_modules(): "networks", "guest", "remote", + "introspect", ] diff --git a/tests/blackbox/test_introspect.py b/tests/blackbox/test_introspect.py new file mode 100644 index 0000000000000000000000000000000000000000..0d761f7da82c7702b003720c10b3e80e7ad2a1a6 --- /dev/null +++ b/tests/blackbox/test_introspect.py @@ -0,0 +1,44 @@ +# +# foris-controller +# Copyright (C) 2020 CZ.NIC, z.s.p.o. (http://www.nic.cz/) +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# + + +import pytest + +from foris_controller_testtools.fixtures import ( + infrastructure, + only_backends, + start_buses, + ubusd_test, + mosquitto_test, +) + + +@pytest.mark.only_backends(["mock"]) +def test_list_modules(infrastructure, start_buses): + res = infrastructure.process_message( + { + "module": "introspect", + "action": "list_modules", + "kind": "request", + } + ) + + assert "error" not in res + assert "data" in res + assert isinstance(res["data"]["modules"], list)