FrankLaszlo

Active Member
Dec 19, 2008
35
0
56
I'm working on a project with the cPanel API, and my current task is implementing a way to automatically add/remove MX entries. (Specifically this is for the automation of setting up domains for google apps).

The main problem I am having is removing the existing MX entries. For some reason, my code will remove only remove zone of the MX records, even though I can clearly see it stepping through each one, and I get a valid status response from the API. Here is the code I am using to accomplish this:

Code:
        $query = "xml-api/dumpzone?domain=$domain";
        $zdata = cpdo($whmip, $whmhash, $query);
        foreach ($zdata['result']['record'] as $key => $val) {
            if ($val['type'] == "MX") {
                $line = $val['Line'];
                $exchange = $val['exchange'];
                $q = "xml-api/removezonerecord?zone=$domain&Line=$line";
                $mxdata = cpdo($whmip, $whmhash, $q);
                if ($mxdata['result']['status'] == "0") {
                    print "Removal of $exchange failed. -- ";
                    print $mxdata['result']['statusmsg'];
                    print "\n";
                } else {
                    print "$exchange removed.\n";
                    print_r($mxdata);
                }
          }
The cpdo() function returns an array from based on the query. Here is what the output looks like when attempting to remove some gmail MX records.

Code:
aspmx.l.google.com removed.
Array
(
    [result] => Array
        (
            [status] => 1
            [statusmsg] => Bind reload skipped on TEST (nameserver disabled)








        )

)
alt1.aspmx.l.google.com removed.
Array
(
    [result] => Array
        (
            [status] => 1
            [statusmsg] => Bind reload skipped on TEST (nameserver disabled)








        )

)
alt2.aspmx.l.google.com removed.
Array
(
    [result] => Array
        (
            [status] => 1
            [statusmsg] => Bind reload skipped on TEST (nameserver disabled)








        )

)
aspmx2.googlemail.com removed.
Array
(
    [result] => Array
        (
            [status] => 1
            [statusmsg] => Bind reload skipped on TEST (nameserver disabled)








        )

)
aspmx3.googlemail.com removed.
Array
(
    [result] => Array
        (
            [status] => 1
            [statusmsg] => Bind reload skipped on TEST (nameserver disabled)








        )

)
aspmx4.googlemail.com removed.
Array
(
    [result] => Array
        (
            [status] => 1
            [statusmsg] => Bind reload skipped on TEST (nameserver disabled)








        )

)
aspmx5.googlemail.com removed.
Array
(
    [result] => Array
        (
            [status] => 1
            [statusmsg] => Bind reload skipped on TEST (nameserver disabled)








        )

)
And here is the resulting MX entries in the zone file after this was ran:

Code:
testingaso123.com.      900     IN      MX      0       aspmx.l.google.com.
testingaso123.com.      900     IN      MX      10      alt2.aspmx.l.google.com.
testingaso123.com.      900     IN      MX      20      aspmx3.googlemail.com.
testingaso123.com.      900     IN      MX      20      aspmx5.googlemail.com.
One thing I had thought may be happening. Is after the MX record gets removed, the line numbers change. But I'm not 100% sure how to avoid this. Maybe I can try to add the MX entries to an array, reverse the order after the foreach loop, and then go through and delete them? That would make sure the line numbers wouldn't change I believe. Any help with this would be greatly appreciated.
 
Last edited:

MattDees

Well-Known Member
Apr 29, 2005
416
1
243
Houston, TX
cPanel Access Level
Root Administrator
This is a good question.

I'd like to take a look at this a little closer than forums could provide.

Could you please open a ticket titled "removezonerecord ATTN: Matt Dees" and provide logins + access to the script in question (and steps to reproduce)?

I understand if not, but it would make this much easier to troubleshoot :)

tickets.cpanel.net/submit/
 

FrankLaszlo

Active Member
Dec 19, 2008
35
0
56
Hey Mike, while I got you interested :)

Do you know of a way with the API to flip the local and remote SMTP server switch? (to modify /etc/localdomains and /etc/remotedomains)
 

FrankLaszlo

Active Member
Dec 19, 2008
35
0
56
Actually, I just answered my own question at the end. It was an issue of removing a line, and all line numbers after that changing.

What I ended up doing what adding the MX records to an array within the foreach loop and removing them in another loop after reverse sorting them:

Code:
        $rmRec = array();
        $query = "xml-api/dumpzone?domain=$domain";
        $zdata = cpdo($whmip, $whmhash, $query);
        foreach ($zdata['result']['record'] as $key => $val) {
            if ($val['type'] == "MX") {
                $rmRec[] = (array('line' => $val['Line'], 'name' => $val['exchange']));
            } elseif (($val['type'] == "CNAME") && ($val['name'] == "mail.$domain.") && ($mailCNAME)) {
                $rmRec[] = (array('line' => $val['Line'], 'name' => $val['name']));
            }
        }
        rsort($rmRec);
        foreach ($rmRec as $k) {
            $line = $k['line'];
            $name = $k['name'];
            $q = "xml-api/removezonerecord?zone=$domain&Line=$line";
            $rmdata = cpdo($whmip, $whmhash, $q);
            if ($rmdata['result']['status'] == "0") {
                print "Removal of $name failed. -- ";
                print $rmdata['result']['statusmsg'];
                print "\n";
            } else {
                print "$name removed.\n";
            }
        }
One thing I noticed is how slow this can be. It would be much nicer if there was a function in the API to batch edit a zone and remove/add multiple lines at once. Perhaps if the "Line" argument accepted a comma separated list of line numbers?
 

FrankLaszlo

Active Member
Dec 19, 2008
35
0
56
Ya, I just found that as you posted this. Thanks.

Would be a lot better to do it directly with the xml-api rather than having to fall over to the API2 system.
 

MattDees

Well-Known Member
Apr 29, 2005
416
1
243
Houston, TX
cPanel Access Level
Root Administrator
Hey Mike, while I got you interested :)

Do you know of a way with the API to flip the local and remote SMTP server switch? (to modify /etc/localdomains and /etc/remotedomains)
I don't see anything in the XMLAPI to do this, however this should be able to do what you want (with, unfortunately, doing a few other things at the same time).

ApiEmail < ApiDocs/Api2 < TWiki

which can be called via the cpanel xml-api call

CallingAPIFunctions < AllDocumentation/AutomationIntegration < TWiki


that being said, I will be putting in a feature request to add this to the modifyacct XMLAPI call.
 

FrankLaszlo

Active Member
Dec 19, 2008
35
0
56
Can you tell me whats wrong with this? I cant seem to get it to operate properly:

Code:
           if ($config == "aso") {
            $xmlin = urlencode("<cpanelaction><module>Email</module><func>setalwaysaccept</func><apiversion>2</apiversion><args><domain>$domain</domain><mxcheck>local</mxcheck></args></cpanelaction>");
            $q = "xml-api/cpanel?username=$cpuser&module=Email&func=setalwaysaccept&xmlin=$xmlin";
        } else {
            $xmlin = urlencode("<cpanelaction><module>Email</module><func>setalwaysaccept</func><apiversion>2</apiversion><args><domain>$domain</domain><mxcheck>remote</mxcheck></args></cpanelaction>");
            $q = "xml-api/cpanel?username=$cpuser&module=Email&func=setalwaysaccept&xmlin=$xmlin";

        }
        print $q;
        $sdata = cpdo($whmip, $whmhash, $q);
        print_r($sdata);
I tried it with and without the urlencode() function. without it, it seemed to trim off all the xml tags in xmlin.

Here is what its outputting (and not changing the mxcheck as I want it to)

Code:
xml-api/cpanel?username=asotest&module=Email&func=setalwaysaccept&xmlin=%3Ccpanelaction%3E%3Cmodule%3EEmail%3C%2Fmodule%3E%3Cfunc%3Esetalwaysaccept%3C%2Ffunc%3E%3Capiversion%3E2%3C%2Fapiversion%3E%3Cargs%3E%3Cdomain%3Etestingaso123.com%3C%2Fdomain%3E%3Cmxcheck%3Eremote%3C%2Fmxcheck%3E%3C%2Fargs%3E%3C%2Fcpanelaction%3E
Array
(
    [apiversion] => 2
    [event] => Array
        (
            [result] => 1
        )

    [func] => setalwaysaccept
    [module] => Email
)
 

FrankLaszlo

Active Member
Dec 19, 2008
35
0
56
Here is what the cPanel error_log is saying:

Code:
[2010-05-13 02:36:47 -0400] warn [Cpanel::AcctUtils::Owner] Invalid user at /usr/local/cpanel/Cpanel/AcctUtils/Owner.pm line 27
        Cpanel::AcctUtils::Owner::getowner(undef) called at /usr/local/cpanel/Whostmgr/XMLUI/cPanel.pm line 44
        Whostmgr::XMLUI::cPanel::cpanel_exec(HASH(0xf0e6f0), IO::Socket::SSL=GLOB(0x262f6e0), 1, HASH(0x26b9e00)) called at cpsrvd-ssl line 5109
        main::dodoc_whostmgrd() called at cpsrvd-ssl line 1066
        main::dodoc(HASH(0xfab2d0)) called at cpsrvd-ssl line 932
[2010-05-13 02:36:47 -0400] warn [cpsrvd-ssl] Could not resolve uid () or gid () at /usr/local/cpanel/Cpanel/AccessIds/SetUids.pm line 46
        Cpanel::AccessIds::SetUids::setuids(undef) called at /usr/local/cpanel/Whostmgr/XMLUI/cPanel.pm line 55
        Whostmgr::XMLUI::cPanel::cpanel_exec(HASH(0xf0e6f0), IO::Socket::SSL=GLOB(0x262f6e0), 1, HASH(0x26b9e00)) called at cpsrvd-ssl line 5109
        main::dodoc_whostmgrd() called at cpsrvd-ssl line 1066
        main::dodoc(HASH(0xfab2d0)) called at cpsrvd-ssl line 932
[2010-05-13 02:36:50 -0400] warn [cpanel] User file '/var/cpanel/users/root' is empty or non-existent. at /usr/local/cpanel/Cpanel/Config/LoadCpUserFile.pm line 35
        Cpanel::Config::LoadCpUserFile::load('root') called at /usr/local/cpanel/Cpanel/Config/LoadCpUserFile.pm line 158
        Cpanel::Config::LoadCpUserFile::loadcpuserfile('root') called at /usr/local/cpanel/Cpanel.pm line 96
        Cpanel::initcp(Cpanel=HASH(0x18604e30)) called at cpanel line 269
Not 100% sure, but it sounds like the api2 functionality isn't working with the root account's access hash.. Is this intended?
 

FrankLaszlo

Active Member
Dec 19, 2008
35
0
56
Nevermind. I dug through the xmlapi class that was posted up here and found out out to do it. Modified my query to something like this:

Code:
            $q = "xml-api/cpanel?user=$cpuser&cpanel_xmlapi_module=Email&cpanel_xmlapi_func=setalwaysaccept&cpanel_xmlapi_apiversion=2&domain=$domain&mxcheck=remote";