]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
datamodel: additional headers for json-schema
authorAleš Mrázek <ales.mrazek@nic.cz>
Thu, 7 Mar 2024 12:52:58 +0000 (13:52 +0100)
committerAleš Mrázek <ales.mrazek@nic.cz>
Mon, 9 Sep 2024 12:28:32 +0000 (14:28 +0200)
python/knot_resolver/client/commands/schema.py
python/knot_resolver/datamodel/__init__.py
python/knot_resolver/datamodel/config_schema.py
python/knot_resolver/datamodel/globals.py
python/knot_resolver/manager/server.py
python/knot_resolver/utils/modeling/base_schema.py

index f55384247d18ce7eda2bf0308e84a43d9a9a0351..0c63f398e976a79d68e64efebf9d1eedb41965dc 100644 (file)
@@ -4,7 +4,7 @@ import sys
 from typing import List, Optional, Tuple, Type
 
 from knot_resolver.client.command import Command, CommandArgs, CompWords, register_command
-from knot_resolver.datamodel.config_schema import KresConfig
+from knot_resolver.datamodel import kres_config_json_schema
 from knot_resolver.utils.requests import request
 
 
@@ -46,7 +46,7 @@ class SchemaCommand(Command):
                 sys.exit(1)
             schema = response.body
         else:
-            schema = json.dumps(KresConfig.json_schema(), indent=4)
+            schema = json.dumps(kres_config_json_schema(), indent=4)
 
         if self.file:
             with open(self.file, "w") as f:
index a0174acc5758832bc5505ea46693cb6af04ca7f3..81fd1ee9964019f66ec4aab3272686efd455a07d 100644 (file)
@@ -1,3 +1,3 @@
-from .config_schema import KresConfig
+from .config_schema import KresConfig, kres_config_json_schema
 
-__all__ = ["KresConfig"]
+__all__ = ["KresConfig", "kres_config_json_schema"]
index fa108e79c219476d56742144d00227ffaf871f35..7d8b0b8d6dad642d42fa7e9dcf8eadc600aa7fec 100644 (file)
@@ -3,11 +3,12 @@ import os
 import socket
 from typing import Any, Dict, List, Literal, Optional, Tuple, Union
 
-from knot_resolver.constants import API_SOCK_PATH_DEFAULT, RUN_DIR_DEFAULT, WORKERS_MAX_DEFAULT
+from knot_resolver.constants import API_SOCK_PATH_DEFAULT, RUN_DIR_DEFAULT, VERSION, WORKERS_MAX_DEFAULT
 from knot_resolver.datamodel.cache_schema import CacheSchema
 from knot_resolver.datamodel.dns64_schema import Dns64Schema
 from knot_resolver.datamodel.dnssec_schema import DnssecSchema
 from knot_resolver.datamodel.forward_schema import ForwardSchema
+from knot_resolver.datamodel.globals import Context, get_global_validation_context, set_global_validation_context
 from knot_resolver.datamodel.local_data_schema import LocalDataSchema, RPZSchema, RuleSchema
 from knot_resolver.datamodel.logging_schema import LoggingSchema
 from knot_resolver.datamodel.lua_schema import LuaSchema
@@ -234,3 +235,25 @@ def get_rundir_without_validation(data: Dict[str, Any]) -> WritableDir:
     """
 
     return WritableDir(data["rundir"] if "rundir" in data else RUN_DIR_DEFAULT, object_path="/rundir")
+
+
+def kres_config_json_schema() -> Dict[str, Any]:
+    """
+    At this moment, to create any instance of 'ConfigSchema' even with default values, it is necessary to set the global context.
+    In the case of generating a JSON schema, strict validation must be turned off, otherwise it may happen that the creation of the JSON schema fails,
+    It may fail due to non-existence of the directory/file or their rights.
+    This should be fixed in the future. For more info, see 'datamodel.globals.py' module.
+    """
+
+    context = get_global_validation_context()
+    set_global_validation_context(Context(None, False))
+
+    schema = KresConfig.json_schema(
+        schema_id=f"https://www.knot-resolver.cz/documentation/v{VERSION}/_static/config.schema.json",
+        title="Knot Resolver configuration JSON schema",
+        description=f"Version Knot Resolver {VERSION}",
+    )
+    # setting back to previous values
+    set_global_validation_context(context)
+
+    return schema
index 610323fa06d1ad649365488a6eed7a68161faa4b..88f95c2a4d3cf677371505e727729b003c9f94d2 100644 (file)
@@ -38,6 +38,10 @@ def set_global_validation_context(context: Context) -> None:
     _global_context = context
 
 
+def get_global_validation_context() -> Context:
+    return _global_context
+
+
 def reset_global_validation_context() -> None:
     global _global_context
     _global_context = Context(None)
index d9f7f9eeac4a6db7838e0b8ab96b168cdbdd99d0..ea2b419c0762e9e8f531786980fe48dd9e1a29c4 100644 (file)
@@ -21,6 +21,7 @@ from knot_resolver.constants import CONFIG_FILE_PATH_DEFAULT, PID_FILE_NAME
 from knot_resolver.controller import get_best_controller_implementation
 from knot_resolver.controller.exceptions import SubprocessControllerExecException
 from knot_resolver.controller.registered_workers import command_single_registered_worker
+from knot_resolver.datamodel import kres_config_json_schema
 from knot_resolver.datamodel.cache_schema import CacheClearRPCSchema
 from knot_resolver.datamodel.config_schema import KresConfig, get_rundir_without_validation
 from knot_resolver.datamodel.globals import Context, set_global_validation_context
@@ -282,7 +283,7 @@ class Server:
 
     async def _handler_schema(self, _request: web.Request) -> web.Response:
         return web.json_response(
-            KresConfig.json_schema(), headers={"Access-Control-Allow-Origin": "*"}, dumps=partial(json.dumps, indent=4)
+            kres_config_json_schema(), headers={"Access-Control-Allow-Origin": "*"}, dumps=partial(json.dumps, indent=4)
         )
 
     async def _handle_view_schema(self, _request: web.Request) -> web.Response:
index aca3be05fc6d32982f37c04b8bce43f872e340a2..13539fe04a8255c3271c90b2ee1193a2218d8bf7 100644 (file)
@@ -754,14 +754,31 @@ class BaseSchema(Serializable):
         return True
 
     @classmethod
-    def json_schema(cls: Type["BaseSchema"], include_schema_definition: bool = True) -> Dict[Any, Any]:
+    def json_schema(
+        cls: Type["BaseSchema"],
+        schema_id: Optional[str] = None,
+        title: Optional[str] = None,
+        description: Optional[str] = None,
+        include_schema_definition: bool = True,
+    ) -> Dict[Any, Any]:
         if cls._LAYER is not None:
-            return cls._LAYER.json_schema(include_schema_definition=include_schema_definition)
+            return cls._LAYER.json_schema(
+                schema_id=schema_id,
+                title=title,
+                description=description,
+                include_schema_definition=include_schema_definition,
+            )
 
         schema: Dict[Any, Any] = {}
         if include_schema_definition:
             schema["$schema"] = "https://json-schema.org/draft/2020-12/schema"
-        if cls.__doc__ is not None:
+        if schema_id is not None:
+            schema["$id"] = schema_id
+        if title is not None:
+            schema["title"] = title
+        if description is not None:
+            schema["description"] = description
+        elif cls.__doc__ is not None:
             schema["description"] = _split_docstring(cls.__doc__)[0]
         schema["type"] = "object"
         schema["properties"] = _get_properties_schema(cls)