<?php
//
// Device Type Flags (devices.type_code)
//
define('CSD_TYPE_CISCO', 1);
define('CSD_TYPE_ALTEONWEB', 2);
define('CSD_TYPE_ALTEONAPP', 3);
$CSD_TYPES = array(
CSD_TYPE_CISCO => 'Cisco IOS-based Device',
CSD_TYPE_ALTEONWEB => 'Nortel Alteon - Web Switch',
CSD_TYPE_ALTEONAPP => 'Nortel Alteon - Application Switch'
);
//
// Device State Flags (devices.state_code)
//
define('CSD_STATE_UNCHK', 1);
define('CSD_STATE_DISABLED', 2);
define('CSD_STATE_INIT', 3);
define('CSD_STATE_CHG', 4);
define('CSD_STATE_UNCHG', 5);
define('CSD_STATE_FAIL', 6);
define('CSD_STATE_SYSERR', 7);
define('CSD_STATE_ARCHIVED', 8);
$CSD_STATES = array(
CSD_STATE_UNCHK => 'Unchecked',
CSD_STATE_DISABLED => 'Disabled',
CSD_STATE_INIT => 'Transfer OK, initial configuration saved',
CSD_STATE_CHG => 'Transfer OK, new configuration saved',
CSD_STATE_UNCHG => 'Transfer OK, no changes detected',
CSD_STATE_FAIL => 'Transfer failed',
CSD_STATE_SYSERR => 'A system error occured',
CSD_STATE_ARCHIVED => 'Archived'
);
$CSD_STATE_ICONS = array(
CSD_STATE_UNCHK => 'device_act',
CSD_STATE_DISABLED => 'device_inact',
CSD_STATE_INIT => 'device_act',
CSD_STATE_CHG => 'device_act',
CSD_STATE_UNCHG => 'device_act',
CSD_STATE_FAIL => 'alert',
CSD_STATE_SYSERR => 'alert',
CSD_STATE_ARCHIVED => 'device_inact'
);
//
// SNMP V3 Auth Protocols (devices.v3_auth)
//
define('CSD_V3AUTH_NONE', 0);
define('CSD_V3AUTH_MD5', 1);
define('CSD_V3AUTH_SHA', 2);
$CSD_V3AUTHS = array(
CSD_V3AUTH_NONE => 'Plain text',
CSD_V3AUTH_MD5 => 'MD5 Message Digest',
CSD_V3AUTH_SHA => 'SHA-1 Message Digest'
);
//
// SNMP V3 Privacy Types (devices.v3_priv)
//
define('CSD_V3PRIV_NONE', 0);
define('CSD_V3PRIV_DES', 1);
define('CSD_V3PRIV_AES', 2);
define('CSD_V3PRIV_3DES', 3);
$CSD_V3PRIVS = array(
CSD_V3PRIV_NONE => 'Unencrypted',
CSD_V3PRIV_DES => 'DES-56 Encryption',
CSD_V3PRIV_AES => 'AES-128 Encryption',
CSD_V3PRIV_3DES => '3DES-168 Encryption'
);
//
// Search - Boolean Logic
//
define('CSS_BOOL_LIKE', 1);
define('CSS_BOOL_NOTLIKE', 2);
$CSS_LOGIC = array(
CSS_BOOL_LIKE => 'is like',
CSS_BOOL_NOTLIKE => 'is not like'
);
$CSS_QUERY = array(
CSS_BOOL_LIKE => 'LIKE',
CSS_BOOL_NOTLIKE => 'NOT LIKE'
);
class CSDevice
{
private $rec; // Our device record
private $revisions; // Our revisions array
// Constructor
// Initialises this CSDevice object
//
public function __construct($id)
{
global $CS;
if (empty($id))
throw new Exception('CSDevice: invalid device identifier');
$this->rec = $CS->getDb()->GetOneRecord('SELECT * FROM `devices` WHERE `device_id` = ?', $id);
if (!$this->rec)
throw new Exception('Cannot find device');
$this->revisions = null;
}
public function __destruct() { }
public function __get($field)
{
if (array_key_exists($field, $this->rec))
return $this->rec[$field];
return null;
}
public function __set($field, $value)
{
// If the value exists in the db record, update it
if (array_key_exists($field, $this->rec))
{
global $CS;
$CS->getDb()->UpdateRecord('UPDATE `devices` SET `'.$field.'` = ? WHERE `device_id` = ?',
array($value, $this->rec['device_id']));
$this->rec[$field] = $value;
return true;
}
return false;
}
// GetVersion()
// Returns the Version tag from sysDescr, or the full sysDescr if not found.
//
public function GetVersion()
{
$s = $this->sys_descr;
if (empty($s))
return 'Unknown';
$i = stripos($s, 'Version');
if ($i)
{
$j = stripos($s, ',', $i);
if ($j)
return substr($s, $i, ($j - $i));
}
// Default to the full string
return $this->sys_descr;
}
// LoadRevisionArray()
// Generates an array containing all revision information about thie device, but
// does not actually interpret any configuration.
//
// Used to generate the HTML output for Device View.
//
public function LoadRevisionArray()
{
global $CS;
try {
$res = $CS->getDb()->GetRecords('SELECT `revision_id`,`device_id`,`revision`,`created`,LENGTH(`data`) AS "approx_size" '.
'FROM `revisions` WHERE `device_id` = ? ORDER BY `revision` DESC', $this->device_id);
// Create revision list if it's null
if (is_null($this->revisions))
$this->revisions = array();
foreach($res as $rec)
$this->revisions[] = new CSConfig($rec, $this);
}
catch (Exception $e) {
throw new Exception('Cannot load device revisions: '.$e->getMessage());
}
}
public function GetRevisionArray() { return $this->revisions; }
// GetRevisionHistory()
// Traverse the revisions array and return an array of formatted text
// to enter into a HTML table. The caller must not need to do any formatting.
//
public function GetRevisionHistory()
{
if (!is_array($this->revisions))
throw new Exception('CSDevice::GetRevisionHistory(): the revision array is not valid!'); // Could just load it?
$rows = array();
foreach($this->revisions as $i => $rev)
{
if (array_key_exists($i + 1, $this->revisions)) {
$compare = '<a href="Compare.php?from='.$this->revisions[$i + 1]->revision_id.
'&to='.$rev->revision_id.'">Compare to r'.$this->revisions[$i + 1]->revision.'</a>';
} else {
$compare = 'Initial Revision';
}
$rows[] = array(
$rev->revision.' (<a href="Download.php?revision_id='.$rev->revision_id.'">download</a>)',
$rev->created,
$rev->approx_size,
$compare
);
}
//
// If we have no revisions loaded, add a dummy row so the user knows
// there are no revisions...
//
if (count($rows) == 0)
$rows[] = array('None', '', '', '');
return $rows;
}
// GetRevisionCount()
// Returns how many config revisions this device has.
//
public function GetRevisionCount()
{
global $CS;
// If the revision list is already loaded, we may as well just count that!
if (!is_null($this->revisions))
return count($this->revisions);
try {
$res = $CS->getDb()->GetRecords('SELECT COUNT(*) AS "revision_count" FROM `revisions` '.
'WHERE `device_id` = ?', $this->device_id);
} catch (Exception $e) {
throw new Exception('Cannot get revision count: '.$e->getMessage());
}
return $res['revision_count'];
}
// GetGroupById()
// Queries database for group_id specified and builds an array from the data received
// Call with includeDevices=FALSE to emit the device array from this node and any children
//
// Returned array contains:
// name - human-readable name of the group
// group_id - the group_id provided
// children - Array of child nodes (recursive!)
// devices - Array of deviceId => deviceHostname array pairs
//
public static function GetGroupById($id, $includeDevices=TRUE, $viewArchive=FALSE)
{
global $CS;
// Group entry for this parent_id
$parent_rec = $CS->getDb()->GetOneRecord('SELECT `group_id`,`name` FROM `groups` WHERE `group_id` = ?', $id);
// Build a node for group
$group = array(
'name' => $parent_rec['name'],
'group_id' => $parent_rec['group_id'],
'children' => array(),
'devices' => null
);
// Now we want all children that belong to this node.
$res = $CS->getDb()->GetRecords('SELECT `group_id` FROM `groups` WHERE `parent_id` = ? ORDER BY `name` ASC', $id);
foreach ($res as $child_rec)
{
$group['children'][] = CSDevice::GetGroupById($child_rec['group_id'], $includeDevices, $viewArchive);
}
// Finally, we load all devices associated with this group
if ($includeDevices)
{
$group['devices'] = $CS->getDb()->GetRecords('SELECT `device_id`,`hostname`,`state_code` '.
'FROM `devices` WHERE `group_id` = ? AND `state_code` '.($viewArchive ? '=' : '!=').' '.CSD_STATE_ARCHIVED.' '.
'ORDER BY `hostname` ASC', $id);
}
return $group;
}
// LoadGroupNode()
// Takes an Array prepared by GetGroupById() and adds nodes to the tree
//
public static function LoadGroupNode(CSTreeView &$tree, $parentId, Array $node, $showEmptyNodes=FALSE)
{
global $CSD_STATE_ICONS;
if (empty($parentId))
throw new Exception('CSDevice::LoadGroupName() called without parentId');
//
// See if we can trim any nodes before we begin. A node can be trimmed if
// it has no devices and no child nodes.
//
if (!$showEmptyNodes)
{
if (count($node['devices']) == 0 && count($node['children']) == 0)
return;
}
//
// First build a new node onto the tree
//
$thisNodeId = $tree->AddNode($parentId, array(
'label' => $node['name'],
'icon' => 'folder',
'group_id' => $node['group_id']
));
//
// Now process this nodes children, but parent is thisNodeId
//
foreach($node['children'] as $child)
CSDevice::LoadGroupNode($tree, $thisNodeId, $child, $showEmptyNodes);
//
// Now process this nodes devices...
//
if (is_array($node['devices']))
{
foreach($node['devices'] as $device)
{
$tree->AddNode($thisNodeId, array(
'label' => $device['hostname'],
'href' => 'View.php?device_id='.$device['device_id'],
'target' => 'MainFrame',
'icon' => $CSD_STATE_ICONS[$device['state_code']],
'expand' => FALSE
));
}
}
}
// GetGroupMenuList()
// Returns an array of groups that can be used to populate a CSFormControl
// Call with skipLevelZero=TRUE to stop top-level being added to the list
//
public static function GetGroupMenuList(Array $rootNode, $nodeLevel=0, $skipLevelZero=FALSE)
{
$groupList = array();
// GetGroupById(0) will return a node with no group_id or name, which is top-level
// So, we need to catch it here to avoid blindly adding to the list
//
if (!empty($rootNode['group_id']))
{
if (array_key_exists($rootNode['group_id'], $groupList))
throw new Exception('CSDevice::GetGroupMenuList() with duplicate group nodes');
$groupList[$rootNode['group_id']] = str_repeat('-', $nodeLevel).' '.$rootNode['name'];
}
else if (!$skipLevelZero)
{
if ($nodeLevel != 0)
throw new Exception('CSDevice::GetGroupMenuList() at top-level node but nodeLevel is not zero!');
$groupList[0] = 'Top Level';
}
$nodeLevel++;
foreach($rootNode['children'] as $childNode)
{
// Add the list of child nodes...
$groupList = $groupList + CSDevice::GetGroupMenuList($childNode, $nodeLevel, $skipLevelZero);
}
return $groupList;
}
}
?>