diff --git a/application/classes/controller/domain.php b/application/classes/controller/domain.php new file mode 100644 index 0000000..5cca653 --- /dev/null +++ b/application/classes/controller/domain.php @@ -0,0 +1,78 @@ +%s domains.'),$do->count_all()); + $output .= '
'; + $output .= '
'; + + $select = array(); + $select[NULL] = ''; + + foreach ($do->find_all() as $domain) + $select[$domain->DOMAIN_NAME] = $domain->DOMAIN_NAME; + + $output .= Form::open('/domain/detail',array('id'=>'domain_detail')); + $output .= sprintf('%s: %s',_('Choose a domain to view'),Form::select('domain_name',$select,NULL,array('id'=>'domain_name'))); + $output .= Form::submit('form_submit',_('Go')); + $output .= Form::close(); + + Script::add(array( + 'type'=>'stdin', + 'data'=>' +$(document).ready(function () {$("#domain_name").change(function () { + $("#domain_name").trigger("submit"); + });});' + )); + + Block::add(array( + 'title'=>_('TSM Domains'), + 'body'=>$output, + )); + } + + public function action_detail($domain_name=NULL) { + if (is_null($domain_name) AND (empty($_POST['domain_name']) OR ! $domain_name = $_POST['domain_name'])) { + SystemMessage::add(array( + 'title'=>_('DOMAIN_NAME is required'), + 'type'=>'error', + 'body'=>_('The domain name is required.'), + )); + + Request::current()->redirect('domain'); + } + + $do = ORM::factory('domain',$domain_name); + if (! $do->loaded()) { + SystemMessage::add(array( + 'title'=>_('Unknown DOMAIN_NAME'), + 'type'=>'error', + 'body'=>sprintf(_('The domain [%s] does not exist?.'),$domain_name), + )); + + Request::current()->redirect('domain'); + } + + Block::add(array( + 'title'=>sprintf(_('Node Information for Domain %s'),$do->DOMAIN_NAME), + 'body'=>View::factory('domain/detail')->set('do',$do) + )); + } +} +?> diff --git a/application/classes/controller/node.php b/application/classes/controller/node.php index 77386ce..b84df33 100644 --- a/application/classes/controller/node.php +++ b/application/classes/controller/node.php @@ -29,7 +29,7 @@ class Controller_NODE extends Controller_TemplateDefault { $select[$node->NODE_NAME] = $node->NODE_NAME; $output .= Form::open('/node/detail',array('id'=>'node_detail')); - $output .= sprintf('%s: %s',_('Choose a new to view'),Form::select('node_name',$select,NULL,array('id'=>'node_name'))); + $output .= sprintf('%s: %s',_('Choose a node to view'),Form::select('node_name',$select,NULL,array('id'=>'node_name'))); $output .= Form::submit('form_submit',_('Go')); $output .= Form::close(); @@ -48,10 +48,26 @@ $(document).ready(function () {$("#node_name").change(function () { } public function action_detail($node_name=NULL) { - if (is_null($node_name) AND (empty($_POST['node_name']) OR ! $node_name = $_POST['node_name'])) - throw new Kohana_Exception('Missing NODE_NAME'); + if (is_null($node_name) AND (empty($_POST['node_name']) OR ! $node_name = $_POST['node_name'])) { + SystemMessage::add(array( + 'title'=>_('NODE_NAME is required'), + 'type'=>'error', + 'body'=>_('The node name is required.'), + )); + + Request::current()->redirect('node'); + } $no = ORM::factory('node',$node_name); + if (! $no->loaded()) { + SystemMessage::add(array( + 'title'=>_('Unknown NODE_NAME'), + 'type'=>'error', + 'body'=>sprintf(_('The node [%s] does not exist?.'),$node_name), + )); + + Request::current()->redirect('node'); + } Block::add(array( 'title'=>sprintf('%s %s',_('Detailed Node Information for'),$no->NODE_NAME), @@ -73,15 +89,5 @@ $(document).ready(function () {$("#node_name").change(function () { 'body'=>View::factory('nodes/detail_schedule')->set('node',$no), )); } - - public function action_summary() { - $do = ORM::factory('domain'); - - foreach ($do->find_all() as $domain) - Block::add(array( - 'title'=>_('Node Information by Domain'), - 'body'=>View::factory('nodes/summary')->set('do',$domain) - )); - } } ?> diff --git a/application/classes/controller/tree.php b/application/classes/controller/tree.php index d661c3d..8f45255 100644 --- a/application/classes/controller/tree.php +++ b/application/classes/controller/tree.php @@ -23,20 +23,20 @@ class Controller_Tree extends Controller_lnApp_Tree { */ public function action_json($id=null,array $data=array()) { // @todo Our menu options + array_push($data,array( + 'id'=>'domain', + 'name'=>'Domain Info', + 'state'=>'none', + 'attr_id'=>'1', + 'attr_href'=>URL::Site('domain'), + )); + array_push($data,array( 'id'=>'node', 'name'=>'Node Info', 'state'=>'none', 'attr_id'=>'1', - 'attr_href'=>URL::Site('/node'), - )); - - array_push($data,array( - 'id'=>'node_summary', - 'name'=>'Node Summary', - 'state'=>'none', - 'attr_id'=>'1', - 'attr_href'=>URL::Site('/node/summary'), + 'attr_href'=>URL::Site('node'), )); array_push($data,array( @@ -44,7 +44,7 @@ class Controller_Tree extends Controller_lnApp_Tree { 'name'=>'Server Activity Gantt', 'state'=>'none', 'attr_id'=>'1', - 'attr_href'=>URL::Site('/server/gantt'), + 'attr_href'=>URL::Site('server/gantt'), )); return parent::action_json($id,$data); diff --git a/application/classes/model/domain.php b/application/classes/model/domain.php index 37356bd..f245204 100644 --- a/application/classes/model/domain.php +++ b/application/classes/model/domain.php @@ -17,7 +17,9 @@ class Model_DOMAIN extends ORMTSM { ); protected $_has_many = array( + 'MGMTCLASS'=>array('foreign_key'=>'DOMAIN_NAME','far_key'=>'DOMAIN_NAME'), 'NODE'=>array('foreign_key'=>'DOMAIN_NAME','far_key'=>'DOMAIN_NAME'), + 'SCHEDULE_CLIENT'=>array('foreign_key'=>'DOMAIN_NAME','far_key'=>'DOMAIN_NAME') ); // Pools used by a domain. @@ -83,5 +85,17 @@ class Model_DOMAIN extends ORMTSM { return $count; } + + // $dtype is BACKUP or ARCHIVE + // $ptype is pool type (PRIMARY,ACTIVE,COPY) + public function getStorageModeNodes($dtype,$ptype,$spo='') { + $result = array(); + + foreach ($this->NODE->find_all() as $no) + if ($no->getStorageModeData($dtype,$ptype,$spo)) + array_push($result,$no); + + return $result; + } } ?> diff --git a/application/classes/model/node.php b/application/classes/model/node.php index 2bd0b1c..56f621c 100644 --- a/application/classes/model/node.php +++ b/application/classes/model/node.php @@ -16,6 +16,9 @@ class Model_NODE extends ORMTSM { 'NODE_NAME'=>'ASC', ); + protected $_has_one = array( + 'DOMAIN'=>array('foreign_key'=>'DOMAIN_NAME','far_key'=>'DOMAIN_NAME'), + ); protected $_has_many = array( 'FILESPACE'=>array('foreign_key'=>'NODE_NAME','far_key'=>'NODE_NAME'), 'VOLUMEUSAGE'=>array('foreign_key'=>'NODE_NAME','far_key'=>'NODE_NAME'), @@ -60,7 +63,14 @@ class Model_NODE extends ORMTSM { private $pools = array(); public function tsmclientversion() { - return sprintf('%s.%s.%s.%s',$this->CLIENT_VERSION,$this->CLIENT_RELEASE,$this->CLIENT_LEVEL,$this->CLIENT_SUBLEVEL); + if ($this->CLIENT_VERSION) + return sprintf('%s.%s.%s.%s',$this->CLIENT_VERSION,$this->CLIENT_RELEASE,$this->CLIENT_LEVEL,$this->CLIENT_SUBLEVEL); + else + return ''; + } + + public function platform() { + return sprintf('%s %s',$this->PLATFORM_NAME,$this->CLIENT_OS_LEVEL ? '('.$this->CLIENT_OS_LEVEL.')' : ''); } // @todo This needs to return the global configuration. @@ -133,6 +143,12 @@ class Model_NODE extends ORMTSM { return $this->pools[$dtype]; } + // Test to see if a node has any data of type + // $dtype is BACKUP (Bkup) or ARCHIVE (Arch) + public function hasData($dtype) { + return $this->getStoragePools($dtype) ? TRUE : FALSE; + } + public function getAllStoragePoolsType($ptype) { $result = array(); @@ -188,6 +204,7 @@ class Model_NODE extends ORMTSM { return $count; } + // $ptype is pool type (PRIMARY,ACTIVE,COPY) public function getStorageTypeFiles($ptype,$spo='') { $count = 0; @@ -210,6 +227,7 @@ class Model_NODE extends ORMTSM { return $count; } + // $ptype is pool type (PRIMARY,ACTIVE,COPY) public function getStorageTypeData($ptype,$spo='') { $count = 0; diff --git a/application/classes/model/schedule/client.php b/application/classes/model/schedule/client.php index 6d3067f..a083807 100644 --- a/application/classes/model/schedule/client.php +++ b/application/classes/model/schedule/client.php @@ -16,10 +16,18 @@ class Model_SCHEDULE_CLIENT extends ORMTSM { 'SCHEDULE_NAME'=>'ASC', ); + protected $_has_many = array( + 'ASSOCIATION'=>array('foreign_key'=>'SCHEDULE_NAME','far_key'=>'SCHEDULE_NAME'), + ); + protected $_display_filters = array( 'STARTTIME'=>array( array('ORMTSM::date',array(':value','h:m')), ), ); + + public function getNodes() { + return $this->ASSOCIATION->find_all(); + } } ?> diff --git a/application/classes/model/volume.php b/application/classes/model/volume.php index 727cd9f..4c0f3df 100644 --- a/application/classes/model/volume.php +++ b/application/classes/model/volume.php @@ -41,5 +41,13 @@ class Model_VOLUME extends ORMTSM { public function getNodesOnVol($dtype) { return $this->VOLUMEUSAGE->select('NODE_NAME')->distinct(TRUE)->where('COPY_TYPE','=',$dtype)->find_all()->count(); } + + public function isScratch() { + return $this->SCRATCH === 'YES' ? TRUE : FALSE; + } + + public function location() { + return $this->display('LOCATION'); + } } ?> diff --git a/application/views/domain/detail.php b/application/views/domain/detail.php new file mode 100644 index 0000000..aca8fa9 --- /dev/null +++ b/application/views/domain/detail.php @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + $ctype) { ?> + + + + + + + NODE->find_all() as $no) { ?> + + + + + + + $ctype) { ?> + + + + + + + + + +
Nodes in this Domain
 
NodeVersionOSLast AccessLast IP Addr(Vol/Fil/Dat)
NODE_NAME,$no->NODE_NAME); ?>tsmclientversion(); ?>platform(); ?>display('LASTACC_TIME'); ?>display('TCP_ADDRESS'); ?>hasData($btype) ? 'Y' : 'N'; ?>getStorageTypeVols($type)); ?>getStorageTypeFiles($type); ?>getStorageTypeData($type); ?>
+
 
+ + + + + + + + + + + + + + + + + + + + + + + $ctype) { ?> + + + + + + + + + getStoragePoolsType($btype,$type) as $spo) { ?> + + + + + + + + + + + + + + + + + + + +
Storage Pools used by nodes in this Domain
 
Storage PoolScr UseScr AvlAccessRec %Util %Migr %High/LowNextNodesVolsFilesMB
 
 STGPOOL_NAME; ?>display('NUMSCRATCHUSED'); ?>display('MAXSCRATCH'); ?>display('ACCESS'); ?>display('RECLAIM'); ?>display('PCT_UTILIZED'); ?>display('PCT_MIGR'); ?>HIGHMIG,$spo->LOWMIG); ?>display('NEXTSTGPOOL'); ?>getStorageModeNodes($btype,$type,$spo)); ?>getStorageModeVols($ctype,$type,$spo)); ?>getStorageModeFiles($btype,$type,$spo); ?>getStorageModeData($btype,$type,$spo); ?>
+
 
+ + + + + + + + + + + + + + + + + + + + + + $ctype) { ?> + + + + + + + + + getStoragePoolsType($btype,$type) as $spo) { ?> + + + + + getStorageModeVols($ctype,$type,$spo) as $vuo) { ?> + + + + + + + + + + + + + + + + + + + +
Sequential Volumes needed to restore Data for Nodes in this Domain
 
VolumeStatusAccessScrPct %Rec %MountedWritesR/W ErrFSNodesLocation
 
 DISPLAY('STGPOOL_NAME'); ?>
 VOLUME_NAME; ?>VOLUME->display('STATUS'); ?>VOLUME->display('ACCESS'); ?>VOLUME->isScratch() ? 'Y' : 'N'; ?>VOLUME->display('PCT_UTILIZED'); ?>VOLUME->display('PCT_RECLAIM'); ?>VOLUME->display('TIMES_MOUNTED'); ?>VOLUME->display('WRITE_PASS'); ?>VOLUME->READ_ERRORS,$vuo->VOLUME->WRITE_ERRORS); ?>VOLUME->getFSOnVol($ctype); ?>VOLUME->getNodesOnVol($ctype); ?>VOLUME->location(); ?>
+
 
+ set('domain',$do); ?> +
 
+ + + + + + + + + + + + + + + + + SCHEDULE_CLIENT->find_all() as $so) { ?> + + + + + + + + + + +
Schedules used in this Domain
 
ScheduleStart TimeDurationRepeatValid DayPriorityNodes
display('SCHEDULE_NAME'); ?>display('STARTTIME'); ?>DURATION,$so->DURUNITS); ?>PERIOD,$so->PERUNITS); ?>display('DAYOFWEEK'); ?>display('PRIORITY'); ?>getNodes()); ?>
+
diff --git a/application/views/nodes/detail.php b/application/views/nodes/detail.php index 9bece46..cae9808 100644 --- a/application/views/nodes/detail.php +++ b/application/views/nodes/detail.php @@ -10,11 +10,15 @@ Node Name - display('NODE_NAME'); ?> (display('TCP_ADDRESS'); ?>) + display('NODE_NAME'); ?> (URL ? HTML::anchor($node->URL,$node->display('TCP_ADDRESS')) : $node->display('TCP_ADDRESS'); ?>) + + + Node Contact + display('CONTACT'); echo $node->EMAIL_ADDRESS ? ' ('.HTML::mailto($node->EMAIL_ADDRESS).')' : ''; ?> Operating Sytem - display('PLATFORM_NAME'),$node->display('CLIENT_OS_LEVEL')); ?> + platform(); ?> TSM Client Version @@ -105,8 +109,12 @@   - Client Option Set - display('OPTION_SET'); ?> + Domain + DOMAIN,$node->display('DOMAIN')); ?> + + + Client Option Set + display('OPTION_SET'); ?> Collocation Group @@ -140,53 +148,7 @@ - - - - - - - - - - - - - - - - - - - MGMTCLASS->where('SET_NAME','=','ACTIVE')->find_all() as $mco) { ?> - - - - - - - - - - - - - - - - - - - - - MGMTCLASS->where('SET_NAME','=','ACTIVE')->find_all() as $mco) { ?> - - - - - - -
Policy Settings
 
Backup Settings
MGMT ClassHSM Pool1st Backup PoolVer ExistVer DelFrequency
display('CLASS_NAME'); ?>DEFAULTMC=='Yes' ? ' *' : ''; ?>display('MIGDESTINATION'); ?>COPYGROUP_BU->display('DESTINATION'); ?>COPYGROUP_BU->display('VEREXISTS'),$mco->COPYGROUP_BU->display('RETEXTRA')); ?>COPYGROUP_BU->display('VERDELETED'),$mco->COPYGROUP_BU->display('RETONLY')); ?>COPYGROUP_BU->display('FREQUENCY'); ?>
 
Archive Settings
MGMT ClassDestinationRetain
display('CLASS_NAME'); ?>DEFAULTMC=='Yes' ? ' *' : ''; ?>COPYGROUP_AR->display('DESTINATION'); ?>COPYGROUP_AR->display('RETVER'); ?>
+ set('domain',$node->DOMAIN); ?> diff --git a/application/views/nodes/detail_schedule.php b/application/views/nodes/detail_schedule.php index c244a82..c5ff57a 100644 --- a/application/views/nodes/detail_schedule.php +++ b/application/views/nodes/detail_schedule.php @@ -75,7 +75,7 @@ - + EVENT->find_all() as $eo) { ?> diff --git a/application/views/nodes/policy.php b/application/views/nodes/policy.php new file mode 100644 index 0000000..1af1dc6 --- /dev/null +++ b/application/views/nodes/policy.php @@ -0,0 +1,47 @@ +
Status Completed Result
display('SCHEDULED_START'); ?>
+ + + + + + + + + + + + + + + + + + MGMTCLASS->where('SET_NAME','=','ACTIVE')->find_all() as $mco) { ?> + + + + + + + + + + + + + + + + + + + + + MGMTCLASS->where('SET_NAME','=','ACTIVE')->find_all() as $mco) { ?> + + + + + + +
Policy Settings
 
Backup Settings
MGMT ClassHSM Pool1st Backup PoolVer ExistVer DelFrequency
display('CLASS_NAME'); ?>DEFAULTMC=='Yes' ? ' *' : ''; ?>display('MIGDESTINATION'); ?>COPYGROUP_BU->display('DESTINATION'); ?>COPYGROUP_BU->display('VEREXISTS'),$mco->COPYGROUP_BU->display('RETEXTRA')); ?>COPYGROUP_BU->display('VERDELETED'),$mco->COPYGROUP_BU->display('RETONLY')); ?>COPYGROUP_BU->display('FREQUENCY'); ?>
 
Archive Settings
MGMT ClassDestinationRetain
display('CLASS_NAME'); ?>DEFAULTMC=='Yes' ? ' *' : ''; ?>COPYGROUP_AR->display('DESTINATION'); ?>COPYGROUP_AR->display('RETVER'); ?>
diff --git a/application/views/nodes/summary.php b/application/views/nodes/summary.php deleted file mode 100644 index fedd817..0000000 --- a/application/views/nodes/summary.php +++ /dev/null @@ -1,108 +0,0 @@ - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Node Information for Nodes in Domain DOMAIN_NAME; ?>
 
- - - - - - - - - - - NODE->find_all() as $no) { ?> - - - - - - - - - - - - -
NodeVersionLast AccessLast IP Addr(Vol/Fil/Dat)
NODE_NAME,$no->NODE_NAME); ?>tsmclientversion(); ?>display('LASTACC_TIME'); ?>display('TCP_ADDRESS'); ?>getStorageTypeVols($type)); ?>getStorageTypeFiles($type); ?>getStorageTypeData($type); ?>
-
 
Storage Pools used by nodes in this domain
 
- - - - - - - - $ctype) { ?> - - - - - - - - - getStoragePoolsType($btype,$type) as $spo) { ?> - - - - - - - - - - -
Storage PoolVolsFilesMB
 
 STGPOOL_NAME; ?>getStorageModeVols($ctype,$type,$spo)); ?>getStorageModeFiles($btype,$type,$spo); ?>getStorageModeData($btype,$type,$spo); ?>
-
 
Sequential Volumes needed to restore Data for Nodes in this domain
 
 
Policy in this domain
 
 
Schedules used in this domain
 
-