http://modulesgarden.com * CONTACT -> contact@modulesgarden.com * * * This software is furnished under a license and may be used and copied * only in accordance with the terms of such license and with the * inclusion of the above copyright notice. This software or any other * copies thereof may not be provided or otherwise made available to any * other person. No title to and ownership of the software is hereby * transferred. * * **********************************************************************/ namespace ModulesGarden\Servers\ProxmoxVps\App\Http\Actions; use Illuminate\Database\Capsule\Manager as DB; use ModulesGarden\ProxmoxAddon\App\Events\Vps\LxcUpdateEvent; use ModulesGarden\ProxmoxAddon\App\Events\Vps\QemuUpdateEvent; use ModulesGarden\ProxmoxAddon\App\Jobs\Vps\Agent\ConfigureNetworkJob; use ModulesGarden\ProxmoxAddon\App\Jobs\Vps\LoadBalancer as LoadBalancer; use ModulesGarden\ProxmoxAddon\App\Jobs\Vps\RebootVmJob; use ModulesGarden\ProxmoxAddon\App\Jobs\Vps\Reinstall\BackupVmJob; use ModulesGarden\ProxmoxAddon\App\Jobs\Vps\Reinstall\CreateVmJob; use ModulesGarden\ProxmoxAddon\App\Jobs\Vps\Reinstall\DeleteVmJob; use ModulesGarden\ProxmoxAddon\App\Libs\Format; use ModulesGarden\ProxmoxAddon\App\Models\Job; use ModulesGarden\ProxmoxAddon\App\Models\Whmcs\ToDoList; use ModulesGarden\ProxmoxAddon\App\Models\Whmcs\Upgrade; use ModulesGarden\ProxmoxAddon\App\Services\ApiService; use ModulesGarden\ProxmoxAddon\App\Services\EmailService; use ModulesGarden\ProxmoxAddon\App\Services\LoadBalancerService; use ModulesGarden\ProxmoxAddon\App\Services\Utility; use ModulesGarden\ProxmoxAddon\App\Services\Vps\HostingService; use ModulesGarden\ProxmoxAddon\App\Services\Vps\IpSetIpFilterService; use ModulesGarden\ProxmoxAddon\App\Services\Vps\NetworkService; use ModulesGarden\ProxmoxAddon\App\Services\Vps\ProductService; use ModulesGarden\ProxmoxAddon\App\Services\Vps\UserService; use ModulesGarden\Servers\ProxmoxVps\App\Helpers\AppParams; use ModulesGarden\Servers\ProxmoxVps\App\Helpers\ProxmoxAddonValidator; use ModulesGarden\Servers\ProxmoxVps\Core\App\Controllers\Instances\AddonController; use ModulesGarden\Servers\ProxmoxVps\Core\UI\Traits\WhmcsParams; use function ModulesGarden\ProxmoxAddon\Core\Helper\fire; use function ModulesGarden\ProxmoxAddon\Core\Helper\queue; use function ModulesGarden\ProxmoxAddon\Core\Helper\sl; use ModulesGarden\Servers\ProxmoxVps\App\Enum\ConfigurableOption; class ChangePackage extends AddonController { use WhmcsParams; use ApiService; use ProductService; use UserService; use HostingService; /** * @var NetworkService */ private $networkService; /** * @var IpSetIpFilterService */ private $ipSetIpFilterService; /** * @var EmailService */ private $emailService; /** * ChangePackage constructor. * @param $networkService */ public function __construct() { $this->networkService = new NetworkService(); $this->ipSetIpFilterService = new IpSetIpFilterService(); $this->emailService = new EmailService(); } public function execute($params = null) { if(!ProxmoxAddonValidator::isInstalled()){ return ProxmoxAddonValidator::failAsString(); } (new AppParams())->initFromWhmcsParams(); try { $this->manuallyUpgrade(); //Disk $this->diskSizeValidation(); $this->createReinstallJob(); //Add IP Addresses if (!Utility::isIpManagerProxmoxVPSIntegration()) { list($requestIPv4, $requestIPv6) = $this->networkService->getIpAddressesRequest(); $this->networkService->hasIp($requestIPv4, $requestIPv6, $this->vm()->getNode()) ->addIp($requestIPv4, $requestIPv6, $this->vm()->getNode()); } //Unassing ip addresses and delete network if(!Utility::isIpManagerProxmoxVPSIntegration()) { $this->networkService->unassignIpAddressesAndDeleteNetwork(); } //Load Balancer if (!Job::waiting()->ofHostingId($this->getWhmcsParamByKey("serviceid"))->ofJob(LoadBalancer\UpgradeVmJob::class)->count() && $this->configuration()->isLoadBalancer() && in_array($this->configuration()->getLoadBalancerOnUpgrade(), ["block", "migrate"])) { $loadBalancer = new LoadBalancerService($this->getWhmcsParamByKey('serverid')); $loadBalancer->setApi($this->api()); //Disk $disk = $this->configuration()->getDiskSize(); Utility::unitFormat($disk, "gb", 'bytes'); if ($this->getWhmcsConfigOption(ConfigurableOption::DISK_SIZE)) { $disk = $this->getWhmcsConfigOption(ConfigurableOption::DISK_SIZE); Utility::unitFormat($disk, $this->configuration()->getDiskUnit(), 'bytes'); } //RAM $ram = $this->configuration()->getMemory(); Utility::unitFormat($ram, "mb", 'bytes'); if ($this->getWhmcsConfigOption(ConfigurableOption::MEMORY)) { $ram = $this->getWhmcsConfigOption(ConfigurableOption::MEMORY); Utility::unitFormat($ram, $this->configuration()->getMemoryUnit(), 'bytes'); } if ($this->configuration()->isQemu()) { $socket = $this->getWhmcsConfigOption(ConfigurableOption::SOCKETS,$this->configuration()->getSockets() ); $cores = $this->getWhmcsConfigOption(ConfigurableOption::CORES_PER_SOCKET, $this->configuration()->getCores()) ; $cpu = $socket * $cores; } else if ($this->configuration()->isLxc()) { $cpu = $this->getWhmcsConfigOption(ConfigurableOption::CORES, $this->configuration()->getCores()) ; } $loadBalancer->setExcludeVmid($this->vm()->getVmid()); //Upgrade on current node if ($this->configuration()->getLoadBalancerOnUpgrade() == "block") { $loadBalancerNodes = $loadBalancer->findByNode($this->vm()->getNode()); $loadBalancerNodes = $loadBalancerNodes->findByRam($ram) ->findByCpu($cpu) ->findByDisk($disk); if ($loadBalancerNodes->isEmpty()) { throw new \Exception("Load Balancer: Cannot find free resources on node: " . $this->vm()->getNode()); } } else { if ($this->configuration()->getLoadBalancerOnUpgrade() == "migrate") { //Allow to upgrade process, after previous migration vm to the server with free space. $loadBalancerNodes = $loadBalancer->findByNode($this->vm()->getNode()); $loadBalancerNodes = $loadBalancerNodes->findByRam($ram) ->findByCpu($cpu) ->findByDisk($disk); if ($loadBalancerNodes->isEmpty()) { $loadBalancerNodes = $loadBalancer->findByVmCreate(); $nodesForUser = $loadBalancer->findNotUser($this->getWhmcsParamByKey('userid')); if (!$nodesForUser->isEmpty()) { $loadBalancerNodes = $nodesForUser; } $targetNode = $loadBalancerNodes->findByRam($ram) ->findByCpu($cpu) ->findByDisk($disk) ->findByVms(1) ->nodeLowLoad(); if ($this->configuration()->isLoadBalancerShutdownOnUpgrade()) { $job = queue(LoadBalancer\ShutdownVmJob::class, ['hostingId' => $this->getWhmcsParamByKey('serviceid'), "targetNode" => $targetNode], null, "hosting", $this->getWhmcsParamByKey("serviceid")); } $job = queue(LoadBalancer\MigrateVmJob::class, ['hostingId' => $this->getWhmcsParamByKey('serviceid'), "targetNode" => $targetNode], $job->id, "hosting", $this->getWhmcsParamByKey("serviceid")); queue(LoadBalancer\UpgradeVmJob::class, ['hostingId' => $this->getWhmcsParamByKey('serviceid'), "targetNode" => $targetNode], $job->id, "hosting", $this->getWhmcsParamByKey("serviceid")); return true; } } } } if ($this->configuration()->isQemu()) { $evnet = new QemuUpdateEvent($this->vm()); $evnet->setChangeVmPassword(false); fire($evnet); } elseif ($this->configuration()->isLxc()) { fire(new LxcUpdateEvent($this->vm())); } //hosting limit $this->saveUsageLimit(); //reboot if ($this->configuration()->isRebootVmAfterChangePackage() && $this->vm()->isRunning() && !Job::waiting()->ofJob(RebootVmJob::class)->ofHostingId($this->getWhmcsParamByKey("serviceid"))->count()) { $parentId = queue(RebootVmJob::class, ['hostingId' => $this->getWhmcsParamByKey('serviceid')], null, "hosting", $this->getWhmcsParamByKey("serviceid")); } if($this->configuration()->isAgentConfigureNetwork()){ $parentId = queue(ConfigureNetworkJob::class, ['hostingId' => $this->getWhmcsParamByKey('serviceid')], $parentId, "hosting", $this->getWhmcsParamByKey("serviceid")); } //IP Filter if ($this->configuration()->isIpsetIpFilter()) { $this->ipSetIpFilterService->create(); } return "success"; } catch (\Exception $ex) { return $ex->getMessage(); } } private function manuallyUpgrade() { $scriptFile = substr($_SERVER['SCRIPT_NAME'], strrpos($_SERVER['SCRIPT_NAME'], DIRECTORY_SEPARATOR) + 1); if (!$this->configuration()->getUpgradeNotificationTemplateId() || $scriptFile == "clientsservices.php") { return; } if ($this->configuration()->isToDoList()) { $title = sprintf('Manually Upgrade - Service ID: %s', $this->getWhmcsParamByKey('serviceid')); if (!ToDoList::ofTitle($title)->pending()->count()) { $entity = new ToDoList(); $entity->fill( [ 'date' => date("Y-m-d H:i:s"), "duedate" => date("Y-m-d H:i:s"), 'title' => $title, "status" => "Pending", "description" => "An upgrade order has received its payment, automatic upgrades has been disabled and requires manually processing.", "admin" => 0, ] ); $entity->save(); } } //Send Admin notification $this->emailService->template($this->configuration()->getUpgradeNotificationTemplateId()); global $customadminpath; $adminDir = $customadminpath ? $customadminpath : "admin"; $adminAreaLink = $GLOBALS['CONFIG']['SystemURL'] . "/{$adminDir}"; $hosting = $GLOBALS['CONFIG']['SystemURL'] . "/{$adminDir}/clientsservices.php?id=" . $this->getWhmcsParamByKey('serviceid'); $emailVars = [ "client_id" => $this->getWhmcsParamByKey('clientsdetails')['id'], "service_id" => $this->getWhmcsParamByKey('serviceid'), "service_product" => "{$hosting}", "service_domain" => $this->getWhmcsParamByKey('domain'), "whmcs_admin_link" => "{$adminAreaLink}", ]; $this->emailService->vars($emailVars)->sendToAdmin(); throw new \Exception("Automaticall upgrade has been disabled by admin"); } private function createReinstallJob() { if (!$this->getWhmcsConfigOption(ConfigurableOption::OS_TEMPLATE)) { return; } if (!Upgrade::ofHostingId($this->getWhmcsParamByKey('serviceid'))->pending()->today()->count()) { return; } $pg = "tblproductconfiggroups"; $pl = "tblproductconfiglinks"; $po = "tblproductconfigoptions"; $optionId = DB::table($po) ->select("{$po}.id") ->leftJoin($pg, "{$pg}.id", "=", "{$po}.gid") ->leftJoin($pl, "{$pl}.gid", "=", "{$pg}.id") ->where("{$pl}.pid", $this->getWhmcsParamByKey("pid")) ->where("{$po}.optionname", "like", "VM Template|%") ->value("id"); if (!$optionId) { return; } if (!Upgrade::ofHostingId($this->getWhmcsParamByKey('serviceid'))->pending()->today()->ofOptionId($optionId)->count()) { return; } if ($this->configuration()->isQemu()) { if ($this->getWhmcsConfigOption(ConfigurableOption::OS_TEMPLATE)=== "0") { return; } } $arguments = [ 'hostingId' => $this->getWhmcsParamByKey('serviceid'), "osTemplate" => $this->getWhmcsConfigOption(ConfigurableOption::OS_TEMPLATE), "password" => encrypt($this->getWhmcsParamByKey("password")) ]; if ($this->configuration()->isBackupVmBeforeReinstall()) { $job = queue(BackupVmJob::class, $arguments, null, "hosting", $this->getWhmcsParamByKey("serviceid")); } $job = queue(DeleteVmJob::class, $arguments, $job->id, "hosting", $this->getWhmcsParamByKey("serviceid")); $job = queue(CreateVmJob::class, $arguments, $job->id, "hosting", $this->getWhmcsParamByKey("serviceid")); } protected function diskSizeValidation(){ $diskSize = $this->configuration()->getDiskSize(); if ($this->getWhmcsConfigOption(ConfigurableOption::DISK_SIZE)) { $diskSize = $this->getWhmcsConfigOption(ConfigurableOption::DISK_SIZE); Utility::unitFormat($diskSize, $this->configuration()->getDiskUnit(), 'bytes'); }else{ Utility::unitFormat($diskSize, "gb", 'bytes'); } $masterHddSize = $this->vm()->getMasterHddSize(); Utility::unitFormat($masterHddSize, "gb", 'bytes'); if ($diskSize < $masterHddSize) { throw new \Exception(sprintf('Downgrading disk size is restricted. Request Disk size: %s, VM disk size: %s', Format::convertBytes($diskSize), Format::convertBytes($masterHddSize))); } } }