%PDF- %PDF-
Direktori : /var/www/projetos/suporte.iigd.com.br.old/src/Inventory/Asset/ |
Current File : //var/www/projetos/suporte.iigd.com.br.old/src/Inventory/Asset/InventoryNetworkPort.php |
<?php /** * --------------------------------------------------------------------- * * GLPI - Gestionnaire Libre de Parc Informatique * * http://glpi-project.org * * @copyright 2015-2022 Teclib' and contributors. * @copyright 2003-2014 by the INDEPNET Development Team. * @copyright 2010-2022 by the FusionInventory Development Team. * @licence https://www.gnu.org/licenses/gpl-3.0.html * * --------------------------------------------------------------------- * * LICENSE * * This file is part of GLPI. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. * * --------------------------------------------------------------------- */ namespace Glpi\Inventory\Asset; use DBmysqlIterator; use Glpi\Inventory\Conf; use IPAddress; use IPNetwork; use Item_DeviceNetworkCard; use NetworkName; use NetworkPort; use NetworkPortAggregate; use QueryParam; use Toolbox; use Unmanaged; trait InventoryNetworkPort { protected $ports = []; protected $ipnetwork_stmt; protected $idevice_stmt; protected $networks = []; protected $itemtype; private $items_id; public function handle() { parent::handle(); $this->handlePorts(); } /** * Get network ports * * @return array */ public function getNetworkPorts(): array { return $this->ports; } /** * Add network ports * * @param $ports * * @return $this */ public function addNetworkPorts($ports): self { $this->ports += $ports; return $this; } private function isMainPartial(): bool { if ($this instanceof MainAsset) { return $this->isPartial(); } else { if (isset($this->main_asset) && method_exists($this->main_asset, 'isPartial')) { return $this->main_asset->isPartial(); } } return false; } /** * Manage network ports * * @param string $itemtype Item type, will take current item per default * @param integer $items_id Item ID, will take current item per default * * @return void */ public function handlePorts($itemtype = null, $items_id = null) { $this->itemtype = $itemtype ?? $this->item->getType(); $this->items_id = $items_id ?? $this->item->fields['id']; if (!$this->isMainPartial()) { $this->cleanUnmanageds(); } $this->handleIpNetworks(); $this->handleUpdates(); $this->handleCreates(); $this->handleDeletesManagementPorts(); if (method_exists($this, 'handleAggregations')) { $this->handleAggregations(); } $this->itemtype = null; $this->items_id = null; } /** * Handle devices that would no longer be unmanaged * * @return void */ private function cleanUnmanageds() { global $DB; $networkport = new NetworkPort(); $unmanaged = new Unmanaged(); $criteria = [ 'FROM' => NetworkPort::getTable(), 'WHERE' => [ 'itemtype' => 'Unmanaged', 'mac' => new QueryParam() ] ]; $it = new DBmysqlIterator(null); $it->buildQuery($criteria); $query = $it->getSql(); $stmt = $DB->prepare($query); foreach ($this->ports as $port) { if (!$this->isMainPartial() && property_exists($port, 'mac') && $port->mac != '') { $stmt->bind_param( 's', $port->mac ); $DB->executeStatement($stmt); $results = $stmt->get_result(); if ($results->num_rows > 0) { $row = $results->fetch_object(); $unmanageds_id = $row->items_id; $input = [ 'logical_number' => $port->logical_number, 'itemtype' => $this->itemtype, 'items_id' => $this->items_id, 'is_dynamic' => 1, 'name' => addslashes($port->name) ]; $networkport->update($input); $unmanaged->delete(['id' => $unmanageds_id], true); } } } } /** * Store IP networks and prepare ports to manage later * * @return void */ private function handleIpNetworks() { global $DB; $ipnetwork = new IPNetwork(); foreach ($this->ports as $port) { if ( !property_exists($port, 'gateway') || $port->gateway == '' || !property_exists($port, 'netmask') || $port->netmask == '' || !property_exists($port, 'subnet') || $port->subnet == '' ) { // Ignore ports with incomplete information continue; } if ($this->ipnetwork_stmt == null) { $criteria = [ 'COUNT' => 'cnt', 'FROM' => IPNetwork::getTable(), 'WHERE' => [ 'entities_id' => $this->entities_id, 'address' => new QueryParam(), 'netmask' => new QueryParam(), 'gateway' => new QueryParam(), ] ]; $it = new DBmysqlIterator(null); $it->buildQuery($criteria); $query = $it->getSql(); $stmt = $DB->prepare($query); $this->ipnetwork_stmt = $stmt; } $stmt = $this->ipnetwork_stmt; $stmt->bind_param( 'sss', $port->subnet, $port->netmask, $port->gateway ); $DB->executeStatement($stmt); $results = $stmt->get_result(); $row = $results->fetch_object(); $count = $row->cnt; if ($count == 0) { $input = [ 'name' => sprintf('%s/%s - %s', $port->subnet, $port->netmask, $port->gateway), 'network' => sprintf('%s/%s', $port->subnet, $port->netmask), 'gateway' => $port->gateway, 'entities_id' => $this->entities_id ]; $ipnetwork->add(Toolbox::addslashes_deep($input)); } } } /** * Add a network port into dtaabase * * @param \stdClass $port Port data * * @return integer */ private function addNetworkPort(\stdClass $port) { $networkport = new NetworkPort(); $input = (array)$port; foreach ($input as $key => $data) { if (is_array($data)) { unset($input[$key]); } } $input = Toolbox::addslashes_deep($input); $input = array_merge( $input, [ 'entities_id' => $this->entities_id, 'items_id' => $this->items_id, 'itemtype' => $this->itemtype, 'is_dynamic' => 1 ] ); if (!isset($input['trunk']) || empty($input['trunk'])) { $input['trunk'] = 0; } $netports_id = $networkport->add($input); return $netports_id; } /** * Add a network name into database * * @param integer $items_id Port id * @param string $name Network name * * @return integer */ protected function addNetworkName($items_id, $name = null) { $networkname = new NetworkName(); $input = [ 'entities_id' => $this->entities_id, 'is_dynamic' => 1, 'items_id' => $items_id, 'is_recursive' => 0, 'itemtype' => 'NetworkPort' ]; if ($name !== null) { $input['name'] = $name; } $netname_id = $networkname->add($input); return $netname_id; } /** * Add several ip addresses into database * * @param array $ips IP adresses to add * @param integer $items_id NetworkName id * * @return void */ private function addIPAddresses(array $ips, $items_id) { $ipaddress = new IPAddress(); foreach ($ips as $ip) { $input = [ 'items_id' => $items_id, 'itemtype' => 'NetworkName', 'name' => addslashes($ip), 'is_dynamic' => 1 ]; $ipaddress->add($input); } } /** * Hanlde network instantiation * * @return void */ private function handleUpdates() { global $DB; $db_ports = []; $networkport = new NetworkPort(); $iterator = $DB->request([ 'SELECT' => ['id', 'name', 'mac', 'instantiation_type', 'logical_number'], 'FROM' => 'glpi_networkports', 'WHERE' => [ 'items_id' => $this->items_id, 'itemtype' => $this->itemtype, 'is_dynamic' => 1 ] ]); foreach ($iterator as $row) { $id = $row['id']; unset($row['id']); if (is_null($row['mac'])) { $row['mac'] = ''; } if (preg_match("/[^a-zA-Z0-9 \-_\(\)]+/", $row['name'])) { $row['name'] = Toolbox::addslashes_deep($row['name']); } foreach (['name', 'mac', 'instantiation_type'] as $field) { if ($row[$field] !== null) { $row[$field] = strtolower($row[$field]); } } $db_ports[$id] = $row; } $netname_stmt = null; $ports = $this->ports; if (method_exists($this, 'getManagementPorts')) { $ports += $this->getManagementPorts(); } foreach ($ports as $key => $data) { foreach ($db_ports as $keydb => $datadb) { //keep trace of logical number from db $db_lnumber = $datadb['logical_number']; unset($datadb['logical_number']); $comp_data = []; foreach (['name', 'mac', 'instantiation_type'] as $field) { if (property_exists($data, $field)) { $comp_data[$field] = strtolower($data->$field); } else { $comp_data[$field] = ""; } } //check if port exists in database if ($comp_data != $datadb) { continue; } //check for logical number change if (property_exists($data, 'logical_number') && $data->logical_number != $db_lnumber) { $networkport->update( [ 'id' => $keydb, 'logical_number' => $data->logical_number ] ); } //handle instantiation type if (property_exists($data, 'instantiation_type')) { $type = $data->instantiation_type; //handle only ethernet and fiberchannel $this->handleInstantiation($type, $data, $keydb, true); } $ips = $data->ipaddress ?? []; if (count($ips)) { //handle network name if ($netname_stmt == null) { $criteria = [ 'SELECT' => 'id', 'FROM' => NetworkName::getTable(), 'WHERE' => [ 'itemtype' => 'NetworkPort', 'items_id' => new QueryParam() ] ]; $it = new DBmysqlIterator(null); $it->buildQuery($criteria); $query = $it->getSql(); $netname_stmt = $DB->prepare($query); } $netname_stmt->bind_param( 's', $keydb ); $DB->executeStatement($netname_stmt); $results = $netname_stmt->get_result(); if ($results->num_rows) { $row = $results->fetch_object(); $netname_id = $row->id; } else { $netname_id = $this->addNetworkName($keydb); } //Handle ipaddresses $db_addresses = []; $iterator = $DB->request([ 'SELECT' => ['id', 'name'], 'FROM' => 'glpi_ipaddresses', 'WHERE' => [ 'items_id' => $netname_id, 'itemtype' => 'NetworkName' ] ]); foreach ($iterator as $db_data) { $db_addresses[$db_data['id']] = $db_data['name']; } foreach ($ips as $ip_key => $ip_data) { foreach ($db_addresses as $db_ip_key => $db_ip_data) { if ($ip_data == $db_ip_data) { unset($ips[$ip_key]); unset($db_addresses[$db_ip_key]); //result found in db, useless to continue break 1; } } } if (!$this->isMainPartial() && count($db_addresses) && count($ips)) { $ipaddress = new IPAddress(); //deleted IP addresses foreach (array_keys($db_addresses) as $id_ipa) { $ipaddress->delete(['id' => $id_ipa], true); } } if (count($ips)) { $this->addIPAddresses($ips, $netname_id); } } unset($db_ports[$keydb]); unset($this->networks[$key]); unset($this->ports[$key]); if (method_exists($this, 'getManagementPorts') && method_exists($this, 'setManagementPorts')) { $managements = $this->getManagementPorts(); unset($managements[$key]); $this->setManagementPorts($managements); } $this->portUpdated($data, $keydb); } } //delete remaining network ports, if any if (!$this->isMainPartial() && count($db_ports)) { foreach ($db_ports as $netpid => $netpdata) { if ($netpdata['name'] != 'management') { //prevent removing internal management port $networkport->delete(['id' => $netpid], true); } } } } protected function portUpdated(\stdClass $port, int $netports_id) { //does nothing } /** * Handle network port instantiation * * @param string $type Instantiation class name * @param \stdClass $data Data * @param integer $ports_id NetworkPort id * @param boolean $load Whether to load db results * * @return void */ private function handleInstantiation($type, $data, $ports_id, $load) { global $DB; if (!in_array($type, ['NetworkPortEthernet', 'NetworkPortFiberchannel'])) { return; } $instance = new $type(); $input = []; if ($instance->getFromDB($ports_id)) { $input = $instance->fields; } $input['networkports_id'] = $ports_id; if (property_exists($data, 'speed')) { $input['speed'] = $data->speed; $input['speed_other_value'] = $data->speed; } if (property_exists($data, 'wwn')) { $input['wwn'] = $data->wwn; } if (property_exists($data, 'mac')) { if ($this->idevice_stmt == null) { $criteria = [ 'SELECT' => 'id', 'FROM' => Item_DeviceNetworkCard::getTable(), 'WHERE' => [ 'itemtype' => $this->itemtype, 'items_id' => $this->items_id, 'mac' => new QueryParam() ] ]; $it = new DBmysqlIterator(null); $it->buildQuery($criteria); $query = $it->getSql(); $this->idevice_stmt = $DB->prepare($query); } $stmt = $this->idevice_stmt; $stmt->bind_param( 's', $data->mac ); $DB->executeStatement($stmt); $results = $stmt->get_result(); if ($results->num_rows > 0) { $row = $results->fetch_object(); $input['items_devicenetworkcards_id'] = $row->id; } } //store instance if ($instance->isNewItem()) { $instance->add(Toolbox::addslashes_deep($input)); } else { $instance->update(Toolbox::addslashes_deep($input)); } } /** * Handle network ports, name and instantiation creation * * @return void */ private function handleCreates() { $ports = $this->ports; if (method_exists($this, 'getManagementPorts')) { $ports += $this->getManagementPorts(); } foreach ($ports as $port) { $netports_id = $this->addNetworkPort($port); if (count(($port->ipaddress ?? []))) { $netnames_id = $this->addNetworkName($netports_id, $port->netname ?? null); $this->addIPAddresses($port->ipaddress, $netnames_id); } if (property_exists($port, 'instantiation_type')) { $type = $port->instantiation_type; $this->handleInstantiation($type, $port, $netports_id, false); } $this->portCreated($port, $netports_id); } } /** * Delete Management Ports if needed * * @return void */ private function handleDeletesManagementPorts() { if (method_exists($this, 'getManagementPorts')) { if (empty($this->getManagementPorts())) { //remove all port management ports $networkport = new NetworkPort(); $networkport->deleteByCriteria([ "itemtype" => $this->itemtype, "items_id" => $this->items_id, "instantiation_type" => NetworkPortAggregate::getType(), "name" => "Management" ], 1); } } } protected function portCreated(\stdClass $port, int $netports_id) { //does nothing } public function checkConf(Conf $conf): bool { return $conf->component_networkcard == 1; } }