]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
manager: datamodel: prediction moved to cache
authorAleš Mrázek <ales.mrazek@nic.cz>
Fri, 28 Jul 2023 13:57:19 +0000 (15:57 +0200)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Tue, 1 Aug 2023 07:20:55 +0000 (07:20 +0000)
manager/knot_resolver_manager/datamodel/cache_schema.py
manager/knot_resolver_manager/datamodel/options_schema.py
manager/knot_resolver_manager/datamodel/templates/cache.lua.j2
manager/knot_resolver_manager/datamodel/types/types.py
manager/tests/unit/datamodel/test_cache_schema.py [moved from manager/tests/unit/datamodel/test_options_schema.py with 51% similarity]

index ad0211f8f16a80e3dab1fb1c346f486d0de21e2f..7eeda1f46c1cd287b9f9f016cac2e87f40cc5e37 100644 (file)
@@ -1,4 +1,4 @@
-from typing import List, Optional, Union
+from typing import Any, List, Optional, Union
 
 from typing_extensions import Literal
 
@@ -64,27 +64,59 @@ class GarbageCollectorSchema(ConfigSchema):
     dry_run: bool = False
 
 
-class CacheSchema(ConfigSchema):
+class PredictionSchema(ConfigSchema):
     """
-    DNS resolver cache configuration.
+    Helps keep the cache hot by prefetching expiring records and learning usage patterns and repetitive queries.
 
     ---
-    storage: Cache storage of the DNS resolver.
-    size_max: Maximum size of the cache.
-    garbage_collector: Use the garbage collector (kres-cache-gc) to periodically clear cache.
-    ttl_min: Minimum time-to-live for the cache entries.
-    ttl_max: Maximum time-to-live for the cache entries.
-    ns_timeout: Time interval for which a nameserver address will be ignored after determining that it does not return (useful) answers.
-    prefill: Prefill the cache periodically by importing zone data obtained over HTTP.
+    window: Sampling window length.
+    period: Number of windows that can be kept in memory.
     """
 
-    storage: Dir = lazy_default(Dir, "/var/cache/knot-resolver")
-    size_max: SizeUnit = SizeUnit("100M")
-    garbage_collector: Union[GarbageCollectorSchema, Literal[False]] = GarbageCollectorSchema()
-    ttl_min: TimeUnit = TimeUnit("5s")
-    ttl_max: TimeUnit = TimeUnit("6d")
-    ns_timeout: TimeUnit = TimeUnit("1000ms")
-    prefill: Optional[List[PrefillSchema]] = None
+    window: TimeUnit = TimeUnit("15m")
+    period: IntNonNegative = IntNonNegative(24)
+
+
+class CacheSchema(ConfigSchema):
+    class Raw(ConfigSchema):
+        """
+        DNS resolver cache configuration.
+
+        ---
+        storage: Cache storage of the DNS resolver.
+        size_max: Maximum size of the cache.
+        garbage_collector: Use the garbage collector (kres-cache-gc) to periodically clear cache.
+        ttl_min: Minimum time-to-live for the cache entries.
+        ttl_max: Maximum time-to-live for the cache entries.
+        ns_timeout: Time interval for which a nameserver address will be ignored after determining that it does not return (useful) answers.
+        prefill: Prefill the cache periodically by importing zone data obtained over HTTP.
+        prediction: Helps keep the cache hot by prefetching expiring records and learning usage patterns and repetitive queries.
+        """
+
+        storage: Dir = lazy_default(Dir, "/var/cache/knot-resolver")
+        size_max: SizeUnit = SizeUnit("100M")
+        garbage_collector: Union[GarbageCollectorSchema, Literal[False]] = GarbageCollectorSchema()
+        ttl_min: TimeUnit = TimeUnit("5s")
+        ttl_max: TimeUnit = TimeUnit("6d")
+        ns_timeout: TimeUnit = TimeUnit("1000ms")
+        prefill: Optional[List[PrefillSchema]] = None
+        prediction: Union[bool, PredictionSchema] = False
+
+    _LAYER = Raw
+
+    storage: Dir
+    size_max: SizeUnit
+    garbage_collector: Union[GarbageCollectorSchema, Literal[False]]
+    ttl_min: TimeUnit
+    ttl_max: TimeUnit
+    ns_timeout: TimeUnit
+    prefill: Optional[List[PrefillSchema]]
+    prediction: Union[Literal[False], PredictionSchema]
+
+    def _prediction(self, obj: Raw) -> Any:
+        if obj.prediction is True:
+            return PredictionSchema()
+        return obj.prediction
 
     def _validate(self):
         if self.ttl_min.seconds() >= self.ttl_max.seconds():
index e95e5f88b4e5d36f8399a583ef6c63d95ae75b44..d0bb0399acc638e6b0958ac90ab7b2cf1e172752 100644 (file)
@@ -1,75 +1,36 @@
-from typing import Any, Union
-
 from typing_extensions import Literal
 
-from knot_resolver_manager.datamodel.types import IntNonNegative, TimeUnit
 from knot_resolver_manager.utils.modeling import ConfigSchema
 
 GlueCheckingEnum = Literal["normal", "strict", "permissive"]
 
 
-class PredictionSchema(ConfigSchema):
+class OptionsSchema(ConfigSchema):
     """
-    Helps keep the cache hot by prefetching expiring records and learning usage patterns and repetitive queries.
+    Fine-tuning global parameters of DNS resolver operation.
 
     ---
-    window: Sampling window length.
-    period: Number of windows that can be kept in memory.
+    glue_checking: Glue records scrictness checking level.
+    minimize: Send minimum amount of information in recursive queries to enhance privacy.
+    query_loopback: Permits queries to loopback addresses.
+    reorder_rrset: Controls whether resource records within a RRSet are reordered each time it is served from the cache.
+    query_case_randomization: Randomize Query Character Case.
+    priming: Initializing DNS resolver cache with Priming Queries (RFC 8109)
+    rebinding_protection: Protection against DNS Rebinding attack.
+    refuse_no_rd: Queries without RD (recursion desired) bit set in query are answered with REFUSED.
+    time_jump_detection: Detection of difference between local system time and expiration time bounds in DNSSEC signatures for '. NS' records.
+    violators_workarounds: Workarounds for known DNS protocol violators.
+    serve_stale: Allows using timed-out records in case DNS resolver is unable to contact upstream servers.
     """
 
-    window: TimeUnit = TimeUnit("15m")
-    period: IntNonNegative = IntNonNegative(24)
-
-
-class OptionsSchema(ConfigSchema):
-    class Raw(ConfigSchema):
-        """
-        Fine-tuning global parameters of DNS resolver operation.
-
-        ---
-        glue_checking: Glue records scrictness checking level.
-        minimize: Send minimum amount of information in recursive queries to enhance privacy.
-        query_loopback: Permits queries to loopback addresses.
-        reorder_rrset: Controls whether resource records within a RRSet are reordered each time it is served from the cache.
-        query_case_randomization: Randomize Query Character Case.
-        priming: Initializing DNS resolver cache with Priming Queries (RFC 8109)
-        rebinding_protection: Protection against DNS Rebinding attack.
-        refuse_no_rd: Queries without RD (recursion desired) bit set in query are answered with REFUSED.
-        time_jump_detection: Detection of difference between local system time and expiration time bounds in DNSSEC signatures for '. NS' records.
-        violators_workarounds: Workarounds for known DNS protocol violators.
-        serve_stale: Allows using timed-out records in case DNS resolver is unable to contact upstream servers.
-        prediction: Helps keep the cache hot by prefetching expiring records and learning usage patterns and repetitive queries.
-        """
-
-        glue_checking: GlueCheckingEnum = "normal"
-        minimize: bool = True
-        query_loopback: bool = False
-        reorder_rrset: bool = True
-        query_case_randomization: bool = True
-        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, PredictionSchema] = False
-
-    _LAYER = Raw
-
-    glue_checking: GlueCheckingEnum
-    minimize: bool
-    query_loopback: bool
-    reorder_rrset: bool
-    query_case_randomization: bool
-    priming: bool
-    rebinding_protection: bool
-    refuse_no_rd: bool
-    time_jump_detection: bool
-    violators_workarounds: bool
-    serve_stale: bool
-    prediction: Union[Literal[False], PredictionSchema]
-
-    def _prediction(self, obj: Raw) -> Any:
-        if obj.prediction is True:
-            return PredictionSchema()
-        return obj.prediction
+    glue_checking: GlueCheckingEnum = "normal"
+    minimize: bool = True
+    query_loopback: bool = False
+    reorder_rrset: bool = True
+    query_case_randomization: bool = True
+    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
index 3571577187d25d5caab62e38c44cb256807d3dca..0d942841ca2d32203fcbd5d3c5f0aa7935525d86 100644 (file)
@@ -15,4 +15,13 @@ prefill.config({
     }
 {% endfor %}
 })
-{% endif %}
\ No newline at end of file
+{% endif %}
+
+{% if cfg.cache.prediction %}
+-- cache.prediction
+modules.load('predict')
+predict.config({
+    window = {{ cfg.cache.prediction.window.minutes() }}
+    period = {{ cfg.cache.prediction.period }}
+})
+{% endif %}
index c8b533215e9d343007972470f2d3baa637617341..f558da0de24135de9ef9ede81c033ce974383b30 100644 (file)
@@ -60,6 +60,9 @@ class SizeUnit(UnitBase):
 class TimeUnit(UnitBase):
     _units = {"us": 1, "ms": 10**3, "s": 10**6, "m": 60 * 10**6, "h": 3600 * 10**6, "d": 24 * 3600 * 10**6}
 
+    def minutes(self) -> int:
+        return self._base_value // 1000**2 // 60
+
     def seconds(self) -> int:
         return self._base_value // 1000**2
 
similarity index 51%
rename from manager/tests/unit/datamodel/test_options_schema.py
rename to manager/tests/unit/datamodel/test_cache_schema.py
index f6bd5c3e019d4d82409b494d6aacdc6a8b034d7a..f5c3030aced3d23e11dd502f8b792af698fabf42 100644 (file)
@@ -1,7 +1,7 @@
-from knot_resolver_manager.datamodel.options_schema import OptionsSchema
+from knot_resolver_manager.datamodel.cache_schema import CacheSchema
 
 
 def test_prediction_true_defaults():
-    o = OptionsSchema({"prediction": True})
+    o = CacheSchema({"prediction": True})
     assert str(o.prediction.window) == "15m"
     assert int(o.prediction.period) == 24