I always getting the same error (Create domain ‘example.com’ failed) (or any domain) when trying to create new DNS zone with Powerdns API call.
My request:
$ch = curl_init(); curl_setopt($ch, CURLOPT_URL,'http://127.0.0.1:953/api/v1/servers/localhost/zones'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, "{"name":"example.com.", "kind":"Native", "masters": [], "nameservers":["ns1.example.com.", "ns2.example.com."]}"); $headers = array(); $headers[] = 'X-Api-Key: MY-KEY'; $headers[] = 'Accept: application/json'; $headers[] = 'Content-Type: application/json'; curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); $result = curl_exec($ch); if (curl_errno($ch)) { echo 'Error:' . curl_error($ch); } curl_close($ch);
Similar api call to get a list of DNS zones is working. GET request work properly but not POST. Can anyone help, please?
My pdns.conf file is:
api=yes api-key=MY-KEY
Maybe i have to change something in settings of my powerdns, idk really. I would be very grateful for any help!
Server response after POST request is 422 error (Unprocessable Entity)
HTTP/1.1 422 Unprocessable Entity Access-Control-Allow-Origin: * Connection: close Content-Length: 52 Content-Security-Policy: default-src ‘self’; style-src ‘self’ ‘unsafe-inline’ Content-Type: application/json Server: PowerDNS/4.4.1 X-Content-Type-Options: nosniff X-Frame-Options: deny X-Permitted-Cross-Domain-Policies: none X-Xss-Protection: 1; mode=block
This is my pdns.conf file cat /etc/pdns/pdns.conf bind-ignore-broken-records=yes setuid=named setgid=named launch=bind log-dns-queries=yes loglevel=5 bind-config=/etc/named.conf bind-dnssec-db=/var/cpanel/pdns/dnssec.db local-address-nonexist-fail=no distributor-threads=1 disable-axfr=yes webserver=yes api=yes webserver-address=127.0.0.1 webserver-allow-from=0.0.0.0/0 webserver-password=SERVER-KEY #gmysql-dnssec=no webserver-port=953 api-key=MY-KEY upgrade-unknown-types=1
Advertisement
Answer
Your code looks correct.
One big problem with your response.
Content-Length: 52
It should be Content-Length: 111
.
I have been testing your code with two apps
One to send the curl request
One to receive it and respond with the request details.
Early on in my testing when I removed the Content-Type: application/json
,
I would see a content length of just over 50 bytes.
Below is my app. It gets 111 bytes.
If you change your curl url to http://eatled.com/receiveheader.php
You should get this:
Response Content-Length: 111 Content-Type: application/json Accept: application/json Accept-Encoding: deflate, gzip, br Host: eatled.com X-Api-Key: MY-KEY BODY {"name":"example.com.", "kind":"Native", "masters": [], "nameservers":["ns1.example.com.", "ns2.example.com."]} array ( 'name' => 'example.com.', 'kind' => 'Native', 'masters' => array ( ), 'nameservers' => array ( 0 => 'ns1.example.com.', 1 => 'ns2.example.com.', ), )
The source code:
sandbox.php
<?php header('Content-Type: text/plain; charset=UTF-8'); $jsn = "{"name":"example.com.", "kind":"Native", "masters": [], "nameservers":["ns1.example.com.", "ns2.example.com."]}"; $data = json_decode($post,1); $post = $jsn; $request = array(); $request[] = "Content-Type: application/json"; $request[] = "Accept: application/json"; $request[] = "X-Api-Key: MY-KEY"; $ch = curl_init(); curl_setopt($ch, CURLOPT_HTTPHEADER, $request); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_URL, 'http://eatled.com/receiveheader.php'); curl_setopt($ch, CURLOPT_HEADER, false); curl_setopt($ch, CURLOPT_TIMEOUT,10); curl_setopt($ch, CURLOPT_FAILONERROR,true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_ENCODING,""); curl_setopt($ch, CURLOPT_VERBOSE, true); curl_setopt($ch, CURLOPT_POSTFIELDS,$post); $data = curl_exec($ch); $info = rawurldecode(var_export(curl_getinfo($ch),true)); echo "nResponsen$data"; echo "ncurl_getinfo =n$info"; ?>
receiveheaders.php
<?php header('Content-Type: text/plain; charset=UTF-8'); foreach (getallheaders() as $name => $value) { echo "$name: $valuen"; } echo "nBODYn"; $jsn = file_get_contents('php://input'); echo "n$jsnnnn"; $data = json_decode($jsn,1); var_export($data); echo "n$_POSTn"; var_export($_POST); echo "n$_FILESn"; var_export($_FILES); echo "n$_SERVERn"; var_export($_SERVER); ?>
END OF UPDATE
Add these two headers.
$headers[] = 'Accept: application/json'; $headers[] = 'Content-Type: application/json';
Right now the error you are getting is because the request content-type is
'CONTENT_TYPE' => 'application/x-www-form-urlencoded',
If use just used the content-type header and not accept, you’d get a different error. The API manual says you cannot use curl’s default Accept: */*