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 MGProvision\Proxmox\v2\repository; use MGProvision\Proxmox\v2\models\Node; use MGProvision\Proxmox\v2\ProxmoxApiException; /** * Description of NodeRepository * * @author Pawel Kopec * @version 1.0.0 */ class NodeRepository extends AbstractRepository { private $online = true; /** * * @param string $hostname * @param string $ipAddress * @return string * @throws ProxmoxApiException */ public function findWithHostOrIp($hostname, $ipAddress) { if (empty($hostname) && empty($ipAddress)) { throw new ProxmoxApiException('Server\'s Hostname is empty'); } //Hostname if (preg_match('/\:/', $hostname)) { list($host, $port) = explode(":", $hostname); $port = (int) $port; if (is_string($host)) { $hostname = $host; } } //IpAddress if (preg_match('/\:/', $ipAddress)) { list($host, $port) = explode(":", $ipAddress); $port = (int) $port; if (is_string($host)) { $ipAddress = $host; } } //cluster nodes $clusterConfig = $this->api()->get('/cluster/config/nodes', array()); foreach ($clusterConfig as $config){ if ($config['node'] && $config['ring0_addr'] && $config['ring0_addr'] == $ipAddress || ( $hostname && $config['ring0_addr'] == $hostname)){ return new Node($config['node']); } } //All nodes to array $nodes = array(); $result = $this->api()->get("/nodes"); foreach ($result as $ret) { if ($this->online && $ret['status'] && $ret['status'] != 'online' ) { continue; } $nodes[] = $ret['node']; } $nodes = array_filter($nodes); //Check if only one node if(count($nodes) === 1) { return new Node($nodes[0]); } //Find by hostname if ($hostname && !filter_var($hostname, FILTER_VALIDATE_IP)) { $temp = explode(".", $hostname); $hostNode = current($temp); if ($hostNode) { foreach ($nodes as $node) { if (strtolower($hostNode) == strtolower($node)) { return new Node($node); } } } } //Find by Ip Address foreach ($nodes as $node) { $networks = $this->api()->get('/nodes/' . $node . '/network', array()); foreach ($networks as $n) { try { if (!$n['iface']) { continue; } $res = $this->api()->get('/nodes/' . $node . '/network/' . $n['iface'], array()); if(!$res['address']){ continue; } if ($res['address'] && preg_match('/\//', $res['address'])) { $res['address'] = preg_replace('/\/(.*)*/', '', $res['address']); } if ($res['address'] && $res['address'] == $ipAddress || ( $hostname && $res['address'] == $hostname)) return new Node($node); } catch (\Exception $ex) {//interface does not exist if(!preg_match('/interface does not exist/',$ex->getMessage())){ throw $ex; } } } } if (empty($ipAddress)) { throw new ProxmoxApiException('Server\'s IP Address is empty'); } throw new ProxmoxApiException('Node for IP Address "' . $ipAddress . '" not found'); } /** * * @param float $bytes * @return Node * @throws ProxmoxApiException */ public function findByDiskSize($bytes) { $nodes_arr = array(); $nodes = $this->api()->get('/nodes'); foreach ($nodes as $nodeValues) { if ($this->online && $nodeValues['status'] && $nodeValues['status'] != 'online' ) { continue; } $node = $nodeValues['node']; $nodeStatus = $this->api()->get("/nodes/{$node}/status"); $nodeStorages = $this->api()->get("/nodes/{$node}/storage"); $storages = array(); foreach ($nodeStorages as $ns) { $storages[] = array( "storage" => $ns['storage'], "avail" => $ns['avail'], "content" => $ns['content'] ); } if (empty($storages)) continue; $nodes_arr[] = array( 'node' => $node, "memory" => $nodeStatus['memory']['free'], //order by "memory":"free" "storages" => $storages// re-order by "avail ); } foreach ($nodes_arr as $nk => $row) { $memory[$nk] = $row['memory']; foreach ($row['storages'] as $sk => $storage) { $storages[$sk] = $storage['avail']; } $r = array_multisort($storages, SORT_DESC, $row['storages']); $nodes_arr[$nk]['storages'] = $row['storages']; } $r = array_multisort($memory, SORT_DESC, $nodes_arr); $storage = null; $backup_storage = null; foreach ($nodes_arr[0]["storages"] as $s) { if ($storage == null && ( strpos($s['content'], 'rootdir') !== false || strpos($s['content'], 'images') !== false )) $storage = $s['storage']; if ($backup_storage == null && strpos($s['content'], 'backup') !== false) $backup_storage = $s['storage']; } $selectedNode = array(); foreach ($nodes_arr as $n) { if ($n["storages"]["0"]["avail"] > $bytes) { return new Node($n['node']); break; } } throw new ProxmoxApiException(sprintf("Storage with free space \"%s\" bytes not found", $bytes)); } /** * * @return Node[] */ public function fetch() { $data = array(); $result = $this->api()->get("/nodes"); foreach ($result as $ret) { if ($this->online && $ret['status'] && $ret['status'] != 'online' ) { continue; } $data[] = new Node($ret['node']); } return $data; } public function findOnline($online) { $this->online = (boolean) $online; return $this; } }