Please whitelist cPanel in your adblocker so that you’re able to see our version release promotions, thanks!

The Community Forums

Interact with an entire community of cPanel & WHM users!

JSON API & DNS Records

Discussion in 'cPanel Developers' started by doni49, Jun 9, 2013.

  1. doni49

    doni49 Well-Known Member

    Joined:
    Oct 4, 2006
    Messages:
    74
    Likes Received:
    0
    Trophy Points:
    156
    Hi all. I tried all day yesterday to find the solution to this with no luck (and yes that did include searching the forums). So now I'm here to specifically ask.

    I have a RaspberryPi at home and want to connect to it remotely but my IP address is not static. I'd really prefer not to pay for a dynamic DNS service when I'm already paying for a personal domain name and hosting service. I've already added a dns zone that points to my home and it works. I can use raspihome.domainname.com to access the RasPi.

    Now I want to set up a script on my hosting account that will update the IP address as needed. My intention is to set up a cron job on the RasPi that will connect to the server script (via HTTPS) to provide it with the updated IP address.

    I found the following script for using cPanel's JSON API to manange the dnszone entries. But it's not working.

    The first php file is what I've got in public_html (this is the page I load in my web browser). When I load it in my browser, the page is blank. I looked at the page source code just to be sure and the following is all that's there.

    Why won't it return the DNS entries?

    Code:
    <html><body>
    <pre></pre></body></html>
    
    ShowDNSRecords.php:
    PHP:
    <html><body>
    <?php
      
    include "/home/username/cron-scripts/classdns.php";
      
    $zones = new zone_records("username""password""domainname""domainname");
      
    $r $zones->DNSrecords;
      echo 
    "<pre>";
      
    $r;
      echo 
    "</pre>";
    ?>
    </body></html>
    classdns.inc.php
    PHP Script to Edit DNS Records in CPanel - Stack Overflow
    PHP:
    <?php
    //Code by Scott Stevens
    //Last Edited 21 December 2012
    //This code is in the public domain

    //While not required (there can be no requirements in the
    //public domain) I ask that you please include this
    //information in any derivative works, along with a summary
    //of the modifications made.


    class zone_records {
        private 
    $auth "";
        private 
    $connection "";
        private 
    $basequery "";
        private 
    $zonedomain "";
        private 
    $DNSrecords = array();

        public function 
    __construct($user$pass$location$domain) {
            
    $this->auth "Authorization: Basic ".base64_encode($user.":".$pass);
            
    $this->connection $location;
            
    $this->basequery "https://".$location.":2083/json-api/cpanel?";
            
    $this->zonedomain $domain;
            
    $this->updaterecords(); //get new records
        
    }

        public function 
    __get($var) {
            return (
    $var=="DNSrecords" $this->DNSrecords NULL);
        }

        public function 
    doquery($function$params$headers=array()) {
            
    //query the cpanel server and do the query's bidding
            
    $curl curl_init();
            
    $init_params = array( "cpanel_jsonapi_module" => "ZoneEdit""cpanel_jsonapi_func" => $function"cpanel_jsonapi_version" => "2""domain" => $this->zonedomain );
            
    $query $this->basequery.http_build_query($init_params)."&".http_build_query($params);
            
    $headers[] = $this->auth;
            
    $options = array(    CURLOPT_URL                => $query,
                                
    CURLOPT_SSL_VERIFYPEER     => 0,        //Allow self-signed cert :P
                                
    CURLOPT_SSL_VERIFYHOST     => 0,        //Allow cert hostname mismatch
                                
    CURLOPT_HEADER            => 0,        //Output: Header not included
                                
    CURLOPT_RETURNTRANSFER    => 1,        //Output: Contents included
                                
    CURLOPT_HTTPHEADER        => $headers    //Auth
                                
    );
            
    curl_setopt_array($curl$options);
            
    $result curl_exec($curl);

            if (
    $result === false) { throw new Exception("cURL Execution Error ".curl_error($curl)." in $query"0); } //error handling for failure
            
    curl_close($curl);
            
    //echo $result;
            
    return json_decode($resulttrue);
        }

        public function 
    updaterecords() {
            
    //A RECORDS
            
    $records $this->doquery("fetchzone", array(), array());

            if (
    $records["cpanelresult"]["data"][0]["status"]!=|| !array_key_exists("record"$records["cpanelresult"]["data"][0])) {
                throw new 
    Exception("Bad zonefile result ".var_export($recordstrue), 404); }
            
    $records $records["cpanelresult"]["data"][0]["record"];
            
    //now start sorting records

            
    $newrecords = array();
            foreach (
    $records as $i) {
                if (
    $i["type"]=="A") {
                    
    //MUST MATCH: address==record, class==IN, **type==A, line==Line
                    
    if ($i["address"]!=$i["record"] || $i["Line"]!=$i["line"] || $i["class"]!="IN" || array_key_exists($i["line"], $newrecords)) {
                        throw new 
    Exception("Bad A record ".var_export($itrue), 404); }
                
    $newrecords[$i["line"]] = new DNSrecord("A"$i["name"], $i["record"], $i["line"], $i["ttl"], $this);
                }
                if (
    $i["type"]=="CNAME") {
                    
    //MUST MATCH: cname==record, class==IN, **type==CNAME, line==Line
                    
    if ($i["cname"]!=$i["record"] || $i["Line"]!=$i["line"] || $i["class"]!="IN" || array_key_exists($i["line"], $newrecords)) {
                        throw new 
    Exception("Bad CNAME record ".var_export($itrue), 404); }
                
    $newrecords[$i["line"]] = new DNSrecord("CNAME"$i["name"], $i["record"], $i["line"], $i["ttl"], $this);
                }
            }

            
    $this->DNSrecords = array();
            foreach (
    $newrecords as $key => $value) { $this->DNSrecords[$key] = $value; }
        }

        public function 
    addrecord($type$name$target$ttl) {
            if (
    $type!="A" && $type!="CNAME") {
                throw new 
    Exception("Invalid type '$type'"0); }
            if (!
    preg_match("/^([a-zA-Z0-9\-]+\.)*".preg_quote($this->zonedomain)."\.$/"$name)) {
                throw new 
    Exception("Invalid name '$name'"0); }
            if (!
    is_numeric($ttl)) {
                throw new 
    Exception("Invalid TTL '$ttl'"0); }
            if ((
    $type=="A" && !preg_match(DNSrecord::$valid_ip$target)) || ($type=="CNAME" && !preg_match(DNSrecord::$valid_domain$target))) {
                throw new 
    Exception("Invalid target '$target'"0); }

            
    $targetname = ($type=="A" "address" : ($type=="CNAME" "cname" "txtdata"));
            
    $params = array(    "type"        => $type,
                                
    "name"        => $name,
                                
    $targetname    => $target,
                                
    "ttl"        => $ttl,
                                
    "class"        => DNSrecord::$class);
            
    $result $this->doquery("add_zone_record"$params, array());
            
    $this->updaterecords();
            return 
    $result//todo: check status?
        
    }

        public function 
    deleterecord($line) {
            if (!
    array_key_exists($line$this->DNSrecords)) { throw new Exception("Record does not exist"0); }
            
    $result $this->doquery("remove_zone_record", array("line" => $line), array());
            
    $this->updaterecords();
            return 
    $result//todo: check status?
        
    }
    }

    /********************************************************************************/

    class DNSrecord {
        public static 
    $class "IN";
        public static 
    $valid_ip "/^(((((1[0-9])|[1-9])?[0-9])|(2(([0-4][0-9])|(5[0-5]))))\.){3}((((1[0-9])|[1-9])?[0-9])|(2(([0-4][0-9])|(5[0-5]))))$/";
        
    //"((((1[0-9])|[1-9])?[0-9])|(2(([0-4][0-9])|(5[0-5]))))"
        
    public static $valid_domain "/^([a-zA-Z0-9\-]+\.){2,}[a-zA-Z0-9\-]{2,}$/";
        private 
    $type "";
        private 
    $name "";
        private 
    $target "";
        private 
    $line 0;
        private 
    $ttl 0;
        public 
    $zone_records NULL;

        public function 
    __construct($type$name$target$line$ttl$zone_records) {
            
    $this->type $type;
            
    $this->name $name;
            
    $this->target $target;
            
    $this->line $line;
            
    $this->ttl $ttl;
            
    $this->zone_records $zone_records;
        }

        public function 
    __get($var) {
            
    /************ This function allows the properties to be fetched (but not the zone records object) *************/
            
    $temp_array = array(    "type"        => $this->type,
                                    
    "name"        => $this->name,
                                    
    "target"    => $this->target,
                                    
    "line"        => $this->line,
                                    
    "ttl"        => $this->ttl);
            return (
    array_key_exists($var$temp_array) ? $temp_array[$var] : NULL);
        }

        public function 
    __set($var$val) {
            if (
    $var=="target") {
                if (
    $this->type=="A" && preg_match(self::$valid_ip$val)===0) { throw new Exception("Invalid IP record '$val', ".self::$valid_ip0); }
                if (
    $this->type=="CNAME" && !preg_match(self::$valid_domain$val)) { throw new Exception("Invalid subdomain record '$val'"0); }
                
    $this->target $val;
                
    $this->update();
            } else if (
    $var=="ttl") {
                if (!
    is_numeric($val)) { throw new Exception("Invalid TTL '$val'"0); }
                
    $this->ttl $val;
                
    $this->update();
            } else { throw new 
    Exception("Tried to edit inaccessible property '$var'"403); }
        }

        private function 
    update() {
            
    //curl call to update line
            
    $targetname = ($this->type=="A" "address" : ($this->type=="CNAME" "cname" "txtdata"));
            
    $params = array(    "line"            => $this->line,
                                
    "type"            => $this->type,
                                
    $targetname        => $this->target,
                                
    "ttl"            => $this->ttl,
                                
    "class"            => self::$class);
            
    $result $this->zone_records->doquery("edit_zone_record"$params, array());
            
    $this->zone_records->updaterecords();
            
    //todo: return result or check status?
        
    }
    }
    ?>
     
    #1 doni49, Jun 9, 2013
    Last edited: Jun 9, 2013
  2. cPanelMichael

    cPanelMichael Technical Support Community Manager
    Staff Member

    Joined:
    Apr 11, 2011
    Messages:
    44,749
    Likes Received:
    1,886
    Trophy Points:
    363
    cPanel Access Level:
    Root Administrator
    Twitter:
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
Loading...

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice