API for DNS management

Endre Ottem

Verified User
Joined
Jul 4, 2019
Messages
13
Hi guys!

Like many others, I'm currently in the process of moving from cPanel to DirectAdmin. We have spent years developing our own admin and client area using API calls to cPanel. We are now in the process of rewriting them to work with DirectAdmin, but find some things missing in the API docs - and also some weird output, especially in the API for fetching, adding and updating DNS records.

When I fetch all DNS records for a domain, this is what I get:
Code:
Array
(
    [A] => endretest=1.2.3.4
    [endretest2] => 1.2.3.5
    [ftp] => 1.2.3.4
    [mail] => 1.2.3.4
    [pop] => 1.2.3.4
    [smtp] => 1.2.3.4
    [www] => 1.2.3.4
    [domainname_no_] => 1.2.3.4
NS=ns1.domainname.no.=domainname.no.
    [ns2_domainname_no_] => domainname.no.
MX=mail=10
CNAME=
PTR=
TXT=domainname.no.="v=spf1 a mx ip4:1.2.3.4 ~all"
AAAA=
SRV=
SPF=
TLSA=
CAA=
DS=

)

The first A-record looks like this:
[A] => endretest=1.2.3.4

A is the key, while the value contains the pointer name (endretest) and the pointer value (1.2.3.4).

The subsequent A-records look like this:
[endretest2] => 1.2.3.5
[ftp] => 1.2.3.4
[mail] => 1.2.3.4

Here, the pointer name is the key (e.g. "endretest2") and the value is the pointer value (ip address).

Further down the list, it gets even weirder. After listing the A records, there's only two records left in the array:
key:
Code:
domainname_no_
value:
Code:
1.2.3.4 NS=ns1.domainname.no.=domainname.no.

key:
Code:
ns2_domainname_no_
value:
Code:
domainname.no. MX=mail=10 CNAME= PTR= TXT=domainname.no.="v=spf1 a mx ip4:1.2.3.4 ~all" AAAA= SRV= SPF= TLSA= CAA= DS=

I've tried using both:
Code:
/CMD_API_DNS_CONTROL?domain=domainname.no&info=yes&urlencoded=yes

and:
Code:
/CMD_API_DNS_ADMIN?domain=domainname.no&info=yes&urlencoded=yes

Can anyone explain the logic to me? Or is there some other commands that does this in a more logical way?

Also, I can't seem to find any docs for adding, updating or deleting records in the zone. Perhaps I'm not looking at the right place (the API docs are a bit "unstructured").
 
I'm guessing the lack of replies means that the API doesn't really have a way of fetching and showing the contens of a zone file in a way that makes sense? I have tried to search the forums and on the Internet, but it doesn't seem like there exists a good solution. I don't quite understand the logic of the output in my post above, except that there doesn't seem to be any logic. Or is it a bug? :confused:

I have figured out most of the DirectAdmin API (not thanks to the docs, unfortunately). At least the things we have been trying to achieve so far has worked, so it's a bit of a bummer to be stuck on something as simple as getting the records from a zone file.

What I was hoping for, and kinda expecting, was something like the way the cPanel API presents the records of a zone file:
Code:
Array
(
    [0] => Array
        (
            [ttl] => 86400
            [line] => 1
            [raw] => ; cPanel first:78.0.21 (update_time):1559139678 Cpanel::ZoneFile::VERSION:1.3 hostname:cp09.domainname.com latest:78.0.24
            [Line] => 1
            [type] => :RAW
            [record] => 
        )

    [1] => Array
        (
            [Line] => 2
            [raw] => ; Zone file for apitest.com
            [type] => :RAW
            [record] => 
            [ttl] => 86400
            [line] => 2
        )

    [2] => Array
        (
            [record] => 
            [type] => $TTL
            [line] => 3
            [Line] => 3
            [ttl] => 14400
        )

    [3] => Array
        (
            [serial] => 2019052902
            [retry] => 1800
            [Lines] => 6
            [line] => 4
            [minimum] => 86400
            [Line] => 4
            [class] => IN
            [name] => apitest.com.
            [ttl] => 86400
            [mname] => cp09.domainname.com
            [rname] => cp09.domainname2.com
            [expire] => 1209600
            [type] => SOA
            [refresh] => 3600
            [record] => 
        )

    [4] => Array
        (
            [Line] => 10
            [raw] => 
            [type] => :RAW
            [record] => 
            [ttl] => 86400
            [line] => 10
        )

    [5] => Array
        (
            [ttl] => 86400
            [name] => apitest.com.
            [class] => IN
            [line] => 11
            [nsdname] => cp09.domainname.com
            [Line] => 11
            [record] => 
            [type] => NS
        )

    [6] => Array
        (
            [Line] => 12
            [type] => NS
            [record] => 
            [class] => IN
            [ttl] => 86400
            [name] => apitest.com.
            [line] => 12
            [nsdname] => ns2.domainname.com
        )

    [7] => Array
        (
            [record] => 
            [type] => :RAW
            [raw] => 
            [Line] => 13
            [line] => 13
            [ttl] => 86400
        )

    [8] => Array
        (
            [raw] => 
            [Line] => 14
            [record] => 
            [type] => :RAW
            [ttl] => 86400
            [line] => 14
        )

    [9] => Array
        (
            [Line] => 15
            [type] => A
            [record] => 1.2.3.50
            [address] => 1.2.3.50
            [class] => IN
            [name] => apitest.com.
            [ttl] => 14400
            [line] => 15
        )

    [10] => Array
        (
            [Line] => 16
            [raw] => 
            [record] => 
            [type] => :RAW
            [ttl] => 86400
            [line] => 16
        )

    [11] => Array
        (
            [class] => IN
            [ttl] => 14400
            [name] => apitest.com.
            [line] => 17
            [exchange] => mail.apitest.com
            [Line] => 17
            [type] => MX
            [record] => 
            [preference] => 10
        )

    [12] => Array
        (
            [raw] => 
            [Line] => 18
            [type] => :RAW
            [record] => 
            [ttl] => 86400
            [line] => 18
        )

    [13] => Array
        (
            [type] => CNAME
            [record] => apitest.com
            [Line] => 19
            [cname] => apitest.com
            [line] => 19
            [class] => IN
            [name] => mail.apitest.com.
            [ttl] => 14400
        )

    [14] => Array
        (
            [name] => www.apitest.com.
            [ttl] => 14400
            [class] => IN
            [line] => 20
            [cname] => apitest.com
            [Line] => 20
            [record] => apitest.com
            [type] => CNAME
        )

    [15] => Array
        (
            [address] => 1.2.3.51
            [record] => 1.2.3.51
            [type] => A
            [Line] => 21
            [line] => 21
            [ttl] => 14400
            [name] => ftp.apitest.com.
            [class] => IN
        )

    [16] => Array
        (
            [Line] => 22
            [type] => TXT
            [record] => v=spf1 ip4:1.2.3.50 +a +mx ~all
            [class] => IN
            [ttl] => 14400
            [name] => apitest.com.
            [line] => 22
            [unencoded] => 1
            [char_str_list] => Array
                (
                    [0] => "v=spf1 ip4:1.2.3.50 +a +mx ~all"
                )

            [txtdata] => v=spf1 ip4:1.2.3.50 +a +mx ~all
        )

    [17] => Array
        (
            [line] => 23
            [class] => IN
            [ttl] => 14400
            [name] => cpcontacts.apitest.com.
            [type] => A
            [record] => 1.2.3.50
            [address] => 1.2.3.50
            [Line] => 23
        )

    [18] => Array
        (
            [class] => IN
            [ttl] => 14400
            [name] => webmail.apitest.com.
            [line] => 24
            [Line] => 24
            [type] => A
            [record] => 1.2.3.50
            [address] => 1.2.3.50
        )

    [19] => Array
        (
            [line] => 25
            [ttl] => 14400
            [name] => cpcalendars.apitest.com.
            [class] => IN
            [record] => 1.2.3.50
            [address] => 1.2.3.50
            [type] => A
            [Line] => 25
        )

    [20] => Array
        (
            [Line] => 26
            [type] => A
            [address] => 1.2.3.50
            [record] => 1.2.3.50
            [class] => IN
            [ttl] => 14400
            [name] => webdisk.apitest.com.
            [line] => 26
        )

    [21] => Array
        (
            [line] => 27
            [class] => IN
            [ttl] => 14400
            [name] => whm.apitest.com.
            [type] => A
            [address] => 1.2.3.50
            [record] => 1.2.3.50
            [Line] => 27
        )

    [22] => Array
        (
            [class] => IN
            [ttl] => 14400
            [name] => cpanel.apitest.com.
            [line] => 28
            [Line] => 28
            [type] => A
            [record] => 1.2.3.50
            [address] => 1.2.3.50
        )

    [23] => Array
        (
            [type] => TXT
            [record] => v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyfs4sZ/zrLohEFtigMfE8B+XoswujgIcM7uJH2M2/B9CIlD6+oxM6uIjy27AVKLam+NKz2MHoRyIWgqrl76+43SqwbmXZRvYBxzM1Rh2bs2/bzjauvMR8P0uduA7Nvnf6oy5yi+TywgxbZDaJZ2ubtmszySBXXkqBdA985QIMv+fDp3K64frIskISA2L7jGLTaIDuetpZO7b1e0QhGYJy5vgooNccBvgRrag0sxu/4Ot3H4w9Fr0KRnwqoxiRriBbsplghBfri01GaX17btbRqPdftymALp/2+lZ9d31OAa7ugFuCz9fsT2YJ04muLkxomayYvwIkMGAqcNaLiQnwIDAQAB;
            [Line] => 29
            [line] => 29
            [unencoded] => 1
            [txtdata] => v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyfs4sZ/zrLohhEFtigMfE8B+XoswujgIcM7uJH2M2/B9CIlD6+oxM6uIjy27AVKLam+NKz2MHoRyIWgqrl76+43SqwbmXZRvYBxzM1Rh2bs2/bzjauvMR8P0uduA7Nvnf6oy5yi+TywgxbZDaJZ2ubtmszySBXXkqBdA985QIMv+fDp3K64frIskISA2L7jGLTaIDuetpZO7b1e0QhGYJy5vgooNccBvgRrag0sxu/4Ot3H4w9Fr0KRnwqoxiRriBbsplghBfri01GaX17btbRqPdftymALp/2+lZ9d31OAa7ugFuCz9fsT2YJ04muLkxomayYvwIkMGAqcNaLiQnwIDAQAB;
            [char_str_list] => Array
                (
                    [0] => "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQhEFtigCgKCAQEAsyfs4sZ/zrLohIeyHkMfE8B+XoswujgIcM7uJH2M2/B9CIlD6+oxM6uIjy27AVHufn+NKz2MHoRyIWgqrl76+43SqwbmXZRvYBxzM1Rh2bs2/bzjauvMR8P0uduA7Nvnf6oy5yi+TywgxbZDaJZ2ubtmszySBXXkqBdA985QIMv+fDp3K64frIskISL7jGL"
                    [1] => TaIDuetpZO7b1e0QhGYJy5vgooNccBvgRrag0sxu/4Ot3H4w9hEFtigwqoxiRriBbsplghBfri01GaX17btbRqPdftymALp/2+lZ9d31OAa7ugFuCz9fsT2YJ04KLamxomayYvwIkMGAqcNaLiQnwIDAQAB\;
                )

            [class] => IN
            [ttl] => 14400
            [name] => default._domainkey.apitest.com.
        )

    [24] => Array
        (
            [ttl] => 300
            [name] => subdomene.apitest.com.
            [class] => IN
            [line] => 30
            [Line] => 30
            [address] => 1.2.3.4
            [record] => 1.2.3.4
            [type] => A
        )

    [25] => Array
        (
            [address] => 11.22.11.22
            [record] => 11.22.11.22
            [type] => A
            [Line] => 31
            [line] => 31
            [name] => subdomene.apitest.com.
            [ttl] => 300
            [class] => IN
        )

    [26] => Array
        (
            [line] => 32
            [ttl] => 300
            [name] => endretester.apitest.com.
            [class] => IN
            [address] => 109.44.55.123
            [record] => 109.44.55.123
            [type] => A
            [Line] => 32
        )

    [27] => Array
        (
            [Line] => 33
            [type] => AAAA
            [record] => 2a01:4f8:c2c:ac91:0:0:0:2
            [address] => 2a01:4f8:c2c:ac91:0:0:0:2
            [class] => IN
            [ttl] => 14400
            [name] => ipv6.apitest.com.
            [line] => 33
        )

    [28] => Array
        (
            [port] => 5060
            [line] => 34
            [priority] => 10
            [weight] => 100
            [ttl] => 14400
            [name] => _sip._tcp.apitest.com.
            [target] => target.server.com
            [class] => IN
            [record] => 
            [type] => SRV
            [Line] => 34
        )

)

I've been struggling with this one thing for days now, so I would really appreciate it if someone could point me in the right direction. If DirectAdmin's API can't serve DNS records in another way than what I'm showing in my previous post, please let me know. I would rather not spend even more hours trying to do something that isn't actually doable. :p
 
Hello,

Open in a browser /CMD_API_DNS_ADMIN?domain=domain%2Ecom and you will see a DNS zone in its raw text format.

If you need a structured output you can request a JSON-formated output: see /CMD_API_DNS_ADMIN?domain=domain%2Ecom&json=yes&redirect=yes


Good thing about DirectAdmin API is that you can connect to a server as admin using a regular endpoint and then request an API in the same browser's session (true for GET requests).
 
Hello,

Open in a browser /CMD_API_DNS_ADMIN?domain=domain%2Ecom and you will see a DNS zone in its raw text format.

If you need a structured output you can request a JSON-formated output: see /CMD_API_DNS_ADMIN?domain=domain%2Ecom&json=yes&redirect=yes


Good thing about DirectAdmin API is that you can connect to a server as admin using a regular endpoint and then request an API in the same browser's session (true for GET requests).

Thanks Alex!

Turns out to be completely my fault. In order to get straight into testing the API quickly, I simply rewrote some code I've been using for another API (I believe it was for Virtualmin). The function I used to fetch and return the data did a string to array conversion that completely f**cked up the result. Looking at the result I got directly in the browser made me realize I was doing something wrong, so that was a great tip. :)

The JSON output is perfectly formatted.
 
Found another obstacle. I created a new MX record in DirectAdmin. Instead of putting it on the domain itself, I wanted it on a subdomain - like this:
Code:
subdomain.domainname.com.  MX  10  target.server.com.

The subdomain is ommited in the API result, so it appears to be placed on the domain name:
Code:
{
"type": "MX",
"name": "target.n247.no.",
"value": "10",
"combined": "name=target.n247.no.&value=10"
}
 
Hello,

This is the related change:
https://www.directadmin.com/features.php?id=1497

so add full_mx_records=yes to the request, and you'll get the correct output.
It's inverse due to the old container class not allowing duplicate "left-side" items, so a domain.com. zone couldn't have multiple MX records, so the design was to flip it, so the MX server (right-side) was the index, and the 10 priority was the value.
But with id=1497, duplicates were allowed in the container (assuming they had a different "10 mx.domain.com." right-side).

Sample json call/output:
Code:
CMD_DNS_ADMIN?domain=test.com&full_mx_records=yes&json=yes
output:
Code:
        {
            "type": "MX",
            "name": "test.com.",
            "value": "10 mail",
            "combined": "name=test.com.&value=10 mail",
            "ttl": "14400"
        },
Sorry for the confusion. We are working on a better KB and versioning system which should help unify things into one place.

John
 
Back
Top