Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cloudflare_dns: unable to add SRV records using example from docs #5167

Closed
1 task done
martin-schlossarek opened this issue Aug 24, 2022 · 13 comments
Closed
1 task done
Labels
bug This issue/PR relates to a bug has_pr module module net_tools plugins plugin (any type)

Comments

@martin-schlossarek
Copy link

martin-schlossarek commented Aug 24, 2022

Summary

I'm unable to add SRV records using the example from the official documentation:

- name: Create an SRV record _foo._tcp.example.net
  community.general.cloudflare_dns:
    domain: example.net
    service: foo
    proto: tcp
    port: 3500
    priority: 10
    weight: 20
    type: SRV
    value: fooserver.example.net

This will result in an api error:

failed: [localhost] (item={...}) => {
    "ansible_loop_var": "item",
    "changed": false,
    "invocation": {
        "module_args": {
            "account_api_key": null,
            "account_email": null,
            "algorithm": null,
            "api_token": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
            "cert_usage": null,
            "hash_type": null,
            "key_tag": null,
            "port": 3500,
            "priority": 10
            "proto": "tcp",
            "proxied": false,
            "record": "@",
            "selector": null,
            "service": "foo",
            "solo": null,
            "state": "present",
            "timeout": 30,
            "ttl": 1,
            "type": "SRV",
            "value": "fooserver.example.net",
            "weight": 20,
            "zone": "example.net"
        }
    },
    "item": {
        ...
    },
    "msg": "API bad request; Status: 400; Method: POST: Call: /zones/$somehash/dns_records; Error details: code: 1004, error: DNS Validation Error; code: 9000, error: DNS name is invalid.; "
} 

After digging a little bit in the code I noticed that the name item requires the record item to be set (which is not documented): https://github.com/ansible-collections/community.general/blob/main/plugins/modules/net_tools/cloudflare_dns.py#L690

In order to get this to work you have to modify the yaml to:

- name: Create an SRV record _foo._tcp.example.net
  community.general.cloudflare_dns:
    domain: example.net
    service: foo
    proto: tcp
    port: 3500
    priority: 10
    weight: 20
    type: SRV
    value: fooserver.example.net
    record: _foo._tcp  # required!

Either the record item should be generated automatically or setting proto and service is useless.

EDIT: Does also not work. This will create an "_foo._tcp._foo._tcp.example.net" entry

Issue Type

Bug Report

Component Name

cloudflare_dns

Ansible Version

$ ansible --version
ansible [core 2.12.5]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/user/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.10/site-packages/ansible
  ansible collection location = /home/user/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.10.4 (main, Mar 25 2022, 00:00:00) [GCC 12.0.1 20220308 (Red Hat 12.0.1-0)]
  jinja version = 3.0.3
  libyaml = True

Community.general Version

$ ansible-galaxy collection list community.general
# /usr/lib/python3.10/site-packages/ansible_collections
Collection        Version
----------------- -------
community.general 4.8.1

# /home/user/.ansible/collections/ansible_collections
Collection        Version
----------------- -------
community.general 5.1.0

Configuration

$ ansible-config dump --only-changed

OS / Environment

Fedora 36

Steps to Reproduce

- name: Create an SRV record _foo._tcp.example.net
  community.general.cloudflare_dns:
    domain: example.net
    service: foo
    proto: tcp
    port: 3500
    priority: 10
    weight: 20
    type: SRV
    value: fooserver.example.net

Expected Results

domain entries should be added

Actual Results

api error

Code of Conduct

  • I agree to follow the Ansible Code of Conduct
@ansibullbot
Copy link
Collaborator

Files identified in the description:

If these files are incorrect, please update the component name section of the description or use the !component bot command.

click here for bot help

@ansibullbot
Copy link
Collaborator

@ansibullbot ansibullbot added bug This issue/PR relates to a bug module module net_tools plugins plugin (any type) labels Aug 24, 2022
@martin-schlossarek
Copy link
Author

After fiddling aroung with the raw cloudflare api I think I found the problem.

In line 404 record is set to zone if no custom record was set.

        if self.record == '@':
            self.record = self.zone

In line 690 record is spliced to a zero length string (if no custom record was given)

	                "name": params['record'][:-len('.' + params['zone'])],

This results in an empty name and throws errors at the cloudflare api.

In order to get this to work you have to specify a record like this:

  • @.example.net or example.net.example.net for the root domain
  • subdomain.example.net for subdomains

Is this really intended? All other record types (a, aaaa, cname, ...) expect record to be the shortname of the subdomain or @

@martin-schlossarek
Copy link
Author

The easiest fix would be to simply remove the splicing of record.

@@ -7,7 +7,7 @@
                 "port": params['port'],
                 "weight": params['weight'],
                 "priority": params['priority'],
-                "name": params['record'][:-len('.' + params['zone'])],
+                "name": params['record'],
                 "proto": params['proto'],
                 "service": params['service']
             }

martin-schlossarek pushed a commit to martin-schlossarek/community.general that referenced this issue Aug 25, 2022
This commit removes the splicing of the record entry which resulted in malformed api calls. record must be the name of the subdomain or "@"
@felixfontein
Copy link
Collaborator

The easiest fix would be to simply remove the splicing of record.

But isn't that breaking the module for everyone who creates a SRV entry for a proper subdomain?

How about to simply replace params['record'][:-len('.' + params['zone'])] by params['record'][:-len('.' + params['zone'])] or '@' to make sure that if the result is empty, @ is used?

@martin-schlossarek
Copy link
Author

martin-schlossarek commented Aug 27, 2022

Why? Just use the subdomain as record like in a, aaaa, cname ... entries:

- name: Create SRV records
  community.general.cloudflare_dns:
    zone: mydomain.tld
    record: subdomain
    type: SRV
    proto: tcp
    service: mysrv
    value: example.com
    port: 443
    api_token: "{{ cloudflare_api_token }}"

This works with my modified code:

image

@felixfontein
Copy link
Collaborator

I don't know, I neither wrote the original code nor am using that API. You wrote

This results in an empty name and throws errors at the cloudflare api.

which indicates that the empty string is a problem. That's why I did that suggestion.

I still don't know whether your change breaks the module for use-cases that worked so far or not.

@martin-schlossarek
Copy link
Author

which indicates that the empty string is a problem. That's why I did that suggestion.

Actually this is not the only problem. The whole line makes no sense to me.:

"name": params['record'][:-len('.' + params['zone'])],

Quick test:

def test(record, zone ):
  print("name: ''" + record[:-len('.' + zone)])

>>> test("@", "example.net")
name: ''
>>> test("", "example.net")
name: ''
>>> test("subdomain", "example.net")
name: ''
>>> test("verylongsubdomain", "example.net")
name: 'veryl'
>>> test("another.subdomain", "example.net")
name: 'anoth'
>>> test("subdomain.example.net", "example.net")
name: 'subdomain'
>>> test("@.example.net", "example.net")
name: '@'

@felixfontein
Copy link
Collaborator

The way I understand it, record is supposed to be the full FQDN. So basically the examples in

>>> test("@", "example.net")
name: ''
>>> test("", "example.net")
name: ''
>>> test("subdomain", "example.net")
name: ''
>>> test("verylongsubdomain", "example.net")
name: 'veryl'
>>> test("another.subdomain", "example.net")
name: 'anoth'

make no sense.

@felixfontein
Copy link
Collaborator

But then, this is contrary to what the docs say: https://github.com/ansible-collections/community.general/blob/main/plugins/modules/net_tools/cloudflare_dns.py#L88-L95

Now the problem is that if someone was using this module with specifying the record for SRV records in the way the module expected it, then your change will suddenly break them. Since this has been the behavior for the module for at least the last 3+ years, this is not a good idea.

@felixfontein
Copy link
Collaborator

In fact, this change has been there since December 2016: ansible/ansible@85d41db

@ansibullbot
Copy link
Collaborator

Files identified in the description:

If these files are incorrect, please update the component name section of the description or use the !component bot command.

click here for bot help

@felixfontein
Copy link
Collaborator

Should be fixed by #5972. That fix will appear in the next 5.x.y and 6.x.y releases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This issue/PR relates to a bug has_pr module module net_tools plugins plugin (any type)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants