Bulk transfer domains from TransIP
From Openprovider API documentation
Before using this script, please make sure to read API General Examples
Using this script is at your own risk!
<?php
$help = "Available parameters:
-f: (required) name of file containing domains to transfer
-d: (optional) how to handle DNS zones; allowed values:
0: (default) do not create DNS zones in Openprovider; use existing
nameservers
1: create DNS zones in Openprovider based on TransIP DNS records;
put the domain on the Openprovider nameservers after transfer;
existing zones will not be overwritten
overwrite: create DNS zones, overwrite any existing zones
-h: (optional) how to handle contacts; allowed values:
0: (default) the script checks if another TransIP contact with the
same data was processed before; if so, re-use that contact instead
of creating a new one
1: create a new Openprovider handle for every domain contact, even if
the data is similar to a previously processed contact
-v: (optional) whether or not to show extended information during runtime;
allowed values:
0: (default) don't show additional ouput
1: show additional ouput
-t: (optional) whether to run in test mode or not; allowed values:
0: run live
1: (default) run in test mode / read-only; no contacts or zones will
be created, no domains will be transferred
Examples:
Run in test mode, full debugging output:
php transfer-from-transip.php -f domains.txt -v1 -t1
Run in live mode: transfer domains while create DNS zones (but do not
overwrite existing ones), show limited output:
php transfer-from-transip.php -f domains.txt -t0 -d1
Full documentation is available at https://openprovider.zendesk.com/hc/en-us/articles/360019994414
";
// Openprovider API credentials
$auth = array('username' => $op_user, 'hash' => $op_hash);
// TransIP and Openprovider API
require_once('Transip/DomainService.php');
require_once('API.php');
$api = new OP_API ('https://api.openprovider.eu');
// Read runtime parameters
$opts = getopt('f:d:t:h:v:', array('help'));
$domainFile = $opts['f']; // filename (required)
$withDns = $opts['d']; // 0, 1 or overwrite (default = 0)
$forceNewHandles = $opts['h']; // 0 or 1 (default = 0)
$verbose = $opts['v']; // 0 or 1 (default = 0)
$testMode = $opts['t']; // 0 or 1 (default = 1)
if (isset($opts['help'])) {
echo $help;
exit;
}
// Get list with domains to transfer
if (file_exists($domainFile)) {
$domains = file($domainFile, FILE_IGNORE_NEW_LINES);
}
else {
die("Cannot find domain list; file [$f] does not exist\n");
}
// Check other parameters
if (!in_array($withDns, array(0, 1, 'overwrite'))) {
$withDns = 0;
}
if (!in_array($testMode, array(0, 1))) {
$testMode = 1;
}
if (!in_array($forceNewHandles, array(0, 1))) {
$forceNewHandles = 0;
}
if (!in_array($verbose, array(0, 1))) {
$verbose = 0;
}
// Keep track of handles that were already created
$handleRelations = array();
if (!$forceNewHandles) {
if (file_exists('transip-handle-relations.dat')) {
if ($f = fopen('transip-handle-relations.dat', 'r')) {
while (!feof($f)) {
list($md5, $opHandle) = fgetcsv($f);
$handleRelations[$md5] = $opHandle;
}
fclose($f);
}
else {
die("Cannot open file transip-handle-relations.dat\n");
}
}
$fHandles = fopen('transip-handle-relations.dat', 'a');
}
foreach ($domains as $dom) {
$continue = true;
if ($verbose) {
echo "Starting domain $dom\n";
echo "Retrieve data for domain $dom from TransIP API\n";
}
try {
$domain = Transip_DomainService::getInfo($dom);
if ($verbose) {
echo "TransIP returned the following data for domain $dom:\n";
print_r($domain);
}
}
catch(SoapFault $e) {
// It is possible that an error occurs when connecting to the TransIP Soap API,
// those errors will be thrown as a SoapFault exception.
echo "@@ERROR: An error occurred while querying the TransIP API for domain [$dom]: ".htmlspecialchars($e->getMessage())."\n";
continue;
}
$args = array();
// Nameservers
if ($verbose) {
echo "Preparing nameservers for domain [$dom]\n";
}
if ($withDns) {
if (!$domain->dnsEntries) {
echo "@@ERROR: no DNS entries found for import in Openprovider for $dom; skipping this domain\n";
continue;
}
if (createOpenproviderZone($dom, $domain->dnsEntries)) {
$args['nsGroup'] = 'dns-openprovider';
}
else {
echo "@@ERROR: while creating DNS zone for $dom; skipping this domain\n";
continue;
}
}
else {
if (isset($domain->nameservers)) {
foreach ($domain->nameservers as $ns) {
$args['nameServers'][] = array(
'name' => $ns->hostname,
'ip' => (isset($ns->ipv4) ? $ns->ipv4 : NULL),
'ip6' => (isset($ns->ipv6) ? $ns->ipv6 : NULL),
);
}
}
}
// Contacts (handles)
if ($verbose) {
echo "Preparing contact handles for domain [$dom]\n";
}
foreach ($domain->contacts as $contact) {
$type = ;
switch ($contact->type) {
case 'registrant' : $type = 'owner'; break;
case 'administrative' : $type = 'admin'; break;
case 'technical' : $type = 'tech'; break;
default : echo "@@WARNING: invalid contact type ".$contact->type." for domain [$dom]; skipping\n"; break;
}
unset($contact->type);
$hash = md5(implode(, get_object_vars($contact)));
if (!$forceNewHandles && isset($handleRelations[$hash])) {
$opHandle = $handleRelations[$hash];
}
else {
if ($opHandle = createOpenproviderContact($contact)) {
if (!$testMode) {
fwrite($fHandles, $hash.','.$opHandle."\n");
$handleRelations[$hash] = $opHandle;
}
}
else {
echo "@@ERROR while creating Openprovider contact for $type of $dom\n";
$continue = false;
continue 2;
}
}
$args[$type.'Handle'] = $opHandle;
}
// Authcode
$args['authCode'] = $domain->authCode;
// Unlock domain, if required
if ($verbose) {
echo "Unlocking domain [$dom] (if applicable)\n";
}
if ($domain->isLocked) {
if ($testMode) {
echo "TEST MODE: skipping unlocking domain\n";
}
else {
try {
$isLocked = Transip_DomainService::unsetLock($dom);
}
catch(SoapFault $e)
{
// It is possible that an error occurs when connecting to the TransIP Soap API,
// those errors will be thrown as a SoapFault exception.
echo "@@ERROR: An error occurred while unlocking domain [$dom]: " . htmlspecialchars($e->getMessage())."\n";
}
}
}
list($d, $e) = explode('.', $dom, 2);
$args['domain'] = array(
'name' => $d,
'extension' => $e,
);
$args['period'] = 1;
if ($verbose) {
echo "Start transfer for domain [$dom] in Openprovider with the following data array:\n";
print_r($args);
}
if ($testMode) {
echo "TEST MODE: skip domain transfer for [$dom]\n";
}
else {
$request = new OP_Request;
$request->setCommand('transferDomainRequest')
->setAuth($auth)
->setArgs($args);
$reply = $api->process($request);
if ($reply->getFaultCode() != 0) {
echo "@@ERROR on domain transfer [$dom]: ".$reply->getFaultCode().' - '.$reply->getFaultString()."\n";
if ($verbose) {
echo "Full data array:\n";
print_r($args);
}
}
else {
echo "Transfer for $dom successfully requested\n";
}
}
}
function createOpenproviderZone($domain, $dnsEntries) {
global $api, $auth;
global $testMode, $withDns, $verbose;
list($d, $e) = explode('.', $domain, 2);
// Check if a zone already exists
$request = new OP_Request;
$request->setCommand('retrieveZoneDnsRequest')
->setAuth($auth)
->setArgs(array(
'name' => $domain,
'withRecords' => false,
'withHistory' => false
));
$reply = $api->process($request);
$response = $reply->getValue();
if ($response) {
if ($withDns == 'overwrite') {
if ($testMode) {
echo "@@WARNING: TEST MODE: Zone for [$domain] already exists, skip removing of existing zone\n";
}
else {
echo "@@WARNING: Zone for [$domain] already exists; removing existing zone\n";
$request = new OP_Request;
$request->setCommand('deleteZoneDnsRequest')
->setAuth($auth)
->setArgs(array(
'domain' => array(
'name' => $d,
'extension' => $e
),
));
$reply = $api->process($request);
$response = $reply->getValue();
}
}
else {
echo "@@WARNING: Zone for [$domain] already exists; skipping import\n";
}
}
$records = array();
foreach ($dnsEntries as $record) {
if (in_array($record->type, array('NS', 'SOA'))) {
continue;
}
if (in_array($record->type, array('MX', 'SRV'))) {
list($prio, $value) = explode(' ', $record->content, 2);
}
else {
$prio = NULL;
$value = $record->content;
}
$records[] = array(
'type' => $record->type,
'name' => ($record->name == '@' ? : $record->name),
'value' => ($value == '@' ? $domain : $value),
'prio' => $prio,
'ttl' => ($record->expire < 600 ? 600 : $record->expire),
);
}
if ($testMode) {
echo "TEST MODE - skip DNS zone creation for $domain\n";
if ($verbose) {
echo "Zone contents:\n";
print_r($records);
}
return true;
}
else {
$request = new OP_Request;
$request->setCommand('createZoneDnsRequest')
->setAuth($auth)
->setArgs(array(
'domain' => array(
'name' => $d,
'extension' => $e,
),
'type' => 'master',
'records' => $records,
));
$reply = $api->process($request);
if ($reply->getFaultCode() != 0) {
echo "@@ERROR on DNS zone creation for [$domain]: ".$reply->getFaultCode().' - '.$reply->getFaultString()."; full data array:\n";
print_r($records);
return false;
}
else {
if ($verbose) {
echo "DNS zone for $domain successfully created with the following records:\n";
print_r($records);
}
return true;
}
}
}
function createOpenproviderContact($contact) {
global $api, $auth;
global $testMode, $verbose;
// Split telephone number
// Country code separated?
$matches = array();
if (preg_match('/^(\+?\d+)[ \-\.](.*)$/', $contact->phoneNumber, $matches)) {
$tel1 = (substr($matches[1], 0, 1) == '+' ? : '+').$matches[1];
$rest = preg_replace('/[^\d]/', , $matches[2]);
}
// Else consider first 2 numbers the country code
else {
$tel = preg_replace('/[^\d]/', , $contact->phoneNumber);
$tel1 = '+'.substr($tel, 0, 2);
$rest = $matches[2];
}
$tel2 = substr($rest, 0, 2);
$tel3 = substr($rest, 2);
// Split address number
$matches = array();
if (preg_match('/^\d+$/', $contact->number)) {
$number = $contact->number;
$suffix = NULL;
}
else if (preg_match('/^(\d+)([^\d].*)$/', $contact->number, $matches)) {
$number = $matches[1];
$suffix = $matches[2];
}
else {
$number = 1;
$suffix = $contact->number;
}
$args = array(
'companyName' => $contact->companyName,
'name' => array(
'firstName' => $contact->firstName,
'prefix' => $contact->middleName,
'lastName' => $contact->lastName,
),
'phone' => array(
'countryCode' => $tel1,
'areaCode' => $tel2,
'subscriberNumber' => $tel3,
),
'address' => array(
'street' => $contact->street,
'number' => $number,
'suffix' => $suffix,
'zipcode' => $contact->postalCode,
'city' => $contact->city,
'country' => strtoupper($contact->country),
),
'email' => $contact->email,
'additionalData' => ($contact->companyKvk ? array('companyRegistrationNumber' => $contact->companyKvk) : NULL),
);
if ($testMode) {
echo "TEST MODE - skip handle creation\n";
if ($verbose) {
echo "Handle details are the following:\n";
print_r($args);
}
return true;
}
else {
$request = new OP_Request;
$request->setCommand('createCustomerRequest')
->setAuth($auth)
->setArgs($args);
$reply = $api->process($request);
if ($reply->getFaultCode() != 0) {
echo "@@ERROR on contact creation for [$domain]: ".$reply->getFaultCode().' - '.$reply->getFaultString()."; full data array:\n";
print_r($args);
return false;
}
else {
$response = $reply->getValue();
if ($verbose) {
echo "Successfully created handle ".$response['handle']."\n";
}
return $response['handle'];
}
}
}
?>