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