]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
datamodel: options: section completed, tests
authorAleš <ales.mrazek@nic.cz>
Wed, 8 Sep 2021 13:53:36 +0000 (15:53 +0200)
committerAleš Mrázek <ales.mrazek@nic.cz>
Fri, 8 Apr 2022 14:17:52 +0000 (16:17 +0200)
manager/knot_resolver_manager/datamodel/config.py
manager/knot_resolver_manager/datamodel/lua_template.j2
manager/knot_resolver_manager/datamodel/options_config.py [new file with mode: 0644]
manager/tests/datamodel/test_options_config.py [new file with mode: 0644]

index 77215e16472be243dd71deb073d6fdf970d52a84..8b80195ccec813c670155f598814c9de175905f4 100644 (file)
@@ -6,6 +6,7 @@ from jinja2 import Environment, Template
 from knot_resolver_manager.datamodel.dns64_config import Dns64, Dns64Strict
 from knot_resolver_manager.datamodel.lua_config import Lua, LuaStrict
 from knot_resolver_manager.datamodel.network_config import Network, NetworkStrict
+from knot_resolver_manager.datamodel.options_config import Options, OptionsStrict
 from knot_resolver_manager.datamodel.server_config import Server, ServerStrict
 from knot_resolver_manager.utils import DataParser, DataValidator
 
@@ -23,6 +24,7 @@ _LUA_TEMPLATE = _import_lua_template()
 
 class KresConfig(DataParser):
     server: Server = Server()
+    options: Options = Options()
     network: Network = Network()
     dns64: Union[bool, Dns64] = False
     lua: Lua = Lua()
@@ -30,6 +32,7 @@ class KresConfig(DataParser):
 
 class KresConfigStrict(DataValidator):
     server: ServerStrict
+    options: OptionsStrict
     network: NetworkStrict
     dns64: Union[bool, Dns64Strict]
     lua: LuaStrict
index f5610a632f6145185aa0a26468cafc2f4db4a709..c9ad79abf6bb2d5d70575b07282ac6f139e69505 100644 (file)
@@ -21,9 +21,22 @@ net.listen('{{ item.address }}', {{ item.port }}, {
 
 -- MODULES
 modules = {
+    {{ "'rebinding < iterate'," if cfg.options.rebinding_protection }}
+    {{ "'workarounds < iterate'," if cfg.options.violators_workarounds }}
+    {{ "'serve_stale < cache'," if cfg.options.serve_stale }}
     {{ "dns64 = '"+cfg.dns64.prefix+"'," if cfg.dns64 }}
 }
 
+-- OPTIONS section
+mode('{{ cfg.options.glue_checking }}')
+option('NO_MINIMIZE', {{ 'false' if cfg.options.qname_minimisation else 'true' }})
+option('ALLOW_LOCAL', {{ 'true' if cfg.options.query_loopback else 'false' }})
+option('REORDER_RR', {{ 'true' if cfg.options.reorder_rrset else 'false' }})
+option('NO_0X20', {{ 'false' if cfg.options.query_case_randomization else 'true' }})
+{{ "modules.unload('priming')" if not cfg.options.query_priming }}
+{{ "modules.unload('detect_time_jump')" if not cfg.options.time_jump_detection }}
+{{ "modules.unload('refuse_nord')" if not cfg.options.refuse_no_rd }}
+
 {% endif %}
 -- LUA section
 {% if cfg.lua.script_file %}
diff --git a/manager/knot_resolver_manager/datamodel/options_config.py b/manager/knot_resolver_manager/datamodel/options_config.py
new file mode 100644 (file)
index 0000000..8c29cc7
--- /dev/null
@@ -0,0 +1,61 @@
+from typing import Union
+
+from knot_resolver_manager.utils import DataParser, DataValidator
+from knot_resolver_manager.utils.types import LiteralEnum
+
+from .types import TimeUnit
+
+GlueCheckingEnum = LiteralEnum["normal", "strict", "permissive"]
+
+
+class Prediction(DataParser):
+    window: TimeUnit = TimeUnit("15m")
+    period: int = 24
+
+
+class Options(DataParser):
+    glue_checking: GlueCheckingEnum = "normal"
+    qname_minimisation: bool = True
+    query_loopback: bool = False
+    reorder_rrset: bool = True
+    query_case_randomization: bool = True
+    query_priming: bool = True
+    rebinding_protection: bool = False
+    refuse_no_rd: bool = True
+    time_jump_detection: bool = True
+    violators_workarounds: bool = False
+    serve_stale: bool = False
+
+    prediction: Union[bool, Prediction] = False
+
+
+class PredictionStrict(DataValidator):
+    window: int
+    period: int
+
+    def _validate(self) -> None:
+        pass
+
+
+class OptionsStrict(DataValidator):
+    glue_checking: GlueCheckingEnum
+    qname_minimisation: bool
+    query_loopback: bool
+    reorder_rrset: bool
+    query_case_randomization: bool
+    query_priming: bool
+    rebinding_protection: bool
+    refuse_no_rd: bool
+    time_jump_detection: bool
+    violators_workarounds: bool
+    serve_stale: bool
+
+    prediction: Union[bool, PredictionStrict]
+
+    def _prediction(self, obj: Options) -> Union[bool, Prediction]:
+        if obj.prediction is True:
+            return Prediction()
+        return obj.prediction
+
+    def _validate(self) -> None:
+        pass
diff --git a/manager/tests/datamodel/test_options_config.py b/manager/tests/datamodel/test_options_config.py
new file mode 100644 (file)
index 0000000..ec57bee
--- /dev/null
@@ -0,0 +1,66 @@
+from knot_resolver_manager.datamodel.options_config import Options, OptionsStrict
+from knot_resolver_manager.datamodel.types import TimeUnit
+from knot_resolver_manager.utils.data_parser_validator import Format
+
+yaml = """
+glue-checking: strict
+qname-minimisation: false
+query-loopback: true
+reorder-rrset: false
+query-case-randomization: false
+query-priming: true
+rebinding-protection: false
+refuse-no-rd: false
+time-jump-detection: false
+violators-workarounds: true
+serve-stale: true
+prediction:
+    window: 10m
+    period: 20
+"""
+
+config = Options.from_yaml(yaml)
+strict = OptionsStrict(config)
+
+
+def test_parsing():
+    assert config.glue_checking == "strict"
+    assert config.qname_minimisation == False
+    assert config.query_loopback == True
+    assert config.reorder_rrset == False
+    assert config.query_case_randomization == False
+    assert config.query_priming == True
+    assert config.rebinding_protection == False
+    assert config.refuse_no_rd == False
+    assert config.time_jump_detection == False
+    assert config.violators_workarounds == True
+    assert config.serve_stale == True
+
+    assert config.prediction.window == TimeUnit("10m")
+    assert config.prediction.period == 20
+
+
+def test_validating():
+    assert strict.glue_checking == "strict"
+    assert strict.qname_minimisation == False
+    assert strict.query_loopback == True
+    assert strict.reorder_rrset == False
+    assert strict.query_case_randomization == False
+    assert strict.query_priming == True
+    assert strict.rebinding_protection == False
+    assert strict.refuse_no_rd == False
+    assert strict.time_jump_detection == False
+    assert strict.violators_workarounds == True
+    assert strict.serve_stale == True
+
+    assert strict.prediction.window == 10 * 60
+    assert strict.prediction.period == 20
+
+
+def test_prediction_true_defaults():
+    x = config.copy_with_changed_subtree(Format.JSON, "/prediction", "true")
+    y = OptionsStrict(x)
+
+    assert x.prediction == True
+    assert y.prediction.window == 900
+    assert y.prediction.period == 24