metaregistrar / php-epp-client

Object-oriented PHP EPP Client
https://www.metaregistrar.com/docs/
MIT License
214 stars 159 forks source link

NameServers Update #217

Closed swartjie closed 4 years ago

swartjie commented 5 years ago

Hey Guys,

Ok so I am faced with a strange issue, when updating certain domains, I am getting an error message that says glue cannot be associated with nameservers, and then lists the current nameservers (not the new ones)

So I suspect, it's because the old ns records are not removed in the update command...

This is a sample of the update command where the ns records are processed:

        if (is_array($nameservers)) {
            if (!$add) {
                $add = new eppDomain($domainname);
            }
            foreach ($nameservers as $nameserver) {
                $add->addHost(new eppHost($nameserver));
            }
        }

Do I need to remove the old NS records and add them to the $del variable? And if so, What would be the correct way to do so?

metaregistrar commented 5 years ago

Yes, to properly add nameservers you will also have to remove the old ones. Please find example code here:

<?php
include 'vendor/autoload.php';
use Metaregistrar\EPP\eppConnection;
use Metaregistrar\EPP\eppException;
use Metaregistrar\EPP\eppDomain;
use Metaregistrar\EPP\eppHost;
use Metaregistrar\EPP\eppInfoDomainRequest;
use Metaregistrar\EPP\eppDnssecInfoDomainResponse;
use Metaregistrar\EPP\eppDnssecUpdateDomainRequest;
use Metaregistrar\EPP\eppUpdateDomainResponse;
use Metaregistrar\EPP\eppSecdns;

$domainname = '';
$nameservers = ['suspend1.yourdomainprovider.net','suspend2.yourdomainprovider.net'];
try {
    if ($conn = eppConnection::create('clientsettings.ini',false)) {
        // Connect and login to the EPP server
        if ($conn->login()) {
            echo "$domainname\n";
            updatedomain($conn,$domainname,$nameservers);
            $conn->logout();
        }
    }
} catch (eppException $e) {
    echo "ERROR: " . $e->getMessage() . "\n\n";
}

function infodomain(eppConnection $conn, $domainname) {
    try {
        $domain = new eppDomain($domainname);
        $info = new eppInfoDomainRequest($domain);
        if ($response = $conn->request($info)) {
            /* @var $response eppDnssecInfoDomainResponse */
            return [$response->getDomainNameservers(),$response->getKeys()];
        }
    } catch (eppException $e) {
        echo $e->getMessage() . "\n";
    }

}

function updatedomain(eppConnection $conn, $domainname, $nameservers) {
    try {
        $domain = new eppDomain($domainname);
        list($currentns,$currentkeys) = infodomain($conn,$domainname);
        $del = null;
        if ((is_array($currentkeys)) && (count($currentkeys)>0)) {
            $del = new eppDomain($domainname);
            foreach ($currentkeys as $key) {
                /* @var $key eppSecdns */
                $del->addSecdns($key);
            }
        }
        if ((is_array($currentns)) && (count($currentns)>0)) {
            if (!$del) {
                $del = new eppDomain($domainname);
            }
            foreach ($currentns as $host) {
                /* @var eppHost $host */
                if (!in_array($host->getHostname(),$nameservers)) {
                    $del->addHost($host);
                } else {
                    unset($nameservers[$host->getHostname()]);
                }
            }
        } else {

        }
        $add = null;
        if ((is_array($nameservers)) && (count($nameservers)>0)) {
            $add = new eppDomain($domainname);
            foreach ($nameservers as $ns) {
                $add->addHost(new eppHost($ns));
            }
        }
        $update = new eppDnssecUpdateDomainRequest($domain,$add,$del,null);
        if ($response = $conn->request($update)) {
            /* @var $response eppUpdateDomainResponse */
            return true;
        }
    } catch (eppException $e) {
        echo $e->getMessage() . "\n";
        die();
    }

}

Basically what the code does is use infodomain to check what nameservers and DNSSEC keys are set for the domain name, and only change that what is necessary.

swartjie commented 4 years ago

Hey Guys,

Ok so I played around after our last conversation and I changed things a little bit to try and accomodate the deleting and adding of the nameservers... But I am still getting the same message pop up...

Can you please advise? Please check the code below, I do run a domain info to get the NS and remove old ones, only adding new ones... So I am not sure why it;s still throwing the glue error?

function modifydomain($domainname, $registrant = null, $admincontact = null, $techcontact = null, $billingcontact = null, $nameservers = null, $status = null, $autorenew = null) { $response = null; try { // First, retrieve the current domain info. Nameservers can be unset and then set again. $del = null; $domain = new eppDomain($domainname); $info = new eppInfoDomainRequest($domain); if ($response = $this->conn->request($info)) { // If new nameservers are given, get the old ones to remove them if (is_array($nameservers)) { / @var Metaregistrar\EPP\eppInfoDomainResponse $response / $oldns = $response->getDomainNameservers(); if (is_array($oldns)) { if (!$del) { $del = new eppDomain($domainname); } foreach ($oldns as $ns) { $del->addHost($ns); } } } if ($admincontact) { $oldadmin = $response->getDomainContact(eppContactHandle::CONTACT_TYPE_ADMIN); if ($oldadmin == $admincontact) { $admincontact = null; } else { if (!$del) { $del = new eppDomain($domainname); } $del->addContact(new eppContactHandle($oldadmin, eppContactHandle::CONTACT_TYPE_ADMIN)); } } if ($techcontact) { $oldtech = $response->getDomainContact(eppContactHandle::CONTACT_TYPE_TECH); if ($oldtech == $techcontact) { $techcontact = null; } else { if (!$del) { $del = new eppDomain($domainname); } $del->addContact(new eppContactHandle($oldtech, eppContactHandle::CONTACT_TYPE_TECH)); } } } // In the UpdateDomain command you can set or add parameters // - Registrant is always set (you can only have one registrant) // - Admin, Tech, Billing contacts are Added (you can have multiple contacts, don't forget to remove the old ones) // - Nameservers are Added (you can have multiple nameservers, don't forget to remove the old ones $mod = null; if ($registrant) { $mod = new eppDomain($domainname); $mod->setRegistrant(new eppContactHandle($registrant)); } $add = null; if ($admincontact) { if (!$add) { $add = new eppDomain($domainname); } $add->addContact(new eppContactHandle($admincontact, eppContactHandle::CONTACT_TYPE_ADMIN)); } if ($techcontact) { if (!$add) { $add = new eppDomain($domainname); } $add->addContact(new eppContactHandle($techcontact, eppContactHandle::CONTACT_TYPE_TECH)); } if ($billingcontact) { if (!$add) { $add = new eppDomain($domainname); } $add->addContact(new eppContactHandle($billingcontact, eppContactHandle::CONTACT_TYPE_BILLING)); } if (is_array($nameservers)) {

Add New

            if (!$add) {
                $add = new eppDomain($domainname);
            }
            foreach ($nameservers as $nameserver) {
                $add->addHost(new eppHost($nameserver));
            }
        }

        if($status!=NULL){
            if($status=='clientHold'){
                if (!$add) $add = new eppDomain($domainname);
                $add->addStatus(\Metaregistrar\EPP\eppDomain::STATUS_CLIENT_HOLD);
            }else if($status=='rem_clientHold'){
                if (!$del) $del = new eppDomain($domainname);
                $del->addStatus(\Metaregistrar\EPP\eppDomain::STATUS_CLIENT_HOLD);
            }
        }

        $update = new eppUpdateDomainRequest($domain, $add, $del, $mod, true);
        //echo $update->saveXML();
        if ($response = $this->conn->request($update)) {
            /* @var eppUpdateDomainResponse $response */
            //echo $response->getResultMessage() . "\n";
            return true;
        }
    } catch (eppException $e) {
        throw new \Exception($e->getMessage());
        if ($response instanceof eppUpdateDomainResponse) {
            throw new \Exception($response->textContent);
        }
    }
}