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.

Using API in perl scripts on virtual hostings

Discussion in 'cPanel Developers' started by DmitPet, Mar 6, 2012.

  1. DmitPet

    DmitPet Member

    Joined:
    Mar 6, 2012
    Messages:
    6
    Likes Received:
    0
    Trophy Points:
    1
    cPanel Access Level:
    Website Owner
    Hi guys,

    First of all sorry for my english, but I really need your help. I have several virtual hostings with cpanel, and I want to manage them (addon,delete new domains, make msql bases etc.) from my perl scripts. Is it possible for me? For example, I want to addon new domains. I tried something like that:
    use API::CPanel;
    Code:
    API::CPanel::Domain::add_addon_domain({
        auth_user   => 'username', 
        auth_passwd => 'qwerty', 
        host        => '11.22.33.44',
        dir         => '/newdomain', 
        newdomain   => 'newdomain', 
        pass        => 'xxx',    
        subdomain   => 'ftp',
    });
    but without any success.
    When I make request using browser https://myhost:2083/xml-api/functionname answer is: "<result>0</result><reason>Token denied</reason>".
    Can you please show me the simple perl code, for example for addon new domain?
    Look forward to your answer ...
     
  2. cPDan

    cPDan cPanel Staff
    Staff Member

    Joined:
    Mar 9, 2004
    Messages:
    711
    Likes Received:
    4
    Trophy Points:
    18
    Hello!

    You might also want to try a module that cPanel develops and maintains:
    cPanel::PublicAPI - search.cpan.org

    That error message means that your request needs to incorporate the “Security Token”. How that works and how to do it is outlined here:

    Making your script work with security tokens in cPanel & WHM - cPanel Integration
     
  3. DmitPet

    DmitPet Member

    Joined:
    Mar 6, 2012
    Messages:
    6
    Likes Received:
    0
    Trophy Points:
    1
    cPanel Access Level:
    Website Owner
    Thanks for answer, but when I try "https://myhost:2083/cpsess1471282806/xml-api/functionname" I have 404 error :( Is it mean that I cann't use API as simple user?
    And about cPanel::PublicAPI. As I understand it is modul for cpanel owners. I am only user :( Am I wrong?
     
  4. cPDan

    cPDan cPanel Staff
    Staff Member

    Joined:
    Mar 9, 2004
    Messages:
    711
    Likes Received:
    4
    Trophy Points:
    18
    It is either a legit 404 or your session is not valid (or not if it does not exist). That is documented at the URL I sent previously.

    Non-resellers are unable to do WHM specific requests like the web interface.
     
  5. KostonConsulting

    KostonConsulting Well-Known Member

    Joined:
    Jun 17, 2010
    Messages:
    255
    Likes Received:
    1
    Trophy Points:
    18
    Location:
    San Francisco, CA
    cPanel Access Level:
    Root Administrator

    You'll need to use the following format for cPanel API2 calls:

    Code:
    https://myhost:2083/cpsess1471282806/xml-api/cpanel?cpanel_xmlapi_module=MODULE&cpanel_xmlapi_func=FUNC&cpanel_xmlapi_apiversion=2
    So for example, to add an addon domain, use:

    Code:
    https://myhost.com:2083/cpsessxxx/xml-api/cpanel?cpanel_xmlapi_module=AddonDomain&cpanel_xmlapi_func=addaddondomain&cpanel_xmlapi_apiversion=2&newdomain=addondomain.com&subdomain=addondomain.domain.com&dir=/home/user/addondomain

    Here are the docs for AddonDomain::addaddondomain:

    ApiAddonDomain < ApiDocs/Api2 < TWiki



    I don't know what API::Cpanel is but it is not an official cPanel method to connect to their API.


    If you're running the perl script on the cPanel server, you can just load up Cpanel::AddonDomain with:

    Code:
    BEGIN{
      unshift(@INC, '/usr/local/cpanel');
    }
    use Cpanel::AddonDomain ();
    

    If you're not on a cPanel server, I'd recommend using Net::SSLeay and HTTP::Request::Common to craft your API requests.
     
  6. DmitPet

    DmitPet Member

    Joined:
    Mar 6, 2012
    Messages:
    6
    Likes Received:
    0
    Trophy Points:
    1
    cPanel Access Level:
    Website Owner
    Ok, thanks a lot. I've done everything I need.
    Hm, I'am to fast :) I have one more problem. Everything work fine, but one virtual host "Bluehost" make me crazy :(
    Sub that I made:
    Code:
    sub AddonDomain { 
     my ($host,$username,$password,$domain)=@_;
     if ($domain=~/http\:\/\//) {$domain=~s/http\:\/\///}
     my $subdomain=$domain;
     $subdomain=~s/\.[^\n]+//;
     my $cp = cPanel::PublicAPI->new( 
           'user' => $username,
           'pass' => $password,
           'host' => $host,
           'debug' => 1,
         );
    
     my @result = $cp->cpanel_api2_request('cpanel',
        { 
            'module' => 'AddonDomain',
            'func' => 'addaddondomain',
        },
        {
            'dir' => "public_html/$domain",
            'newdomain' => $domain,
            'subdomain' => $subdomain,
        },
      );
     my $d = Data::Dumper->new(\@result);
     my $out=$d->Dump;
     if ($out=~/was successfully parked/) {return 1;} else {print "$out\n";return 0;}
    }
    
    but when I try to addon domain to bluehost I have answer from debug:
    Code:
    debug: Using user param from object creation
    debug: Using pass param from object creation
    debug: loaded serializer: JSON::Syck
    debug: api_request: ( cPanel::PublicAPI=HASH(0x1977c030), cpanel, /json-api/cpanel, GET, HASH(0x1977bfa0),  )
    debug: failed to load encoder: cPanel/CPAN/URI/Escape.pm
    debug: loaded encoder: URI/Escape.pm
    debug: Found port for service cpanel to be 2083 (usessl=1)
    debug: GET /json-api/cpanel?cpanel_jsonapi_module=AddonDomain&subdomain=DOMAIN&newdomain=DOMAIN&cpanel_jsonapi_apiversion=2&cpanel_jsonapi_func=addaddondomain&dir=public_html%2FDOMAIN HTTP/1.1
    Host: box706.bluehost.com
    Connection: Close
    User-Agent: cPanel::PublicAPI (perl) 1.002
    Authorization: Basic xxxxxxxxxxxxxxxxxxxxxxxxx
    
    
    debug: HTTP LINE[HTTP/1.1 200 OK
    ]
    debug: HEADER[content-type]=[text/plain; charset="utf-8"]
    debug: HEADER[connection]=[Keep-Alive]
    debug: HEADER[keep-alive]=[timeout=70, max=200]
    debug: HEADER[date]=[Wed, 07 Mar 2012 20:33:46 GMT]
    debug: HEADER[x-keep-alive-count]=[1]
    debug: HEADER[content-length]=[0]
    debug: HEADER[server]=[cpsrvd/11.30.5.6]
    debug: READ TYPE=content-length
    There was an issue with parsing the following response from cPanel or WHM:
    
    There was an issue with parsing the following response from cPanel or WHM:
    
    I guess that problem is "debug: GET /json-api/cpanel?cpanel_jsonapi_module=AddonDomain&subdomain= ......" must be xml-api not json-api. Could you please tell me what must I do?
     
    #6 DmitPet, Mar 7, 2012
    Last edited by a moderator: Mar 8, 2012
  7. cPanelDavidN

    cPanelDavidN Integration Developer
    Staff Member

    Joined:
    Dec 17, 2009
    Messages:
    571
    Likes Received:
    1
    Trophy Points:
    18
    Location:
    Houston, TX
    cPanel Access Level:
    Root Administrator
    DmitPet,

    I dont' know why you're receiving that error, but you can find out the raw response like so:
    Code:
    my $cp = cPanel::PublicAPI->new(
           'user' => $username,
           'pass' => $password,
           'host' => $host,
           'debug' => 1,
         );
    
     my $result = $cp->cpanel_api2_request('cpanel',
        {
            'module' => 'AddonDomain',
            'func' => 'addaddondomain',
        },
        {
            'dir' => "public_html/$domain",
            'newdomain' => $domain,
            'subdomain' => $subdomain,
        },
        'xml'
      );
    
    # for illustration puposes
    print Dumper $result;
    
    By adding one more input argument to cpanel_api2_request, being either 'json' or 'xml', it will make the query with that requested format and return the raw response.

    Normally, the queries are made with the 'json' format and then parsed and returned as a hash ref...which, if you're getting a valid response, is great; It would let you avoid (or at least provide a alternative to) the Dumper and the string pattern matching...you can just look with the data->result container

    Example output from the above code block:
    Code:
    $VAR1 = '<?xml version="1.0" ?>
      <cpanelresult>
        <apiversion>2</apiversion>
        <data>
          <reason>Deleted domain: tester.blah.net
    Bind reloading on myserver using rndc zone: [blah.net]
    The subdomain, tester.blah.net has been removed.</reason>
          <result>1</result>
        </data>
        <event>
          <result>1</result>
        </event>
        <func>addaddondomain</func>
        <module>AddonDomain</module>
        <postevent>
          <result>1</result>
        </postevent>
        <preevent>
          <result>1</result>
        </preevent>
      </cpanelresult>
    ';
    
    Regards,
    -DavidN
     
  8. DmitPet

    DmitPet Member

    Joined:
    Mar 6, 2012
    Messages:
    6
    Likes Received:
    0
    Trophy Points:
    1
    cPanel Access Level:
    Website Owner
    Thanks cPanelDavidN, but I got $VAR1 = undef; in that case :(
    Strange, very strange. If I try using another function, for example "$cp->cpanel_api2_request('cpanel',{'module' => 'AddonDomain','func' => 'listaddondomains ',},);" everything work fine.
     
  9. cPanelDavidN

    cPanelDavidN Integration Developer
    Staff Member

    Joined:
    Dec 17, 2009
    Messages:
    571
    Likes Received:
    1
    Trophy Points:
    18
    Location:
    Houston, TX
    cPanel Access Level:
    Root Administrator
    DmitPet,

    That is strange. What response do you get if you manually use a browser?

    Manual XML/JSON API queries via browser
    1. Login to cPanel in a browser
    2. Go to the address bar of your browser
    3. Erase everything after the cPanel token (cpsessxxxxx)
    4. Manually add the XML/JSON API URL and query parameters
      Example:
      Code:
      https://myhost.com:2083/cpsessxxx/xml-api/cpanel?cpanel_xmlapi_module=AddonDomain&cpanel_xmlapi_func=addaddondomain&cpanel_xmlapi_apiversion=2&newdomain=addondomain.com&subdomain=addondomain.domain.com&dir=/home/user/addondomain
    5. Send request in browser ('go' button, return key, etc)

    -DavidN
     
  10. KostonConsulting

    KostonConsulting Well-Known Member

    Joined:
    Jun 17, 2010
    Messages:
    255
    Likes Received:
    1
    Trophy Points:
    18
    Location:
    San Francisco, CA
    cPanel Access Level:
    Root Administrator
    Just a few quick comments. I'd definitely recommend using a reference for the data that you get back from PublicAPI as shown in David's code. If you're expecting an array and the data comes back as a scalar (which it should) or hash, you'll have problems. With a reference, you can check the datatype with ref() and then act accordingly:

    Code:
    my $result = $cp->cpanel_api2_request('cpanel',
    

    The second is that I've also had issues acting after AddonDomain::addaddondomain because the function may give a result => 0 when it actually fails. Rather than checking for specific text to see if it has completed, you can check the list of Addons with AddonDomain::listaddondomains to see if the domain you expected to be added was. This will be more future proof, especially if cPanel allows for these error messages to be translated at some point in the future.


    Finally, I'd recommend parsing the output from PublicAPI with XML::Simple before acting on it. You should be looking for some key parts of the response each time as if for some reason the output includes error messages or debug information, your code may not function as expected in the future. XML::Simple::XMLin($result) should load up the response into a hashref for you.
     
  11. DmitPet

    DmitPet Member

    Joined:
    Mar 6, 2012
    Messages:
    6
    Likes Received:
    0
    Trophy Points:
    1
    cPanel Access Level:
    Website Owner
    Thanks a lot KostonConsulting, I will remake my subs :)
     
  12. DmitPet

    DmitPet Member

    Joined:
    Mar 6, 2012
    Messages:
    6
    Likes Received:
    0
    Trophy Points:
    1
    cPanel Access Level:
    Website Owner
Loading...

Share This Page