Skip to content

DOCS: Described the TransIP API limitations.#3

Closed
cafferata wants to merge 1 commit into
mainfrom
docs/transip-api-limitations
Closed

DOCS: Described the TransIP API limitations.#3
cafferata wants to merge 1 commit into
mainfrom
docs/transip-api-limitations

Conversation

@cafferata
Copy link
Copy Markdown
Owner

No description provided.

@cafferata cafferata force-pushed the docs/transip-api-limitations branch from 6865bb4 to 4b6dd90 Compare January 11, 2024 19:01
@cafferata cafferata force-pushed the docs/transip-api-limitations branch from 4b6dd90 to 84f046e Compare January 11, 2024 19:19
@cafferata cafferata closed this Jan 11, 2024
@cafferata cafferata deleted the docs/transip-api-limitations branch January 11, 2024 20:25
cafferata pushed a commit that referenced this pull request Dec 16, 2025
…nge (DNSControl#3855)

Fixes DNSControl#3854 

Unfortunately I couldn't run the integrationTests properly as INWX
doesn't seem to have properly updated their sandbox environment (it
still presents `int` instead of `string` like production). Hence, the
tests do fail. I don't want to run this against my own production
account, to be frank.

See:
```shell
$ curl -X POST https://api.ote.domrobot.com/xmlrpc/ -H "Content-Type: application/xml" -d '<?xml version="1.0" encoding="UTF-8"?>
<methodCall>
   <methodName>nameserver.info</methodName>
   <params>
      <param>
         <value>
            <struct>
               <member>
                  <name>user</name>
                  <value>
                     <string>[USER]</string>
                  </value>
               </member>
               <member>
                  <name>lang</name>
                  <value>
                     <string>en</string>
                  </value>
               </member>
               <member>
                  <name>pass</name>
                  <value>
                     <string>[PASS]</string>
                  </value>
               </member>
               <member>
                  <name>domain</name>
                  <value>
                     <string>[DOMAIN]</string>
                  </value>
               </member>
            </struct>
         </value>
      </param>
   </params>
</methodCall>' | xmllint --format - | grep -iE "id|roId" -C3
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  3968    0  2971  100   997  13375   4488 --:--:-- --:--:-- --:--:-- 17954
            <value>
              <struct>
                <member>
                  <name>roId</name>
                  <value>
                    <int>9677</int>
                  </value>
--
                        <value>
                          <struct>
                            <member>
                              <name>id</name>
                              <value>
                                <int>118057</int>
                              </value>
--
                        <value>
                          <struct>
                            <member>
                              <name>id</name>
                              <value>
                                <int>118060</int>
                              </value>
--
                        <value>
                          <struct>
                            <member>
                              <name>id</name>
                              <value>
                                <int>79610</int>
                              </value>
--
                        <value>
                          <struct>
                            <member>
                              <name>id</name>
                              <value>
                                <int>77243</int>
                              </value>
--
            </value>
          </member>
          <member>
            <name>svTRID</name>
            <value>
              <string>20251127--ote</string>
            </value>
```

Hence, only done manualy tests via `dnscontrol push --domains
<example.com>`:
(tested create, delete and modify)

```text
CONCURRENTLY checking for 0 zone(s)
SERIALLY checking for 1 zone(s)
Serially checking for zone: "example.tld"
CONCURRENTLY gathering records of 0 zone(s)
SERIALLY gathering records of 1 zone(s)
Serially Gathering: "example.tld"
******************** Domain: example.tld
3 corrections (PK-INWX)
#1: - DELETE _test1.example.tld TXT "123" ttl=43200
SUCCESS!
#2: ± MODIFY _test2.example.tld TXT ("1234" ttl=43200) -> ("12345" ttl=43200)
SUCCESS!
#3: + CREATE _test4.example.tld TXT "123" ttl=43200
SUCCESS!
Done. 3 corrections.
```
cafferata pushed a commit that referenced this pull request May 14, 2026
When using the Unifi provider with Unifi Network 10.2.105, a number of
errors cause DNSControl to fail to apply changes.

## Metadata in payload

```
FAILURE! failed to create record: [UNIFI] POST /integration/v1/sites/88f7af54-98f8-306a-a1c7-c9349722b1f6/dns/policies -> 400: {"statusCode":400,"statusName":"BAD_REQUEST","code":"api.request.unknown-property","message":"Unknown request body property '$.metadata'","timestamp":"2026-04-18T20:41:19.600263489Z","requestPath":"/integration/v1/sites/88f7af54-98f8-306a-a1c7-c9349722b1f6/dns/policies","requestId":"f9cceb4c-4e6d-4119-a6a6-e29fa2211b40"}
```

Looking over the documentation at
https://developer.ui.com/network/v10.1.84/creatednspolicy, it seems the
`metadata` field this provider was attempting to write to is documented
as read-only.

This PR updates the provider to no longer set the `metadata` field when
making requests to the API:
```
#3: + CREATE auth.domain.uk A 10.1.1.2 ttl=1
[UNIFI] [DEBUG] POST https://10.1.1.1/proxy/network/integration/v1/sites/88f7af54-98f8-306a-a1c7-c9349722b1f6/dns/policies
Payload: {"type":"A_RECORD","enabled":true,"domain":"auth.domain.uk","ttlSeconds":1,"ipv4Address":"10.1.1.2"}
[UNIFI] [DEBUG] Response (201): {"type":"A_RECORD","id":"a9238946-8cbe-4be5-b65e-1b5106e049c9","enabled":true,"metadata":{"origin":"USER_DEFINED"},"domain":"auth.domain.uk","ipv4Address":"10.1.1.2","ttlSeconds":1}
SUCCESS!
```

## ID in payload
The ID was provided in the path (as expected), but also the request
payload, which Unifi's validation did not like.
```
Payload: {"type":"A_RECORD","id":"e90619e0-3bce-46b3-a79e-27440ca3bb58","enabled":true,"domain":"auth.domain.uk","ipv4Address":"10.1.1.2"}
[UNIFI] [DEBUG] Response (400): {"statusCode":400,"statusName":"BAD_REQUEST","code":"api.request.unknown-property","message":"Unknown request body property '$.id'","timestamp":"2026-04-22T18:13:30.314225148Z","requestPath":"/integration/v1/sites/88f7af54-98f8-306a-a1c7-c9349722b1f6/dns/policies/e90619e0-3bce-46b3-a79e-27440ca3bb58","requestId":"003508a3-1da7-47a8-9b16-7faba232fa66"}
```

## Omitted TTL
The documentation on the Unifi site doesn't list this field as required
so I'm somewhat confused by this, however, the provider omitted this
field for a value of 300s, and this resulted in the following error:

```
[UNIFI] [DEBUG] POST https://10.1.1.1/proxy/network/integration/v1/sites/88f7af54-98f8-306a-a1c7-c9349722b1f6/dns/policies
Payload: {"type":"A_RECORD","enabled":true,"domain":"auth.domain.uk","ipv4Address":"10.1.1.2"}
[UNIFI] [DEBUG] Response (400): {"statusCode":400,"statusName":"BAD_REQUEST","code":"api.request.error","message":"ttlSeconds must not be null","timestamp":"2026-04-22T18:13:30.393200035Z","requestPath":"/integration/v1/sites/88f7af54-98f8-306a-a1c7-c9349722b1f6/dns/policies","requestId":"327b03ae-7793-476b-bedf-353c6d30bd64"}
```

I don't see any harm including it even if it matches the default (if
anything, I think it's a marginal improvement - in the event unifi
changed defaults, the config from DNSControl should be the source of
truth).

## Record pagination
When checking existing DNS record state, the existing implementation
made a single call to `GET `/v1/sites/{siteId}/dns/policies`. This had a
default limit of 25 records, so could cause errors when re-creating
existing records:
```
[UNIFI] [DEBUG] POST https://10.1.1.1/proxy/network/integration/v1/sites/88f7af54-98f8-306a-a1c7-c9349722b1f6/dns/policies
Payload: {"type":"A_RECORD","enabled":true,"domain":"auth.domain.uk","ttlSeconds":300,"ipv4Address":"10.1.1.2"}
[UNIFI] [DEBUG] Response (400): {"statusCode":400,"statusName":"BAD_REQUEST","code":"api.dns.policy.validation.record-already-exists","message":"DNS policy with the same type and properties already exists","timestamp":"2026-04-22T18:36:29.445574077Z","requestPath":"/integration/v1/sites/88f7af54-98f8-306a-a1c7-c9349722b1f6/dns/policies","requestId":"f45e7ecf-ae97-468b-9be2-1fee036c380b"}
FAILURE! failed to create record: [UNIFI] POST /integration/v1/sites/88f7af54-98f8-306a-a1c7-c9349722b1f6/dns/policies -> 400: {"statusCode":400,"statusName":"BAD_REQUEST","code":"api.dns.policy.validation.record-already-exists","message":"DNS policy with the same type and properties already exists","timestamp":"2026-04-22T18:36:29.445574077Z","requestPath":"/integration/v1/sites/88f7af54-98f8-306a-a1c7-c9349722b1f6/dns/policies","requestId":"f45e7ecf-ae97-468b-9be2-1fee036c380b"}
```
I've updated this to paginate results to ensure all records are fetched.
<!--
## Before submiting a pull request

Please make sure you've run the following commands from the root
directory.

    bin/generate-all.sh

(this runs commands like "go generate", fixes formatting, and so on)

## Release changelog section

Help keep the release changelog clear by pre-naming the proper section
in the GitHub pull request title.

Some examples:
* CICD: Add required GHA permissions for goreleaser
* DOCS: Fixed providers with "contributor support" table
* ROUTE53: Allow R53_ALIAS records to enable target health evaluation

More examples/context can be found in the file .goreleaser.yml under the
'build' > 'changelog' key.
!-->
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.

1 participant