listen:
- interface: 127.0.0.1@5353
-# views:
-# - subnets: [ 0.0.0.0/0, "::/0" ]
-# answer: refused
- # - subnets: [ 0.0.0.0/0, "::/0" ]
- # tags: [t01, t02, t03]
- # options:
- # minimize: true # default
- # dns64: true # default
- # - subnets: [10.0.10.0/24] # can be single value
- # answer: allow
+views:
+ - subnets: [127.0.0.0/24]
+ tags: [t01, t02, t03]
+ options:
+ dns64: false
+ - subnets: [ 0.0.0.0/0, "::/0" ]
+ answer: refused
+ - subnets: [10.0.10.0/24]
+ answer: allow
# local-data:
# ttl: 1d
{% if not cfg.lua.script_only %}
+-- FFI library
+local C = require('ffi').C
+
-- hostname
hostname('{{ cfg.hostname }}')
{% include "network.lua.j2" %}
-- VIEWS section ------------------------------------
-{# {% include "views.lua.j2" %} #}
+{% include "views.lua.j2" %}
-- LOCAL-DATA section -------------------------------
{# {% include "local_data.lua.j2" %} #}
+{% macro quotes(string) -%}
+'{{ string }}'
+{%- endmacro %}
+
{# Return string or table of strings #}
{% macro string_table(table) -%}
{%- if table is string -%}
{% macro policy_flags(flags) -%}
policy.FLAGS({
-{%- if flags is string -%}
-'{{ flags.upper().replace("-", "_")|string }}'
-{%- else -%}
-{%- for flag in flags|list -%}
-'{{ flag.upper().replace("-", "_") }}',
-{%- endfor -%}
-{%- endif -%}
+{{- flags -}}
})
{%- endmacro %}
assert(C.kr_view_insert_action('{{ subnet }}',{{ action }})==0)
{%- endmacro %}
-
-{% macro view_options_flags(options) -%}
-policy.FLAGS({
-{%- if not options.minimize -%}
-'NO_MINIMIZE',
-{%- endif -%}
-{%- if not options.dns64 -%}
-'DNS64_DISABLE',
-{%- endif -%}
-})
+{% macro view_flags(options) -%}
+{% if not options.minimize -%}
+"NO_MINIMIZE",
+{%- endif %}
+{% if not options.dns64 -%}
+"DNS64_DISABLE",
+{%- endif %}
{%- endmacro %}
-
{% macro view_answer(answer) -%}
{%- if answer == 'allow' -%}
policy.TAGS_ASSIGN({})
{%- elif answer == 'refused' -%}
-policy.REFUSE
+'policy.REFUSE'
{%- elif answer == 'noanswer' -%}
-policy.NO_ANSWER
+'policy.NO_ANSWER'
{%- endif -%}
{%- endmacro %}
-{% from 'macros/view_macros.lua.j2' import view_insert_action, view_options_flags, view_answer %}
-{% from 'macros/policy_macros.lua.j2' import policy_tags_assign %}
-
-local C = require('ffi').C
+{% from 'macros/common_macros.lua.j2' import quotes %}
+{% from 'macros/view_macros.lua.j2' import view_insert_action, view_flags, view_answer %}
+{% from 'macros/policy_macros.lua.j2' import policy_flags, policy_tags_assign %}
+{% if cfg.views %}
{% for view in cfg.views %}
{% for subnet in view.subnets %}
{% if view.tags -%}
{{ view_insert_action(subnet, policy_tags_assign(view.tags)) }}
-{% elif view.answer -%}
+{% elif view.answer %}
{{ view_insert_action(subnet, view_answer(view.answer)) }}
{%- endif %}
-{{ view_insert_action(subnet, view_options_flags(view.options)) }}
+{%- set flags = view_flags(view.options) -%}
+{% if flags -%}
+{{ view_insert_action(subnet, quotes(policy_flags(flags))) }}
+{%- endif %}
{% endfor %}
{% endfor %}
+{% endif %}
-from typing import List, Optional, Union
+from typing import List, Optional
+
from typing_extensions import Literal
from knot_resolver_manager.utils.modeling import ConfigSchema
from knot_resolver_manager.datamodel.types import IDPattern, IPNetwork
options: Configuration options for clients identified by the view.
"""
- subnets: Optional[Union[List[IPNetwork], IPNetwork]]
+ subnets: List[IPNetwork]
tags: Optional[List[IDPattern]] = None
answer: Optional[Literal["allow", "refused", "noanswer"]] = None
options: ViewOptionsSchema = ViewOptionsSchema()
assert tmpl.render(rule=rule, postrule=True) == f"policy.add({rule},true)"
-def test_policy_flags():
- flags: List[PolicyFlagEnum] = ["no-cache", "no-edns"]
- tmpl_str = """{% from 'macros/policy_macros.lua.j2' import policy_flags %}
-{{ policy_flags(flags) }}"""
-
- tmpl = template_from_str(tmpl_str)
- assert tmpl.render(flags=flags[1]) == f"policy.FLAGS({{'{flags[1].upper().replace('-', '_')}'}})"
- assert (
- tmpl.render(flags=flags) == f"policy.FLAGS({{{str(flags).upper().replace('-', '_').replace(' ', '')[1:-1]},}})"
- )
-
-
def test_policy_tags_assign():
tags: List[str] = ["t01", "t02", "t03"]
tmpl_str = """{% from 'macros/policy_macros.lua.j2' import policy_tags_assign %}
assert tmpl.render(subnet=subnet, action=action) == f"assert(C.kr_view_insert_action('{ subnet }',{ action })==0)"
-def test_view_options_flags():
- tmpl_str = """{% from 'macros/view_macros.lua.j2' import view_options_flags %}
-{{ view_options_flags(options) }}"""
+def test_view_flags():
+ tmpl_str = """{% from 'macros/view_macros.lua.j2' import view_flags %}
+{{ view_flags(options) }}"""
tmpl = template_from_str(tmpl_str)
options = ViewOptionsSchema({"dns64": False, "minimize": False})
- assert tmpl.render(options=options) == "policy.FLAGS({'NO_MINIMIZE','DNS64_DISABLE',})"
- assert tmpl.render(options=ViewOptionsSchema()) == "policy.FLAGS({})"
+ assert tmpl.render(options=options) == '"NO_MINIMIZE","DNS64_DISABLE",'
+ assert tmpl.render(options=ViewOptionsSchema()) == ""
def test_view_answer():
"val,res",
[
("allow", "policy.TAGS_ASSIGN({})"),
- ("refused", "policy.REFUSE"),
- ("noanswer", "policy.NO_ANSWER"),
+ ("refused", "'policy.REFUSE'"),
+ ("noanswer", "'policy.NO_ANSWER'"),
],
)
def test_view_answer(val: Any, res: Any):
{{ view_answer(view.answer) }}"""
tmpl = template_from_str(tmpl_str)
- view = ViewSchema({"subnets": "10.0.0.0/8", "answer": val})
+ view = ViewSchema({"subnets": ["10.0.0.0/8"], "answer": val})
assert tmpl.render(view=view) == res