octodns / octodns-cloudflare

Cloudflare DNS provider for octoDNS
MIT License
24 stars 18 forks source link

Proxy and auto-ttl on subdomain #89

Closed barnumbirr closed 6 months ago

barnumbirr commented 6 months ago

Hi,

I have the following www subdomain record

www:
  - type: A
    value: 213.186.33.5
  - type: TXT
    value: "4|https://example.de"

Using the latest (v0.0.4) version of octodns-cloudflare, I'd like proxy and set auto-ttl for the www subdomain as follows

www:
  octodns:
    cloudflare:
      proxied: true
      auto-ttl: true
  - type: A
    value: 213.186.33.5
  - type: TXT
    value: "4|https://example.de"

however this results in the following stacktrace:

Traceback (most recent call last):
  File "/usr/local/bin/octodns-sync", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/octodns/cmds/sync.py", line 62, in main
    manager.sync(
  File "/usr/local/lib/python3.11/dist-packages/octodns/manager.py", line 769, in sync
    ps, d = future.result()
            ^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/octodns/manager.py", line 62, in result
    return self.func(*self.args, **self.kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/octodns/manager.py", line 509, in _populate_and_plan
    source.populate(zone, lenient=lenient)
  File "/usr/local/lib/python3.11/dist-packages/octodns/provider/yaml.py", line 363, in populate
    self._populate_from_file(source, zone, lenient)
  File "/usr/local/lib/python3.11/dist-packages/octodns/provider/yaml.py", line 307, in _populate_from_file
    yaml_data = safe_load(fh, enforce_order=self.enforce_order)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/octodns/yaml.py", line 71, in safe_load
    return load(stream, SortEnforcingLoader if enforce_order else ContextLoader)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/yaml/__init__.py", line 81, in load
    return loader.get_single_data()
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/yaml/constructor.py", line 49, in get_single_data
    node = self.get_single_node()
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/yaml/composer.py", line 36, in get_single_node
    document = self.compose_document()
               ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/yaml/composer.py", line 55, in compose_document
    node = self.compose_node(None, None)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/yaml/composer.py", line 84, in compose_node
    node = self.compose_mapping_node(anchor)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/yaml/composer.py", line 133, in compose_mapping_node
    item_value = self.compose_node(node, item_key)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/yaml/composer.py", line 84, in compose_node
    node = self.compose_mapping_node(anchor)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/yaml/composer.py", line 127, in compose_mapping_node
    while not self.check_event(MappingEndEvent):
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/yaml/parser.py", line 98, in check_event
    self.current_event = self.state()
                         ^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/yaml/parser.py", line 438, in parse_block_mapping_key
    raise ParserError("while parsing a block mapping", self.marks[-1],
yaml.parser.ParserError: while parsing a block mapping
  in "./config/personal/example.com.yaml", line 70, column 3
expected <block end>, but found '-'
  in "./config/personal/example.com.yaml", line 74, column 3

Is there now way to manage a subdomain with multiple entries while using proxy?

ross commented 6 months ago

The multi-type setup is an array of record details, each starting with the - so the octodns bit needs to live under the one of those you'd like it to apply to, something like:

www:
  - octodns:
       cloudflare:
         proxied: true
         auto-ttl: true
    type: A
    value: 213.186.33.5
  - type: TXT
    value: "4|https://example.de"

There's a lot to not like about YAML, it's the best of not great options, but arrays are probably my least favorite and regardless is the most non-obvious.

barnumbirr commented 6 months ago

Ah, I see. I'd like the octodns bit to apply to both records so I ended up doing something like this:

www:
  - octodns:
      cloudflare:
        proxied: true
        auto-ttl: true
    type: A
    value: 213.186.33.5
  - octodns:
      cloudflare:
        proxied: true
        auto-ttl: true
    type: TXT
    value: "4|https://example.de"

I would say that this all makes sense in my head now but that would be a lie. The joys of YAML... 😏 Thanks for your help!

ross commented 6 months ago

For bonus points/if you're going to be using that block a lot you can utilize YAML anchors to avoid some duplication, haven't tested it, but I think this should work.

www:
  - octodns: &SHARED_OCTODNS
      cloudflare:
        proxied: true
        auto-ttl: true
    type: A
    value: 213.186.33.5
  - octodns: *SHARED_OCTODNS
    type: TXT
    value: "4|https://example.de"

There's a bit more detail and description in the basic example https://github.com/octodns/octodns/blob/main/examples/basic/config/my-domain.com.yaml

barnumbirr commented 6 months ago

Thanks, it works. Also, my mind is blown as I had no idea YAML anchors were a thing in octodns.

ross commented 6 months ago

Also, my mind is blown as I had no idea YAML anchors were a thing in octodns

They're actually part of the YAML standard and supported by pyyaml. The rabbit hole goes much much deeper, but that's kind of where I stop with things as they quickly get more complicated/confusing than useful.