diff --git a/README.md b/README.md index 7aefed9..531fb6d 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,12 @@ -# PHP-CLI SHELL for PATCHMANAGER +PHP-CLI SHELL for PATCHMANAGER +------------------- This repository is the addon for PHP-CLI SHELL about PATCHMANAGER service. You have to use base PHP-CLI SHELL project that is here: https://github.com/cloudwatt/php-cli-shell_base -# REQUIREMENTS +REQUIREMENTS +------------------- #### PATCHMANAGER * Import profiles which are in addons/dcim/ressources @@ -16,7 +18,8 @@ __*/!\ Do not rename custom profiles*__ __*/!\ Version 2.0 add new profiles!*__ -# INSTALLATION +INSTALLATION +------------------- #### APT PHP Ubuntu only, you can get last PHP version from this PPA: @@ -35,11 +38,33 @@ pcre.jit=0 ``` *To locate your php.ini, use this command: php -i | grep "Configuration File"* + +## USE PHAR + +Download last PHAR release and its key from [releases](https://github.com/cloudwatt/php-cli-shell_patchmanager/releases) + +![wizard](documentation/readme/wizard.gif) + +Wizard help: +`$ php php-cli-shell.phar --help` + +Create firewall configuration with command: +`$ php php-cli-shell.phar configuration:application:factory dcim` +*For more informations about configuration file, see 'CONFIGURATION FILE' section* + +Create firewall launcher with command: +`$ php php-cli-shell.phar launcher:application:factory dcim` + +__*The PHAR contains all PHP-CLI SHELL components (Base, DCIM, IPAM and Firewall)*__ + + +## USE SOURCE + #### REPOSITORIES * git clone https://github.com/cloudwatt/php-cli-shell_base -* git checkout tags/v2.1.1 +* git checkout tags/v2.1.2 * git clone https://github.com/cloudwatt/php-cli-shell_patchmanager -* git checkout tags/v2.1.1 +* git checkout tags/v2.1.2 * Merge these two repositories #### CONFIGURATION FILE @@ -64,6 +89,10 @@ pcre.jit=0 * vim patchmanager.php * Change [DCIM_SERVER_KEY] with the key of your PatchManager server in configuration file + +EXECUTION +------------------- + #### CREDENTIALS FILE /!\ For security reason, you can use a read only account! __*Change informations which are between []*__ @@ -71,10 +100,7 @@ __*Change informations which are between []*__ * read -sr USER_PASSWORD_INPUT * export DCIM_[DCIM_SERVER_KEY]_LOGIN=[YourLoginHere] * export DCIM_[DCIM_SERVER_KEY]_PASSWORD=$USER_PASSWORD_INPUT - __Change [DCIM_SERVER_KEY] with the key of your PatchManager server in configuration file__ - - -# EXECUTION + __Change [DCIM_SERVER_KEY] with the key of your PatchManager server in configuration file__ #### SHELL Launch PHP-CLI Shell for PatchManager service diff --git a/addons/dcim/api/equipment.php b/addons/dcim/api/equipment.php index e2fcd11..50ed33a 100644 --- a/addons/dcim/api/equipment.php +++ b/addons/dcim/api/equipment.php @@ -385,13 +385,16 @@ public function getSlotIds($slotLabel = null) */ public function getModuleId($slotId) { - if($this->equipmentExists() && C\Tools::is('int&&>0', $slotId)) { + if($this->equipmentExists() && C\Tools::is('int&&>0', $slotId)) + { $result = $this->_adapter->getEquipmentIdBySlotId($slotId); - return ($this->_adapter->isValidReturn($result)) ? ((int) $result) : (false); - } - else { - return false; + + if($this->_adapter->isValidReturn($result)) { + return (int) $result; + } } + + return false; } /** diff --git a/addons/dcim/api/equipment/abstract.php b/addons/dcim/api/equipment/abstract.php index b95dd67..c60dd62 100644 --- a/addons/dcim/api/equipment/abstract.php +++ b/addons/dcim/api/equipment/abstract.php @@ -36,4 +36,33 @@ protected function _getObject() { return false; } + + /** + * Return the parent equipment ID this is on + * + * @return false|int + */ + abstract public function getParentEquipmentId(); + + /** + * Return the first top module equipment ID this is on + * + * @return false|int + */ + public function getModuleEquipmentId() + { + $parentEquipmentId = $this->getParentEquipmentId(); + return ($parentEquipmentId !== false) ? ($this->_getModuleEquipmentId($parentEquipmentId)) : (false); + } + + /** + * Return the first top module equipment ID this is on + * + * @return int + */ + protected function _getModuleEquipmentId($equipmentId, $moduleId = false) + { + $parentEquipId = $this->_adapter->getParentEquipmentIdByEquipmentId($equipmentId); + return ($this->_adapter->isValidReturn($parentEquipId)) ? ($this->_getModuleEquipmentId($parentEquipId, $equipmentId)) : ($moduleId); + } } \ No newline at end of file diff --git a/addons/dcim/api/equipment/port.php b/addons/dcim/api/equipment/port.php index c38fce5..8393f97 100644 --- a/addons/dcim/api/equipment/port.php +++ b/addons/dcim/api/equipment/port.php @@ -139,10 +139,7 @@ public function getEndConnectedPortId() */ public function getParentEquipmentId() { - if(!$this->hasPortId() || !$this->portExists()) { - return false; - } - else + if($this->portExists()) { $result = $this->_adapter->getParentEquipmentIdByPortId($this->getPortId()); @@ -154,23 +151,6 @@ public function getParentEquipmentId() return false; } - /** - * Return the first top module equipment ID this port is on - * - * @return false|int - */ - public function getModuleEquipmentId() - { - $parentEquipmentId = $this->getParentEquipmentId(); - return ($parentEquipmentId !== false) ? ($this->_getModuleEquipmentId($parentEquipmentId)) : (false); - } - - protected function _getModuleEquipmentId($equipmentId, $moduleId = false) - { - $parentEquipId = $this->_adapter->getParentEquipmentIdByEquipmentId($equipmentId); - return ($this->_adapter->isValidReturn($parentEquipId)) ? ($this->_getModuleEquipmentId($parentEquipId, $equipmentId)) : ($moduleId); - } - /** * Return the top equipment ID this port is on * diff --git a/addons/dcim/api/equipment/slot.php b/addons/dcim/api/equipment/slot.php index 6c3c6c0..7c6bfa5 100644 --- a/addons/dcim/api/equipment/slot.php +++ b/addons/dcim/api/equipment/slot.php @@ -48,21 +48,27 @@ public function isEmpty() return ($this->getChildEquipmentId() === false); } - public function getChildEquipmentId() + /** + * Return the parent equipment ID this slot is on + * + * @return false|int + */ + public function getParentEquipmentId() { - if(!$this->hasSlotId() || !$this->slotExists()) { - return false; - } - elseif($this->_childEquipmentId === null) { - $result = $this->_adapter->getEquipmentIdBySlotId($this->getSlotId()); - $this->_childEquipmentId = ($this->_adapter->isValidReturn($result)) ? ((int) $result) : (false); + if($this->slotExists()) + { + $result = $this->_adapter->getParentEquipmentIdBySlotId($this->getSlotId()); + + if($this->_adapter->isValidReturn($result)) { + return (int) $result; + } } - return $this->_childEquipmentId; + return false; } /** - * Return the top equipment ID this port is on + * Return the top equipment ID this slot is on * * @return false|int */ @@ -125,6 +131,24 @@ public function getEquipmentApi() return $this->_equipmentApi; } + /** + * Return the child equipment ID this slot is on + * + * @return false|int + */ + public function getChildEquipmentId() + { + if(!$this->hasSlotId() || !$this->slotExists()) { + return false; + } + elseif($this->_childEquipmentId === null) { + $result = $this->_adapter->getEquipmentIdBySlotId($this->getSlotId()); + $this->_childEquipmentId = ($this->_adapter->isValidReturn($result)) ? ((int) $result) : (false); + } + + return $this->_childEquipmentId; + } + /** * @param bool $resetObjectId * @return void diff --git a/addons/dcim/connector/soap.php b/addons/dcim/connector/soap.php index 9b6a12e..414b94e 100644 --- a/addons/dcim/connector/soap.php +++ b/addons/dcim/connector/soap.php @@ -98,6 +98,31 @@ public function __construct(Service $service, C\Config $config, $server, $login, protected function _initSoapAPI($key, $server, $urn, $httpProxy, $httpsProxy) { $this->_soapAPI->{$key} = new C\Soap($server.'/'.$urn, 'DCIM_'.$key, $this->_debug); + + switch(substr($server, 0, 6)) + { + case 'http:/': + if(C\Tools::is('string&&!empty', $httpProxy)) { + $useHttpProxy = $httpProxy; + } + break; + case 'https:': + if(C\Tools::is('string&&!empty', $httpsProxy)) { + $useHttpProxy = $httpsProxy; + } + break; + default: + throw new Exception("L'adresse du serveur DCIM doit commencer par http ou https", E_USER_ERROR); + } + + if(isset($useHttpProxy) && preg_match('#^(http(?:s)?:\/\/[^:]*)(?::([0-9]*))?$#i', $useHttpProxy, $matches)) + { + $this->_soapAPI->{$key}->setOpt('proxy_host', $matches[1]); + + if(isset($matches[2])) { + $this->_soapAPI->{$key}->setOpt('proxy_port', $matches[2]); + } + } } public function getServerId() @@ -242,7 +267,7 @@ public function getCabinetIdsByLocationId($locationId) $cabinetIds = array(); $cabinetLabels = $this->getCabinetLabelsByLocationId($locationId); - foreach($cabinetLabels as $index => $cabinetLabel) + foreach($cabinetLabels as $cabinetLabel) { if($this->isValidReturn($cabinetLabel)) { @@ -269,6 +294,11 @@ public function getCabinetLabelsByLocationId($locationId) return $this->_castToString($cabinetLabels); } + /** + * @param int $locationId + * @param string $cabinetLabel + * @return int|string Cabinet ID or string if an error occurs + */ public function getCabinetIdByLocationIdCabinetLabel($locationId, $cabinetLabel) { $args = $this->getArgs(array($cabinetLabel, $locationId)); @@ -765,23 +795,35 @@ public function getReportResults($reportName, array $wildCards = null) $results = $this->_soapAPI->search->reportToClient($args); // [ERROR] [ERROR] Incorrect format of the Wild Cards. - if($this->isValidReturn($results)) { + if($this->isValidReturn($results)) + { $bytes = explode(';', $results->return); //$csv = implode(array_map("chr", $bytes)); $csv = pack('C*', ...$bytes); $csv = str_replace("\n\000", '', $csv); $csv = explode("\n", $csv); + array_walk($csv, function(&$line, $key) { $line = str_getcsv($line, $this->_reportCsvDelimiter); }); + $keys = array_shift($csv); + array_walk($keys, function(&$key) { $key = mb_strtolower($key); $key = str_replace(' ', '_', $key); }); - array_walk($csv, function(&$value, $key, $keys) { - $value = array_combine($keys, $value); + + array_walk($csv, function(&$value, $key, $keys) + { + if(count($keys) === count($value)) { + $value = array_combine($keys, $value); + } + else { + throw new Exception("DCIM report result is not valid, head field number (".count($keys).") do not match value field number (".count($value).")", E_USER_ERROR); + } }, $keys); + return $csv; } diff --git a/addons/dcim/equipment.php b/addons/dcim/equipment.php index 5783e2a..6876caf 100644 --- a/addons/dcim/equipment.php +++ b/addons/dcim/equipment.php @@ -3,14 +3,10 @@ use Core as C; - abstract class Equipment implements \ArrayAccess, \IteratorAggregate, \Countable + abstract class Equipment { - protected static $_environments; - - /** - * @var Addon\Dcim\Api_Equipment - */ - protected $_equipmentApi = null; + const PORT_INTERFACE_SEPARATOR = Equipment_Port::INTERFACE_SEPARATOR; + const INT_INTERFACE_SEPARATOR = Equipment_Interface::INTERFACE_SEPARATOR; /** * @var int @@ -18,37 +14,37 @@ abstract class Equipment implements \ArrayAccess, \IteratorAggregate, \Countable protected $_equipmentId = null; /** - * @var Addon\Dcim\Equipment_Slot[] + * @var Addon\Dcim\Api_Equipment */ - protected $_slots = array(); + protected $_equipmentApi = null; /** - * @var Addon\Dcim\Equipment_Port[] + * @var Addon\Dcim\Equipment_Module[] */ - protected $_ports = array(); + protected $_modules = array(); /** * @var Addon\Dcim\Equipment_Interface[] */ - protected $_ints = array(); + protected $_interfaces = array(); /** * Slot datas * @var array */ - protected $_slotsDatas = null; + protected $_dataSlots = null; /** * Port datas * @var array */ - protected $_portsDatas = null; + protected $_dataPorts = null; /** * Interface datas * @var array */ - protected $_intsDatas = null; + protected $_dataInterfaces = null; /** * Datas @@ -56,104 +52,411 @@ abstract class Equipment implements \ArrayAccess, \IteratorAggregate, \Countable */ protected $_datas = array(); + /** + * @var int + */ + protected $_debug = 3; // 0 = disable, 1 = info, 2 = info+, 3 = info++ + + + public function __construct($equipmentId, Api_Equipment $apiEquipment = null) + { + $this->_equipmentId = (int) $equipmentId; // Test equipmentId or cast to INT + + if($apiEquipment !== null && $apiEquipment->id === $this->_equipmentId) { + $this->_equipmentApi = $apiEquipment; + } + else { + $this->_equipmentApi = new Api_Equipment($this->_equipmentId); + } + + $this->_init(); + } + + protected function _init() + { + } - public function __construct($equipmentId) + public function getEquipmentId() { - $this->_equipmentId = (int) $equipmentId; - $this->_equipmentApi = new Api_Equipment($this->_equipmentId); // /!\ Ne pas passer null + return $this->_equipmentId; } - public static function getInstance($equipmentId) + public function getEquipmentApi() + { + return $this->_equipmentApi; + } + + /** + * @param mixed $attribute + * @return int Module ID + */ + protected function _retrieveModuleId($attribute) { - $Api_Equipment = new Api_Equipment($equipmentId); - $hostName = self::_getHostName($Api_Equipment); - return (static::isEquipment($hostName)) ? (new static($equipmentId)) : (false); + if($attribute instanceof Equipment_Slot) { + $moduleId = $attribute->getModuleId(); + } + elseif($attribute instanceof Equipment_Port) { + $moduleId = $attribute->getModuleId(); + } + elseif($attribute instanceof Equipment_Interface) + { + if($attribute->isPhysical()) { + $Equipment_Port = $attribute->retrievePort(); + $moduleId = $Equipment_Port->getModuleId(); + } + else { + throw new Exception("It is not possible to retrieve module from virtual interface '".$attribute->interfaceName."'", E_USER_ERROR); + } + } + elseif($attribute instanceof Equipment_Module) { + $moduleId = $attribute->getModuleId(); + } + elseif(C\Tools::is('int&&>0', $attribute)) { + $moduleId = (int) $attribute; + } + elseif($attribute === null) { + $moduleId = false; + } + else { + throw new Exception("Can not retrieve module, attribute '".gettype($attribute)."' is not compatible", E_USER_ERROR); + } + + return ($moduleId !== false) ? ($moduleId) : ($this->equipmentId); } - public function declareSlot(Equipment_Slot $Equipment_Slot) + /** + * @param mixed $attribute + * @return Addon\Dcim\Equipment_Module + */ + protected function _retrieveModule($attribute) { - $slotKey = $Equipment_Slot->getSlotKey(); + $moduleId = $this->_retrieveModuleId($attribute); - if(array_key_exists($slotKey, $this->_slots)) { - throw new Exception("Ce slot est déjà déclaré @ ".$slotKey, E_USER_ERROR); + if(!array_key_exists($moduleId, $this->_modules)) { + $this->_modules[$moduleId] = new Equipment_Module($this, $moduleId); } - $this->_slots[$slotKey] = $Equipment_Slot; + return $this->_modules[$moduleId]; + } + + /** + * @param string|Addon\Dcim\Equipment_Slot $name Slot object or key + * @return bool + */ + public function slotExists($name) + { + return ($this->retrieveSlot($name) !== false); + } + + /** + * @param Addon\Dcim\Equipment_Slot $slot + * @return $this + */ + public function declareSlot(Equipment_Slot $slot) + { + $Equipment_Module = $this->_retrieveModule($slot); + $Equipment_Module->declareSlot($slot); + $this->_slotCleaner(); return $this; } - abstract public function declarePort(Equipment_Port $Equipment_Port); + /** + * @param string|Addon\Dcim\Equipment_Slot $name Slot object or key + * @return false|Addon\Dcim\Equipment_Slot + */ + public function retrieveSlot($name) + { + if(is_object($name)) + { + if($name instanceof Equipment_Slot) { + $Equipment_Module = $this->_retrieveModule($name); + return $Equipment_Module->retrieveSlot($name); + } + else { + throw new Exception("Slot name must be a string or an Equipment_Slot object, '".gettype($name)."' given", E_USER_ERROR); + } + } + else + { + foreach($this->_modules as $Equipment_Module) + { + $result = $Equipment_Module->retrieveSlot($name); + + if($result !== false) { + return $result; + } + } + } - public function undeclarePort(Equipment_Port $Equipment_Port) + return false; + } + + /** + * @return Addon\Dcim\Equipment_Slot[] Slot objects + */ + public function getSlots() { - $portKey = $Equipment_Port->getPortKey(); - unset($this->{$portKey}); + $slots = array(); - $this->_datas = array(); - $this->_portsDatas = null; - $this->_intsDatas = null; + foreach($this->_modules as $Equipment_Module) { + $results = $Equipment_Module->getSlots(); + $results = array_values($results); + $slots = array_merge($slots, $results); + } + return $slots; + } + + /** + * @param Addon\Dcim\Equipment_Slot $slot + * @return $this + */ + public function undeclareSlot(Equipment_Slot $slot) + { + $Equipment_Module = $this->_retrieveModule($slot); + $Equipment_Module->undeclareSlot($slot); + $this->_slotCleaner(); return $this; } - public function declareInterface(Equipment_Interface $Equipment_Interface) + /** + * @param string|Addon\Dcim\Equipment_Port $name Port object or key + * @return bool + */ + public function portExists($name) { - $intKey = $Equipment_Interface->getIntKey(); - $intIndex = $Equipment_Interface->getIntIndex(); + return ($this->retrievePort($name) !== false); + } - if($intIndex !== false) { $intKey .= '__'.$intIndex; } + /** + * @param Addon\Dcim\Equipment_Port $port + * @return $this + */ + public function declarePort(Equipment_Port $port) + { + /** + * Un port est une interface physique! + * + * Un port est obligatoirement lié à une interface virtuelle car + * il permet d'interconnecter directement deux équipements + * + * Par conséquent, un port est l'interface entre deux équipements + */ + $this->_newInterface($port); + + $Equipment_Module = $this->_retrieveModule($port); + $Equipment_Module->declarePort($port); + $this->_portCleaner(); + return $this; + } + + /** + * @param string|Addon\Dcim\Equipment_Port $name Port object or key + * @return false|Addon\Dcim\Equipment_Port + */ + public function retrievePort($name) + { + if(is_object($name)) + { + if($name instanceof Equipment_Port) { + $Equipment_Module = $this->_retrieveModule($name); + return $Equipment_Module->retrievePort($name); + } + else { + throw new Exception("Port name must be a string or an Equipment_Port object, '".gettype($name)."' given", E_USER_ERROR); + } + } + else + { + foreach($this->_modules as $Equipment_Module) + { + $result = $Equipment_Module->retrievePort($name); - if(array_key_exists($intKey, $this->_ints)) { - throw new Exception("Cette interface est déjà déclarée @ ".$intKey, E_USER_ERROR); + if($result !== false) { + return $result; + } + } } - $this->_ints[$intKey] = $Equipment_Interface; - return $this; + return false; } - public function getSlot($slotKey) + /** + * @return Addon\Dcim\Equipment_Port[] Port objects + */ + public function getPorts() { - return (array_key_exists($slotKey, $this->_slots)) ? ($this->_slots[$slotKey]) : (false); + $ports = array(); + + foreach($this->_modules as $Equipment_Module) { + $results = $Equipment_Module->getPorts(); + $results = array_values($results); + $ports = array_merge($ports, $results); + } + + return $ports; } - public function getPort($portKey) + /** + * @param Addon\Dcim\Equipment_Port $port + * @return $this + */ + public function undeclarePort(Equipment_Port $port) { - return (array_key_exists($portKey, $this->_ports)) ? ($this->_ports[$portKey]) : (false); + $Equipment_Module = $this->_retrieveModule($port); + $Equipment_Module->undeclarePort($port); + $this->_portCleaner(); + return $this; } - // /!\ On peut demander une interface physique comme virtuelle - public function getInterface($intKey, $intIndex = false) + /** + * @param Addon\Dcim\Equipment_Port $equipmentPort + * @return void + */ + protected function _newInterface(Equipment_Port $equipmentPort) + { + $Equipment_Interface = new Equipment_Interface($equipmentPort); + $equipmentPort->setInterface($Equipment_Interface); + $this->declareInterface($Equipment_Interface); + } + + /** + * @param string|Addon\Dcim\Equipment_Interface $name Interface object or ID + * @param null|int $index Interface index + * @return bool + */ + public function interfaceExists($name, $index = null) { - // /!\ On doit traiter les 2 cas - $intKey = str_replace(Equipment_Interface_Physical::INT_SEPARATOR, '__', $intKey, $countPort); - $intKey = str_replace(Equipment_Interface_Virtual::INT_SEPARATOR, '__', $intKey, $countInt); + return ($this->retrieveInterface($name, $index) !== false); + } - if($countPort === 0 && $countInt === 0 && $intIndex !== false) { - $intKey .= '__'.$intIndex; + /** + * @param Addon\Dcim\Equipment_Interface $interface + * @return $this + */ + public function declareInterface(Equipment_Interface $interface) + { + if($interface->isPhysical()) + { + $Equipment_Module = $this->_retrieveModule($interface); + $Equipment_Module->declareInterface($interface); + + /** + * On peut rajouter des interfaces virtuelles sans avoir à nettoyer + * car certaines interfaces virtuelles peuvent dépendre des interfaces physiques + */ + $this->_interfaceCleaner(); } + else + { + $interfaceId = $interface->getInterfaceId(); - return (array_key_exists($intKey, $this->_ints)) ? ($this->_ints[$intKey]) : (false); + if(array_key_exists($interfaceId, $this->_interfaces)) { + throw new Exception("L'interface '".$interface->getInterfaceName()."' est déjà déclarée sous l'ID '".$interfaceId."'", E_USER_ERROR); + } + + $this->_interfaces[$interfaceId] = $interface; + } + + return $this; } - /*public function getPortKeys() + /** + * @param string|Addon\Dcim\Equipment_Interface $name Interface object or ID + * @param null|int $index Interface index + * @return false|Addon\Dcim\Equipment_Interface + */ + public function retrieveInterface($name, $index = null) { - return array_keys($this->ports); + if(is_object($name)) + { + if($name instanceof Equipment_Interface) + { + if($name->isPhysical()) { + $Equipment_Module = $this->_retrieveModule($name); + return $Equipment_Module->retrieveInterface($name); + } + else { + $name = $name->getInterfaceId(); + } + } + else { + throw new Exception("Interface name must be a string or an Equipment_Interface object, '".gettype($name)."' given", E_USER_ERROR); + } + } + else + { + foreach($this->_modules as $Equipment_Module) + { + $result = $Equipment_Module->retrieveInterface($name, $index); + + if($result !== false) { + return $result; + } + } + + if($index !== null) { + $name .= static::INT_INTERFACE_SEPARATOR.$index; + } + } + + return (array_key_exists($name, $this->_interfaces)) ? ($this->_interfaces[$name]) : (false); } - public function getIntKeys() + /** + * @return Addon\Dcim\Equipment_Interface[] + */ + public function getInterfaces() { - return array_keys($this->ints); - }*/ + $interfaces = array(); - public function getEquipmentId() + foreach($this->_modules as $Equipment_Module) { + $results = $Equipment_Module->getInterfaces(); + $results = array_values($results); + $interfaces = array_merge($interfaces, $results); + } + + // Ajouter à la fin les interfaces virtuelles + $thisInterfaces = array_values($this->_interfaces); + $interfaces = array_merge($interfaces, $thisInterfaces); + + return $interfaces; + } + + /** + * @param Addon\Dcim\Equipment_Interface $interface + * @return $this + */ + public function undeclareInterface(Equipment_Interface $interface) { - return $this->_equipmentId; + if($interface->isPhysical()) + { + $Equipment_Module = $this->_retrieveModule($interface); + $Equipment_Module->undeclareInterface($interface); + + /** + * On peut retirer des interfaces virtuelles sans avoir à nettoyer + * car certaines interfaces virtuelles peuvent dépendre + * des interfaces physiques mais pas l'inverse + */ + $this->_interfaceCleaner(); + } + else + { + $interface = $this->retrieveInterface($interface); + + if($interface !== false) { + unset($this->_interfaces[$interface->getInterfaceId()]); + } + } + + return $this; } public function getHostName() { if(!array_key_exists('hostName', $this->_datas)) { - $this->_datas['hostName'] = self::_getHostName($this->_equipmentApi); + $this->_datas['hostName'] = self::_formatEquipmentLabel($this->_equipmentApi); } return $this->_datas['hostName']; @@ -161,57 +464,81 @@ public function getHostName() protected function _getSlots() { - if($this->_slotsDatas === null) + if($this->_dataSlots === null) { - $this->_slotsDatas = array(); // /!\ Important + $this->_dataSlots = array(); // /!\ Important + /** + * /!\ Si deux slots possèdent le même nom + * alors les données de tous ces slots seront mergées + * + * @todo a corriger, trouver une solution + * Si doublon alors créer section modules puis + * ajouter les datas par module (name) dans cette section + */ foreach($this->slots as $slot) { - C\Tools::merge($this->_slotsDatas, $slot->getDatas()); + C\Tools::merge($this->_dataSlots, $slot->getDatas()); } } - return $this->_slotsDatas; + return $this->_dataSlots; } - + protected function _getPorts() { - if($this->_portsDatas === null) + if($this->_dataPorts === null) { - $this->_portsDatas = array(); // /!\ Important + $this->_dataPorts = array(); // /!\ Important + /** + * /!\ Si deux ports possèdent le même nom + * alors les données de tous ces ports seront mergées + * + * @todo a corriger, trouver une solution + * Si doublon alors créer section modules puis + * ajouter les datas par module (name) dans cette section + */ foreach($this->ports as $port) { $datas = $port->getDatas(); $nbDatas = $port->getNeighborDatas(); $allDatas = array_merge_recursive($datas, $nbDatas); - C\Tools::merge($this->_portsDatas, $allDatas); + C\Tools::merge($this->_dataPorts, $allDatas); } } - return $this->_portsDatas; + return $this->_dataPorts; } /** * Retourne les interfaces suivantes: * Port, LA, L3 - **/ - protected function _getInts() + */ + protected function _getInterfaces() { - if($this->_intsDatas === null) + if($this->_dataInterfaces === null) { - $this->_intsDatas = array(); // /!\ Important + $this->_dataInterfaces = array(); // /!\ Important - foreach($this->ints as $int) { - $datas = $int->getDatas(); - $nbDatas = $int->getNeighborDatas(); + /** + * /!\ Si deux interfaces possèdent le même nom + * alors les données de toutes ces interfaces seront mergées + * + * @todo a corriger, trouver une solution + * Si doublon alors créer section modules puis + * ajouter les datas par module (name) dans cette section + */ + foreach($this->interfaces as $interface) { + $datas = $interface->getDatas(); + $nbDatas = $interface->getNeighborDatas(); $allDatas = array_merge_recursive($datas, $nbDatas); - C\Tools::merge($this->_intsDatas, $allDatas); + C\Tools::merge($this->_dataInterfaces, $allDatas); } } - return $this->_intsDatas; + return $this->_dataInterfaces; } - public function getInterfaces() + public function getConfiguration() { if(!array_key_exists('interfaces', $this->_datas)) { @@ -219,11 +546,6 @@ public function getInterfaces() $slotDatas = $this->_getSlots(); $portDatas = $this->_getPorts(); - $intDatas = $this->_getInts(); - -/*echo "\r\nDEBUG 0\r\n\t";var_dump($slotDatas); -echo "\r\n\t";var_dump($portDatas); -echo "\r\n\t";var_dump($intDatas);echo "\r\nEND 0\r\n";*/ $slotKeys = array_keys($slotDatas); $portKeys = array_keys($portDatas); @@ -234,8 +556,8 @@ public function getInterfaces() */ foreach($dualSlotPort as $key) { - $slotIsEmpty = $this->getSlot($key)->isEmpty(); - $portIsConnected = $this->getPort($key)->isConnected(); + $slotIsEmpty = $this->retrieveSlot($key)->isEmpty(); + $portIsConnected = $this->retrievePort($key)->isConnected(); if($slotIsEmpty && !$portIsConnected) { unset($portDatas[$key]); @@ -247,11 +569,12 @@ public function getInterfaces() unset($slotDatas[$key]); } else { - throw new Exception("Un dual port slot ne peut avoir qu'un connecteur actif à la fois", E_USER_ERROR); + throw new Exception("Un dual slot/port ne peut avoir qu'un connecteur actif à la fois", E_USER_ERROR); } } $this->_datas['interfaces'] = $slotDatas; + $interfaceDatas = $this->_getInterfaces(); /** * /!\ Les datas de interface sont prioritaires sur celles de port @@ -262,232 +585,142 @@ public function getInterfaces() * * /!\ On garde les clés des interfaces donc attention au séparateur */ - foreach($intDatas as $key => &$datas) + foreach($interfaceDatas as $interfaceId => &$datas) { - $key = str_replace(Equipment_Interface_Virtual::INT_SEPARATOR, Equipment_Interface_Physical::INT_SEPARATOR, $key); + $Equipment_Interface = $this->retrieveInterface($interfaceId); + $portKey = $Equipment_Interface->getPortKey(); - if(array_key_exists($key, $portDatas)) { - $datas = array_merge($portDatas[$key], $datas); + if(array_key_exists($portKey, $portDatas)) { + $datas = array_merge($portDatas[$portKey], $datas); } } unset($datas); - C\Tools::merge($this->_datas['interfaces'], $intDatas); + /** + * Les slots n'ont pas d'interfaces donc une interface + * ne peut pas écraser les données provenant d'un slot + */ + C\Tools::merge($this->_datas['interfaces'], $interfaceDatas); } + /** + * /!\ Du moins prioritaire au plus + * + * 1. Slot datas + + * 2. Port datas ++ + * 3. Interface datas +++ + */ return $this->_datas['interfaces']; } public function getDatas() { - $this->getHostname(); - $this->getInterfaces(); + $this->getHostName(); + $this->getConfiguration(); return $this->_datas; } - public function offsetSet($offset, $value) + public function printDebugDatas() { - if($value instanceof Equipment_Port) { - $this->declarePort($value); - } + $slotDatas = $this->_getSlots(); + $portDatas = $this->_getPorts(); + $interfaceDatas = $this->_getInterfaces(); + + $header = "-------------------- ".$this->equipmentApi->label." --------------------"; + C\Tools::e(PHP_EOL.$header, 'orange'); + C\Tools::e(PHP_EOL."\tSlot datas:", 'orange'); + C\Tools::e(PHP_EOL.print_r($slotDatas, true).PHP_EOL, 'orange'); + C\Tools::e(PHP_EOL."\tPort datas:", 'orange'); + C\Tools::e(PHP_EOL.print_r($portDatas, true).PHP_EOL, 'orange'); + C\Tools::e(PHP_EOL."\tInterface datas:", 'orange'); + C\Tools::e(PHP_EOL.print_r($interfaceDatas, true).PHP_EOL, 'orange'); + C\Tools::e(PHP_EOL.str_repeat('-', mb_strlen($header)), 'orange'); } - public function offsetExists($offset) + public function reset() { - return $this->issetPort($offset); + $this->_modules = array(); + $this->_interfaces = array(); + $this->resetDatas(); + return $this; } - public function offsetUnset($offset) + public function resetDatas() { - $this->unsetPort($offset); + $this->_datas = array(); + $this->_dataSlots = null; + $this->_dataPorts = null; + $this->_dataInterfaces = null; + return $this; } - public function offsetGet($offset) + protected function _slotCleaner() { - return ($this->issetPort($offset)) ? ($this->_ports[$offset]) : (null); + $this->_dataSlots = null; + $this->_portCleaner(); } - public function getIterator() + protected function _portCleaner() { - return new \ArrayIterator($this->_ports); + $this->_dataPorts = null; + $this->_interfaceCleaner(); } - public function count() + protected function _interfaceCleaner() { - return count($this->_ports); + $this->_dataInterfaces = null; + $this->_datas = array(); } public function __get($name) { switch($name) { + case 'id': + case 'equipmentId': + return $this->getEquipmentId(); + case 'api': + case 'equipmentApi': + return $this->getEquipmentApi(); + case 'name': + case 'equipmentName': + return $this->getHostName(); case 'slots': - return $this->_slots; + return $this->getSlots(); case 'ports': - return $this->_ports; - case 'ints': - return $this->_ints; + return $this->getPorts(); + case 'interfaces': + return $this->getInterfaces(); default: - return $this->getPort($name); - } - } - - public function __set($name, $value) - { - if((is_object($value)) && $value instanceof Equipment_Port) { - $this->declarePort($value); - } - } - - public function __isset($name) - { - return $this->issetPort($name); - } - - public function __unset($name) - { - $this->unsetPort($name); - } - - public function issetSlot($name) - { - if(is_object($name)) - { - if($name instanceof Equipment_Slot) { - $name = $name->getSlotKey(); - } - else { - throw new Exception("Slot name must be a string or an Equipment_Slot object", E_USER_ERROR); - } - } - - return (array_key_exists($name, $this->_slots)); - } - - public function issetPort($name) - { - if(is_object($name)) - { - if($name instanceof Equipment_Port) { - $name = $name->getPortKey(); - } - else { - throw new Exception("Port name must be a string or an Equipment_Port object", E_USER_ERROR); - } + throw new Exception("This attribute '".$name."' does not exist", E_USER_ERROR); } - - return (array_key_exists($name, $this->_ports)); } - public function issetInt($name) + protected static function _formatEquipmentLabel(Api_Equipment $Api_Equipment) { - return $this->issetInterface($name); - } + $equipmentLabel = $Api_Equipment->getEquipmentLabel(); - public function issetInterface($name) - { - if(is_object($name)) - { - if($name instanceof Equipment_Interface) { - $name = $name->getIntKey(); - } - else { - throw new Exception("Interface name must be a string or an Equipment_Interface object", E_USER_ERROR); - } + if($equipmentLabel === false) { + $equipmentId = $Api_Equipment->getEquipmentId(); + throw new Exception("Impossible de résoudre le label pour l'équipement ID '".$equipmentId."'", E_USER_ERROR); } - return (array_key_exists($name, $this->_ints)); + return current(explode('.', $equipmentLabel, 2)); } - // @todo a utiliser ou a supprimer - /*public function isset($object) + public function debug($debug) { - $ReflectionClass = new \ReflectionClass($object); - $ReflectionClass = $ReflectionClass->getParentClass(); - - switch($ReflectionClass->getShortName()) - { - case 'Equipment_Slot': - return $this->issetSlot($object); - case 'Equipment_Port': - return $this->issetPort($object); - case 'Equipment_Interface': - return $this->issetInterface($object); - default: - throw new Exception('Cet object "'.get_class($object).'" n\'est pas reconnu.', E_USER_ERROR); + if($debug === true) { + $this->_debug = 3; } - }*/ - - public function unsetSlot($name) - { - if(is_object($name)) - { - if($name instanceof Equipment_Slot) { - $name = $name->getSlotKey(); - } - else { - throw new Exception("Slot name must be a string or an Equipment_Slot object", E_USER_ERROR); - } + elseif($debug === false) { + $this->_debug = 0; } - - unset($this->_slots[$name]); - return $this; - } - - public function unsetPort($name) - { - if(is_object($name)) - { - if($name instanceof Equipment_Port) { - $name = $name->getPortKey(); - } - else { - throw new Exception("Port name must be a string or an Equipment_Port object", E_USER_ERROR); - } + elseif(C\Tools::is('int&&>0', $debug)) { + $this->_debug = $debug; } - unset($this->_ports[$name]); - return $this; - } - - public function unsetInt($name) - { - return $this->unsetInterface($name); - } - - public function unsetInterface($name) - { - if(is_object($name)) - { - if($name instanceof Equipment_Interface) { - $name = $name->getIntKey(); - } - else { - throw new Exception("Interface name must be a string or an Equipment_Interface object", E_USER_ERROR); - } - } - - unset($this->_ints[$name]); - return $this; - } - - protected static function _getHostName(Api_Equipment $Api_Equipment) - { - $hostName = $Api_Equipment->getEquipmentLabel(); - - if($hostName === false) { - $equipmentId = $Api_Equipment->getEquipmentId(); - throw new Exception("Impossible de résoudre le label pour l'équipement ID \"".$equipmentId."\"", E_USER_ERROR); - } - - return current(explode('.', $hostName, 2)); - } - - abstract public static function isEquipment($label); - - public static function setEnvs(array $environments) - { - self::$_environments = $environments; + return $this->_debug; } } \ No newline at end of file diff --git a/addons/dcim/equipment/interface.php b/addons/dcim/equipment/interface.php index 26f03c7..2566595 100644 --- a/addons/dcim/equipment/interface.php +++ b/addons/dcim/equipment/interface.php @@ -3,61 +3,85 @@ use Core as C; - abstract class Equipment_Interface extends Equipment_Interface_Virtual implements \ArrayAccess, \IteratorAggregate, \Countable + abstract class Equipment_Interface extends Equipment_Interface_Virtual { const INT_PHYSICAL = 0; const INT_VIRTUAL = 1; - /** - * @var Addon\Dcim\Equipment_Port - */ - protected $_equipmentPort; - /** * Physical or virtual interface * @var int */ - protected $_mode; + protected $_mode = null; /** * @var string */ - protected $_intKey; + protected $_interfaceKey = null; /** * @var int */ - protected $_intIndex; + protected $_interfaceIndex = null; + + /** + * @var array + */ + protected $_interfaceLabels = array(); /** * @var string */ protected $_description = null; + /** + * @var array + */ + protected $_neighborDatas = null; + - // index passé lors de l'instanciation permet de garantir que celui-ci ne peut être changé plus tard - public function __construct($port, $index = null) + /** + * $index passé lors de l'instanciation permet de garantir que celui-ci ne peut être changé plus tard + * + * @param Addon\Dcim\Equipment $equipment + * @param string|Addon\Dcim\Equipment_Port $port + * @param null|int $index + * @param null|array $labels + * @return $this + */ + public function __construct(Equipment $equipment, $port, $index = null, array $labels = null) { + parent::__construct($equipment); + if($port instanceof Equipment_Port) { - $this->_mode = self::INT_PHYSICAL; - $this->_equipmentPort = $port; + $this->_port = $port; + $this->_mode = static::INT_PHYSICAL; $portKey = $port->getPortKey(); - $this->_setIntKey($portKey); // /!\ Si un index existe, il sera traité par _setIntKey + $this->_setInterfaceKey($portKey); // /!\ Si un index ou part existent, ils seront traités par _setInterfaceKey $this->setHostName($port->getHostName()); - $this->setIntName($port->getPortName()); + $this->setInterfaceName($port->getPortName()); } elseif(C\Tools::is('string&&!empty', $port)) { - $this->_mode = self::INT_VIRTUAL; + $this->_mode = static::INT_VIRTUAL; - $this->_setIntKey($port); // /!\ Si un index existe, il sera traité par _setIntKey - $this->setIntName($port); + $this->_setInterfaceKey($port); // /!\ Si un index ou part existent, ils seront traités par _setInterfaceKey + + if($index !== null && $this->getInterfaceIndex() === false) { + $this->_setInterfaceIndex($index); + } + + if($labels !== null && count($this->getInterfaceLabels()) === 0) { + $this->_setInterfaceLabels($labels); + } + + $this->setInterfaceName($port); } else { - throw new Exception("Impossible d'instancier une interface", E_USER_ERROR); + throw new Exception("Impossible d'instancier une interface, le port n'est pas du bon type '".gettype($port)."'", E_USER_ERROR); } $this->_setup(); @@ -67,131 +91,287 @@ protected function _setup() { } - protected function _isPhysical() + /** + * @return string + */ + public function getInterfaceId() + { + return $this->_formatInterfaceId(true, true, true); + } + + /** + * @param bool $key + * @param bool $index + * @param bool $labels + * @return string + */ + protected function _formatInterfaceId($key = true, $index = true, $labels = true) { - return ($this->_mode === self::INT_PHYSICAL); + $intId = ''; + + if($key) + { + $intId .= $this->getInterfaceKey(); + + if($index) + { + $intIndex = $this->getInterfaceIndex(); + + if($intIndex !== false) + { + if($this->hasPort()) { + $pSeparator = $this->_port::INTERFACE_SEPARATOR; + } + else { + $pSeparator = $this->_equipment::PORT_INTERFACE_SEPARATOR; + } + + $intId .= $pSeparator.$intIndex; + } + + if($labels) + { + $intLabels = $this->getInterfaceLabels(); + + if(count($intLabels) > 0) { + $vSeparator = static::INTERFACE_SEPARATOR; + $intLabel = implode($vSeparator, $intLabels); + $intId .= $vSeparator.$intLabel; + } + } + } + } + + return $intId; } - protected function _setIntKey($intKey) + /** + * @param string $intKey + * @return $this + */ + protected function _setInterfaceKey($intKey) { - if($this->hasPort()) { - $Equipment_Port = get_class($this->getPort()); - $separator = $Equipment_Port::INT_SEPARATOR; + $hasPort = $this->hasPort(); + + if($hasPort) { + $pSeparator = $this->_port::INTERFACE_SEPARATOR; } else { - $separator = Equipment_Interface_Physical::INT_SEPARATOR; + $pSeparator = $this->_equipment::PORT_INTERFACE_SEPARATOR; } - // /!\ Si la clé possède un index; Séparateur physique si elle vient du port - $intKey = str_replace($separator, self::INT_SEPARATOR, $intKey); - $intKeyParts = explode(self::INT_SEPARATOR, $intKey, 2); + /** + * /!\ Si la clé possède un index alors il est indispensable que le séparateur utilisé soit de type physique + * En général, la clé de l'interface provient du port donc séparateur physique, et les labels sont virtuelles + * + * xe-0/0/69:1.508.123 : key:index.part.part ... + * Un index seul peut exister + * Un label seul peut exister + * Compatible multi-labels + */ + $pSeparator = preg_quote($pSeparator, '#'); + $vSeparator = preg_quote(static::INTERFACE_SEPARATOR, '#'); - $this->_intKey = mb_strtolower($intKeyParts[0]); + /** + * La 3ème parenthèse capturante doit capturer l'ensemble des labels c'est à dire les chiffres et le séparateur (508.123...) + */ + $keyRegex = '([^'.$pSeparator.$vSeparator.']+)'; + $indexRegex = '(?:'.$pSeparator.'([0-9]+))?'; + $labelRegex = '(?:'.$vSeparator.'([0-9'.$vSeparator.']+))?'; + + if(preg_match('#'.$keyRegex.$indexRegex.$labelRegex.'#i', $intKey, $intParts)) + { + // interface key + $this->_interfaceKey = mb_strtolower($intParts[1]); - if(count($intKeyParts) > 1) { - $this->_setIntIndex($intKeyParts[1]); + // interface index + if(isset($intParts[2])) { + $this->_setInterfaceIndex($intParts[2]); + } + + // interface labels + if(isset($intParts[3])) + { + if(!$hasPort) { + $labels = explode(static::INTERFACE_SEPARATOR, $intParts[3]); + $this->_setInterfaceLabels($labels); + } + else + { + /** + * Une interface physique donc lié à un port ne peut pas contenir de labels + * Les labels sont des tags réservés aux interfaces virtuelles + * + * Example les vlans pour les interface réseau + */ + throw new Exception("Impossible d'instancier l'interface physique '".$intKey."', le nom possède des labels '".$intParts[3]."'", E_USER_ERROR); + } + } + } + else { + throw new Exception("Impossible d'instancier l'interface '".$intKey."', le nom n'est pas valide", E_USER_ERROR); } return $this; } - public function getIntKey() + /** + * @return string + */ + public function getInterfaceKey() { - return $this->_intKey; + return $this->_interfaceKey; } - protected function _setIntIndex($intIndex) + protected function _setInterfaceIndex($intIndex) { if($this->_indexIsValid($intIndex)) { - $this->_intIndex = $intIndex; + $this->_interfaceIndex = $intIndex; } + return $this; } - public function getIntIndex() + /** + * @return false|int + */ + public function getInterfaceIndex() { - return ($this->_intIndex !== null) ? ($this->_intIndex) : (false); + return ($this->_interfaceIndex !== null) ? ($this->_interfaceIndex) : (false); } - public function getIntId() + /** + * @param array $intLabels + * @return $this + */ + protected function _setInterfaceLabels(array $intLabels) { - $intKey = $this->getIntKey(); - $intIndex = $this->getIntIndex(); + $this->_interfaceLabels = $intLabels; + return $this; + } - return ($intIndex !== false) ? ($intKey.self::INT_SEPARATOR.$intIndex) : ($intKey); + /** + * @return array + */ + public function getInterfaceLabels() + { + return $this->_interfaceLabels; } - protected function _getKey() + /** + * @return bool + */ + public function isPhysical() { - return $this->getIntId(); + return ($this->_mode === static::INT_PHYSICAL); } - public function hasPort() + /** + * @return bool + */ + public function isVirtual() { - return isset($this->_equipmentPort); + return ($this->_mode === static::INT_VIRTUAL); } - public function getPort() + public function setInterfaceName($intName) { - // @todo a corriger - if($this->hasPort() !== $this->_isPhysical()) { - throw new Exception("", E_USER_ERROR); - } - elseif($this->hasPort() && $this->_isPhysical()) { - return $this->_equipmentPort; - } - else { - return false; + if(C\Tools::is('string&&!empty', $intName)) { + $this->_datas['intName'] = $intName; } + return $this; } - public function getPortId() + public function getInterfaceName() { - $intKey = $this->getIntKey(); - $intIndex = $this->getIntIndex(); + /** + * /!\ Depuis le constructor on renseigne le nom de l'interface + * /!\ Le nom du port ne doit pas pouvoir être changé depuis le port + */ + return $this->_datas['intName']; + } - return ($intIndex !== false) ? ($intKey.Equipment_Port::INT_SEPARATOR.$intIndex) : ($intKey); + /** + * @return string + */ + protected function _getInterfaceId() + { + return $this->getInterfaceId(); } - public function setHostName($hostName) + /** + * @return string + */ + protected function _getInterfaceKey() { - if(C\Tools::is('string&&!empty', $hostName)) { - $this->_datas['hostName'] = $hostName; - } - return $this; + return $this->getInterfaceKey(); } - public function getHostName() + /** + * @return false|int + */ + protected function _getInterfaceIndex() { - return (array_key_exists('hostName', $this->_datas)) ? ($this->_datas['hostName']) : (false); + return $this->getInterfaceIndex(); } - public function setIntName($intName) + /** + * @return array + */ + protected function _getInterfaceLabels() { - if(C\Tools::is('string&&!empty', $intName)) { - $this->_datas['intName'] = $intName; - $this->_datas['portName'] = $intName; // /!\ compatibilité + return $this->getInterfaceLabels(); + } + + /** + * @return string + */ + protected function _getInterfaceName() + { + return $this->getInterfaceName(); + } + + /** + * @return false|Addon\Dcim\Equipment_Port + */ + public function retrievePort() + { + if($this->hasPort() && $this->isPhysical()) { + return $this->_port; + } + elseif($this->hasPort() !== $this->isPhysical()) { + throw new Exception("L'interface '".$this->getInterfaceName()."' n'est pas valide", E_USER_ERROR); + } + else { + return false; + } + } + + public function setHostName($hostName) + { + if(C\Tools::is('string&&!empty', $hostName)) { + $this->_datas['hostName'] = $hostName; } return $this; } - public function getIntName() + public function getHostName() { - /** - * /!\ Depuis le constructor on renseigne le nom de l'interface - * /!\ Le nom du port ne doit pas pouvoir être changé depuis le port - */ - return $this->_datas['intName']; + return (array_key_exists('hostName', $this->_datas)) ? ($this->_datas['hostName']) : (false); } /** * Permet d'indiquer la description de l'interface voisine + * + * @param string $description + * @return $this */ - public function setDescription($desc) + public function setDescription($description) { - if(C\Tools::is('string&&!empty', $desc)) { - $this->_datas['description'] = $desc; + if(C\Tools::is('string&&!empty', $description)) { + $this->_datas['description'] = $description; } + return $this; } @@ -199,134 +379,143 @@ public function setDescription($desc) * /!\ Ne surtout pas retourner la description de datas * La description retournée doit être celle de cette interface * Dans datas, la description est potentiellement celle du voisin + * + * @return string Description */ public function getDescription() { if($this->_description === null) { - $this->_description = $this->getHostName()." ".$this->getIntName(); + $this->_description = $this->getHostName()." ".$this->getInterfaceName(); } return $this->_description; } - // /!\ Doit retourner un tableau + /** + * @return array Return array indexed with interface IDs + */ public function getDatas() { $datas = array(); $this->getHostName(); - $this->getIntName(); + $this->getInterfaceName(); $this->getAttributes(); $this->getDescription(); - $datas[$this->getIntId()] = $this->_datas; + $datas[$this->getInterfaceId()] = $this->_datas; return $datas; } - // /!\ Doit retourner un tableau - // @todo faire comme port sauvegarder dans array - public function getNeighborDatas() + /** + * @return bool + */ + public function hasNeighborInterface() { - if(($port = $this->getPort()) !== false) + return ($this->getNeighborInterface() !== false); + } + + /** + * @return false|Addon\Dcim\Equipment_Interface + */ + public function getNeighborInterface() + { + $port = $this->retrievePort(); + + if($port !== false) { - $nbPort = $port->getNeighborPort(); + $neighborPort = $port->getNeighborPort(); - if($nbPort !== false) + if($neighborPort !== false) { - $nbInt = $nbPort->getInterface(); - - if($nbInt !== false) - { - $datas = array(); - - $leftIntKey = $this->getIntId(); - $rightIntKey = $nbInt->getIntId(); - $nbDatas = $nbInt->getDatas(); - -//echo "\r\nDEBUG 0\r\n\t";var_dump($nbDatas);echo "\r\nEND 0\r\n"; - - $nbDesc = $nbInt->getDescription(); - $datas[$leftIntKey]['description'] = $nbDesc; - - foreach(array_keys(current($nbDatas)) as $key) - { - switch($key) - { - case 'hostName': - case 'intName': - case 'intId': - case 'intIndex': - case 'intIndex2': - case 'intType': { - $value = $nbDatas[$rightIntKey][$key]; - // /!\ Important la clé doit être la clé actuelle côté gauche - $datas[$leftIntKey]['conTo'.ucfirst($key)] = $value; - break; - } - } - } + $neighborInterface = $neighborPort->getInterface(); -//echo "\r\nDEBUG 1\r\n\t";var_dump($datas);echo "\r\nEND 1\r\n"; - - return $datas; + if($neighborInterface !== false) { + return $neighborInterface; } } } - return array(); + return false; } - protected function _indexIsValid($index) + /** + * @param bool $forceToRefresh + * @return array + */ + public function getNeighborDatas($forceToRefresh = false) { - return C\Tools::is('int&&>=0', $index); - } + if(($neighborInterface = $this->getNeighborInterface()) !== false) + { + if($this->_neighborDatas === null || $forceToRefresh) { + $this->_neighborDatas = $this->_getNeighborDatas($neighborInterface); + } - public function offsetSet($offset, $value) - { + return $this->_neighborDatas; + } + else { + return array(); + } } - public function offsetExists($offset) + /** + * @param Addon\Dcim\Equipment_Interface $neighborInterface + * @return array + */ + protected function _getNeighborDatas(Equipment_Interface $neighborInterface) { - return isset($this->{$offset}); - } + $datas = array(); - public function offsetUnset($offset) - { - } + $leftId = $this->getInterfaceId(); + $rightId = $neighborInterface->getInterfaceId(); + $rightDatas = $neighborInterface->getDatas(); - public function offsetGet($offset) - { - $data = $this->{$offset}; - return ($data !== false) ? ($data) : (null); - } + $neighborDescription = $neighborInterface->getDescription(); + $datas[$leftId]['description'] = $neighborDescription; - public function getIterator() - { - $datas = $this->getDatas(); - return new \ArrayIterator($datas); - } - - public function count() - { - $datas = $this->getDatas(); - return count($datas); + foreach($rightDatas[$rightId] as $key => $value) + { + switch($key) + { + case 'hostName': + case 'intName': + case 'intId': + case 'intIndex': + case 'intIndex2': + case 'intType': { + // /!\ Important la clé doit être la clé actuelle côté gauche + $datas[$leftId]['conTo'.ucfirst($key)] = $value; + break; + } + } + } + + return $datas; } public function __get($name) { - $datas = $this->getDatas(); - - if(array_key_exists($name, $datas)) { - return $datas[$key]; + switch($name) + { + case 'interfaceId': { + return $this->getInterfaceId(); + } + case 'interfaceKey': { + return $this->getInterfaceKey(); + } + case 'interfaceIndex': { + return $this->getInterfaceIndex(); + } + case 'interfaceLabels': { + return $this->getInterfaceLabels(); + } + case 'interfaceName': { + return $this->getInterfaceName(); + } + default: { + return parent::__get($name); + } } - - return false; - } - - public function __isset($name) - { - $datas = $this->getDatas(); - return array_key_exists($name, $datas); } } \ No newline at end of file diff --git a/addons/dcim/equipment/interface/abstract.php b/addons/dcim/equipment/interface/abstract.php index ffc0bf2..c8a0de7 100644 --- a/addons/dcim/equipment/interface/abstract.php +++ b/addons/dcim/equipment/interface/abstract.php @@ -3,24 +3,96 @@ use Core as C; - abstract class Equipment_Interface_Abstract + abstract class Equipment_Interface_Abstract implements \ArrayAccess, \IteratorAggregate, \Countable { const INT_ALLOWED_REGEXP = array(); + /** + * @var Addon\Dcim\Equipment + */ + protected $_equipment = null; + + /** + * @var array + */ protected $_attributes = null; + + /** + * @var array + */ protected $_datas = array(); - abstract protected function _getKey(); + /** + * @param Addon\Dcim\Equipment $equipment + * @return $this + */ + public function __construct(Equipment $equipment) + { + $this->_equipment = $equipment; + } + + /** + * @return string + */ + abstract protected function _getInterfaceKey(); + + /** + * Conserne à la fois l'interface physique et virtuelle + * L'index doit être délimité par un séparateur physique + * + * @return false|int + */ + abstract protected function _getInterfaceIndex(); + + /** + * @return string + */ + abstract protected function _getInterfaceName(); + + /** + * @return Addon\Dcim\Equipment + */ + public function getEquipment() + { + return $this->_equipment; + } + + /** + * @param null|string $name + * @return string + */ + protected function _nameToKey($name = null) + { + if($name === null) { + $name = $this->_getInterfaceName(); + } + + return mb_strtolower($name); + } + + /** + * @return array + */ + public function getDataKeys() + { + return array_keys($this->getDatas()); + } - protected function _skipInt() + /** + * @return bool + */ + protected function _skipInterface() { if(count(static::INT_ALLOWED_REGEXP) > 0) { - $intKey = $this->_getKey(); + $interfaceKey = $this->_getInterfaceKey(); - foreach(static::INT_ALLOWED_REGEXP as $regexp) { - if(preg_match('#'.$regexp.'#i', $intKey)) return false; + foreach(static::INT_ALLOWED_REGEXP as $regexp) + { + if(preg_match('#'.$regexp.'#i', $interfaceKey)) { + return false; + } } return true; @@ -31,16 +103,16 @@ protected function _skipInt() } /** - * /!\ Le traitement est insensible à la casse donc on peut utiliser le nom ou la clé + * /!\ Le traitement est insensible à la casse donc on peut utiliser le nom ou la clé */ public function getAttributes() { if($this->_attributes === null) { - $regex = "^([a-z]*)-?(([0-9]{1,4}/){0,}([0-9]{1,4}))(".preg_quote(static::INT_SEPARATOR, '#')."([0-9]))?$"; + $regex = "^([a-z]*)-?(([0-9]{1,4}/){0,}([0-9]{1,4}))(".preg_quote(static::INTERFACE_SEPARATOR, '#')."([0-9]))?$"; $matches = array(); - preg_match('#'.$regex.'#i', $this->_getKey(), $matches); + preg_match('#'.$regex.'#i', $this->_getInterfaceKey(), $matches); $intInfos = array(); $intInfos['intType'] = (isset($matches[1])) ? ($matches[1]) : (null); @@ -64,4 +136,75 @@ public function getAttributes() return $this->_attributes; } + + public function offsetSet($offset, $value) + { + } + + public function offsetExists($offset) + { + return isset($this->{$offset}); + } + + public function offsetUnset($offset) + { + } + + public function offsetGet($offset) + { + /** + * Permet d'éviter de retourner les variables qu'expose __get comme key ou name + */ + $datas = $this->getDatas(); + $key = $this->_nameToKey($offset); + return (array_key_exists($key, $datas)) ? ($datas[$key]) : (null); + } + + public function getIterator() + { + $datas = $this->getDatas(); + return new \ArrayIterator($datas); + } + + public function count() + { + $datas = $this->getDatas(); + return count($datas); + } + + protected function _indexIsValid($index) + { + return C\Tools::is('int&&>=0', $index); + } + + public function __isset($name) + { + $datas = $this->getDatas(); + $key = $this->_nameToKey($name); + return array_key_exists($key, $datas); + } + + public function __get($name) + { + switch($name) + { + case 'key': { + return $this->_getInterfaceKey(); + } + case 'index': { + return $this->_getInterfaceIndex(); + } + case 'name': { + return $this->_getInterfaceName(); + } + case 'equipment': { + return $this->_equipment; + } + default: { + $datas = $this->getDatas(); + $key = $this->_nameToKey($name); + return (array_key_exists($key, $datas)) ? ($datas[$key]) : (false); + } + } + } } \ No newline at end of file diff --git a/addons/dcim/equipment/interface/physical.php b/addons/dcim/equipment/interface/physical.php index f592c2d..ab1cb8f 100644 --- a/addons/dcim/equipment/interface/physical.php +++ b/addons/dcim/equipment/interface/physical.php @@ -3,5 +3,62 @@ abstract class Equipment_Interface_Physical extends Equipment_Interface_Abstract { - const INT_SEPARATOR = ':'; + const INTERFACE_SEPARATOR = ':'; + + + /** + * @return int + */ + abstract protected function _getInterfaceId(); + + /** + * @return Addon\Dcim\Api_Equipment_Abstract + */ + abstract protected function _getInterfaceApi(); + + /** + * @return string + */ + public function getHostName() + { + if(!array_key_exists('hostName', $this->_datas)) { + $this->_datas['hostName'] = $this->_equipment->getHostName(); + } + + return $this->_datas['hostName']; + } + + /** + * @param null|int $connectorId + * @return false|int + */ + abstract public function getEquipmentId($connectorId = null); + + /** + * @param null|int $connectorId + * @return false|int + */ + abstract public function getTopModuleId($connectorId = null); + + /** + * @param null|int $connectorId + * @return false|int + */ + abstract public function getModuleId($connectorId = null); + + public function __get($name) + { + switch($name) + { + case 'id': { + return $this->_getInterfaceId(); + } + case 'api': { + return $this->_getInterfaceApi(); + } + default: { + return parent::__get($name); + } + } + } } \ No newline at end of file diff --git a/addons/dcim/equipment/interface/virtual.php b/addons/dcim/equipment/interface/virtual.php index 33328dd..7b55f52 100644 --- a/addons/dcim/equipment/interface/virtual.php +++ b/addons/dcim/equipment/interface/virtual.php @@ -3,5 +3,87 @@ abstract class Equipment_Interface_Virtual extends Equipment_Interface_Abstract { - const INT_SEPARATOR = '.'; + const INTERFACE_SEPARATOR = '.'; + + /** + * @var Addon\Dcim\Equipment_Port + */ + protected $_port = null; + + + /** + * @return string + */ + abstract protected function _getInterfaceId(); + + /** + * Conserne seulement l'interface virtuelle + * Les labels doivent être délimitées par un séparateur virtuel + * + * @return array + */ + abstract protected function _getInterfaceLabels(); + + /** + * @return bool + */ + public function hasPort() + { + return $this->_port !== null; + } + + /** + * @return false|Addon\Dcim\Equipment_Port + */ + public function retrievePort() + { + if($this->hasPort()) { + return $this->_port; + } + else { + return false; + } + } + + /** + * @return string + */ + public function getPortKey() + { + if($this->hasPort()) { + $separator = $this->_port::INTERFACE_SEPARATOR; + } + else { + $separator = $this->_equipment::PORT_INTERFACE_SEPARATOR; + } + + $intKey = $this->getInterfaceKey(); + $intIndex = $this->getInterfaceIndex(); + + /** + * Un port n'a aucune raison d'avoir des labels (attributs) + * Un port se limite donc à portKey et potentiellement portIndex + * + * Si un port ne respecte pas ce formatage alors il faudra le coder + * Ne pas rajouter interface labels qui correspond à des informations virtuelles + */ + + return ($intIndex !== false) ? ($intKey.$separator.$intIndex) : ($intKey); + } + + public function __get($name) + { + switch($name) + { + case 'id': { + return $this->_getInterfaceId(); // Return string + } + case 'labels': { + return $this->_getInterfaceLabels(); + } + default: { + return parent::__get($name); + } + } + } } \ No newline at end of file diff --git a/addons/dcim/equipment/module.php b/addons/dcim/equipment/module.php new file mode 100644 index 0000000..b144e89 --- /dev/null +++ b/addons/dcim/equipment/module.php @@ -0,0 +1,361 @@ +_equipment = $equipment; + $this->_moduleId = (int) $moduleId; // Test moduleId or cast to INT + $this->_moduleApi = new Api_Equipment($this->_moduleId); + } + + /** + * @return int + */ + public function getModuleId() + { + return $this->_moduleId; + } + + /** + * @return Addon\Dcim\Api_Equipment + */ + public function getModuleApi() + { + return $this->_moduleApi; + } + + /** + * @return string + */ + public function getModuleName() + { + return $this->_moduleApi->label; + } + + /** + * @return Addon\Dcim\Equipment + */ + public function getEquipment() + { + return $this->_equipment; + } + + /** + * @param Addon\Dcim\Equipment_Slot $slot + * @return $this + */ + public function declareSlot(Equipment_Slot $slot) + { + $slotKey = $slot->getSlotKey(); + + if(array_key_exists($slotKey, $this->_slots)) { + throw new Exception("Le slot '".$slot->getSlotName()."' est déjà déclaré sous la clé '".$slotKey."'", E_USER_ERROR); + } + + /** + * Un slot est une interface physique! + * + * Un slot ne peut pas être lié à une interface virtuelle car + * il ne permet pas d'interconnecter directement deux équipements + * + * Par conséquent, un slot seul ne peut être une interface entre deux équipements + */ + + $this->_slots[$slotKey] = $slot; + return $this; + } + + /** + * @param string|Addon\Dcim\Equipment_Slot $name Slot object or key + * @return false|Addon\Dcim\Equipment_Slot + */ + public function retrieveSlot($name) + { + if(is_object($name)) + { + if($name instanceof Equipment_Slot) { + $name = $name->getSlotKey(); + } + else { + throw new Exception("Slot name must be a string or an Equipment_Slot object, '".gettype($name)."' given", E_USER_ERROR); + } + } + + return (array_key_exists($name, $this->_slots)) ? ($this->_slots[$name]) : (false); + } + + /** + * @return Addon\Dcim\Equipment_Slot[] Slot objects + */ + public function getSlots() + { + return $this->_slots; + } + + /** + * @param Addon\Dcim\Equipment_Slot $slot + * @return $this + */ + public function undeclareSlot(Equipment_Slot $slot) + { + $this->unsetSlot($slot); + return $this; + } + + /** + * @param Addon\Dcim\Equipment_Port $port + * @return $this + */ + public function declarePort(Equipment_Port $port) + { + $portKey = $port->getPortKey(); + + if(array_key_exists($portKey, $this->_ports)) { + throw new Exception("Le port '".$port->getPortName()."' est déjà déclaré sous la clé '".$portKey."'", E_USER_ERROR); + } + + $this->_ports[$portKey] = $port; + return $this; + } + + /** + * @param string|Addon\Dcim\Equipment_Port $name Port object or key + * @return false|Addon\Dcim\Equipment_Port + */ + public function retrievePort($name) + { + if(is_object($name)) + { + if($name instanceof Equipment_Port) { + $name = $name->getPortKey(); + } + else { + throw new Exception("Port name must be a string or an Equipment_Port object, '".gettype($name)."' given", E_USER_ERROR); + } + } + + return (array_key_exists($name, $this->_ports)) ? ($this->_ports[$name]) : (false); + } + + /** + * @return Addon\Dcim\Equipment_Port[] Port objects + */ + public function getPorts() + { + return $this->_ports; + } + + /** + * @param Addon\Dcim\Equipment_Port $port + * @return $this + */ + public function undeclarePort(Equipment_Port $port) + { + $this->unsetPort($port); + return $this; + } + + /** + * @param Addon\Dcim\Equipment_Interface $interface + * @return $this + */ + public function declareInterface(Equipment_Interface $interface) + { + $interfaceId = $interface->getInterfaceId(); + + if(array_key_exists($interfaceId, $this->_interfaces)) { + throw new Exception("L'interface '".$interface->getInterfaceName()."' est déjà déclarée sous l'ID '".$interfaceId."'", E_USER_ERROR); + } + + $this->_interfaces[$interfaceId] = $interface; + return $this; + } + + /** + * @param string|Addon\Dcim\Equipment_Interface $name Interface object or ID + * @param null|int $index Interface index + * @return false|Addon\Dcim\Equipment_Interface + */ + public function retrieveInterface($name, $index = null) + { + if(is_object($name)) + { + if($name instanceof Equipment_Interface) { + $name = $name->getInterfaceId(); + } + else { + throw new Exception("Interface name must be a string or an Equipment_Interface object, '".gettype($name)."' given", E_USER_ERROR); + } + } + else + { + if($index !== null) { + $name .= $this->_equipment::INT_INTERFACE_SEPARATOR.$index; + } + } + + return (array_key_exists($name, $this->_interfaces)) ? ($this->_interfaces[$name]) : (false); + } + + /** + * @return Addon\Dcim\Equipment_Interface[] + */ + public function getInterfaces() + { + return $this->_interfaces; + } + + /** + * @param Addon\Dcim\Equipment_Interface $interface + * @return $this + */ + public function undeclareInterface(Equipment_Interface $interface) + { + $this->unsetInterface($interface); + return $this; + } + + /** + * @param string|Addon\Dcim\Equipment_Slot $name Slot object or key + * @return bool + */ + public function issetSlot($name) + { + return ($this->retrieveSlot($name) !== false); + } + + /** + * @param string|Addon\Dcim\Equipment_Port $name Port object or key + * @return bool + */ + public function issetPort($name) + { + return ($this->retrievePort($name) !== false); + } + + /** + * @param string|Addon\Dcim\Equipment_Interface $name Interface object or ID + * @param null|int $index Interface index + * @return bool + */ + public function issetInterface($name, $index = null) + { + return ($this->retrieveInterface($name, $index) !== false); + } + + /** + * @param string|Addon\Dcim\Equipment_Slot $name Slot object or key + * @return $this + */ + public function unsetSlot($name) + { + $Equipment_Slot = $this->retrieveSlot($name); + + if($Equipment_Slot !== false) { + unset($this->_slots[$Equipment_Slot->getSlotKey()]); + } + + return $this; + } + + /** + * @param string|Addon\Dcim\Equipment_Port $name Port object or key + * @return $this + */ + public function unsetPort($name) + { + $Equipment_Port = $this->retrievePort($name); + + if($Equipment_Port !== false) { + unset($this->_ports[$Equipment_Port->getPortKey()]); + } + + return $this; + } + + /** + * @param string|Addon\Dcim\Equipment_Interface $name Interface object or ID + * @param null|int $index Interface index + * @return $this + */ + public function unsetInterface($name, $index = null) + { + $Equipment_Interface = $this->retrieveInterface($name, $index); + + if($Equipment_Interface !== false) { + unset($this->_interfaces[$Equipment_Interface->getInterfaceId()]); + } + + return $this; + } + + /** + * @param mixed $name + * @return mixed + */ + public function __get($name) + { + switch($name) + { + case 'id': + case 'moduleId': + return $this->getModuleId(); + case 'api': + case 'moduleApi': + return $this->getModuleApi(); + case 'name': + case 'moduleName': + return $this->getModuleName(); + case 'equipment': + return $this->getEquipment(); + case 'slots': + return $this->getSlots(); + case 'ports': + return $this->getPorts(); + case 'interfaces': + return $this->getInterfaces(); + default: + throw new Exception("This attribute '".$name."' does not exist", E_USER_ERROR); + } + } + } \ No newline at end of file diff --git a/addons/dcim/equipment/port.php b/addons/dcim/equipment/port.php index cc50447..16b4b62 100644 --- a/addons/dcim/equipment/port.php +++ b/addons/dcim/equipment/port.php @@ -3,141 +3,209 @@ use Core as C; - abstract class Equipment_Port extends Equipment_Interface_Physical implements \ArrayAccess, \IteratorAggregate, \Countable + abstract class Equipment_Port extends Equipment_Interface_Physical { + /** + * @var int + */ + protected $_portId = null; + /** * @var Addon\Dcim\Api_Equipment_Port */ - protected $_equipmentPortApi; + protected $_portApi = null; /** * @var Addon\Dcim\Equipment_Interface */ - protected $_equipmentInterface; + protected $_interface = null; - protected $_portId = null; + /** + * @var string + */ protected $_portKey = null; - protected $_neighborPort = null; + /** + * @var string[] + */ protected $_description = array(); - protected $_nbDatas = array(); + + /** + * @var Addon\Dcim\Equipment_Port + */ + protected $_neighborPort = null; + + /** + * @var array + */ + protected $_neighborDatas = array(); - public function __construct($portId) + /** + * @param Addon\Dcim\Equipment $equipment + * @param int $portId + * @return $this + */ + public function __construct(Equipment $equipment, $portId) { - $this->_portId = (int) $portId; - $this->_equipmentPortApi = new Api_Equipment_Port($this->_portId); // /!\ Ne pas passer null - } + parent::__construct($equipment); - public function skipPort() - { - return $this->_skipInt(); + $this->_portId = (int) $portId; // Test portId or cast to INT + $this->_portApi = new Api_Equipment_Port($this->_portId); } - public function isConnected() + public function getPortId() { - return $this->_equipmentPortApi->isConnected(); + return $this->_portId; } - public function setInterface(Equipment_Interface $Equipment_Interface) + public function getPortKey() { - if($this->_equipmentInterface === null) { - $this->_equipmentInterface = $Equipment_Interface; + if($this->_portKey === null) { + $this->_portKey = $this->_nameToKey(); } - return $this; + return $this->_portKey; } - public function getInterface() + public function getPortIndex() { - if($this->_equipmentInterface === null) { - throw new Exception("L'interface de ce port n'est pas déclarée", E_USER_ERROR); - } - - return $this->_equipmentInterface; + $portKey = $this->getPortKey(); + $portParts = explode(static::INTERFACE_SEPARATOR, $portKey, 2); + return (count($portParts) === 2) ? ($portParts[1]) : (false); } - - public function getPortId() + + public function getPortApi() { - return $this->_portId; + return $this->_portApi; } - protected function _getKey() + public function skipPort() { - return $this->getPortKey(); + return $this->_skipInterface(); } - public function getPortKey() + public function isConnected() { - if($this->_portKey === null) { - $this->_portKey = $this->_nameToKey(); - } + return $this->_portApi->isConnected(); + } - return $this->_portKey; + public function hasInterface() + { + return ($this->_interface !== null); } - protected function _nameToKey($portName = null) + public function setInterface(Equipment_Interface $interface) { - if($portName === null) { - $portName = $this->getPortName(); + if(($port = $interface->retrievePort()) !== false && $port === $this) + { + if(!$this->hasInterface()) { + $this->_interface = $interface; + } + else { + throw new Exception("L'interface '".$interface->interfaceName."' ne peut être déclarée pour le port '".$this->portApi->label."', une interface est déjà présente", E_USER_ERROR); + } + } + else { + throw new Exception("L'interface '".$interface->interfaceName."' ne peut être déclarée car son port '".$port->portApi->label."' ne correspond pas au port '".$this->portApi->label."'", E_USER_ERROR); } - return mb_strtolower($portName); + return $this; } - public function getStatus() + public function getInterface() { - if(!array_key_exists('status', $this->_datas)) { - $this->_datas['status'] = $this->isConnected(); + if(!$this->hasInterface()) { + throw new Exception("L'interface du port '".$this->portApi->label."' n'est pas déclarée", E_USER_ERROR); } - return $this->_datas['status']; + return $this->_interface; } - public function getHostName($portKey = null) + public function getPortName($portKey = null) { - if(!array_key_exists('hostName', $this->_datas)) + if(!array_key_exists('portName', $this->_datas)) { - $hostName = $this->_equipmentPortApi->getTopEquipmentLabel(); + $portName = $this->_portApi->getPortLabel(); - if($hostName === false) { - $equipmentId = $this->_equipmentPortApi->getTopEquipmentId(); - throw new Exception("Impossible de résoudre le label pour l'équipement ID \"".$equipmentId."\"", E_USER_ERROR); + if($portName === false) { + $portId = $this->_portApi->getPortId(); + $hostName = $this->_portApi->getTopEquipmentLabel(); + throw new Exception("Impossible de résoudre le label du port ID '".$portId."' pour l'équipement '".$hostName."'", E_USER_ERROR); } - $this->_datas['hostName'] = current(explode('.', $hostName, 2)); + $this->_datas['portName'] = $portName; } $datas = $this->_getPortDatasByKey($portKey); - if(!array_key_exists('hostName', $datas)) { - $datas['hostName'] = $this->_datas['hostName']; + if(!array_key_exists('portName', $datas)) { + $datas['portName'] = $this->_datas['portName']; } - return $datas['hostName']; + return $datas['portName']; } - public function getPortName($portKey = null) + /** + * @return int + */ + protected function _getInterfaceId() { - if(!array_key_exists('portName', $this->_datas)) - { - $portName = $this->_equipmentPortApi->getPortLabel(); + return $this->getPortId(); + } - if($portName === false) { - $portId = $this->_equipmentPortApi->getPortId(); - throw new Exception("Impossible de résoudre le label du port ID \"".$portId."\"", E_USER_ERROR); - } + /** + * @return Addon\Dcim\Api_Equipment_Abstract + */ + protected function _getInterfaceApi() + { + return $this->getPortApi(); + } - $this->_datas['portName'] = $portName; + /** + * @return string + */ + protected function _getInterfaceKey() + { + return $this->getPortKey(); + } + + /** + * @return string + */ + protected function _getInterfaceIndex() + { + return $this->getPortIndex(); + } + + /** + * @return string + */ + protected function _getInterfaceName() + { + return $this->getPortName(); + } + + public function getStatus() + { + if(!array_key_exists('status', $this->_datas)) { + $this->_datas['status'] = $this->isConnected(); } + return $this->_datas['status']; + } + + public function getHostName($portKey = null) + { + parent::getHostName(); + $datas = $this->_getPortDatasByKey($portKey); - if(!array_key_exists('portName', $datas)) { - $datas['portName'] = $this->_datas['portName']; + if(!array_key_exists('hostName', $datas)) { + $datas['hostName'] = $this->_datas['hostName']; } - return $datas['portName']; + return $datas['hostName']; } public function getDescription($portKey = null) @@ -153,7 +221,9 @@ public function getDescription($portKey = null) return $this->_description[$portKey]; } - // /!\ Doit retourner un tableau + /** + * @return array Return array indexed with port keys + */ public function getDatas() { if(!$this->skipPort()) @@ -171,50 +241,83 @@ public function getDatas() return $datas; } else { - throw new Exception("Ce port ne doit pas être traité", E_USER_ERROR); + throw new Exception("Ce port '".$this->portName."' ne doit pas être traité", E_USER_ERROR); } } - public function getKeys() + /** + * @param null|int $connectorId + * @return false|int + */ + public function getEquipmentId($connectorId = null) { - return array_keys($this->getDatas()); + if($connectorId === null || (int) $connectorId === $this->getPortId()) { + //return $this->_equipment->equipmentId; + return $this->_portApi->getTopEquipmentId(); + } + else { + $Api_Equipment_Port = new Api_Equipment_Port($connectorId); + return $Api_Equipment_Port->getTopEquipmentId(); + } } - public function getEquipmentId($portId = null) + /** + * @param null|int $connectorId + * @return false|int + */ + public function getTopModuleId($connectorId = null) { - if($portId === null || (int) $portId === $this->getPortId()) { - return $this->_equipmentPortApi->getTopEquipmentId(); + if($connectorId === null || (int) $connectorId === $this->getPortId()) { + return $this->_portApi->getModuleEquipmentId(); } else { - $Api_Equipment_Port = new Api_Equipment_Port($portId); - return $Api_Equipment_Port->getTopEquipmentId(); + $Api_Equipment_Port = new Api_Equipment_Port($connectorId); + return $Api_Equipment_Port->getModuleEquipmentId(); } } - public function getModuleId($portId = null) + /** + * @param null|int $connectorId + * @return false|int + */ + public function getModuleId($connectorId = null) { - if($portId === null || (int) $portId === $this->getPortId()) { - return $this->_equipmentPortApi->getModuleEquipmentId(); + if($connectorId === null || (int) $connectorId === $this->getPortId()) { + $moduleId = $this->_portApi->getParentEquipmentId(); } else { - $Api_Equipment_Port = new Api_Equipment_Port($portId); - return $Api_Equipment_Port->getModuleEquipmentId(); + $Api_Equipment_Port = new Api_Equipment_Port($connectorId); + $moduleId = $Api_Equipment_Port->getParentEquipmentId(); } + + return ($moduleId !== $this->equipment->id) ? ($moduleId) : (false); } - public function getNeighborEquipId($portId = null) + public function getNeighborEquipmentId($portId = null) { - if($portId === null) { - $portId = $this->getNeighborPortId(); + if($portId === null || (int) $portId === $this->getPortId()) + { + $portId = $this->getPortId(); + + if($this->hasNeighborPort()) { + return $this->_neighborPort->getEquipmentId(); + } } + $portId = $this->getNeighborPortId($portId); return $this->getEquipmentId($portId); } public function getNeighborPortId($portId = null) { - if($portId === null || (int) $portId === $this->getPortId()) { - $Api_Equipment_Port = $this->_equipmentPortApi; + if($portId === null || (int) $portId === $this->getPortId()) + { + if($this->hasNeighborPort()) { + return $this->_neighborPort->getPortId(); + } + else { + $Api_Equipment_Port = $this->_portApi; + } } else { $Api_Equipment_Port = new Api_Equipment_Port($portId); @@ -237,48 +340,43 @@ public function setNeighborPort(Equipment_Port $portEquipment) { if(!$this->hasNeighborPort()) { $this->_neighborPort = $portEquipment; - $this->_nbDatas = $this->_getNeighborInfos(); + $this->_neighborDatas = $this->_getNeighborDatas(); } return $this; } - protected function _getNeighborInfos() + protected function _getNeighborDatas() { - $port = $this->getNeighborPort(); + $neighborPort = $this->getNeighborPort(); - if($port !== false) + if($neighborPort !== false) { - if($this->getPortId() === $port->getNeighborPortId()) + if($this->getPortId() === $neighborPort->getNeighborPortId()) { $datas = array(); - $leftKeys = $this->getKeys(); - $rightKeys = $port->getKeys(); - $rightDatas = $port->getDatas(); - - foreach($rightKeys as $index => $rightKey) - { - $leftKey = $leftKeys[$index]; + $leftKey = $this->getPortKey(); + $rightKey = $neighborPort->getPortKey(); + $rightDatas = $neighborPort->getDatas(); + $rightDatas = $rightDatas[$rightKey]; - $rightDesc = $port->getDescription($rightKey); - $datas[$leftKey]['description'] = $rightDesc; + $rightDescription = $neighborPort->getDescription($rightKey); + $datas[$leftKey]['description'] = $rightDescription; - foreach(array_keys($rightDatas[$rightKey]) as $key) + foreach($rightDatas as $index => $value) + { + switch($index) { - switch($key) - { - case 'hostName': - case 'portName': - case 'intId': - case 'intIndex': - case 'intIndex2': - case 'intType': { - $value = $rightDatas[$rightKey][$key]; - // /!\ Important la clé doit être la clé actuelle côté gauche - $datas[$leftKey]['conTo'.ucfirst($key)] = $value; - break; - } + case 'hostName': + case 'portName': + case 'intId': + case 'intIndex': + case 'intIndex2': + case 'intType': { + // /!\ Important la clé doit être la clé actuelle côté gauche + $datas[$leftKey]['conTo'.ucfirst($index)] = $value; + break; } } } @@ -286,21 +384,27 @@ protected function _getNeighborInfos() return $datas; } else { - throw new Exception("L'ID du port voisin ne correspond pas à l'ID du port déclaré", E_USER_ERROR); + $eMessage = "('".$this->portName."', '".$neighborPort->portName."')"; + throw new Exception("L'ID du port voisin ne correspond pas à l'ID du port voisin déclaré ".$eMessage, E_USER_ERROR); } } else { - $portName = $this->getPortName(); - throw new Exception("Le port voisin du port '".$portName."' n'est pas déclaré", E_USER_ERROR); + throw new Exception("Le port voisin pour le port '".$this->portName."' n'est pas déclaré", E_USER_ERROR); } } - // /!\ Doit retourner un tableau + /** + * @return array + */ public function getNeighborDatas() { - return ($this->hasNeighborPort()) ? ($this->_nbDatas) : (array()); + return ($this->hasNeighborPort()) ? ($this->_neighborDatas) : (array()); } + /** + * @param array $datas + * @return $this + */ public function setNeighborDatas(array $datas) { throw new Exception("Il est interdit de changer les données du port voisin", E_USER_ERROR); @@ -313,7 +417,7 @@ protected function &_getPortDatasByIndex($index = null) return $this->_datas; } else { - throw new Exception("L'index du port est invalide", E_USER_ERROR); + throw new Exception("L'index '".$index."' du port '".$this->portApi->label."' est invalide", E_USER_ERROR); } } @@ -323,62 +427,32 @@ protected function &_getPortDatasByKey($key = null) return $this->_datas; } else { - throw new Exception("La clé du port est invalide", E_USER_ERROR); + throw new Exception("La clé '".$key."' du port '".$this->portApi->label."' est invalide", E_USER_ERROR); } } - protected function _indexIsValid($index) - { - return C\Tools::is('int&&>=0', $index); - } - - public function offsetSet($offset, $value) - { - } - - public function offsetExists($offset) - { - return isset($this->{$offset}); - } - - public function offsetUnset($offset) - { - } - - public function offsetGet($offset) - { - $data = $this->{$offset}; - return ($data !== false) ? ($data) : (null); - } - - public function getIterator() - { - $datas = $this->getDatas(); - return new \ArrayIterator($datas); - } - - public function count() - { - $datas = $this->getDatas(); - return count($datas); - } - public function __get($name) { - $datas = $this->getDatas(); - $key = $this->_nameToKey($name); - - if(array_key_exists($key, $datas)) { - return $datas[$key]; + switch($name) + { + case 'portId': { + return $this->getPortId(); + } + case 'portApi': { + return $this->getPortApi(); + } + case 'portKey': { + return $this->getPortKey(); + } + case 'portIndex': { + return $this->getPortIndex(); + } + case 'portName': { + return $this->getPortName(); + } + default: { + return parent::__get($name); + } } - - return false; - } - - public function __isset($name) - { - $keys = $this->getKeys(); - $key = $this->_nameToKey($name); - return in_array($key, $keys, true); } } \ No newline at end of file diff --git a/addons/dcim/equipment/slot.php b/addons/dcim/equipment/slot.php index 2ce7a53..a54623a 100644 --- a/addons/dcim/equipment/slot.php +++ b/addons/dcim/equipment/slot.php @@ -1,17 +1,17 @@ _slotId = (int) $slotId; - $this->_equipmentSlotApi = new Api_Equipment_Slot($this->_slotId); // /!\ Ne pas passer null - } + parent::__construct($equipment); - public function skipSlot() - { - return $this->_skipInt(); + $this->_slotId = (int) $slotId; // Test slotId or cast to INT + $this->_slotApi = new Api_Equipment_Slot($this->_slotId); } - public function isEmpty() - { - return $this->_equipmentSlotApi->isEmpty(); - } - public function getSlotId() { return $this->_slotId; } - protected function _getKey() - { - return $this->getSlotKey(); - } - public function getSlotKey() { if($this->_slotKey === null) { @@ -59,55 +46,38 @@ public function getSlotKey() return $this->_slotKey; } - protected function _nameToKey($slotName = null) + public function getSlotIndex() { - if($slotName === null) { - $slotName = $this->getSlotName(); - } - - return mb_strtolower($slotName); + $slotKey = $this->getSlotKey(); + $slotParts = explode(static::INTERFACE_SEPARATOR, $slotKey, 2); + return (count($slotParts) === 2) ? ($slotParts[1]) : (false); } - public function getEquipmentId() + public function getSlotApi() { - return $this->_equipmentSlotApi->getTopEquipmentId(); + return $this->_slotApi; } - public function getStatus() + public function skipSlot() { - if(!array_key_exists('status', $this->_datas)) { - $this->_datas['status'] = !$this->isEmpty(); - } - - return $this->_datas['status']; + return $this->_skipInterface(); } - public function getHostName() + public function isEmpty() { - if(!array_key_exists('hostName', $this->_datas)) - { - $hostName = $this->_equipmentSlotApi->getTopEquipmentLabel(); - - if($hostName === false) { - $equipmentId = $this->_Api_Equipment_Port->getTopEquipmentId(); - throw new Exception("Impossible de résoudre le label pour l'équipement ID \"".$equipmentId."\"", E_USER_ERROR); - } - - $this->_datas['hostName'] = current(explode('.', $hostName, 2)); - } - - return $this->_datas['hostName']; + return $this->_slotApi->isEmpty(); } public function getSlotName() { if(!array_key_exists('slotName', $this->_datas)) { - $slotName = $this->_equipmentSlotApi->getSlotLabel(); + $slotName = $this->_slotApi->getSlotLabel(); if($slotName === false) { - $slotId = $this->_equipmentSlotApi->getSlotId(); - throw new Exception("Impossible de résoudre le label du slot ID \"".$slotId."\"", E_USER_ERROR); + $slotId = $this->_slotApi->getSlotId(); + $hostName = $this->_portApi->getTopEquipmentLabel(); + throw new Exception("Impossible de résoudre le label du slot ID '".$slotId."' pour l'équipement '".$hostName."'", E_USER_ERROR); } $this->_datas['slotName'] = $slotName; @@ -116,6 +86,55 @@ public function getSlotName() return $this->_datas['slotName']; } + /** + * @return int + */ + protected function _getInterfaceId() + { + return $this->getSlotId(); + } + + /** + * @return Addon\Dcim\Api_Equipment_Abstract + */ + protected function _getInterfaceApi() + { + return $this->getSlotApi(); + } + + /** + * @return string + */ + protected function _getInterfaceKey() + { + return $this->getSlotKey(); + } + + /** + * @return int + */ + protected function _getInterfaceIndex() + { + return $this->getSlotIndex(); + } + + /** + * @return string + */ + protected function _getInterfaceName() + { + return $this->getSlotName(); + } + + public function getStatus() + { + if(!array_key_exists('status', $this->_datas)) { + $this->_datas['status'] = !$this->isEmpty(); + } + + return $this->_datas['status']; + } + public function getDescription() { if($this->_description === null) { @@ -125,7 +144,9 @@ public function getDescription() return $this->_description; } - // /!\ Doit retourner un tableau + /** + * @return array Return array indexed with slot keys + */ public function getDatas() { if(!$this->skipSlot()) @@ -143,57 +164,79 @@ public function getDatas() return $datas; } else { - throw new Exception("Ce slot ne doit pas être traité", E_USER_ERROR); + throw new Exception("Ce slot '".$this->slotName."' ne doit pas être traité", E_USER_ERROR); } } - public function offsetSet($offset, $value) - { - } - - public function offsetExists($offset) - { - return isset($this->{$offset}); - } - - public function offsetUnset($offset) + /** + * @param null|int $connectorId + * @return false|int + */ + public function getEquipmentId($connectorId = null) { + if($connectorId === null || (int) $connectorId === $this->getSlotId()) { + return $this->_slotApi->getTopEquipmentId(); + } + else { + $Api_Equipment_Slot = new Api_Equipment_Slot($connectorId); + return $Api_Equipment_Slot->getTopEquipmentId(); + } } - public function offsetGet($offset) + /** + * @param null|int $connectorId + * @return false|int + */ + public function getTopModuleId($connectorId = null) { - $data = $this->{$offset}; - return ($data !== false) ? ($data) : (null); + if($connectorId === null || (int) $connectorId === $this->getSlotId()) { + return $this->_slotApi->getModuleEquipmentId(); + } + else { + $Api_Equipment_Slot = new Api_Equipment_Slot($connectorId); + return $Api_Equipment_Slot->getModuleEquipmentId(); + } } - public function getIterator() + /** + * @param null|int $connectorId + * @return false|int + */ + public function getModuleId($connectorId = null) { - $datas = $this->getDatas(); - return new ArrayIterator($datas); - } + if($connectorId === null || (int) $connectorId === $this->getSlotId()) { + $moduleId = $this->_slotApi->getParentEquipmentId(); + } + else { + $Api_Equipment_Slot = new Api_Equipment_Slot($connectorId); + $moduleId = $Api_Equipment_Slot->getParentEquipmentId(); + } - public function count() - { - $datas = $this->getDatas(); - return count($datas); + return ($moduleId !== $this->equipment->id) ? ($moduleId) : (false); } public function __get($name) { - $datas = $this->getDatas(); - $key = $this->_nameToKey($name); - - if(array_key_exists($key, $datas)) { - return $datas[$key]; + switch($name) + { + case 'slotId': { + return $this->getSlotId(); + } + case 'slotApi': { + return $this->getSlotApi(); + } + case 'slotKey': { + return $this->getSlotKey(); + } + case 'slotIndex': { + return $this->getSlotIndex(); + } + case 'slotName': { + return $this->getSlotName(); + } + default: { + return parent::__get($name); + } } - - return false; - } - - public function __isset($name) - { - $keys = $this->getKeys(); - $key = $this->_nameToKey($name); - return in_array($key, $keys, true); } } \ No newline at end of file diff --git a/applications/dcim/launchers/dcim.php b/applications/dcim/launchers/dcim.php index 20171d3..3df19a4 100644 --- a/applications/dcim/launchers/dcim.php +++ b/applications/dcim/launchers/dcim.php @@ -1,7 +1,7 @@ isOneShotCall()) { $printInfoMessages = true; diff --git a/dcim.php.example b/dcim.php.example index 442a588..bd6465e 100644 --- a/dcim.php.example +++ b/dcim.php.example @@ -1,6 +1,10 @@