872b5ee06e17bd4eb356c697074aa776b72f24bf
[plewww.git] / planetlab / nodes / nodes.php
1 <?php
2
3 // $Id$
4
5 // Require login
6 require_once 'plc_login.php';
7
8 // Get session and API handles
9 require_once 'plc_session.php';
10 global $plc, $api;
11
12 // Print header
13 require_once 'plc_drupal.php';
14 include 'plc_header.php';
15
16 // Common functions
17 require_once 'plc_functions.php';
18 require_once 'plc_objects.php';
19 require_once 'plc_peers.php';
20 require_once 'plc_visibletags2.php';
21 require_once 'linetabs.php';
22 require_once 'table2.php';
23 require_once 'nifty.php';
24 require_once 'toggle.php';
25 require_once 'columns.php';
26
27 // keep css separate for now
28 drupal_set_html_head('
29 <link href="/planetlab/css/my_slice.css" rel="stylesheet" type="text/css" />
30 ');
31
32
33 ini_set("memory_limit","64M");
34 //error_reporting(0);
35
36 // -------------------- 
37 // recognized URL arguments
38 $peerscope=$_GET['peerscope'];
39 $pattern=$_GET['pattern'];
40 $site_id=intval($_GET['site_id']);
41 $slice_id=intval($_GET['slice_id']);
42 $person_id=intval($_GET['person_id']);
43
44 // --- decoration
45 $title="Nodes";
46 $tabs=array();
47 $tabs []= tab_nodes();
48 if (count (plc_my_site_ids()) == 1) {
49     $tabs []= tab_nodes_mysite();
50 } else {
51     $tabs []= tab_nodes_all_mysite();
52 }
53 $tabs []= tab_nodes_local();
54
55 // -------------------- 
56 $node_filter=array();
57
58 //////////////////
59 // performs sanity check and summarize the result in a single column
60 function node_status ($node) {
61
62   $messages=array();
63   if ($node['node_type'] != 'regular' && $node['node_type'] != 'reservable' ) 
64     $messages []= $node['node_type'];
65
66   // checks on local nodes only
67   if ( ( ! $node['peer_id']) ) {
68     // has it got interfaces 
69     if (count($node['interface_ids']) == 0) 
70       $messages []= "No interface";
71   }
72   return plc_vertical_table($messages,'plc-warning');
73 }
74
75
76 $first_time_configuration = false;
77
78 if (plc_is_admin()) 
79         $default_configuration = "ID:f|hostname:f|ST:f|AU:f|RES:f";
80 else
81         $default_configuration = "hostname:f|ST:f|AU:f|RES:f";
82
83 //$extra_default = "LCN|DN|R|L|OS|MS|SN";
84 $column_configuration = "";
85 $slice_column_configuration = "";
86 $show_configuration = "";
87 $show_columns_message = '1';
88
89
90 $PersonTags=$api->GetPersonTags (array('person_id'=>$plc->person['person_id']));
91 //print_r($PersonTags);
92 foreach ($PersonTags as $ptag) {
93         if ($ptag['tagname'] == 'columnconf')
94         {
95                 $column_configuration = $ptag['value'];
96                 $conf_tag_id = $ptag['person_tag_id'];
97         }
98         if ($ptag['tagname'] == 'showconf')
99         {
100                 $show_configuration = $ptag['value'];
101                 $show_tag_id = $ptag['person_tag_id'];
102         }
103 }
104
105 //print("column configuration = ".$column_configuration);
106
107 $nodesconf_exists = false;
108 if ($column_configuration == "")
109 {
110         $first_time_configuration = true;
111         $column_configuration = "nodes;default";
112         $nodesconf_exists = true;
113 }
114 else {
115         $slice_conf = explode(";",$column_configuration);
116         for ($i=0; $i<count($slice_conf); $i++ ) {
117                 if ($slice_conf[$i] == "nodes")
118                 {
119                         $i++;
120                         $slice_column_configuration = $slice_conf[$i];
121                         $nodesconf_exists = true;
122                         break;
123                 }
124                 else
125                 {
126                         $i++;
127                         $slice_column_configuration = $slice_conf[$i];
128                 }
129         }
130 }
131
132 if ($nodesconf_exists == false)
133         $column_configuration = $column_configuration.";nodes;default";
134 //panos: need to define an "empty" configuration here (for the moment A column
135 //will be added by default the first time
136
137
138 if ($slice_column_configuration == "" || $slice_column_configuration == "default")
139         $full_configuration = $default_configuration;
140         
141 else
142         $full_configuration = $default_configuration."|".$slice_column_configuration;
143
144 //print("full configuration = ".$full_configuration);
145
146 // fetch nodes 
147 $node_fixed_columns=array('node_type','site_id','boot_state','last_contact','interface_ids','peer_id', 'slice_ids');
148
149 $fix_columns = array();
150 if (plc_is_admin()) 
151 $fix_columns[]=array('tagname'=>'node_id', 'header'=>'ID', 'type'=>'string', 'title'=>'The ID the node');
152 $fix_columns[]=array('tagname'=>'hostname', 'header'=>'hostname', 'type'=>'string', 'title'=>'The name of the node');
153 $fix_columns[]=array('tagname'=>'peer_id', 'header'=>'AU', 'type'=>'string', 'title'=>'Authority');
154 $fix_columns[]=array('tagname'=>'run_level', 'header'=>'ST', 'type'=>'string', 'title'=>'Status');
155 $fix_columns[]=array('tagname'=>'node_type', 'header'=>'RES', 'type'=>'string', 'title'=>'Reservable');
156
157
158 $visibletags = new VisibleTags ($api, 'node');
159 $visibletags->columns();
160 $tag_columns = $visibletags->headers();
161
162 //columns that are not defined as extra myslice tags
163 $extra_columns = array();
164 //MyPLC columns
165 $extra_columns[]=array('tagname'=>'sitename', 'header'=>'SN', 'type'=>'string', 'title'=>'Site name', 'fetched'=>true, 'source'=>'myplc');
166 $extra_columns[]=array('tagname'=>'domain', 'header'=>'DN', 'type'=>'string', 'title'=>'Toplevel domain name', 'fetched'=>true, 'source'=>'myplc');
167 $extra_columns[]=array('tagname'=>'ipaddress', 'header'=>'IP', 'type'=>'string', 'title'=>'IP Address', 'fetched'=>true, 'source'=>'myplc');
168 $extra_columns[]=array('tagname'=>'fcdistro', 'header'=>'OS', 'type'=>'string', 'title'=>'Operating system', 'fetched'=>false, 'source'=>'myplc');
169 $extra_columns[]=array('tagname'=>'date_created', 'header'=>'DA', 'source'=>'myplc', 'type'=>'date', 'title'=>'Date added', 'fetched'=>false);
170 $extra_columns[]=array('tagname'=>'arch', 'header'=>'A', 'source'=>'myplc', 'type'=>'string', 'title'=>'Architecture', 'fetched'=>false);
171 if (plc_is_admin()) { 
172 $extra_columns[]=array('tagname'=>'deployment', 'header'=>'DL', 'source'=>'myplc', 'type'=>'string', 'title'=>'Deployment', 'fetched'=>false);
173 }
174
175 //CoMon Live data
176 //NOTE: Uncomment these lines if CoMon provides information for your nodes
177
178 //$extra_columns[]=array('tagname'=>'bwlimit', 'header'=>'BW', 'source'=>'comon', 'type'=>'sortAlphaNumericTop', 'title'=>'Bandwidth limit', 'fetched'=>false);
179 //$extra_columns[]=array('tagname'=>'numcores', 'header'=>'CC', 'source'=>'comon', 'type'=>'sortAlphaNumericTop', 'title'=>'Number of CPU Cores', 'fetched'=>false);
180 //$extra_columns[]=array('tagname'=>'cpuspeed', 'header'=>'CR', 'source'=>'comon', 'type'=>'sortAlphaNumericTop', 'title'=>'CPU clock rate', 'fetched'=>false);
181 //$extra_columns[]=array('tagname'=>'disksize', 'header'=>'DS', 'source'=>'comon', 'type'=>'sortAlphaNumericTop', 'title'=>'Disk size', 'fetched'=>false);
182 //$extra_columns[]=array('tagname'=>'gbfree', 'header'=>'DF', 'source'=>'comon', 'type'=>'sortAlphaNumericTop', 'title'=>'Currently available disk space', 'fetched'=>false);
183 //$extra_columns[]=array('tagname'=>'memsize', 'header'=>'MS', 'source'=>'comon', 'type'=>'sortAlphaNumericTop', 'title'=>'Memory size', 'fetched'=>false);
184 //$extra_columns[]=array('tagname'=>'numslices', 'header'=>'SM', 'source'=>'comon', 'type'=>'sortAlphaNumericTop', 'title'=>'Number of slices in memory', 'fetched'=>false);
185 //$extra_columns[]=array('tagname'=>'uptime', 'header'=>'UT', 'source'=>'comon', 'type'=>'sortAlphaNumericTop', 'title'=>'Continuous uptime until now', 'fetched'=>false);
186
187 //TopHat Live data
188 //NOTE: Uncomment these lines if TopHat provides information for your nodes
189 //$extra_columns[]=array('tagname'=>'asn', 'header'=>'AS', 'source'=>'tophat', 'type'=>'string', 'title'=>'AS Number', 'fetched'=>false);
190 //$extra_columns[]=array('tagname'=>'city', 'header'=>'LCY', 'source'=>'tophat', 'type'=>'string', 'title'=>'City', 'fetched'=>false);
191 //$extra_columns[]=array('tagname'=>'region', 'header'=>'LRN', 'source'=>'tophat', 'type'=>'string', 'title'=>'Region', 'fetched'=>false);
192 //$extra_columns[]=array('tagname'=>'country', 'header'=>'LCN', 'source'=>'tophat', 'type'=>'string', 'title'=>'Country', 'fetched'=>false);
193 //$extra_columns[]=array('tagname'=>'continent', 'header'=>'LCT', 'source'=>'tophat', 'type'=>'string', 'title'=>'Continent', 'fetched'=>false);
194 //$extra_columns[]=array('tagname'=>'hopcount', 'header'=>'HC', 'source'=>'tophat', 'type'=>'sortAlphaNumericTop', 'title'=>'Hop count from reference node', 'fetched'=>false);
195 ////$extra_columns[]=array('tagname'=>'rtt', 'header'=>'RTT', 'source'=>'tophat', 'type'=>'sortAlphaNumericTop', 'title'=>'Round trip time from reference node', 'fetched'=>false);
196 ////$extra_columns[]=array('tagname'=>'agents', 'header'=>'MA', 'source'=>'tophat', 'type'=>'sortAlphaNumericTop', 'title'=>'Co-located measurement agents', 'fetched'=>true);
197 ////$extra_columns[]=array('tagname'=>'agents_sonoma', 'header'=>'MAS', 'source'=>'tophat', 'type'=>'sortAlphaNumericTop', 'title'=>'Co-located SONoMA agents', 'fetched'=>true);
198 ////$extra_columns[]=array('tagname'=>'agents_etomic', 'header'=>'MAE', 'source'=>'tophat', 'type'=>'sortAlphaNumericTop', 'title'=>'Co-located ETOMIC agents', 'fetched'=>true);
199 ////$extra_columns[]=array('tagname'=>'agents_tdmi', 'header'=>'MAT', 'source'=>'tophat', 'type'=>'sortAlphaNumericTop', 'title'=>'Co-located TDMI agents', 'fetched'=>true);
200 ////$extra_columns[]=array('tagname'=>'agents_dimes', 'header'=>'MAD', 'source'=>'tophat', 'type'=>'sortAlphaNumericTop', 'title'=>'Co-located DIMES agents', 'fetched'=>true);
201
202
203 $ConfigureColumns =new PlekitColumns($full_configuration, $fix_columns, $tag_columns, $extra_columns);
204
205 $visiblecolumns = $ConfigureColumns->node_tags();
206
207 $node_columns=array_merge($node_fixed_columns,$visiblecolumns);
208
209 //$visibletags = new VisibleTags ($api, 'node');
210 //$visiblecolumns = $visibletags->column_names();
211 //print("<p>OLD");
212 //print_r($visiblecolumns);
213 //$node_columns=array_merge($node_fixed_columns,$visiblecolumns);
214
215
216 // server-side filtering - set pattern in $_GET for filtering on hostname
217 if ($pattern) {
218   $node_filter['hostname']=$pattern;
219   $title .= " matching " . $pattern;
220  } else {
221   $node_filter['hostname']="*";
222  }
223
224 // server-side selection on peerscope
225 $peerscope=new PeerScope($api,$_GET['peerscope']);
226 $node_filter=array_merge($node_filter,$peerscope->filter());
227 $title .= ' - ' . $peerscope->label();
228
229 if ($site_id) {
230   $sites=$api->GetSites(array($site_id));
231   $site=$sites[0];
232   $name=$site['name'];
233   $login_base=$site['login_base'];
234   $title .= t_site($site);
235   $tabs []= tab_site($site);
236   $node_filter['site_id']=array($site_id);
237 }
238
239 if ($slice_id) {
240   $slices=$api->GetSlices(array($slice_id),array('node_ids','name'));
241   $slice=$slices[0];
242   $title .= t_slice($slice);
243   $tabs []= tab_slice($slice);
244   $node_filter['node_id'] = $slice['node_ids'];
245  }
246
247 // person_id is set : this is mostly oriented towards people managing several sites
248 if ($person_id) {
249   // avoid doing a useless call to GetPersons if the person_id is already known though $plc,
250   // as this is mostly done for the 'all my sites nodes' link
251   if ($person_id == plc_my_person_id()) { 
252     $person=plc_my_person();
253     $site_ids = plc_my_site_ids();
254   } else {
255     // fetch the person's site_ids
256     $persons = $api->GetPersons(array('person_id'=>$person_id),array('person_id','email','site_ids'));
257     $person=$persons[0];
258     $site_ids=$person['site_ids'];
259   }
260   $title .= t_person($person);
261   $node_filter['site_id']=$site_ids;
262  }
263
264 // go
265 //print("getting nodes ".$node_columns);
266 //print_r($node_columns);
267 $nodes=$api->GetNodes($node_filter,$node_columns);
268
269 //print("<p> GOT NODES </p>");
270 //print_r($nodes);
271
272 $ConfigureColumns->fetch_live_data($nodes);
273
274 $show_conf = explode(";",$show_configuration);
275 foreach ($show_conf as $ss) {
276         if ($ss =="columns")
277                 $show_columns_message = '0';
278 }
279
280
281
282 // build site_ids - interface_ids
283 $site_ids=array();
284 $interface_ids=array();
285 if ($nodes) foreach ($nodes as $node) {
286   $site_ids []= $node['site_id'];
287   $interface_ids = array_merge ($interface_ids,$node['interface_ids']);
288 }
289
290 // fetch related interfaces
291 $interface_columns=array('ip','node_id','interface_id');
292 $interface_filter=array('is_primary'=>TRUE,'interface_id'=>$interface_ids);
293 $interfaces=$api->GetInterfaces($interface_filter,$interface_columns);
294
295 $interface_hash=array();
296 foreach ($interfaces as $interface) $interface_hash[$interface['node_id']]=$interface;
297
298 // fetch related sites
299 $site_columns=array('site_id','login_base');
300 $site_filter=array('site_id'=>$site_ids);
301 $sites=$api->GetSites($site_filter,$site_columns);
302
303 $site_hash=array();
304 foreach ($sites as $site) $site_hash[$site['site_id']]=$site;
305
306 // --------------------
307 drupal_set_title($title);
308
309 plekit_linetabs($tabs);
310
311 if ( ! $nodes ) {
312   drupal_set_message ('No node found');
313   return;
314  }
315   
316 $nifty=new PlekitNifty ('','objects-list','big');
317 $nifty->start();
318 $headers = array (); $offset=0;
319 $notes=array();
320 $notes [] = "For information about the different columns please see the <b>node table layout</b> tab above or <b>mouse over</b> the column headers";
321
322
323 /*
324 // fixed columns
325 if (plc_is_admin()) { 
326   $short="I"; $long="node_id"; $type='int'; 
327         $headers[$short]=array('type'=>$type,'title'=>$long); $notes []= "$short = $long";
328   $offset=1; 
329  }
330 $short="P"; $long="Peer"; $type='string'; 
331         $headers[$short]=array('type'=>$type,'title'=>$long); $notes []= "$short = $long";
332 $short="D"; $long="toplevel domain name"; $type='string'; 
333         $headers[$short]=array('type'=>$type,'title'=>$long); $notes []= "$short = $long";
334 $headers["Site"]="string";
335 $headers["Hostname"]="string";
336 $short="IP"; $long="IP Address"; $type='sortIPAddress'; 
337         $headers[$short]=array('type'=>$type,'title'=>$long); $notes []= "$short = $long";
338 $short="ST"; $long=Node::status_footnote(); $type='string'; 
339         $headers[$short]=array('type'=>$type,'title'=>$long); $notes []= "$short = $long";
340 $short="SL"; $long="Number of slivers"; $type='int'; 
341         $headers[$short]=array('type'=>$type,'title'=>$long); $notes []= "$short = $long";
342
343 $headers=array_merge($headers,$visibletags->headers());
344 $notes=array_merge($notes,$visibletags->notes());
345 $short="?"; $long="extra status info"; $type='string'; 
346         $headers[$short]=array('type'=>$type,'title'=>$long); $notes []= "$short = $long";
347 */
348
349 $info_header = array();
350 $short="?"; $long="extra status info"; $type='string'; 
351 $info_header[$short]=array('type'=>$type,'title'=>$long, 'label'=>'?', 'header'=>'?', 'visible'=>true); 
352 //$notes []= "$short = $long";
353 //$info_header["?"] = "none";
354 $headers = array_merge($ConfigureColumns->get_headers(),$info_header);
355
356 if ($first_time_configuration)
357 $column_conf_visible = '1';
358 else
359 $column_conf_visible = '0';
360
361 $toggle_nodes=new PlekitToggle('nodes-column-configuration',
362                                "Node table layout",
363                                array('visible'=>$column_conf_visible, 'info_div'=>'note_columns_div'));
364 $toggle_nodes->start();
365 print("<div id='debug'></div>");
366 print("<input type='hidden' id='slice_id' value='nodes' />");
367 print("<input type='hidden' id='person_id' value='".$plc->person['person_id']."' />");
368 print("<input type='hidden' id='conf_tag_id' value='".$conf_tag_id."' />");
369 print("<input type='hidden' id='show_tag_id' value='".$show_tag_id."' />");
370 print("<input type='hidden' id='show_configuration' value='".$show_configuration."' />");
371 print("<input type='hidden' id='column_configuration' value='".$slice_column_configuration."' />");
372 print("<br><input type='hidden' size=80 id='full_column_configuration' value='".$column_configuration."' />");
373 print("<input type='hidden' id='defaultConf' value='".$default_configuration."'></input>");
374
375 if ($show_columns_message == '0')
376 $note_display = "display:none;";
377 else
378 $note_display = "";
379
380
381 print <<<EOF
382 <div class="note-div" id='note_columns_div' style='$note_display'>
383 <table class='center'><tr><td class='top'>
384 This tab allows you to customize the columns in the node tables, below. Information on the nodes comes from a variety of monitoring sources. If you, as either a user or a provider of monitoring data, would like to see additional columns made available, please send us your request in mail to <a href="mailto:support@myslice.info">support@myslice.info</a>. You can find more information about the MySlice project at <a href="http://trac.myslice.info">http://trac.myslice.info</a>.
385 </td><td class='top'><span onClick=closeMessage('columns')><img class='reset' src="/planetlab/icons/clear.png" alt="hide message permanently"></span>
386 </td></tr></table>
387 </div>
388 EOF;
389
390 $ConfigureColumns->configuration_panel_html(true);
391 $ConfigureColumns->javascript_init();
392 $toggle_nodes->end();
393
394 $table_options = array('notes'=>$notes,
395                        'search_width'=>15,
396                        'pagesize'=>20,
397                         'configurable'=>true);
398
399 # initial sort on hostnames
400 $table=new PlekitTable ("nodes",$headers,3+$offset, $table_options);
401 $table->start();
402
403 $peers = new Peers ($api);
404 // write rows
405 foreach ($nodes as $node) {
406   //$node_obj = new Node ($node);
407
408   $hostname=$node['hostname'];
409   $node_id=$node['node_id'];
410   $site_id=$node['site_id'];
411   $site=$site_hash[$site_id];
412   $login_base = $site['login_base'];
413   $ip=$interface_hash[$node['node_id']]['ip'];
414   $interface_id=$interface_hash[$node['node_id']]['interface_id'];
415   $peer_id=$node['peer_id'];
416   
417   $table->row_start();
418   $table->cell($node['node_id'], array('display'=>'none'));
419   if (plc_is_admin()) $table->cell(l_node_t($node_id,$node_id));
420   $table->cell (l_node_t($node_id,$hostname));
421   $peers->cell ($table,$peer_id);
422
423   //prefetch some columns
424   $node['domain'] = topdomain($hostname);
425   $node['sitename'] = l_site_t($site_id,$login_base);
426   if ($interface_id)
427         $node['ipaddress'] = l_interface_t($interface_id,$ip);
428   else
429         $node['ipaddress'] = "n/a";
430
431   list($label,$class) = Node::status_label_class_($node);
432   $table->cell ($label,array('class'=>$class));
433   $table->cell( ($node['node_type']=='reservable')?reservable_mark():"" );
434   //$table->cell (count($node['slice_ids']));
435   //foreach ($visiblecolumns as $tagname) $table->cell($node[$tagname]);
436   $ConfigureColumns->cells($table, $node);
437   $table->cell (node_status($node));
438   $table->row_end();
439   
440 }
441
442 $table->end();
443 $nifty->end();
444
445
446 //plekit_linetabs ($tabs,"bottom");
447
448 // Print footer
449 include 'plc_footer.php';
450
451 ?>
452