Home > front end >  Create domain 'example.com' failed Powerdns API
Create domain 'example.com' failed Powerdns API

Time:09-07

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

CodePudding user response:

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.',
  ),
)

LINK TO MY CURL SANDBOX

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 "\nResponse\n$data";
echo "\ncurl_getinfo =\n$info";
?>

receiveheaders.php

<?php
header('Content-Type: text/plain; charset=UTF-8');

foreach (getallheaders() as $name => $value) {
    echo "$name: $value\n";
}
echo "\nBODY\n";
$jsn = file_get_contents('php://input');
echo "\n$jsn\n\n\n";
$data = json_decode($jsn,1);
var_export($data);
echo "\n\$_POST\n";
var_export($_POST);
echo "\n\$_FILES\n";
var_export($_FILES);
echo "\n\$_SERVER\n";
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: */*

CodePudding user response:

Can you try call the API using curl command on the maching running pDNS webserver?

curl -v \
 -H 'Content-Type: application/json' \
 -H 'X-Api-Key: MY-KEY' \
 -H 'Accept: application/json' \
 -X POST -d '{"name":"example.com.", "kind":"Native", "masters": [], "nameservers":["ns1.example.com.", "ns2.example.com."]}' \
 http://127.0.0.1:953/api/v1/servers/localhost/zones

Because I don't know your setup, so I guess that it had something relate to network. If curl request work, you should check webserver-allow-from configuration, you may try to set it to accept from all (0.0.0.0,::).

  • Related