Skip to content

Fix domain handling to work with the latest API version#18

Open
gailingmic wants to merge 1 commit into
ionos-cloud:mainfrom
gailingmic:gailingmic-patch-1
Open

Fix domain handling to work with the latest API version#18
gailingmic wants to merge 1 commit into
ionos-cloud:mainfrom
gailingmic:gailingmic-patch-1

Conversation

@gailingmic

Copy link
Copy Markdown

Hello everyone,

i noticed that this plugin no longer worked because of an API change on your side.
I updated the _find_zone_id call by searching with the root domain instead of the subdomain to reflect that change.

Sincerely,
Michell

Fixed the _find_zone_id call by searching with the root domain instead of the subdomain
@zak905

zak905 commented Dec 9, 2025

Copy link
Copy Markdown
Contributor

Hi @gailingmic, thanks! I am looking into this asap.

@zak905

zak905 commented Dec 9, 2025

Copy link
Copy Markdown
Contributor

I tested the plug-in with a top level domain (e.g certbot-demo.de), and it worked ok. Do you have an example of an input that triggers the failure ?

Ps: the API did not change since the last release.

@gailingmic

gailingmic commented Dec 10, 2025

Copy link
Copy Markdown
Author

Hi :)

i cant provide you the exact Input but i can tell you how to replicate the issue.

Setup a domain (example.de) on DCD Cloud DNS & create A Record for test.example.de. If you now try to request the zone via the API you dont get items returned as you can see here:

GET https://dns.de-fra.ionos.com/zones?filter.zoneName=test.example.de HTTP/1.1
HTTP/1.1 200 OK
Date: Wed, 10 Dec 2025 13:12:46 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 329
Connection: close
Ionos-Request-Id: <REDACTED>
Strict-Transport-Security: max-age=31536000; includeSubDomains
Vary: Origin
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-Ratelimit-Burst: 200
X-Ratelimit-Limit: 3000
X-Ratelimit-Remaining: 0

{
  "id": "<REDACTED>",
  "type": "collection",
  "href": "https://dns.de-fra.ionos.com/zones?filter.zoneName=test.example.de\u0026limit=100\u0026offset=0",
  "items": [],
  "offset": 0,
  "limit": 100,
  "_links": {
    "self": "https://dns.de-fra.ionos.com/zones?filter.zoneName=test.example.de\u0026limit=100\u0026offset=0"
  }
}

if you now only query for the root domain you obviously get the zone correctly.

GET https://dns.de-fra.ionos.com/zones?filter.zoneName=example.de HTTP/1.1
HTTP/1.1 200 OK
Date: Wed, 10 Dec 2025 13:00:11 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 1149
Connection: close
Ionos-Request-Id: <REDACTED>
Strict-Transport-Security: max-age=31536000; includeSubDomains
Vary: Origin
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-Ratelimit-Burst: 200
X-Ratelimit-Limit: 3000
X-Ratelimit-Remaining: 0

{
  "id": "<REDACTED>",
  "type": "collection",
  "href": "https://dns.de-fra.ionos.com/zones?filter.zoneName=example.de\u0026limit=100\u0026offset=0",
  "items": [
    {
      "id": "<REDACTED>",
      "type": "zone",
      "href": "https://dns.de-fra.ionos.com/zones/<REDACTED>",
      "metadata": {
        "createdBy": "ionos:iam:cloud:<REDACTED>:users/<REDACTED>",
        "createdByUserId": "<REDACTED>",
        "createdDate": "2025-12-00T00:00:00.000000Z",
        "lastModifiedBy": "ionos:iam:cloud:<REDACTED>:users/<REDACTED>",
        "lastModifiedByUserId": "<REDACTED>",
        "lastModifiedDate": "2025-12-00T00:00:00.000000Z",
        "resourceURN": "ionos:public-dns:de-fra:31891827:zones/<REDACTED>",
        "nameservers": [
          "ns-ic.ui-dns.com",
          "ns-ic.ui-dns.de",
          "ns-ic.ui-dns.org",
          "ns-ic.ui-dns.biz"
        ],
        "state": "AVAILABLE"
      },
      "properties": {
        "description": "Example Domain",
        "enabled": true,
        "zoneName": "example.de"
      }
    }
  ],
  "offset": 0,
  "limit": 100,
  "_links": {
    "self": "https://dns.de-fra.ionos.com/zones?filter.zoneName=example.de\u0026limit=100\u0026offset=0"
  }
}

If you have a different way to send some informations your way please let me know. I can provide you with the exact example then.

Sincerely,
Michell

@gailingmic

Copy link
Copy Markdown
Author

Hello @zak905
To give a bit more context:
The example in the README.md

certbot certonly \
  --authenticator dns-ionos \
  --dns-ionos-credentials /path/to/credentials.ini \
  --dns-ionos-propagation-seconds 60 \
  --agree-tos \
  --rsa-key-size 4096 \
  -d 'example.com'

calls the function IONOSClient.add_txt_record(self, domain: str, record_name: str, record_content: str) wich results in self._find_zone_id(domain) see here being called with example.com as the argument. This will obviously work because example.com is the FQDN and root domain for this example.

BUT if you want to generate a cert for test.example.com it will fail because it will try to call self._find_zone_id(domain) with test.example.com as its argument wich isnt the root domain but its FQDN... That is the reason why im removing everything but the last 2 parts of the FQDN to get the root domain. see here

Hope that clears it up a little :)

@zak905

zak905 commented Dec 17, 2025

Copy link
Copy Markdown
Contributor

Hi @gailingmic, sorry for the late response. I tested generating a certificate for a second level domain (test-cerbot.example.com) in two ways:

  • creating an A record with the name test-certbot under the zone example.com, as you suggested. For this case, the current plugin does not work indeed. After I switched to your branch, the issuance worked.
  • creating a separate zone for the SLD (curl -H "Authorization: Bearer $TOKEN" --json '{"properties":{"zoneName":"test-certbot.example", "enabled": true}}' -v https://dns.de-fra.ionos.com/zones). With this approach, it works.

On the overall, your change looks good, and works for both cases. I am thinking if there are any additional cases we should also cover. For example, if the root zone is example.co.de, ".".join(domain.split(".")[-2:]) would return co.de

@gailingmic

Copy link
Copy Markdown
Author

Oh youre completely right... i totally forgot co.uk etc. ill push a fixed version later today

@dernapo

dernapo commented Dec 17, 2025

Copy link
Copy Markdown

@gailingmic I didn't test it yet, but it may work if you create a zone for test.example.com, instead of record "test" for the zone example.com

Precondition: example.com is a zone managed by ionos and resolving with ionos name servers

@gailingmic

Copy link
Copy Markdown
Author

@gailingmic I didn't test it yet, but it may work if you create a zone for test.example.com, instead of record "test" for the zone example.com

Precondition: example.com is a zone managed by ionos and resolving with ionos name servers

It should work but i feel this is quite excessive especially when youre creating many domains. But the more i think about this issue the more im leaning towards ionos needing to add an API endpoint / filter option to get the zone based on the FQDN provided.
Otherwise one would have to bruteforce it by removing one part of the domain until it works. And im not entirely sure if thats the desired way of going about it. 😬

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants