The Community Forums

Interact with an entire community of cPanel & WHM users!
  1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

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:
    6
    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 Forums Analyst
    Staff Member

    Joined:
    Apr 11, 2011
    Messages:
    30,774
    Likes Received:
    663
    Trophy Points:
    113
    cPanel Access Level:
    Root Administrator
Loading...

Share This Page