/** * Method to add or replace the node metadata. * Editable attributes: * - config * - cpu * - delay * - ethernet * - icon * - idlepc * - image * - left * - name * - nvram * - ram * - serial * - slots * - top * If an attribute is set and is valid, then it will be used. If an * attribute is not set, then the original is maintained. If in attribute * is set and empty '', then the current one is deleted. * * @param Array $p Parameters * @return int 0 means ok */ public function edit($p) { $modified = False; if (isset($p['config']) && $p['config'] === '') { // Config is empty, unset the current one unset($this->config); $modified = True; } else { if (isset($p['config']) && !checkNodeConfig($p['config'])) { // Config is invalid, ingored error_log(date('M d H:i:s ') . 'WARNING: ' . $GLOBALS['messages'][40003]); } else { if (isset($p['config'])) { $this->config = $p['config']; $modified = True; } } } if (isset($p['delay']) && $p['delay'] === '') { // Delay is empty, unset the current one unset($this->delay); $modified = True; } else { if (isset($p['delay']) && (int) $p['delay'] < 0) { // Delay is invalid, ignored error_log(date('M d H:i:s ') . 'WARNING: ' . $GLOBALS['messages'][40004]); } else { if (isset($p['delay'])) { $this->delay = (int) $p['delay']; } } } if (isset($p['icon']) && $p['icon'] === '') { // Icon is empty, unset the current one unset($this->icon); $modified = True; } else { if (isset($p['icon']) && !checkNodeIcon($p['icon'])) { // Icon is invalid, ignored error_log(date('M d H:i:s ') . 'WARNING: ' . $GLOBALS['messages'][40005]); } else { if (isset($p['icon'])) { $this->icon = $p['icon']; } } } if (isset($p['image']) && ($p['image'] === '' || !checkNodeImage($p['image'], $p['type'], $p['template']))) { // Image is not valid, ignored error_log(date('M d H:i:s ') . 'WARNING: ' . $GLOBALS['messages'][40006]); } else { if (isset($p['image'])) { $this->image = $p['image']; $modified = True; } } if (isset($p['left']) && $p['left'] === '') { // Left is empty, unset the current one unset($this->left); $modified = True; } else { if (isset($p['left']) && !checkPosition($p['left'])) { // Left is not valid, ignored error_log(date('M d H:i:s ') . 'WARNING: ' . $GLOBALS['messages'][40007]); } else { if (isset($p['left'])) { $this->left = $p['left']; $modified = True; } } } if (isset($p['name']) && $p['name'] === '') { // Name is empty, unset the current one unset($this->name); $modified = True; } else { if (isset($p['name']) && !checkNodeName($p['name'])) { // Name is not valid, ignored error_log(date('M d H:i:s ') . 'WARNING: ' . $GLOBALS['messages'][40008]); } else { if (isset($p['name'])) { $this->name = $p['name']; $modified = True; } } } if (isset($p['top']) && $p['top'] === '') { // Top is empty, unset the current one unset($this->top); $modified = True; } else { if (isset($p['top']) && !checkPosition($p['top'])) { // Top is not valid, ignored error_log(date('M d H:i:s ') . 'WARNING: ' . $GLOBALS['messages'][40010]); } else { if (isset($p['top'])) { $this->top = $p['top']; $modified = True; } } } // Specific parameters if ($this->type == 'iol') { if (isset($p['ethernet']) && $p['ethernet'] === '') { // Ethernet interfaces is empty, unset the current one unset($p['ethernet']); $modified = True; } else { if (isset($p['ethernet']) && (int) $p['ethernet'] < 0) { // Ethernet interfaces is invalid, ignored error_log(date('M d H:i:s ') . 'WARNING: ' . $GLOBALS['messages'][40012]); } else { if (isset($p['ethernet']) && $this->ethernet != (int) $p['ethernet']) { // New Ethernet value $this->ethernet = (int) $p['ethernet']; $modified = True; } } } if (isset($p['nvram']) && $p['nvram'] === '') { // NVRAM is empty, unset the current one unset($p['nvram']); $modified = True; } else { if (isset($p['nvram']) && (int) $p['nvram'] <= 0) { // NVRAM is invalid, ignored error_log(date('M d H:i:s ') . 'WARNING: ' . $GLOBALS['messages'][40011]); } else { if (isset($p['nvram'])) { $this->nvram = (int) $p['nvram']; } } } if (isset($p['ram']) && $p['ram'] === '') { // RAM is empty, unset the current one unset($p['ram']); $modified = True; } else { if (isset($p['ram']) && (int) $p['ram'] <= 0) { // RAM is invalid, ignored error_log(date('M d H:i:s ') . 'WARNING: ' . $GLOBALS['messages'][40009]); } else { if (isset($p['ram'])) { $this->ram = (int) $p['ram']; } } } if (isset($p['serial']) && $p['serial'] === '') { // Serial interfaces is empty, unset the current one unset($p['serial']); $modified = True; } else { if (isset($p['serial']) && (int) $p['serial'] < 0) { // Serial interfaces is invalid, ignored error_log(date('M d H:i:s ') . 'WARNING: ' . $GLOBALS['messages'][40013]); } else { if (isset($p['serial']) && $this->serial != (int) $p['serial']) { // New Serial value $this->serial = (int) $p['serial']; $modified = True; } } } } if ($this->type == 'dynamips') { if (isset($p['idlepc']) && $p['idlepc'] === '') { // Idle PC is empty, unset the current one unset($p['idlepc']); $modified = True; } else { if (isset($p['idlepc']) && !checkNodeIdlepc($p['idlepc'])) { // Idle PC is invalid, ignored error_log(date('M d H:i:s ') . 'WARNING: ' . $GLOBALS['messages'][40014]); } else { if (isset($p['idlepc'])) { $this->idlepc = $p['idlepc']; } } } if (isset($p['nvram']) && $p['nvram'] === '') { // NVRAM is empty, unset the current one unset($p['nvram']); $modified = True; } else { if (isset($p['nvram']) && (int) $p['nvram'] <= 0) { // NVRAM is invalid, ignored error_log(date('M d H:i:s ') . 'WARNING: ' . $GLOBALS['messages'][40011]); } else { if (isset($p['nvram'])) { $this->nvram = (int) $p['nvram']; } } } if (isset($p['ram']) && $p['ram'] === '') { // RAM is empty, unset the current one unset($p['ram']); $modified = True; } else { if (isset($p['ram']) && (int) $p['ram'] <= 0) { // RAM is invalid, ignored error_log(date('M d H:i:s ') . 'WARNING: ' . $GLOBALS['messages'][40009]); } else { if (isset($p['ram'])) { $this->ram = (int) $p['ram']; } } } // Loading slots foreach ($p as $key => $module) { if (preg_match('/^slot[0-9]+$/', $key)) { // Found a slot $slot_id = substr($key, 4); if ($module == '') { // Slot is empty, unset the current one unset($this->slots[$slot_id]); $modified = True; } else { if (!isset($this->slots[$slot_id]) || $this->slots[$slot_id] != $module) { // Need to set the slot (previous was empty or different module) $this->setSlot($slot_id, $module); $modified = True; } } } } } if ($this->type == 'qemu') { // TODO check if == vnc or telnet (checkConsole) if (isset($p['console']) && $p['console'] === '') { // Console is empty, unset the current one unset($p['console']); $modified = True; } else { if (isset($p['console'])) { $this->console = htmlentities($p['console']); $modified = True; } } if (isset($p['cpu']) && $p['cpu'] === '') { // Configured CPUs is empty, unset the current one unset($p['cpu']); $modified = True; } else { if (isset($p['cpu']) && (int) $p['cpu'] <= 0) { // Configured CPUs is invalid, ignored error_log(date('M d H:i:s ') . 'WARNING: ' . $GLOBALS['messages'][40011]); } else { if (isset($p['cpu'])) { $this->cpu = (int) $p['cpu']; } } } if (isset($p['ram']) && $p['ram'] === '') { // RAM is empty, unset the current one unset($p['ram']); $modified = True; } else { if (isset($p['ram']) && (int) $p['ram'] <= 0) { // RAM is invalid, ignored error_log(date('M d H:i:s ') . 'WARNING: ' . $GLOBALS['messages'][40009]); } else { if (isset($p['ram'])) { $this->ram = (int) $p['ram']; } } } if (isset($p['ethernet']) && $p['ethernet'] === '') { // Ethernet interfaces is empty, unset the current one unset($p['ethernet']); $modified = True; } else { if (isset($p['ethernet']) && (int) $p['ethernet'] <= 0) { // Ethernet interfaces is invalid, ignored error_log(date('M d H:i:s ') . 'WARNING: ' . $GLOBALS['messages'][40012]); } else { if (isset($p['ethernet']) && $this->ethernet != (int) $p['ethernet']) { // New Ethernet value $this->ethernet = (int) $p['ethernet']; $modified = True; } } } if (isset($p['uuid']) && $p['uuid'] === '') { // UUID is empty, unset the current one unset($this->uuid); $modified = True; } else { if (isset($p['uuid']) && !checkUuid($p['uuid'])) { // UUID is not valid, ignored error_log(date('M d H:i:s ') . 'WARNING: ' . $GLOBALS['messages'][40026]); } else { if (isset($p['uuid'])) { $this->uuid = $p['uuid']; $modified = True; } } } } if ($this->type == 'docker') { if (isset($p['ram']) && $p['ram'] === '') { // RAM is empty, unset the current one unset($p['ram']); $modified = True; } else { if (isset($p['ram']) && (int) $p['ram'] <= 0) { // RAM is invalid, ignored error_log(date('M d H:i:s ') . 'WARNING: ' . $GLOBALS['messages'][40009]); } else { if (isset($p['ram'])) { $this->ram = (int) $p['ram']; } } } if (isset($p['ethernet']) && $p['ethernet'] === '') { // Ethernet interfaces is empty, unset the current one unset($p['ethernet']); $modified = True; } else { if (isset($p['ethernet']) && (int) $p['ethernet'] <= 0) { // Ethernet interfaces is invalid, ignored error_log(date('M d H:i:s ') . 'WARNING: ' . $GLOBALS['messages'][40012]); } else { if (isset($p['ethernet']) && $this->ethernet != (int) $p['ethernet']) { // New Ethernet value $this->ethernet = (int) $p['ethernet']; $modified = True; } } } } if ($modified) { // At least an attribute is changed // Set interface name if (isset($p['ethernet'])) { $this->setEthernets(); } if (isset($p['serial']) && $this->type == 'iol') { $this->setSerials(); } return 0; } else { // No attribute has been changed error_log(date('M d H:i:s ') . 'ERROR: ' . $GLOBALS['messages'][40016]); return 40016; } }
/** * Constructor which load an existent lab or create an empty one. * * @param string $f the file of the lab with full path * @param int $tenant Tenant ID * @return void */ public function __construct($f, $tenant) { $modified = False; if (!is_file($f)) { // File does not exist, create a new empty lab $this->filename = basename($f); $this->path = dirname($f); $this->tenant = (int) $tenant; if (!checkLabFilename($this->filename)) { // Invalid filename error_log('ERROR: ' . $f . ' ' . $GLOBALS['messages'][20001]); throw new Exception('20001'); } if (!checkLabPath($this->path)) { // Invalid path error_log('ERROR: ' . $f . ' ' . $GLOBALS['messages'][20002]); throw new Exception('20002'); } $this->name = substr(basename($f), 0, -4); $this->id = genUuid(); $modified = True; } else { // Load the existent lab $this->filename = basename($f); $this->path = dirname($f); $this->tenant = (int) $tenant; if (!checkLabFilename($this->filename)) { // Invalid filename error_log('ERROR: ' . $f . ' ' . $GLOBALS['messages'][20001]); throw new Exception('20001'); } if (!checkLabPath($this->path)) { // Invalid path error_log('ERROR: ' . $f . ' ' . $GLOBALS['messages'][20002]); throw new Exception('20002'); } libxml_use_internal_errors(true); $xml = simplexml_load_file($f); if (!$xml) { // Invalid XML document error_log('ERROR: ' . $f . ' ' . $GLOBALS['messages'][20003]); throw new Exception('20003'); } // Lab name $result = $xml->xpath('//lab/@name'); if (empty($result)) { // Invalid UNetLab file (attribute is missing) error_log('ERROR: ' . $f . ' ' . $GLOBALS['messages'][20004]); throw new Exception('20004'); return; } else { if (!checkLabName($result[0])) { // Attribute not valid error_log('ERROR: ' . $f . ' ' . $GLOBALS['messages'][20005]); throw new Exception('20005'); return; } else { $this->name = (string) $result[0]; } } // Lab ID $result = $xml->xpath('//lab/@id'); if (empty($result)) { // Lab ID not set, create a new one $this->id = genUuid(); error_log('WARNING: ' . $f . ' ' . $GLOBALS['messages'][20011]); $modified = True; } else { if (!checkUuid($result[0])) { // Attribute not valid $this->id = genUuid(); error_log('WARNING: ' . $f . ' ' . $GLOBALS['messages'][20012]); $modified = True; } else { $this->id = (string) $result[0]; } } // Lab description $result = (string) array_pop($xml->xpath('//lab/description')); if (strlen($result) !== 0) { $this->description = htmlspecialchars($result, ENT_DISALLOWED, 'UTF-8', TRUE); } else { if (strlen($result) !== 0) { error_log('WARNING: ' . $f . ' ' . $GLOBALS['messages'][20006]); } } // Lab author $result = (string) array_pop($xml->xpath('//lab/@author')); if (strlen($result) !== 0) { $this->author = htmlspecialchars($result, ENT_DISALLOWED, 'UTF-8', TRUE); } else { if (strlen($result) !== 0) { error_log('WARNING: ' . $f . ' ' . $GLOBALS['messages'][20007]); } } // Lab version $result = (string) array_pop($xml->xpath('//lab/@version')); if (strlen($result) !== 0 && (int) $result >= 0) { $this->version = $result; } else { if (strlen($result) !== 0) { error_log('WARNING: ' . $f . ' ' . $GLOBALS['messages'][20008]); } } // Lab networks foreach ($xml->xpath('//lab/topology/networks/network') as $network) { $w = array(); if (isset($network->attributes()->id)) { $w['id'] = (string) $network->attributes()->id; } if (isset($network->attributes()->left)) { $w['left'] = (string) $network->attributes()->left; } if (isset($network->attributes()->name)) { $w['name'] = (string) $network->attributes()->name; } if (isset($network->attributes()->top)) { $w['top'] = (string) $network->attributes()->top; } if (isset($network->attributes()->type)) { $w['type'] = (string) $network->attributes()->type; } try { $this->networks[$w['id']] = new Network($w, $w['id'], $this->tenant); } catch (Exception $e) { // Invalid network error_log('WARNING: ' . $f . ':net' . $w['id'] . ' ' . $GLOBALS['messages'][20009]); error_log((string) $e); continue; } } // Lab nodes (networks must be alredy loaded) foreach ($xml->xpath('//lab/topology/nodes/node') as $node_id => $node) { $n = array(); if (isset($node->attributes()->config)) { $n['config'] = (string) $node->attributes()->config; } if (isset($node->attributes()->console)) { $n['console'] = (string) $node->attributes()->console; } if (isset($node->attributes()->cpu)) { $n['cpu'] = (int) $node->attributes()->cpu; } if (isset($node->attributes()->delay)) { $n['delay'] = (string) $node->attributes()->delay; } if (isset($node->attributes()->ethernet)) { $n['ethernet'] = (int) $node->attributes()->ethernet; } if (isset($node->attributes()->icon)) { $n['icon'] = (string) $node->attributes()->icon; } if (isset($node->attributes()->id)) { $n['id'] = (int) $node->attributes()->id; } if (isset($node->attributes()->idlepc)) { $n['idlepc'] = (string) $node->attributes()->idlepc; } if (isset($node->attributes()->image)) { $n['image'] = (string) $node->attributes()->image; } if (isset($node->attributes()->left)) { $n['left'] = (string) $node->attributes()->left; } if (isset($node->attributes()->name)) { $n['name'] = (string) $node->attributes()->name; } if (isset($node->attributes()->nvram)) { $n['nvram'] = (int) $node->attributes()->nvram; } if (isset($node->attributes()->ram)) { $n['ram'] = (int) $node->attributes()->ram; } if (isset($node->attributes()->serial)) { $n['serial'] = (int) $node->attributes()->serial; } if (isset($node->attributes()->template)) { $n['template'] = (string) $node->attributes()->template; } if (isset($node->attributes()->top)) { $n['top'] = (string) $node->attributes()->top; } if (isset($node->attributes()->type)) { $n['type'] = (string) $node->attributes()->type; } if (isset($node->attributes()->uuid)) { $n['uuid'] = (string) $node->attributes()->uuid; } try { $this->nodes[$n['id']] = new Node($n, $n['id'], $this->tenant, $this->id); } catch (Exception $e) { // Invalid node error_log('WARNING: ' . $f . ':node' . $n['id'] . ' ' . $GLOBALS['messages'][20010]); error_log((string) $e); continue; } // Slot must be loaded before interfaces foreach ($node->slot as $slot) { // Loading configured slots for this node $s = array(); if (isset($slot->attributes()->id)) { $s['id'] = (string) $slot->attributes()->id; } if (isset($slot->attributes()->module)) { $s['module'] = (string) $slot->attributes()->module; } if ($this->nodes[$n['id']]->setSlot($s['id'], $s['module']) !== 0) { error_log('WARNING: ' . $f . ':node' . $n['id'] . ':slot' . $s['id'] . ' ' . $GLOBALS['messages'][20013]); } } foreach ($node->interface as $interface) { // Loading configured interfaces for this node $i = array(); if (isset($interface->attributes()->id)) { $i['id'] = (string) $interface->attributes()->id; } if (isset($interface->attributes()->network_id)) { $i['network_id'] = (string) $interface->attributes()->network_id; } if (isset($interface->attributes()->remote_id)) { $i['remote_id'] = (string) $interface->attributes()->remote_id; } if (isset($interface->attributes()->remote_if)) { $i['remote_if'] = (string) $interface->attributes()->remote_if; } if (isset($interface->attributes()->remote_host)) { $i['remote_host'] = (string) $interface->attributes()->remote_host; } if (isset($interface->attributes()->type)) { $i['type'] = (string) $interface->attributes()->type; } switch ($i['type']) { default: error_log('WARNING: ' . $f . ':node' . $n['id'] . ':inv' . $s['id'] . ' ' . $GLOBALS['messages'][20016]); break; case 'ethernet': if ($this->nodes[$n['id']]->linkInterface($i) !== 0) { error_log('WARNING: ' . $f . ':node' . $n['id'] . ':eth' . $i['id'] . ' ' . $GLOBALS['messages'][20014]); } break; case 'serial': // Serial if ($this->nodes[$n['id']]->linkInterface($i) !== 0) { error_log('WARNING: ' . $f . ':node' . $n['id'] . ':ser' . $i['id'] . ' ' . $GLOBALS['messages'][20015]); } break; } } } // startup-config foreach ($xml->xpath('//lab/objects/configs/config') as $config) { $node_id = 0; $config_data = ''; if (isset($config->attributes()->id)) { $node_id = (string) $config->attributes()->id; } $result = (string) array_pop($config->xpath('.')); if (strlen($result) > 0) { $config_data = base64_decode($result); } $rc = $this->nodes[$node_id]->setConfigData($config_data); if ($rc != 0) { error_log('WARNING: ' . $f . ':cfg' . $node_id . ' ' . $GLOBALS['messages'][20037]); continue; } } // Lab Pictures foreach ($xml->xpath('//lab/objects/pictures/picture') as $picture) { $p = array(); if (isset($picture->attributes()->id)) { $p['id'] = (string) $picture->attributes()->id; } if (isset($picture->attributes()->name)) { $p['name'] = (string) $picture->attributes()->name; } if (isset($picture->attributes()->type)) { $p['type'] = (string) $picture->attributes()->type; } $result = (string) array_pop($picture->xpath('./data')); if (strlen($result) > 0) { $p['data'] = base64_decode($result); } $result = (string) array_pop($picture->xpath('./map')); if (strlen($result) > 0) { $p['map'] = html_entity_decode($result); } try { $this->pictures[$p['id']] = new Picture($p, $p['id']); } catch (Exception $e) { // Invalid picture error_log('WARNING: ' . $f . ':pic' . $p['id'] . ' ' . $GLOBALS['messages'][20020]); error_log((string) $e); continue; } } // Update attached network count $this->setNetworkCount(); } if ($modified) { // Need to save $rc = $this->save(); if ($rc != 0) { throw new Exception($rc); return $rc; } } return 0; }
/** * Constructor which load an existent lab or create an empty one. * * @param string $f the file of the lab with full path * @param int $tenant Tenant ID * @return void */ public function __construct($f, $tenant) { $modified = False; if (!is_file($f)) { // File does not exist, create a new empty lab $this->filename = basename($f); $this->path = dirname($f); $this->tenant = (int) $tenant; if (!checkLabFilename($this->filename)) { // Invalid filename error_log(date('M d H:i:s ') . 'ERROR: ' . $f . ' ' . $GLOBALS['messages'][20001]); throw new Exception('20001'); } if (!checkLabPath($this->path)) { // Invalid path error_log(date('M d H:i:s ') . 'ERROR: ' . $f . ' ' . $GLOBALS['messages'][20002]); throw new Exception('20002'); } $this->name = substr(basename($f), 0, -4); $this->id = genUuid(); $modified = True; $this->scripttimeout = 600; } else { // Load the existent lab $this->filename = basename($f); $this->path = dirname($f); $this->tenant = (int) $tenant; if (!checkLabFilename($this->filename)) { // Invalid filename error_log(date('M d H:i:s ') . 'ERROR: ' . $f . ' ' . $GLOBALS['messages'][20001]); throw new Exception('20001'); } if (!checkLabPath($this->path)) { // Invalid path error_log(date('M d H:i:s ') . 'ERROR: ' . $f . ' ' . $GLOBALS['messages'][20002]); throw new Exception('20002'); } libxml_use_internal_errors(true); $xml = simplexml_load_file($f); if (!$xml) { // Invalid XML document error_log(date('M d H:i:s ') . 'ERROR: ' . $f . ' ' . $GLOBALS['messages'][20003]); throw new Exception('20003'); } // Lab name $patterns[0] = '/\\.unl$/'; $replacements[0] = ''; $this->name = preg_replace($patterns, $replacements, basename($f)); // Lab ID $result = $xml->xpath('//lab/@id'); if (empty($result)) { // Lab ID not set, create a new one $this->id = genUuid(); error_log(date('M d H:i:s ') . 'WARNING: ' . $f . ' ' . $GLOBALS['messages'][20011]); $modified = True; } else { if (!checkUuid($result[0])) { // Attribute not valid $this->id = genUuid(); error_log(date('M d H:i:s ') . 'WARNING: ' . $f . ' ' . $GLOBALS['messages'][20012]); $modified = True; } else { $this->id = (string) $result[0]; } } // Lab description $result = (string) array_pop($xml->xpath('//lab/description')); if (strlen($result) !== 0) { $this->description = htmlspecialchars($result, ENT_DISALLOWED, 'UTF-8', TRUE); } else { if (strlen($result) !== 0) { error_log(date('M d H:i:s ') . 'WARNING: ' . $f . ' ' . $GLOBALS['messages'][20006]); } } // Lab body $result = (string) array_pop($xml->xpath('//lab/body')); if (strlen($result) !== 0) { $this->body = htmlspecialchars($result, ENT_DISALLOWED, 'UTF-8', TRUE); } else { if (strlen($result) !== 0) { error_log(date('M d H:i:s ') . 'WARNING: ' . $f . ' ' . $GLOBALS['messages'][20006]); } } // Lab author $result = (string) array_pop($xml->xpath('//lab/@author')); if (strlen($result) !== 0) { $this->author = htmlspecialchars($result, ENT_DISALLOWED, 'UTF-8', TRUE); } else { if (strlen($result) !== 0) { error_log(date('M d H:i:s ') . 'WARNING: ' . $f . ' ' . $GLOBALS['messages'][20007]); } } // Lab version $result = (string) array_pop($xml->xpath('//lab/@version')); if (strlen($result) !== 0 && (int) $result >= 0) { $this->version = $result; } else { if (strlen($result) !== 0) { error_log(date('M d H:i:s ') . 'WARNING: ' . $f . ' ' . $GLOBALS['messages'][20008]); } } // Lab networks foreach ($xml->xpath('//lab/topology/networks/network') as $network) { $w = array(); if (isset($network->attributes()->id)) { $w['id'] = (string) $network->attributes()->id; } if (isset($network->attributes()->left)) { $w['left'] = (string) $network->attributes()->left; } if (isset($network->attributes()->name)) { $w['name'] = (string) $network->attributes()->name; } if (isset($network->attributes()->top)) { $w['top'] = (string) $network->attributes()->top; } if (isset($network->attributes()->type)) { $w['type'] = (string) $network->attributes()->type; } try { $this->networks[$w['id']] = new Network($w, $w['id'], $this->tenant); } catch (Exception $e) { // Invalid network error_log(date('M d H:i:s ') . 'WARNING: ' . $f . ':net' . $w['id'] . ' ' . $GLOBALS['messages'][20009]); error_log(date('M d H:i:s ') . (string) $e); continue; } } // Lab nodes (networks must be alredy loaded) foreach ($xml->xpath('//lab/topology/nodes/node') as $node_id => $node) { $n = array(); if (isset($node->attributes()->config)) { $n['config'] = (string) $node->attributes()->config; } if (isset($node->attributes()->console)) { $n['console'] = (string) $node->attributes()->console; } if (isset($node->attributes()->cpu)) { $n['cpu'] = (int) $node->attributes()->cpu; } if (isset($node->attributes()->delay)) { $n['delay'] = (string) $node->attributes()->delay; } if (isset($node->attributes()->ethernet)) { $n['ethernet'] = (int) $node->attributes()->ethernet; } if (isset($node->attributes()->icon)) { $n['icon'] = (string) $node->attributes()->icon; } if (isset($node->attributes()->id)) { $n['id'] = (int) $node->attributes()->id; } if (isset($node->attributes()->idlepc)) { $n['idlepc'] = (string) $node->attributes()->idlepc; } if (isset($node->attributes()->image)) { $n['image'] = (string) $node->attributes()->image; } if (isset($node->attributes()->left)) { $n['left'] = (string) $node->attributes()->left; } if (isset($node->attributes()->name)) { $n['name'] = (string) $node->attributes()->name; } if (isset($node->attributes()->nvram)) { $n['nvram'] = (int) $node->attributes()->nvram; } if (isset($node->attributes()->ram)) { $n['ram'] = (int) $node->attributes()->ram; } if (isset($node->attributes()->serial)) { $n['serial'] = (int) $node->attributes()->serial; } if (isset($node->attributes()->template)) { $n['template'] = (string) $node->attributes()->template; } if (isset($node->attributes()->top)) { $n['top'] = (string) $node->attributes()->top; } if (isset($node->attributes()->type)) { $n['type'] = (string) $node->attributes()->type; } if (isset($node->attributes()->uuid)) { $n['uuid'] = (string) $node->attributes()->uuid; } $n['config'] == 'Exported' ? $n['config'] = '1' : $n['config']; // Fix startup-config $n['config'] == 'None' ? $n['config'] = '0' : $n['config']; // Fix startup-config // If config is empty, force "None" $result = (string) array_pop($xml->xpath('//lab/objects/configs/config[@id="' . $n['id'] . '"]')); if (strlen($result) == 0) { $n['config'] = 0; $config_data = False; } else { $config_data = base64_decode($result); } // F5 needs a first mac address if ($n['template'] == "bigip") { if (isset($node->attributes()->firstmac)) { $n['firstmac'] = (string) $node->attributes()->firstmac; } else { $n['firstmac'] = (string) '00:' . sprintf('%02x', $this->tenant) . ':' . sprintf('%02x', $this->id / 512) . ':' . sprintf('%02x', $this->id % 512) . ':00:10'; } } try { $this->nodes[$n['id']] = new Node($n, $n['id'], $this->tenant, $this->id); } catch (Exception $e) { // Invalid node error_log(date('M d H:i:s ') . 'WARNING: ' . $f . ':node' . $n['id'] . ' ' . $GLOBALS['messages'][20010]); error_log(date('M d H:i:s ') . (string) $e); continue; } // Slot must be loaded before interfaces foreach ($node->slot as $slot) { // Loading configured slots for this node $s = array(); if (isset($slot->attributes()->id)) { $s['id'] = (string) $slot->attributes()->id; } if (isset($slot->attributes()->module)) { $s['module'] = (string) $slot->attributes()->module; } if ($this->nodes[$n['id']]->setSlot($s['id'], $s['module']) !== 0) { error_log(date('M d H:i:s ') . 'WARNING: ' . $f . ':node' . $n['id'] . ':slot' . $s['id'] . ' ' . $GLOBALS['messages'][20013]); } } foreach ($node->interface as $interface) { // Loading configured interfaces for this node $i = array(); if (isset($interface->attributes()->id)) { $i['id'] = (string) $interface->attributes()->id; } if (isset($interface->attributes()->network_id)) { $i['network_id'] = (string) $interface->attributes()->network_id; } if (isset($interface->attributes()->remote_id)) { $i['remote_id'] = (string) $interface->attributes()->remote_id; } if (isset($interface->attributes()->remote_if)) { $i['remote_if'] = (string) $interface->attributes()->remote_if; } if (isset($interface->attributes()->remote_host)) { $i['remote_host'] = (string) $interface->attributes()->remote_host; } if (isset($interface->attributes()->type)) { $i['type'] = (string) $interface->attributes()->type; } switch ($i['type']) { default: error_log(date('M d H:i:s ') . 'WARNING: ' . $f . ':node' . $n['id'] . ':inv' . $s['id'] . ' ' . $GLOBALS['messages'][20016]); break; case 'ethernet': if ($this->nodes[$n['id']]->linkInterface($i) !== 0) { error_log(date('M d H:i:s ') . 'WARNING: ' . $f . ':node' . $n['id'] . ':eth' . $i['id'] . ' ' . $GLOBALS['messages'][20014]); } break; case 'serial': // Serial if ($this->nodes[$n['id']]->linkInterface($i) !== 0) { error_log(date('M d H:i:s ') . 'WARNING: ' . $f . ':node' . $n['id'] . ':ser' . $i['id'] . ' ' . $GLOBALS['messages'][20015]); } break; } } // startup-config (read before) if ($config_data !== False) { $rc = $this->nodes[$n['id']]->setConfigData($config_data); if ($rc != 0) { error_log(date('M d H:i:s ') . 'WARNING: ' . $f . ':cfg' . $node_id . ' ' . $GLOBALS['messages'][20037]); } } } // lab script timeout $result = (string) array_pop($xml->xpath('//lab/@scripttimeout')); if (strlen($result) !== 0 && (int) $result >= 300) { $this->scripttimeout = $result; } else { if (strlen($result) !== 0) { error_log(date('M d H:i:s ') . 'WARNING: ' . $f . ' ' . $GLOBALS['messages'][20045]); $this->scripttimeout = 300; } } // Lab Pictures foreach ($xml->xpath('//lab/objects/pictures/picture') as $picture) { $p = array(); if (isset($picture->attributes()->id)) { $p['id'] = (string) $picture->attributes()->id; } if (isset($picture->attributes()->name)) { $p['name'] = (string) $picture->attributes()->name; } if (isset($picture->attributes()->type)) { $p['type'] = (string) $picture->attributes()->type; } $result = (string) array_pop($picture->xpath('./data')); if (strlen($result) > 0) { $p['data'] = base64_decode($result); } $result = (string) array_pop($picture->xpath('./map')); if (strlen($result) > 0) { $p['map'] = html_entity_decode($result); } try { $this->pictures[$p['id']] = new Picture($p, $p['id']); } catch (Exception $e) { // Invalid picture error_log(date('M d H:i:s ') . 'WARNING: ' . $f . ':pic' . $p['id'] . ' ' . $GLOBALS['messages'][20020]); error_log(date('M d H:i:s ') . (string) $e); continue; } } // Text Objects foreach ($xml->xpath('//lab/objects/textobjects/textobject') as $textobject) { $p = array(); if (isset($textobject->attributes()->id)) { $p['id'] = (string) $textobject->attributes()->id; } if (isset($textobject->attributes()->name)) { $p['name'] = (string) $textobject->attributes()->name; } if (isset($textobject->attributes()->type)) { $p['type'] = (string) $textobject->attributes()->type; } $result = (string) array_pop($textobject->xpath('./data')); if (strlen($result) > 0) { $p['data'] = $result; } try { $this->textobjects[$p['id']] = new TextObject($p, $p['id']); } catch (Exception $e) { // Invalid picture error_log(date('M d H:i:s ') . 'WARNING: ' . $f . ':obj' . $p['id'] . ' ' . $GLOBALS['messages'][20041]); error_log(date('M d H:i:s ') . (string) $e); continue; } } // Update attached network count $this->setNetworkCount(); } if ($modified) { // Need to save $rc = $this->save(); if ($rc != 0) { throw new Exception($rc); return $rc; } } return 0; }