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\UI\Admin\Product\Providers; use MGProvision\Proxmox\v2\models\Node; use MGProvision\Proxmox\v2\repository\ClusterResourcesRepository; use MGProvision\Proxmox\v2\repository\FileRepository; use MGProvision\Proxmox\v2\repository\NodeRepository; use MGProvision\Proxmox\v2\repository\StorageRepository; use ModulesGarden\ProxmoxAddon\App\Models\CloudInitScript; use ModulesGarden\ProxmoxAddon\App\Models\IpAddress; use ModulesGarden\ProxmoxAddon\App\Models\ProductConfiguration; use ModulesGarden\ProxmoxAddon\App\Models\Whmcs\Product; use ModulesGarden\ProxmoxAddon\App\Repositories\Vps\ProductConfigurationRepository; use ModulesGarden\ProxmoxAddon\App\Services\ApiService; use ModulesGarden\ProxmoxAddon\App\Services\Vps\ProductService; use ModulesGarden\Servers\ProxmoxVps\App\Enum\JobPeriod; use ModulesGarden\Servers\ProxmoxVps\App\UI\Admin\Product\Forms\MainForm; use ModulesGarden\Servers\ProxmoxVps\Core\FileReader\Reader\Json; use ModulesGarden\Servers\ProxmoxVps\Core\Models\Whmcs\EmailTemplate; use ModulesGarden\Servers\ProxmoxVps\Core\ModuleConstants; use ModulesGarden\Servers\ProxmoxVps\Core\UI\Interfaces\AdminArea; use ModulesGarden\Servers\ProxmoxVps\Core\UI\Widget\Forms\DataProviders\BaseDataProvider; use ModulesGarden\Servers\ProxmoxVps\Core\UI\Widget\Forms\Fields\Switcher; use function ModulesGarden\Servers\ProxmoxVps\Core\Helper\sl; class ProductProvider extends BaseDataProvider implements AdminArea { use ApiService; use ProductService; private $productId; /** * @var ProductConfigurationRepository */ protected $configuration; /** * @var Node */ private $node; /** * ProductConfigurationProvider constructor. * @param $productId */ public function __construct($productId) { if (!is_numeric($productId)) { throw new \InvalidArgumentException("The product id must be definded."); } $this->configuration = new ProductConfigurationRepository($productId); $this->productId = $productId; } public function isSupportedModule() { return Product::where("id", $this->configuration->getProductId()) ->where("servertype", "proxmoxVPS")->count() == 1; } public function read() { foreach ($this->configuration->all() as $key => $value) { //multiselect if (is_array($value)) { $this->data[sprintf("customconfigoption[%s][]", $key)] = $value; continue; } $this->data[sprintf("customconfigoption[%s]", $key)] = $value; } $this->initApi(); $this->defaultRead(); if (!$this->configuration->getVirtualization() || $this->configuration->isQemu()) { //kvm $this->qemuRead(); } else { //lxc $this->lxcRead(); } } private function initApi() { $lang = sl("lang"); $product = Product::where("id", $this->productId)->firstOrFail(); sl("whmcsParams")->setParams($product->getParams()); } private function defaultRead() { $lang = sl("lang"); //Virtualization $this->availableValues["customconfigoption[virtualization]"] = ["qemu" => $lang->tr("KVM"), "lxc" => $lang->tr("LXC")]; //Default Node $this->availableValues["customconfigoption[defaultNode]"] = ["serverNode" => $lang->tr('Server-Node'), "autoNode" => $lang->tr('Auto-Node')]; $nodeRepository = new NodeRepository(); $nodeRepository->setApi($this->api()); $nodeRepository->findOnline(true); foreach ($nodeRepository->fetch() as $node) { $this->availableValues["customconfigoption[defaultNode]"][$node->getNode()] = $node->getNode(); } //realm foreach ($this->api()->get("/access/domains") as $d) { if (!$d['realm']) { continue; } $this->availableValues["customconfigoption[realm]"][$d['realm']] = $lang->tr($d['comment']); } //userRole foreach ($this->api()->get("/access/roles") as $r) { if (!$r['roleid']) { continue; } $this->availableValues["customconfigoption[userRole]"][$r['roleid']] = $lang->tr($r['roleid']); } //welcomeEmailTemplateId $this->availableValues["customconfigoption[welcomeEmailTemplateId]"][0] = ""; foreach (EmailTemplate::where('type', "product")->pluck("name", "id")->all() as $key => $value) { $this->availableValues["customconfigoption[welcomeEmailTemplateId]"][$key] = $value; } //reinstallEmailTemplateId $this->availableValues["customconfigoption[reinstallEmailTemplateId]"][0] = ""; foreach (EmailTemplate::where('type', "product")->pluck("name", "id")->all() as $key => $value) { $this->availableValues["customconfigoption[reinstallEmailTemplateId]"][$key] = $value; } //upgradeNotificationTemplateId $this->availableValues["customconfigoption[serviceCreationFailedTemplateId]"][0] = ""; foreach (EmailTemplate::where('type', "admin")->where("custom", 1)->pluck("name", "id")->all() as $key => $value) { $this->availableValues["customconfigoption[serviceCreationFailedTemplateId]"][$key] = $value; } //upgradeNotificationTemplateId $this->availableValues["customconfigoption[upgradeNotificationTemplateId]"] = $this->availableValues["customconfigoption[serviceCreationFailedTemplateId]"]; //loadBalancerOnUpgrade $this->availableValues["customconfigoption[loadBalancerOnUpgrade]"] = ['0' => $lang->tr('None'), "block" => $lang->tr("Block"), "migrate" => $lang->tr("Migrate")]; //backupStorage if (in_array($this->configuration->getDefaultNode(), $this->availableValues["customconfigoption[defaultNode]"])) { $this->node = new Node($this->configuration->getDefaultNode()); } else {//"Auto-Node" or 'Server-Node' or empty $servePrivateIP = $this->getServerPrivateIpAddress(); $serverIp = $servePrivateIP ? $servePrivateIP : $this->getWhmcsParamByKey('serverip'); $this->node = $nodeRepository->findWithHostOrIp($this->getWhmcsParamByKey('serverhostname'), $serverIp ); } $this->node->setApi($this->api()); $storageRepository = new StorageRepository(); $storageRepository->findByNodes([$this->node->getNode()]) ->findEnabed(); foreach ($storageRepository->fetch() as $entity) { if (!in_array("backup", $entity->getContentAsArray())) { continue; } $this->availableValues["customconfigoption[backupStorage]"] [$entity->getStorage()] = $lang->tr($entity->getStorage()); } //clusterState $this->availableValues["customconfigoption[clusterState]"] = ['' => "", 'started' => $lang->tr('Started'), 'stopped' => $lang->tr('Stopped'), 'enabled' => $lang->tr('Enabled'), 'disabled' => $lang->tr('Disabled'), 'ignored' => $lang->tr('Ignored')]; //firewallInterfaces $this->availableValues["customconfigoption[firewallInterfaces][]"] = ["venet" => $lang->tr("venet"), "eth" => $lang->tr("eth\d+")]; //clusterGroup $this->availableValues["customconfigoption[clusterGroup]"] = ['' => ""]; foreach ($this->api()->get('/cluster/ha/groups') as $g) { $this->availableValues["customconfigoption[clusterGroup]"][$g['group']] = ucfirst($g['group']); } //suspensionAction $this->availableValues["customconfigoption[suspensionAction]"] = ['0' => $lang->tr('Default'), "stop" => $lang->tr('Stop VM'), 'shutdown' => $lang->tr('Shutdown VM')]; if ($this->configuration()->isQemu()) { $this->availableValues["customconfigoption[suspensionAction]"]["suspend"] = $lang->tr("Pause VM"); $this->availableValues["customconfigoption[suspensionAction]"]["hibernate"] = $lang->tr("Hibernate VM"); } //tag $this->availableValues["customconfigoption[tags][]"]; foreach (IpAddress::select("tag")->whereNotNull("tag")->where("tag", ">", 0)->groupBy("tag")->pluck("tag")->all() as $tag) { $this->availableValues["customconfigoption[tags][]"][$tag] = $tag; } //pool $this->availableValues["customconfigoption[pool]"]=[""]; foreach ($this->api()->get('/pools') as $pool) { $this->availableValues["customconfigoption[pool]"][$pool['poolid']] = $lang->tr($pool['poolid']); } //permissionSnapshotJobPeriod $this->availableValues["customconfigoption[permissionSnapshotJobPeriod][]"] = [ JobPeriod::HOURLY => $lang->tr(JobPeriod::HOURLY), JobPeriod::DAILY => $lang->tr(JobPeriod::DAILY ) ]; //permissionFirewalOptions $this->availableValues["customconfigoption[permissionFirewalOptions][]"] = [ "enable" => $lang->abtr("Enable/Disable Firewall"), "dhcp" => $lang->abtr("DHCP"), "radv" => $lang->abtr("Allow Router Advertisement"), "ndp" => $lang->abtr("NDP"), "macfilter" => $lang->abtr("MAC Filter"), "ipfilter" => $lang->abtr("IP Filter"), ]; } /** * KVM */ private function qemuRead() { $lang = sl("lang"); //ostype $ostype = new Json('ostype.json', ModuleConstants::getFullPathWhmcs('modules', 'addons', 'proxmoxAddon', 'storage', 'app')); foreach ($ostype->get() as $k => $ostype) { $this->availableValues["customconfigoption[ostype]"][$k] = $lang->tr($ostype); } //hotplug $this->availableValues["customconfigoption[hotplug][]"] = [ "disk" => $lang->tr('disk'), "network" => $lang->tr('network'), "usb" => $lang->tr('usb'), "cpu" => $lang->tr('cpu'), "memory" => $lang->tr('memory')]; //keyboard $this->availableValues["customconfigoption[keyboard]"] = ['', 'pt' => $lang->tr('pt'), "tr" => $lang->tr('tr'), 'ja' => $lang->tr('ja'), 'es' => $lang->tr('es'), 'no' => $lang->tr('no'), 'is' => $lang->tr('is'), 'fr-ca' => $lang->tr('fr-ca'), 'fr' => $lang->tr('fr'), 'pt-br' => $lang->tr('pt-br'), 'da' => $lang->tr('da'), 'fr-ch' => $lang->tr('fr-ch'), 'sl' => $lang->tr('sl'), 'de-ch' => $lang->tr('de-ch'), 'en-gb' => $lang->tr('en-gb'), 'it' => $lang->tr('it'), 'en-us' => $lang->tr('en-us'), 'fr-be' => $lang->tr('fr-be'), 'hu' => $lang->tr('hu'), 'pl'=> $lang->tr('pl'), 'nl' => $lang->tr('nl'), 'mk' => $lang->tr('mk'), 'fi' => $lang->tr('fi'), 'lt' => $lang->tr('lt'), 'sv'=> $lang->tr('sv'), 'de' => $lang->tr('de')]; //vga $this->availableValues["customconfigoption[vga]"] = [ "std" => $lang->tr("Standard VGA"), "cirrus" => $lang->tr("Cirrus Logic"), "vmware" => $lang->tr("VMWare"), "serial0" => $lang->tr("Serial terminal 0"), "serial1" => $lang->tr("Serial terminal 1"), "serial2" => $lang->tr("Serial terminal 2"), "serial3" => $lang->tr("Serial terminal 3"), "qxl" => $lang->tr("SPICE"), "qxl2" => $lang->tr("SPICE dual monitor"), "qxl3" => $lang->tr("SPICE three monitor"), "qxl4" => $lang->tr("SPICE four monitor"), ]; //clientNameForContainer $this->availableValues["customconfigoption[clientNameForContainer]"] = [ 0 => 'No', "emptyHostnameOnly" => 'Yes [only when hostname is empty]', "overwriteHostname" => 'Yes [overwrite hostname] ', "overwriteHostnameWithPrefix" => 'Yes [overwrite hostname with container prefix and service id] ', ]; //cloneMode $this->availableValues["customconfigoption[cloneMode]"] = ['1' => $lang->tr('Full Clone'), "0" => $lang->tr("Linked Clone")]; //diskStorage images (Disk Images) $storageRepository = new StorageRepository(); $storageRepository->findByNodes([$this->node->getNode()]) ->findEnabed(); foreach ($storageRepository->fetch() as $entity) { if (!in_array("images", $entity->getContentAsArray())) { continue; } $this->availableValues["customconfigoption[diskStorage]"] [$entity->getStorage()] = $lang->tr($entity->getStorage()); $this->availableValues["customconfigoption[additionalDiskStorage]"] [$entity->getStorage()] = $lang->tr($entity->getStorage()); } //diskType $this->availableValues["customconfigoption[diskType]"] = ["ide" => $lang->tr('IDE'), "sata" => $lang->tr('SATA'), "virtio" => $lang->tr('VIRTIO'), "scsi" => $lang->tr('SCSI')]; //diskFormat $this->availableValues["customconfigoption[diskFormat]"] = ['raw' => $lang->tr('Raw disk image (raw)'), 'qcow2' => $lang->tr('QEMU image format (qcow2)'), 'vmdk' => $lang->tr('VM image format (vmdk)')]; //diskCache $this->availableValues["customconfigoption[diskCache]"] = ['none' => $lang->tr('Default (No Cache)'), 'writethrough' => $lang->tr('Write Through'), 'writeback' => $lang->tr('Write Back'), 'unsafe' => $lang->tr('Write Back (Unsafe)'), 'directsync' => $lang->tr('Direct Sync')]; //scsihw $this->availableValues["customconfigoption[scsihw]"] = [ '0' => $lang->abtr('Default (LSI 53C895A)'), "lsi" => $lang->abtr('LSI 53C895A'), "lsi53c810" => $lang->abtr('LSI 53C810'), 'virtio-scsi-pci' => $lang->abtr('VirtIO SCSI'), "virtio-scsi-single" => $lang->abtr('VirtIO SCSI single'), 'megasas' => $lang->abtr('MegaRAID SAS 8708EM2'), "pvscsi" => $lang->abtr('VMware PVSCSI'), ]; //additionalDiskStorage $this->availableValues["customconfigoption[additionalDiskStorage]"] = $this->availableValues["customconfigoption[diskStorage]"]; //additionalDiskType $this->availableValues["customconfigoption[additionalDiskType][]"] = $this->availableValues["customconfigoption[diskType]"]; //additionalDiskFormat $this->availableValues["customconfigoption[additionalDiskFormat][]"] = $this->availableValues["customconfigoption[diskFormat]"]; if($this->configuration->getAdditionalDiskStorage() && preg_match("/lvm/", $this->configuration->getAdditionalDiskStorage() )){ $this->disabledList["customconfigoption[additionalDiskFormat][]"] = ['qcow2', 'vmdk']; } //additionalDiskCache $this->availableValues["customconfigoption[additionalDiskCache]"] = $this->availableValues["customconfigoption[diskCache]"]; //networkModel $this->availableValues["customconfigoption[networkModel]"] = ['e1000' => $lang->tr('e1000'), 'i82551' => $lang->tr('i82551'), 'i82557b' => $lang->tr('i82557b'), 'i82559er' => $lang->tr('i82559er'), 'ne2k_isa' => $lang->tr('ne2k_isa'), 'ne2k_pci' => $lang->tr('ne2k_pci'), 'pcnet' => $lang->tr('pcnet'), 'rtl8139' => $lang->tr('rtl8139'), 'virtio' => $lang->tr('virtio'), 'vmxnet3' => $lang->tr('vmxnet3')]; //bridge foreach ($this->api()->get("/nodes/{$this->node->getNode()}/network") as $network) { if (!in_array($network['type'], ['bridge', 'OVSBridge'])) { continue; } $this->availableValues["customconfigoption[bridge]"] [$network['iface']] = $lang->tr($network['iface']); } ksort($this->availableValues["customconfigoption[bridge]"]); //privateBridge $this->availableValues["customconfigoption[privateBridge]"] = ['0' => ""] + (array) $this->availableValues["customconfigoption[bridge]"]; //networkPrivateModel $this->availableValues["customconfigoption[networkPrivateModel]"] = $this->availableValues["customconfigoption[networkModel]"]; //bootDevice1 $this->availableValues["customconfigoption[bootDevice1]"] = ['', 'c' => $lang->tr('Hard Disk'), 'd' => $lang->tr('CD-ROM'), 'n' => $lang->tr('Network')]; //bootDevice2 $this->availableValues["customconfigoption[bootDevice2]"] = $this->availableValues["customconfigoption[bootDevice1]"]; //bootDevice3 $this->availableValues["customconfigoption[bootDevice3]"] = $this->availableValues["customconfigoption[bootDevice1]"]; //permissionOsTemplates $clusterResourcesRepository = new ClusterResourcesRepository(); $clusterResourcesRepository->setApi($this->api()); $clusterResourcesRepository->findKvmTemplate(); foreach ($clusterResourcesRepository->fetch() as $resurce) { if (preg_match('/^custom[0-9]*/', $resurce->getName())) { continue; } $this->availableValues["customconfigoption[permissionOsTemplates][]"][$resurce->getName()] = $lang->tr($resurce->getName()); } //osTemplate $this->availableValues["customconfigoption[osTemplate]"] = ['0' => ""] + (array) $this->availableValues["customconfigoption[permissionOsTemplates][]"]; //permissionIsoImage $fileRepository = new FileRepository(); $fileRepository->setApi($this->api()); $fileRepository->findIso(); $fileRepository->findByNode($this->node); $fileRepository->findByStorages($storageRepository->fetchAsArray()); foreach ($fileRepository->fetch() as $file) { $this->availableValues["customconfigoption[permissionIsoImages][]"][$file->getVolid()] = $lang->tr($file->getFriendlyName()); } //isoImage $this->availableValues["customconfigoption[isoImage]"] = ["none" => $lang->tr("None")] + (array)$this->availableValues["customconfigoption[permissionIsoImages][]"]; //memoryUnit $this->availableValues["customconfigoption[memoryUnit]"] = ['mb' => $lang->tr("MB"), "gb" => $lang->tr("GB")]; //diskUnit $this->availableValues["customconfigoption[diskUnit]"] = ['mb' => $lang->tr("MB"), "gb" => $lang->tr("GB"), "tb" => $lang->tr("TB")]; //additionalDiskUnit $this->availableValues["customconfigoption[additionalDiskUnit]"] = ['mb' => $lang->tr("MB"), "gb" => $lang->tr("GB"), "tb" => $lang->tr("TB")]; //cdromType $this->availableValues["customconfigoption[cdromType]"] = $this->availableValues["customconfigoption[diskType]"]; //bios $this->availableValues["customconfigoption[bios]"] = [ '0' => "", 'seabios' => $lang->tr('SeaBIOS'), 'ovmf' => $lang->tr('OVMF (UEFI)') ]; //cloudInitScript $this->availableValues["customconfigoption[cloudInitScript]"] = CloudInitScript::pluck('name','id')->prepend("",0)->toArray(); //machine $jsonData = new Json('machine.json', ModuleConstants::getFullPathWhmcs('modules', 'addons', 'proxmoxAddon', 'storage', 'app')); foreach ($jsonData->get() as $k => $name) { $this->availableValues["customconfigoption[machine]"][$k] = $lang->tr($name); } //cpu $jsonData = new Json('cpu.json', ModuleConstants::getFullPathWhmcs('modules', 'addons', 'proxmoxAddon', 'storage', 'app')); foreach ($jsonData->get() as $k => $name) { $this->availableValues["customconfigoption[cpu]"][$k] = $lang->tr($name); } } /** * LXC */ private function lxcRead() { $lang = sl("lang"); //storage $storageRepository = new StorageRepository(); $storageRepository->findByNodes([$this->node->getNode()]) ->findEnabed(); foreach ($storageRepository->fetch() as $storage) { if (!in_array("rootdir", $storage->getContentAsArray())) { continue; } $this->availableValues["customconfigoption[storage]"][$storage->getStorage()] = $lang->tr($storage->getStorage()); } //arch $this->availableValues["customconfigoption[arch]"] = ['0' => "", 'amd64' => $lang->tr("AMD64"), $lang->tr("i386") => $lang->tr("i386")]; //cmode $this->availableValues["customconfigoption[cmode]"] = ['0' => "", 'shell' => $lang->tr("shell"), "console" => $lang->tr("console"), "tty" => $lang->tr("tty")]; //ostype $this->availableValues["customconfigoption[ostype]"] = ['0' => "", 'debian' => $lang->tr("Debian"), "ubuntu" => $lang->tr("Ubuntu"), "centos" => $lang->tr("centos"), "archlinux" => $lang->tr("Archlinux")]; //osTemplate $fileRepository = new FileRepository(); $fileRepository->setApi($this->api()); $fileRepository->findLxcTemplates(); $fileRepository->findByNode($this->node); $fileRepository->findByStorages($storageRepository->fetchAsArray()); foreach ($fileRepository->fetch() as $file) { $this->availableValues["customconfigoption[osTemplate]"][$file->getVolid()] = $lang->tr($file->getFriendlyName()); } //memoryUnit $this->availableValues["customconfigoption[memoryUnit]"] = ['mb' => $lang->tr("MB"), "gb" => $lang->tr("GB")]; //diskUnit $this->availableValues["customconfigoption[diskUnit]"] = ['mb' => $lang->tr("MB"), "gb" => $lang->tr("GB"), "tb" => $lang->tr("TB")]; //additionalDiskUnit $this->availableValues["customconfigoption[additionalDiskUnit]"] = ['mb' => $lang->tr("MB"), "gb" => $lang->tr("GB"), "tb" => $lang->tr("TB")]; //persimonOsTemplates $this->availableValues["customconfigoption[permissionOsTemplates][]"] = $this->availableValues["customconfigoption[osTemplate]"]; //mountPointStorage foreach ($storageRepository->fetch() as $entity) { if (!in_array("rootdir", $entity->getContentAsArray())) { continue; } $this->availableValues["customconfigoption[mountPointStorage]"][$entity->getStorage()] = $lang->tr($entity->getStorage()); } //mountPointAcl $this->availableValues["customconfigoption[mountPointAcl]"] = ["default" => $lang->tr('Default'), "1" => $lang->tr("On"), "0" => $lang->tr("Off")]; //ipv4NetworkMode $this->availableValues["customconfigoption[ipv4NetworkMode]"] = ["static" => $lang->tr('Static'), "dhcp" => $lang->tr("DHCP")]; //ipv6NetworkMode $this->availableValues["customconfigoption[ipv6NetworkMode]"] = ["static" => $lang->tr('Static'), "dhcp" => $lang->tr("DHCP"), "slaac" => $lang->tr("SLAAC")]; //swapUnit $this->availableValues["customconfigoption[swapUnit]"] = ['mb' => $lang->tr("MB"), "gb" => $lang->tr("GB"), "tb" => $lang->tr("TB")]; //bridge foreach ($this->api()->get("/nodes/{$this->node->getNode()}/network") as $network) { if (!in_array($network['type'], ['bridge', 'OVSBridge'])) { continue; } $this->availableValues["customconfigoption[bridge]"] [$network['iface']] = $lang->tr($network['iface']); } ksort($this->availableValues["customconfigoption[bridge]"]); //privateBridge $this->availableValues["customconfigoption[privateBridge]"] = ['0' => ""] + (array) $this->availableValues["customconfigoption[bridge]"]; } public function update() { $this->loadRequestObj(); if (empty($this->request->get('customconfigoption'))) { return; } try{ $form = new MainForm(); $switcherFields = $form->getSwitcherFields(); $values = $this->request->get('customconfigoption'); foreach ($values as $k => $v) { if (in_array($k, $switcherFields)) { unset($switcherFields[array_search($k, $switcherFields)]); } } foreach ($switcherFields as $switch) { $values[$switch] = "off"; } }catch (\Exception $ex){ //login to proxmox host failed } //delete $this->configuration->flush(); sleep(1); //save $this->configuration->fill((array)$values) ->save(); } public function delete() { $this->configuration->flush(); } public function replicate($replicateProductId){ $_SESSION['proxmoxVPS']= null; if(ProductConfiguration::ofProductId($this->productId)->count()){ return; } /** * @var $entity ProductConfiguration */ foreach (ProductConfiguration::ofProductId($replicateProductId)->get() as $entity) { $newEntity = new ProductConfiguration(); $newEntity->setting = $entity->setting; $newEntity->value = $entity->value; $newEntity->product_id = $this->productId; $newEntity->save(); } } }