###### Working notes about configuration schema


## TODO nit: nest one level deeper inside `dnssec`, probably
dnssec:
  keep-removed: 0
  refresh-time: 10s
  hold-down-time: 30d

## TODO nit: I don't like this name, at least not for the experimental thing we have there
network:
  tls:
    auto_discovery: boolean

#### General questions
Plurals: do we name attributes in plural if they're a list;
  some of them even allow a non-list if using a single element.


#### New-policy brainstorming

dnssec:
  # Convert to key: style instead of list?
  #  - easier to handle in API/CLI (which might be a common action on names with broken DNSSEC)
  #  - allows to supply a value - stamp for expiration of that NTA
  #    (absolute time, but I can imagine API/CLI converting from duration when executed)
  #  - syntax isn't really more difficult, mainly it forces one entry per line (seems OK)
  negative-trust-anchors:
    example.org:
    my.example.net:


view:
  # When a client request arrives, based on the `view` class of rules we may either
  # decide for a direct answer or for marking the request with a set of tags.
  # The concepts of matching and actions are a very good fit for this,
  # and that matches our old policy approach. Matching here should avoid QNAME+QTYPE;
  # instead it's e.g. suitable for access control.
  # RPZ files also support rules that fall into this `view` class.
  #
  # Selecting a single rule: the most specific client-IP prefix
  # that also matches additional conditions.
  - subnet: [ 0.0.0.0/0, ::/0 ]
    answer: refused
    # some might prefer `allow: refused` ?
    # Also, RCODEs are customary in CAPITALS though maybe not in configs.

  - subnet: [ 10.0.0.0/8, 192.168.0.0/16 ]
    # Adding `tags` implies allowing the query.
    tags: [ t1, t2, t3 ] # theoretically we could use space-separated string
    options: # only some of the global options can be overridden in view
      minimize: true
      dns64: true
      rate-limit: # future option, probably (optionally?) structured
    # LATER: rulesets are a relatively unclear feature for now.
    #   Their main point is to allow prioritization and avoid
    #   intermixing rules that come from different sources.
    #   Also some properties might be specifyable per ruleset.
    ruleset: tt

  - subnet: [ 10.0.10.0/24 ] # maybe allow a single value instead of a list?
      # LATER: special addresses?
      #   - for kresd-internal requests
      #   - shorthands for all private IPv4 and/or IPv6;
      #     though yaml's repeated nodes could mostly cover that
      #     or just copy&paste from docs
    answer: allow

# Or perhaps a more complex approach?  Probably not.
# We might have multiple conditions at once and multiple actions at once,
# but I don't expect these to be common, so the complication is probably not worth it.
# An advantage would be that the separation of the two parts would be more visible.
view:
  - match:
      subnet: [ 10.0.0.0/8, 192.168.0.0/16 ]
    do:
      tags: [ t1, t2, t3 ]
      options: # ...


local-data: # TODO: name
  #FIXME: tags - allow assigning them to (groups of) addresses/records.

  addresses: # automatically adds PTR records and NODATA (LATER: overridable NODATA?)
    foo.bar: [ 127.0.0.1, ::1 ]
    my.pc.corp: 192.168.12.95
  addresses-files: # files in /etc/hosts format (and semantics like `addresses`)
    - /etc/hosts

  # Zonefile format seems quite handy here.  Details:
  #  - probably use `local-data.ttl` from model as the default
  #  - and . root to avoid confusion if someone misses a final dot.
  records: |
    example.net. TXT "foo bar"
     A 192.168.2.3
     A 192.168.2.4
    local.example.org AAAA ::1

  subtrees:
  nodata: true # impl ATM: defaults to false, set (only) for each rule/name separately
  # impl: options like `ttl` and `nodata` might make sense to be settable (only?) per ruleset

  subtrees: # TODO: perhaps just allow in the -tagged style, if we can't avoid lists anyway?
    - type: empty
      roots: [ sub2.example.org ] # TODO: name it the same as for forwarding
      tags: [ t2 ]
    - type: nxdomain
      # Will we need to support multiple file formats in future and choose here?
      roots-file: /path/to/file.txt
    - type: empty
      roots-url: https://example.org/blocklist.txt
      refresh: 1d
      # Is it a separate ruleset?  Optionally?  Persistence?
      # (probably the same questions for local files as well)

    - type: redirect
      roots: [ sub4.example.org ]
      addresses: [ 127.0.0.1, ::1 ]

local-data-tagged: # TODO: name (view?); and even structure seems unclear.
  # TODO: allow only one "type" per list entry?  (addresses / addresses-files / subtrees / ...)
  - tags: [ t1, t2 ]
    addresses: #... otherwise the same as local-data
  - tags: [ t2 ]
    records: # ...
  - tags: [ t3 ]
    subtrees: empty
    roots: [ sub2.example.org ]

local-data-tagged: # this avoids lists, so it's relatively easy to amend through API
  "t1 t2": # perhaps it's not nice that tags don't form a proper list?
    addresses:
      foo.bar: [ 127.0.0.1, ::1 ]
  t4:
    addresses:
      foo.bar: [ 127.0.0.1, ::1 ]
local-data: # avoids lists and merges into the untagged `local-data` config subtree
  tagged:   # (getting quite deep, though)
    t1 t2:
      addresses:
        foo.bar: [ 127.0.0.1, ::1 ]
# or even this ugly thing:
local-data-tagged t1 t2:
  addresses:
    foo.bar: [ 127.0.0.1, ::1 ]

forward: # TODO: "name" is from Unbound, but @vcunat would prefer "subtree" or something.
  - name: '.' # Root is the default so could be omitted?
    servers: [2001:148f:fffe::1, 2001:148f:ffff::1, 185.43.135.1, 193.14.47.1]
  # TLS forward, server authenticated using hostname and system-wide CA certificates
  # https://www.knot-resolver.cz/documentation/latest/modules-policy.html?highlight=forward#tls-examples
  - name: '.'
    servers:
      - address: [ 192.0.2.1, 192.0.2.2@5353 ]
        transport: tls
        pin-sha256: Wg==
      - address: 2001:DB8::d0c
        transport: tls
        hostname: res.example.com
        ca-file: /etc/knot-resolver/tlsca.crt
    options:
      # LATER: allow a subset of options here, per sub-tree?
      # Though that's not necessarily related to forwarding (e.g. TTL limits),
      # especially implementation-wise it probably won't matter.


# Too confusing approach, I suppose?  Different from usual way of thinking but closer to internal model.
# Down-sides:
#   - multiple rules for the same name won't be possible (future, with different tags)
#   - loading names from a file won't be possible (or URL, etc.)
rules:
  example.org: &fwd_odvr
    type: forward
    servers: [2001:148f:fffe::1, 2001:148f:ffff::1, 185.43.135.1, 193.14.47.1]
  sub2.example.org:
    type: empty
    tags: [ t3, t5 ]
  sub3.example.org:
    type: forward-auth
    dnssec: no


# @amrazek: current valid config

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

local-data:
  ttl: 1d
  nodata: true
  addresses:
    foo.bar: [ 127.0.0.1, "::1" ]
    my.pc.corp: 192.168.12.95
  addresses-files:
    - /etc/hosts
  records: |
    example.net. TXT "foo bar"
     A 192.168.2.3
     A 192.168.2.4
    local.example.org AAAA ::1
  subtrees:
    - type: empty
      roots: [ sub2.example.org ]
      tags: [ t2 ]
    - type: nxdomain
      roots-file: /path/to/file.txt
    - type: empty
      roots-url: https://example.org/blocklist.txt
      refresh: 1d
    - type: redirect
      roots: [ sub4.example.org ]
      addresses: [ 127.0.0.1, "::1" ]

forward:
  - subtree: '.'
    servers:
      - address: [ 192.0.2.1, 192.0.2.2@5353 ]
        transport: tls
        pin-sha256: Wg==
      - address: 2001:DB8::d0c
        transport: tls
        hostname: res.example.com
        ca-file: /etc/knot-resolver/tlsca.crt
    options:
      dnssec: true  # default
  - subtree: 1.168.192.in-addr.arpa
    servers: [ 192.0.2.1@5353 ]
    options:
      dnssec: false # policy.STUB?
