]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
datamodel: local-data/rules: 'records' added
authorAleš Mrázek <ales.mrazek@nic.cz>
Mon, 28 Aug 2023 11:16:03 +0000 (13:16 +0200)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Tue, 12 Sep 2023 10:12:55 +0000 (12:12 +0200)
manager/knot_resolver_manager/datamodel/local_data_schema.py
manager/knot_resolver_manager/datamodel/templates/macros/local_data_macros.lua.j2
manager/tests/unit/datamodel/test_local_data.py

index 8d7ff0697af318bae429ee45cd77c1014a3fac4c..e891601ce2d08c4f9dbcae221e4ef9a0ae8fd846 100644 (file)
@@ -16,37 +16,40 @@ from knot_resolver_manager.utils.modeling import ConfigSchema
 
 class RuleSchema(ConfigSchema):
     """
-    Local data rule configuration.
+    Local data advanced rule configuration.
 
     ---
     name: Hostname(s).
+    subtree: Type of subtree.
     address: Address(es) to pair with hostname(s).
     file: Path to file(s) with hostname and IP address(es) pairs in '/etc/hosts' like format.
-    subtree: Type of subtree.
+    records: Direct addition of records in DNS zone file format.
     tags: Tags to link with other policy rules.
     ttl: Optional, TTL value used for these answers.
     nodata: Optional, use NODATA synthesis. NODATA will be synthesised for matching name, but mismatching type(e.g. AAAA query when only A exists).
     """
 
     name: Optional[ListOrItem[DomainName]] = None
-    address: Optional[ListOrItem[IPAddress]] = None
     subtree: Optional[Literal["empty", "nxdomain", "redirect"]] = None
+    address: Optional[ListOrItem[IPAddress]] = None
     file: Optional[ListOrItem[File]] = None
+    records: Optional[EscapedStr] = None
     tags: Optional[List[IDPattern]] = None
     ttl: Optional[TimeUnit] = None
     nodata: Optional[bool] = None
 
     def _validate(self) -> None:
-        options_sum = sum([bool(self.address), bool(self.subtree), bool(self.file)])
+        options_sum = sum([bool(self.address), bool(self.subtree), bool(self.file), bool(self.records)])
         if options_sum == 2 and bool(self.address) and self.subtree in {"empty", "redirect"}:
-            pass # these combinations still make sense
+            pass  # these combinations still make sense
         elif options_sum > 1:
             raise ValueError("only one of 'address', 'subtree' or 'file' can be configured")
         elif options_sum < 1:
-            raise ValueError("one of 'address', 'subtree' or 'file' must be configured")
+            raise ValueError("one of 'address', 'subtree', 'file' or 'records' must be configured")
 
-        if bool(self.file) == bool(self.name):
-            raise ValueError("one of 'file' or 'name' must be configured")
+        options_sum2 = sum([bool(self.name), bool(self.file), bool(self.records)])
+        if options_sum2 != 1:
+            raise ValueError("one of 'name', 'file or 'records' must be configured")
 
         if bool(self.nodata) and bool(self.subtree) and not bool(self.address):
             raise ValueError("'nodata' defined but unused with 'subtree'")
index 92e010df356d532872e30de5e71405a0b923c973..d3596490f89c33bcd6caa2af61abae44cc1cd480 100644 (file)
@@ -94,6 +94,8 @@ assert(C.kr_rule_local_subtree(todname('{{ name }}'),
 {% for file in item.file %}
 {{ kr_rule_local_hosts(file, nodata if item.nodata is none else item.nodata, item.ttl or ttl, item.tags) }}
 {% endfor %}
+{% elif item.records %}
+{{ local_data_records(item.records, false, item.ttl or ttl, nodata if item.nodata is none else item.nodata, tags) }}
 {% endif %}
 {% endfor %}
 {%- endmacro %}
index 710fac153c405dc6874f8c8441d7193af9f64559..9842b0b2d603182d072fa7619c8cd014c6215019 100644 (file)
@@ -10,11 +10,13 @@ from knot_resolver_manager.utils.modeling.exceptions import DataValidationError
 @pytest.mark.parametrize(
     "val",
     [
-        {"name": ["sub2.example.org"], "subtree": "empty"},
+        {"name": ["sub2.example.org"], "subtree": "empty", "tags": ["t01"]},
         {"name": ["sub3.example.org", "sub5.example.net."], "subtree": "nxdomain", "ttl": "1h"},
         {"name": ["sub4.example.org"], "subtree": "redirect"},
         {"name": ["sub5.example.org"], "address": ["127.0.0.1"]},
+        {"name": ["sub6.example.org"], "subtree": "redirect", "address": ["127.0.0.1"]},
         {"file": "/etc/hosts", "ttl": "20m", "nodata": True},
+        {"records": "", "ttl": "20m", "nodata": True},
     ],
 )
 def test_subtree_valid(val: Any):
@@ -26,7 +28,7 @@ def test_subtree_valid(val: Any):
     [
         {"subtree": "empty"},
         {"name": ["sub2.example.org"], "file": "/etc/hosts"},
-        {"name": ["sub4.example.org"], "address": ["127.0.0.1"], "subtree": "empty"},
+        {"name": ["sub4.example.org"], "address": ["127.0.0.1"], "subtree": "nxdomain"},
         {"name": ["sub4.example.org"], "subtree": "redirect", "file": "/etc/hosts"},
     ],
 )