| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450 |
- <?php
- namespace MGModule\DNSManager2\mgLibs\custom\task;
- use \Exception;
- use \MGModule\DNSManager2 as main;
- use \MGModule\DNSManager2\mgLibs\custom\helpers\TimeDiffHelper;
- use \MGModule\DNSManager2\mgLibs\custom\manager\DefaultNotifications;
- use \MGModule\DNSManager2\mgLibs\custom\manager\EmailNotificationHelper;
- use \MGModule\DNSManager2\mgLibs\custom\manager\GlobalSettingHelper;
- use \MGModule\DNSManager2\mgLibs\custom\manager\NotificationHelper;
- use \MGModule\DNSManager2\models\custom\globalsetting\GlobalSettingEnum;
- use \MGModule\DNSManager2\mgLibs\custom\manager\LogHelper;
- use MGModule\DNSManager2\models\custom\package\item\PackageItemTypeEnum;
- use MGModule\DNSManager2\mgLibs\MySQL\query;
- use MGModule\DNSManager2\models\custom\reverse;
- use MGModule\DNSManager2\mgLibs\custom\dns\utils\IP;
- use MGModule\DNSManager2\mgLibs\custom\helpers\IPManagerIntegration;
- use \MGModule\DNSManager2\mgLibs\custom\vendor\IPv6;
- use \MGModule\DNSManager2\mgLibs\custom\task\TaskTypeCodesCodes;
- use \MGModule\DNSManager2\models\custom\zone\Zone;
- use \MGModule\DNSManager2\models\custom\task;
- class Cleaner extends TaskAbstract
- {
- protected $abort_after_repeats = array('main' => 0);
- protected $taskTypeCode = TaskTypeCodesCodes::CLEANER;
- public function mainDescription()
- {
- return 'Cleaner';
- }
-
- public function main($params)
- {
- $this->setStatus(task\TaskStatusEnum::IN_PROGRESS);
- $cron_cleaner_run_each = GlobalSettingHelper::getSetting(GlobalSettingEnum::CRON_CLEANER_RUN_EACH ? : 5);
- if(!$this->isReadyToRun( $cron_cleaner_run_each ))
- {
- return true;
- }
- LogHelper::addSuccessLog($this->mainDescription().' ', 'Cron '.$this->mainDescription().' Started');
- $last_id = GlobalSettingHelper::getSetting(GlobalSettingEnum::CRON_CLEANER_LAST_ID) ? : 0;
- $zones_per_run = GlobalSettingHelper::getSetting(GlobalSettingEnum::CRON_CLEANER_ZONES_PER_RUN);
- $zones_per_run < 1 ? $zones_per_run = 1 : '';
-
- $rep = $this->getZonesRepoWithIDGreaterThan($last_id, $zones_per_run);
- $count_filtered = $rep->count();
-
- $details = array();
- $count_removed = 0;
-
- $notify_only = GlobalSettingHelper::getSetting(GlobalSettingEnum::CRON_CLEANER_NOTIFY_ONLY);
- $notify_only = ($notify_only == 'on' || $notify_only === false) ? true : false;
- foreach($rep->get() as $zone)
- {
- try
- {
- $remove = false;
- $reason = '';
- if(GlobalSettingHelper::getSetting(GlobalSettingEnum::CRON_CLEANER_ZONE_NO_PACKAGE_MATCH) == 'on' && $zone->getPackage() === false)
- {
- $remove = true;
- $reason = "There is no matching package";
- }
- $longer_than = GlobalSettingHelper::getSetting(GlobalSettingEnum::CRON_CLEANER_ZONE_UNMODIFIED_LONGER_THAN);
- if(!$remove && !(empty($longer_than) || $longer_than == 0) && $longer_than <= TimeDiffHelper::diff($zone->updated_at)->minutes)
- {
- $remove = true;
- $reason = "Zone remained unmodified for too long";
- }
- if(!$remove && GlobalSettingHelper::getSetting(GlobalSettingEnum::CRON_CLEANER_ZONE_DOMAIN_NOT_EXIST) == 'on')
- {
- $result = main\mgLibs\custom\helpers\WHMCSApiHelper::domainwhois(array(
- 'domain' => $zone->name,
- ));
- if(isset($result['status']) && strtolower($result['status']) == 'available')
- {
- $remove = true;
- $reason = 'Zone domain does not exist';
- }
- }
- $hostingStatuses = unserialize(GlobalSettingHelper::getSetting(GlobalSettingEnum::CRON_CLEANER_ZONE_INACTIVE_SERVICES));
- $domainStatuses = unserialize(GlobalSettingHelper::getSetting(GlobalSettingEnum::CRON_CLEANER_ZONE_INACTIVE_DOMAINS));
- //domain and hosting in one zone
- if(!$remove && !is_null($zone->connectedWithType) && !is_null($zone->connectedWithRelid) && $zone->connectedWithRelid != 0
- && !empty($hostingStatuses) && !empty($domainStatuses)
- )
- {
- $hostingId = null;
- $domainId = null;
- if($zone->type == PackageItemTypeEnum::HOSTING)
- {
- $hostingId = $zone->relid;
- $domainId = $zone->connectedWithRelid;
- }
- else if($zone->type == PackageItemTypeEnum::DOMAIN)
- {
- $domainId = $zone->relid;
- $hostingId = $zone->connectedWithRelid;
- }
- $Hosting = main\models\whmcs\service\repository::factory()->setFilter('id', $hostingId)->one();
- if($Hosting === false || in_array($Hosting->status(), $hostingStatuses))
- {
- $removeHosting = true;
- $reason = 'Assigned service not active';
- }
- $domain = main\models\whmcs\domains\repository::factory()->setFilter('id', $domainId)->one();
- if($domain === false || in_array($domain->status(), $domainStatuses))
- {
- $removeDomain = true;
- }
- if($removeDomain && $removeHosting)
- {
- $remove = true;
- $reason = 'Assigned domain and service not active';
- }
- if(!$remove)
- {
- continue;
- }
- }
- //hosting
- if(!$remove && $zone->type == PackageItemTypeEnum::PRODUCT && !empty($hostingStatuses))
- {
- $Hosting = main\models\whmcs\service\repository::factory()->setFilter('id', $zone->relid)->one();
- if($Hosting === false || in_array($Hosting->status(), $hostingStatuses))
- {
- $remove = true;
- $reason = 'Assigned service not active';
- }
- }
- //domain
- if(!$remove && $zone->type == PackageItemTypeEnum::DOMAIN && !empty($domainStatuses))
- {
- $domain = main\models\whmcs\domains\repository::factory()->setFilter('id', $zone->relid)->one();
- if($domain === false || in_array($domain->status(), $domainStatuses))
- {
- $remove = true;
- $reason = 'Assigned domain not active';
- }
- }
- $at_least_one = unserialize(GlobalSettingHelper::getSetting(GlobalSettingEnum::CRON_CLEANER_ZONE_AT_LEAST_ONE));
- if(!$remove && !empty($at_least_one))
- {
- try
- {
- $module = $zone->getModule();
- $records = $module->getRecords();
- $available_records = $module->getAvailableRecordTypes();
- foreach($at_least_one as $record_type)
- {
- if(!in_array($record_type, $available_records))
- {
- continue;
- }
-
- foreach($records as $record)
- {
- if(strtoupper($record->type) == strtoupper($record_type))
- {
- continue 2;
- }
- }
-
- $remove = true;
- $reason = "Zone does not include required records defined in configuration";
- break;
- }
- }
- catch(Exception $exc)
- {
- \logModuleCall('DNS Manager', 'Cron Cleaner', "Error. When trying to remove dns zone", array($exc->getMessage(), $exc->getTraceAsString()));
- }
- }
-
- if($remove)
- {
- try
- {
- if(!$notify_only)
- {
- $module = $zone->getModule();
- $module->terminateZone();
- $zone->remove();
- $zoneDataToMail = $zone->toArray()['Zone'];
- $zoneDataToMail['zone_name'] = $zoneDataToMail['name'];
- main\mgLibs\custom\manager\EmailNotificationHelper::sendClientNotificationUsingZone(main\mgLibs\custom\manager\DefaultNotifications::GENERAL_ZONE_REMOVED_NOTIFICATION, $zone, $zoneDataToMail);
- LogHelper::addSuccessLog('Cron Cleaner', 'Remove Zone: '.$zone->name.' Reason: '.$reason);
- }
-
- $count_removed++;
- $details[$zone->name] = $reason;
- }
- catch(Exception $exc)
- {
- \logModuleCall('DNS Manager', 'Cron Cleaner', "Error. When trying to remove dns zone", array($exc->getMessage(), $exc->getTraceAsString()));
- }
- }
- $last_id = $zone->id;
- }
- catch(Exception $exc)
- {
- \logModuleCall('DNS Manager', 'Cron Cleaner', "Error. When trying to remove dns zone", array($exc->getMessage(), $exc->getTraceAsString()));
- }
- }
- if($this->getPtrRemoveSettingsStatus())
- {
- try
- {
- list($details, $count_removed) = $this->removePTRs($notify_only, $details, $count_removed);
- }
- catch(Exception $exc)
- {
- \logModuleCall('DNS Manager', 'Cron Cleaner', "Error. When trying to remove rdns", array($exc->getMessage(), $exc->getTraceAsString()));
- }
- }
-
- if($count_filtered < $zones_per_run)
- {
- $last_id = 0;
- }
-
- GlobalSettingHelper::setSetting(GlobalSettingEnum::CRON_CLEANER_LAST_ID, $last_id);
-
- if($count_removed > 0)
- {
- EmailNotificationHelper::sendAdminNotification(
- DefaultNotifications::ADMIN_CRON_CLEANER_NOTIFICATION,
- array(
- 'notify_only' => $notify_only,
- 'zones_removed_count' => $count_removed,
- 'zones_removed' => $details,
- )
- );
- \logModuleCall('DNS Manager', 'Cron Cleaner', $details, array(), array(
- 'zones_removed_count' => $count_removed,
- 'zones_removed' => $details,
- ), array());
-
- $zonesCountWord = $count_removed == 1 ? 'zone' : 'zones';
- if($notify_only)
- {
- NotificationHelper::addInfoNotification("Cron Cleaner - ".$count_removed." ".$zonesCountWord." should be removed");
- LogHelper::addSuccessLog('Cron Cleaner', "End Of Cleaning Run - ".$count_removed." ".$zonesCountWord." should be removed");
- }
- else
- {
- NotificationHelper::addInfoNotification("Cron Cleaner - ".$count_removed." ".$zonesCountWord." removed");
- LogHelper::addSuccessLog('Cron Cleaner', "End Of Cleaning Run - ".$count_removed." ".$zonesCountWord." removed");
- }
- }
- $this->setStatus(task\TaskStatusEnum::FINISHED);
- }
-
- private function getZonesRepoWithIDGreaterThan($id, $zones_per_run)
- {
- $rep = new main\models\custom\zone\Repository();
- $rep->setFilter(0, array(
- 'customQuery' => 'id > :last_id ',
- 'params' => array('last_id' => $id)
- ));
- $rep->limit($zones_per_run);
- return $rep;
- }
-
- private function removePTRs($notify_only, $details = array(), $count_removed = 0)
- {
- $ptrs = query::query(
- "SELECT ptrs.*, h.`id` as `hid`, h.`userid` as `hosuid`, h.`domain`, h.`domainstatus` as `hstatus` "
- . "FROM `dns_manager2_reverse` ptrs "
- . "LEFT JOIN `tblhosting` h ON (ptrs.`ip` = h.`dedicatedip` OR h.`assignedips` LIKE CONCAT('%', ptrs.`ip`, '%'))"
- )->fetchAll();
- foreach($ptrs as $ptr)
- {
- $reverse = new reverse\Reverse($ptr['id']);
- $delete = false;
- $reason = '';
- try
- {
- $ip = new IP($ptr['ip']);
- $intIp = 0;
- if($ip->isIPv6())
- {
- $intIp = IPv6::inet_ptoi((string) $ip);
- $shortIP = IPv6::inet_itop($intIp);
- $hosting = query::query("SELECT `id`, `domainstatus`, `userid` FROM `tblhosting` WHERE `dedicatedip` = :sip OR `assignedips` LIKE CONCAT('%', :sip2, '%')",
- array('sip' => $shortIP, 'sip2' => $shortIP))->fetch();
- $ptr['hid'] = $hosting['id'];
- $ptr['hstatus'] = $hosting['domainstatus'];
- $ptr['hosuid'] = $hosting['userid'];
- }
- }
- catch(Exception $exc)
- {
- \logModuleCall('DNS Manager', 'Cron Cleaner', "Error. When trying to remove rdns", array($exc->getMessage(), $exc->getTraceAsString()));
- continue;
- }
- if(!$ptr['hid'] && GlobalSettingHelper::getSetting(GlobalSettingEnum::RDNS_CUSTOM_IP) == 'on' && IPManagerIntegration::check())
- {
- $ipFromIPM = query::query(
- "SELECT * "
- . "FROM `ip_manager_ips` "
- . "WHERE " . (isset($intIp) && is_string($intIp) && $intIp != 0 ? ("`ip_v6` = " . $intIp) : "`ip` = :ip") . " ;"
- , array('ip' => $ptr['ip'])
- )->fetch();
- if(!empty($ipFromIPM))
- {
- $delete = true;
- $reason = 'IP Exist in IP Manager pools but not Active!';
- }
- }
- if(empty($ipFromIPM))
- {
- if(!$ptr['hid'])
- {
- $delete = true;
- $reason = 'Service #'. $ptr['hid'] .' Not Found!';
- }
- elseif($ptr['hid'] && $ptr['hstatus'] !== 'Active')
- {
- switch( $ptr['hstatus'] )
- {
- case 'Cancelled':
- if( (string)GlobalSettingHelper::getSetting(GlobalSettingEnum::CRON_CLEANER_PTR_SERVICE_CANCELED) === 'on' )
- {
- $reason = 'Service #' . $ptr['hid'] . ' is Cancelled!';
- $delete = true;
- }
- break;
- case 'Terminated':
- if( (string)GlobalSettingHelper::getSetting(GlobalSettingEnum::CRON_CLEANER_PTR_SERVICE_TERMINATED) === 'on' )
- {
- $reason = 'Service #' . $ptr['hid'] . ' is Terminated!';
- $delete = true;
- }
- break;
- case 'Suspended':
- if( (string)GlobalSettingHelper::getSetting(GlobalSettingEnum::CRON_CLEANER_PTR_SERVICE_SUSPENDED) === 'on' )
- {
- $reason = 'Service #' . $ptr['hid'] . ' is Suspended!';
- $delete = true;
- }
- break;
- }
- }
- elseif($ptr['clientid'] != $ptr['hosuid'])
- {
- $delete = true;
- $reason = 'Service #' . $ptr['hid'] . ' Not Belong to Clients PTR!';
- }
- }
-
- if($delete === true)
- {
- try
- {
- if(!$notify_only)
- {
- $helper = new main\mgLibs\custom\reverse\ReverseDNS($reverse);
-
- $zone = new Zone();
- $zone->name = $reverse->name;
- $zone->serverid = $reverse->serverid;
- $module = $zone->getModule();
- $helper->cleanRemove();
- if($module->zoneExists() && count($module->getRDNSRecord($reverse->ip)) <= 1 && (string)GlobalSettingHelper::getSetting(GlobalSettingEnum::DO_NOT_REMOVE_EMPTY_PTR_ZONES) !== 'on')
- {
- $module->terminateZone();
- }
-
- LogHelper::addSuccessLog('Cron Cleaner', 'Remove PTR record: '.$reverse->name.' Reason: '.$reason);
- }
-
- $count_removed++;
- $details["RDNS " . $reverse->name] = "" . $reason;
- }
- catch(Exception $exc)
- {
- \logModuleCall('DNS Manager', 'Cron Cleaner', "Error. When trying to remove rdns", array($exc->getMessage(), $exc->getTraceAsString()));
- }
- }
- }
- return array($details, $count_removed);
- }
- /**
- * @return bool
- */
- private function getPtrRemoveSettingsStatus()
- {
- $settings = [
- GlobalSettingEnum::CRON_CLEANER_PTR_SERVICE_CANCELED,
- GlobalSettingEnum::CRON_CLEANER_PTR_SERVICE_TERMINATED,
- GlobalSettingEnum::CRON_CLEANER_PTR_SERVICE_SUSPENDED
- ];
- foreach( $settings as $value )
- {
- if( (string)GlobalSettingHelper::getSetting($value) === 'on' )
- {
- return true;
- }
- }
- return false;
- }
- }
|