add network configuration screen
[raven.git] / apps / gacksadmin / gacks_functions.php
1 <?php
2
3 require_once 'form.php';
4
5 define(INFINITY, 2147483647);
6
7 define(STATE_PENDING, 0);
8 define(STATE_APPLY, 1);
9 define(STATE_APPLIED, 2);
10 define(STATE_INVOICED, 3);
11
12 define(KIND_CYCLE_CHARGE, 0);
13 define(KIND_SLOT_CHARGE, 1);
14 define(KIND_CYCLE_AGGREGATE, 2);
15 define(KIND_INVOICE, 10);
16 define(KIND_INVOICE_BEST_EFFORT, 11);
17 define(KIND_INVOICE_RESV, 12);
18 define(KIND_ADJUSTMENT, 20);
19 define(KIND_PAYMENT, 30);
20
21 function l_gacks_accounts ()       { return "/db/gacks/accounts.php"; }
22 function l_gacks_add_account ()    { return "/db/gacks/add_account.php"; }
23 function l_gacks_actions ()        { return "/db/gacks/action.php"; }
24 function l_gacks_account ($acctname, $acctkind)    { return "/db/gacks/account.php?account_name=$acctname&account_kind=$acctkind"; }
25 function l_gacks_reservations ()   { return "/db/gacks/reservations.php"; }
26 function l_gacks_reservation_set ()    { return "/db/gacks/reservation_set.php"; }
27 function l_gacks_invoice($name, $token, $state, $start_date, $end_date, $parent) { return "/db/gacks/invoices.php?account_name=$name&account_token=$token&state=$state&start_date=$start_date&end_date=$end_date&parent_id=$parent"; }
28 function l_gacks_all_invoices ()   { return l_gacks_invoice(NULL, NULL, STATE_INVOICED, time() - 30*24*60*60, NULL, NULL); }
29 function l_gacks_weekly ($y=NULL, $m=NULL, $d=NULL)         { return "/db/gacks/weekly.php?invoiceyear=$y&invoicemonth=$m&invoiceday=$d"; }
30 function l_gacks_node_status ()    { return "/db/gacks/nodestatus.php"; }
31 function l_gacks_wizard ()         { return "/db/gacks/wizard.php"; }
32 function l_gacks_nodelist ($account_name=NULL)         { return "/db/gacks/user_nodelist.php?account_name=$account_name"; }
33 function l_gacks_nodelist_download ($acctname) { return "/db/gacks/action.php?action=download-nodelist&account_name=$acctname&format=CSV"; }
34 function l_gacks_image ()         { return "/db/gacks/user_image.php"; }
35 function l_gacks_network ()       { return "/db/gacks/user_network.php"; }
36 function l_gacks_syndicate ()     { return "/db/gacks/user_syndicate.php"; }
37 function l_gacks_user_reservations() { return "/db/gacks/user_reservations.php"; }
38 function l_gacks_edit($item)       { return "/db/gacks/edit.php"; }
39 function l_gacks_delete($item)     { $timeStart=$item['timeStart']; $timeStop=$item['timeStop']; $id=$item['id']; $lastAllocator=end($item['allocatorHRNs']); return "/db/gacks/action.php?action=delete-reservation&timeStart=$timeStart&timeStop=$timeStop&resource_id=$id&lastAllocator=$lastAllocator"; }
40 function l_gacks_service_level($account_name=NULL)   { return "/db/gacks/user_service_level.php?account_name=$account_name"; }
41 function l_gacks_confirm_service($acct, $level, $autoRenew, $enableBestEffort) { return "/db/gacks/user_confirm_service.php?account_name=$acct&level=$level&autoRenew=$autoRenew&enableBestEffort=$enableBestEffort"; }
42 function l_gacks_add_reservation() { return "/db/gacks/user_add_reservation.php"; }
43 function l_gacks_persons()         { return "/db/gacks/user_persons.php"; }
44 function l_gacks_advanced($value, $url)        { $eurl=urlencode($url); return "/db/gacks/action.php?action=set-advanced&value=$value&url=$eurl"; }
45 function l_gacks_summary()         { return "/db/gacks/user_summary.php"; }
46
47 function gacksid($x) { return "gacksid:" . $x; }
48
49 function gackshrn($x) { return "hrn:" . $x; }
50
51 function slice_to_hrn($slice)
52 {
53    $slice = str_replace("_", ".", $slice);
54    $hrn = "plc.vicci." . $slice;
55    return $hrn;
56 }
57
58 function is_time_unimportant($x)
59 {
60     if (($x==KIND_CYCLE_CHARGE) || ($x==KIND_SLOT_CHARGE)) {
61         return FALSE;
62     } else {
63         return TRUE;
64     }
65 }
66
67 function gacks_config()
68 {
69     return parse_ini_file("/etc/gacks/gacks.conf", true);     // see also in gacksclient.php
70 }
71
72 function handle_as_string($handle)
73 {
74     $id = $handle['id'];
75     $unitStart = $handle['unitStart'];
76     $unitStop = $handle['unitStop'];
77     $timeStart = $handle['timeStart'];
78     $timeStop = $handle['timeStop'];
79
80     return "$id#$unitStart-$unitStop#$timeStart-$timeStop";
81 }
82
83 function verify_account_token($account_name, $account_token) {
84     //$handle = fopen("/root/gacks_account_secret.txt", "r");
85     //$secret = fgets($handle, 4096);
86     //fclose($handle);
87
88     $config = gacks_config();
89     $secret = $config['gacks']['account_secret'];
90
91     $secret = trim($secret);
92     $token = sha1($secret . $account_name);
93     $token = substr($token, 0, 8);
94
95     //print $secret . " " . $token . " " . $account_name . " " . $account_token;
96
97     return ($token == $account_token);
98 }
99
100 function gacksid_guess_prefix($x) {
101     if ((strpos($x, ".") !== false) and (strpos($x, "_") == false)) {
102         return "hrn:" . $x;
103     } else if ((strpos($x, ".") == false) and (strpos($x, "_") == true)) {
104         return "slice:" . $x;
105     } else {
106         // XXX this doesn't display an error to the user
107         throw new Exception("unable to guess whether name is a slice or hrn");
108     }
109 }
110
111 function level_selectors($value)
112 {
113     $level_selectors = array();
114     $level_selectors []= array("display"=>"Default", "value"=>"default");
115     $level_selectors []= array("display"=>"Silver", "value"=>"silver");
116     $level_selectors []= array("display"=>"Gold", "value"=>"gold");
117
118     foreach ($level_selectors as &$sel) {
119         if ($sel["value"] == $value) {
120             $sel["selected"] = True;
121         }
122     }
123
124     return $level_selectors;
125 }
126
127 function charge_kind_selectors($value)
128 {
129     $kind_selectors = array();
130     $kind_selectors []= array("display"=>"Cycle Charge", "value"=>"0");
131     $kind_selectors []= array("display"=>"Slot Charge", "value"=>"1");
132     $kind_selectors []= array("display"=>"Invoice Charge", "value"=>"10");
133     $kind_selectors []= array("display"=>"Adjustment", "value"=>"20");
134     $kind_selectors []= array("display"=>"Payment", "value"=>"30");
135
136     foreach ($kind_selectors as &$sel) {
137         if ($sel["value"] == $value) {
138             $sel["selected"] = True;
139         }
140     }
141
142     return $kind_selectors;
143 }
144
145 function bool_text($value, $true, $false)
146 {
147     if ($value) {
148         return $true;
149     } else {
150         return $false;
151     }
152 }
153
154 function bool_selectors($value)
155 {
156     if ($value) {
157         $value = 1;
158     } else {
159         $value = 0;
160     }
161
162     $bool_selectors = array();
163     $bool_selectors []= array("display"=>"Yes", "value"=>"1");
164     $bool_selectors []= array("display"=>"No", "value"=>"0");
165
166     foreach ($bool_selectors as &$sel) {
167         if ($sel["value"] == $value) {
168             $sel["selected"] = True;
169         }
170     }
171
172     return $bool_selectors;
173 }
174
175 function aggregate_records($records)
176 {
177    $aggs = array();
178
179    foreach ($records as $rec) {
180        $rec['key'] = $rec['id'] + '#' + $rec['timeStart'] + "-" + $rec['timeStop'] + ":" + implode(",", $rec['allocatorHRNs']) + ">" + $rec['consumerHRN'];
181        $rec['qty'] = $rec['unitStop'] - $rec['unitStart'];
182
183        $found = False;
184        foreach ($aggs as &$agg) {
185            if ($agg['key'] == $rec['key']) {
186                $agg['qty'] = $agg['qty'] + $rec['qty'];
187                $found = True;
188            }
189        }
190        if (!$found) {
191            $aggs []= $rec;
192        }
193    }
194
195    return $aggs;
196 }
197
198 function record_table($records, $timezone_seconds)
199 {
200     $headers=array();
201     $headers["id"] = "string";
202     $headers["start"] = "string";
203     $headers["stop"] = "string";
204     $headers["lastAllocator"] = "string";
205     $headers["consumer"] = "string";
206     $headers["qty"] = "int";
207     $headers["actions"] = "string";
208
209     $sort_column = 1;
210     $table = new PlekitTable("reservations", $headers, $sort_column);
211     $table->start();
212
213     $aggs = aggregate_records($records);
214
215     foreach ( $aggs as $item ) {
216             $table->row_start();
217             $table->cell($item['id']);
218             $table->cell(strftime("%Y-%m-%d %H:%M:%S", $item['timeStart']+$timezone_seconds));
219             $table->cell(strftime("%Y-%m-%d %H:%M:%S", $item['timeStop']+$timezone_seconds));
220             $table->cell(end($item['allocatorHRNs']));
221             $table->cell($item['consumerHRN']);
222             $table->cell($item['qty']);
223             $table->cell(href(l_gacks_delete($item), "delete")); // href(l_gacks_edit($item), "edit") . " "
224             $table->row_end();
225     }
226
227     $table->end();
228 }
229
230 function charge_detail($charge)
231 {
232     $details = new PlekitDetails(False);
233
234     $details->start();
235
236     $details->form_start(l_gacks_actions(), array());
237
238     $details->th_td("id", $charge["id"]);
239     $details->th_td("object/desc", $charge["object_desc"]);
240     $details->th_td("kind", $charge["kind_id"]);
241     $details->th_td("date", $charge["date"]);
242     $details->th_td("amount", $charge["amount"]);
243     $details->th_td("state", $charge["state"]);
244     $details->th_td("parent_id", $charge["parent_id"]);
245     $details->th_td("account_name", $charge["account_name"]);
246
247     $details->end();
248     $details->form_end();
249 }
250
251 function dollars($amount)
252 {
253     return "$ " . number_format($amount, 2);
254 }
255
256 function invoice_table($invoice, $account_name, $account_token, $options)
257 {
258     $invoice_kind = array();
259     $invoice_kind[KIND_CYCLE_CHARGE] = "best effort";
260     $invoice_kind[KIND_SLOT_CHARGE] = "reservation";
261     $invoice_kind[KIND_CYCLE_AGGREGATE] = "best effort";
262     $invoice_kind[KIND_INVOICE] = "daily invoice";
263     $invoice_kind[KIND_INVOICE_BEST_EFFORT] = "daily invoice";
264     $invoice_kind[KIND_INVOICE_RESV] = "daily invoice";
265     $invoice_kind[KIND_ADJUSTMENT] = "adjustment";
266     $invoice_kind[KIND_PAYMENT] = "payment";
267
268     $headers=array();
269     $headers["id"] = "string";
270     $headers["account_name"] = "string";
271     $headers["date"] = "string";
272     $headers["kind"] = "string";
273     $headers["description"] = "string";
274     $headers["amount"] = "int";
275
276     // ideally it would be nice if we could sort by 3 columns,
277     //    account_name, date, description
278     if ($account_name) {
279         $sort_column = 2; // date
280     } else {
281         $sort_column = 1; // account name
282     }
283
284     $table = new PlekitTable("invoices", $headers, $sort_column);
285     $table->start();
286
287     $charges = $invoice['charges'];
288
289     foreach ( $charges as $item ) {
290             //if ($options['date_only']) {
291             if (is_time_unimportant($item['kind_id'])) {
292                 $date = explode(' ', $item['date']);
293                 $date = $date[0];
294             } else {
295                 $date = $item['date'];
296             }
297             $table->row_start();
298             $table->cell(href(l_gacks_invoice($account_name, $account_token, NULL, NULL, NULL, $item['id']), $item['id']));
299             $table->cell($item['account_name']);
300             $table->cell($date);
301             $table->cell($invoice_kind[$item['kind_id']]);
302             $table->cell($item['object_desc']);
303             $table->cell(dollars($item['amount']), array("align"=>"right"));
304             $table->row_end();
305     }
306
307     $table->end();
308 }
309
310 # from http://cool-php-tutorials.blogspot.com/2010/02/easy-php-date-picker.html
311 function date_picker($name, $y, $m, $d)
312 {
313     $startyear = 2012;
314     $endyear = date("Y");
315
316     $months=array('','January','February','March','April','May',
317     'June','July','August', 'September','October','November','December');
318
319     // Month dropdown
320     $html="<select name=\"".$name."month\">";
321
322     for($i=1;$i<=12;$i++)
323     {
324        $html.="<option value='$i'";
325        if ($i==$m) {
326            $html.=" selected=true";
327        }
328        $html.=">$months[$i]</option>";
329     }
330     $html.="</select> ";
331
332     // Day dropdown
333     $html.="<select name=\"".$name."day\">";
334     for($i=1;$i<=31;$i++)
335     {
336        $html.="<option value='$i'";
337        if ($i==$d) {
338            $html.=" selected=true";
339        }
340        $html.=">$i</option>";
341     }
342     $html.="</select> ";
343
344     // Year dropdown
345     $html.="<select name=\"".$name."year\">";
346
347     for($i=$startyear;$i<=$endyear;$i++)
348     {
349       $html.="<option value='$i'";
350       if ($i==$y) {
351           $html.=" selected=true";
352       }
353       $html.=">$i</option>";
354     }
355     $html.="</select> ";
356
357     return $html;
358 }
359
360 function get_slices($plcapi, $person_id, $fields)
361 {
362     if (!in_array("name", $fields)) {
363         $fields []= "name";
364     }
365
366     $persons = $plcapi->GetPersons(array('person_id'=>$person_id),array('person_id','email','slice_ids','role_ids','site_ids'));
367     $person=$persons[0];
368     $slice_filter=array('slice_id' => $person['slice_ids']);
369     $user_slices=$plcapi->GetSlices($slice_filter,$fields);
370
371     $slices = array();
372     foreach ($user_slices as $slice) {
373         $slices[$slice['name']] = $slice;
374     }
375
376     $is_pi = in_array( 20, $person['role_ids']);
377     if ($is_pi) {
378         $slice_filter=array('site_id'=>$person['site_ids'][0]);
379         $pi_slices = $plcapi->GetSlices($slice_filter, $fields);
380
381         foreach ($pi_slices as $slice) {
382             if (!array_key_exists($slice['name'], $slices)) {
383                 $slices[$slice['name']] = $slice;
384             }
385         }
386     }
387
388     return $slices;
389 }
390
391 function get_account_names($plcapi, $person_id)
392 {
393     $slices = get_slices($plcapi, $person_id, array("name"));
394     $slicenames = array();
395     foreach ($slices as $name => $slice) {
396         $slicenames []= $name;
397     }
398
399     return $slicenames;
400 }
401
402 function account_selectors($plcapi, $person_id, $account_name)
403 {
404     $slicenames = get_account_names($plcapi, $person_id);
405
406     $selectors = array();
407     foreach ($slicenames as $slicename) {
408         if ($slicename == $account_name) {
409             $selectors []= array("display"=>$slicename, "value"=>$slicename, "selected"=>True);
410         } else {
411             $selectors []= array("display"=>$slicename, "value"=>$slicename);
412         }
413     }
414
415     return $selectors;
416 }
417
418 function &find_selector($needle, &$selectors)
419 {
420     foreach ($selectors as &$selector) {
421         if ($selector['value']==$needle) {
422             return $selector;
423         }
424     }
425     return NULL;
426 }
427
428 function select_selector($needle, &$selectors)
429 {
430     $selector = &find_selector($needle, $selectors);
431     if ($selector) {
432         $selector["selected"] = True;
433     }
434 }
435
436 function get_gacks_session()
437 {
438     if (!array_key_exists("gacks", $_SESSION)) {
439         return array("account_name" => NULL);
440     }
441     return $_SESSION['gacks'];
442 }
443
444 function update_gacks_session($updated_session)
445 {
446     $session = get_gacks_session();
447
448     foreach ($updated_session as $key => $value) {
449         $session[$key] = $value;
450     }
451
452     $_SESSION['gacks'] = $session;
453 }
454
455 function get_account_name($api, $_person_id, $form=NULL, $url=NULL)
456 {
457     $session = get_gacks_session();
458
459     $account_name = $_GET['account_name'];
460     if (!$account_name) {
461         $account_name = $_POST['account_name'];
462     }
463     if (!$account_name) {
464         $account_name = $session['account_name'];
465     }
466
467     drupal_add_js("misc/popup.js");
468
469     if ($form == NULL) {
470         $form = new PlekitForm(l_gacks_actions(), array("action"=>"set-account",
471                                                         "url"=>$_SERVER['REQUEST_URI']));
472         $form->start();
473         $needFormEnd = TRUE;
474     } else {
475         $needFormEnd = FALSE;
476     }
477
478     $selectors = account_selectors($api, $_person_id, $account_name);
479
480     if (($account_name != NULL) && (!find_selector($account_name, $selectors))) {
481         $account_name = NULL;
482     }
483
484     print "Slice name:<br>";
485     if ($url != NULL) {
486         $onChange = "PopupMessage(); this.form.action=\"$url\"; this.form.submit();";
487     } else {
488         $onChange = "PopupMessage(); this.form.submit();";
489     }
490     print $form->select_html("account_name", $selectors, array("onChange"=> $onChange));
491
492     if ($needFormEnd) {
493         $form->end();
494     }
495
496     if ((!$account_name) && ($selectors)) {
497         $account_name = $selectors[0]["value"];
498     }
499
500     return $account_name;
501 }
502
503 // This makes a combobox that when it is changed, it will pop up a "Please Wait"
504 // message and refresh the page.
505 //
506 // &$value is passed by reference, so that it will automatically be set to the
507 // first item in the combobox if it is NULL.
508
509 function auto_refresh_combo($form, $name, $selectors, &$value, $url)
510 {
511     foreach ($selectors as &$sel) {
512         if ($sel["value"] == $value) {
513             $sel["selected"] = True;
514         } else {
515             $sel["selected"] = False;
516         }
517     }
518
519     if (($value!=NULL) && (!find_selector($value, $selectors))) {
520         $value = NULL;
521     }
522
523     if ($value==NULL) {
524         if (count($selectors)>=1) {
525             $value = $selectors[0]['value'];
526         }
527     }
528
529     $onChange = "PopupMessage(); this.form.action=\"$url\"; this.form.method=\"get\"; this.form.submit();";
530     return $form->select_html($name, $selectors, array("onChange"=> $onChange));
531 }
532
533 // Combobox for Gacks account names. In addition to the features supported by
534 // auto_refresh_combo, it automatically populates the selectors with the slices
535 // that the user has access to, and gets and sets the account_name in the
536 // session variables.
537
538 function account_name_combo($api, $_person_id, $form, &$account_name, $url)
539 {
540     $session = get_gacks_session();
541     if ($account_name==NULL) {
542         $account_name = $session['account_name'];
543     } else {
544         // If a new $account_name was passed in, then update the session
545         // variable.
546         if ($account_name!=$session['account_name']) {
547              update_gacks_session(array("account_name" => $account_name));
548         }
549     }
550
551     $selectors = account_selectors($api, $_person_id, $account_name);
552
553     return auto_refresh_combo($form, "account_name", $selectors, $account_name, $url);
554 }
555
556 function timezone_combo($form, &$timezone, $url)
557 {
558     $session = get_gacks_session();
559     if ($timezone==NULL) {
560         $timezone = $session['timezone'];
561     } else {
562         // If a new $timezone was passed in, then update the session
563         // variable.
564         if ($timezone!=$session['timezone']) {
565              update_gacks_session(array("timezone" => $timezone));
566         }
567     }
568
569     $selectors = array();
570     for($i=-12;$i<=14;$i++) {
571         if ($i<0) {
572             $selectors []= array("display" => "GMT" . $i, "value" => $i);
573         } else {
574             $selectors []= array("display" => "GMT+" . $i, "value" => $i);
575         }
576     }
577
578     return auto_refresh_combo($form, "timezone", $selectors, $timezone, $url);
579 }
580
581 function account_table($plcapi, $gacksapi, $person_id)
582 {
583     $slices = get_slices($plcapi, $person_id, array("name","person_ids","node_ids"));
584
585     $accounts = array();
586     foreach ($slices as $slicename => $slice) {
587          $accounts[$slicename] = $gacksapi->get_account(gacksid($slicename), "user");
588     }
589
590     $headers=array();
591     $headers["name"] = array("type"=>"string", "title"=>"Name of slice");
592     $headers["level"] = array("type"=>"string", "title"=>"Service level");
593     $headers["be"] = array("type"=>"string", "title"=>"Enable Best Effort service when reservations are not in effect");
594     $headers["users"] = array("type"=>"integer", "title"=>"Number of users authorized in this slice");
595     $headers["slivers"] = array("type"=>"integer", "title"=>"Number of slivers this slice is deployed on");
596     $headers["billing contacts"] = array("type"=>"string", "title"=>"Email addresses of billing contacts for this slice");
597
598     $table = new PlekitTable("accounts", $headers, 0);
599     $table->start();
600
601     foreach ($accounts as $name => $account) {
602         $slice = $slices[$name];
603         $table->row_start();
604         $table->cell(href(l_gacks_service_level($name), $name));
605         $table->cell(href(l_gacks_service_level($name), $account["level"]));
606         $table->cell(href(l_gacks_service_level($name), bool_text(!$account["freezeUnreserved"], "enabled", "disabled")));
607         $table->cell(count($slice["person_ids"]));
608         $table->cell(href(l_gacks_nodelist($name), count($slice["node_ids"])));
609         $table->cell(href(l_gacks_service_level($name), $account["billingContacts"]));
610
611         $table->row_end();
612     }
613
614     $table->end();
615
616 }
617
618 function date_combo($form, $name, &$y, &$m, &$d, $url)
619 {
620     $month_selectors = array();
621     $month_selectors []= array("display" => "Jan", "value" => 1);
622     $month_selectors []= array("display" => "Feb", "value" => 2);
623     $month_selectors []= array("display" => "Mar", "value" => 3);
624     $month_selectors []= array("display" => "Apr", "value" => 4);
625     $month_selectors []= array("display" => "May", "value" => 5);
626     $month_selectors []= array("display" => "Jun", "value" => 6);
627     $month_selectors []= array("display" => "Jul", "value" => 7);
628     $month_selectors []= array("display" => "Aug", "value" => 8);
629     $month_selectors []= array("display" => "Sep", "value" => 9);
630     $month_selectors []= array("display" => "Oct", "value" => 10);
631     $month_selectors []= array("display" => "Nov", "value" => 11);
632     $month_selectors []= array("display" => "Dec", "value" => 12);
633
634     $year_selectors = array();
635     for($i=2012;$i<=2022;$i++) {
636         $year_selectors []= array("display" => $i, "value" => $i);
637     }
638
639     $day_selectors = array();
640     for($i=1;$i<=31;$i++) {
641         $day_selectors []= array("display" => $i, "value" => $i);
642     }
643
644     $m_combo = auto_refresh_combo($form, $name . "_m", $month_selectors, $m, $url);
645     $d_combo = auto_refresh_combo($form, $name . "_d", $day_selectors, $d, $url);
646     $y_combo = auto_refresh_combo($form, $name . "_y", $year_selectors, $y, $url);
647
648     return $m_combo . $d_combo . $y_combo;
649 }
650
651 function get_slice_tag($api, $slicename, $tagname)
652 {
653     $image_tags = $api->GetSliceTags(array("tagname" => $tagname, "name" => $slicename));
654     if (count($image_tags) > 0) {
655         return $image_tags[0]['value'];
656     } else {
657         return NULL;
658     }
659 }
660
661 function set_slice_tag($api, $slicename, $tagname, $value)
662 {
663     $tags = $api->GetSliceTags(array("tagname" => $tagname, "name" => $slicename));
664     if (count($tags) > 0) {
665         if (!$value) {
666             $api->DeleteSliceTag($tags[0]['slice_tag_id']);
667         } else if ($tags[0]['slice_tag_id'] != $value) {
668             $api->UpdateSliceTag($tags[0]['slice_tag_id'], $value);
669         }
670     } else {
671         $api->AddSliceTag($slicename, $tagname, $value);
672     }
673 }
674
675 function get_slice_image($api, $slicename)
676 {
677     return get_slice_tag($api, $slicename, "vref");
678 }
679
680 function set_slice_image($api, $slicename, $value)
681 {
682     set_slice_tag($api, $slicename, "vref", $value);
683 }
684
685 function get_slice_headnode($api, $slicename)
686 {
687     $ipList_tags = $api->GetSliceTags(array("tagname" => "vsys_ipList", "name" => $slicename));
688     if (count($ipList_tags) > 0) {
689         $ipList = $ipList_tags[0]['value'];
690         $ips = explode(",", $ipList);
691         if (count($ips)>0) {
692             return $ips[0];
693         } else {
694             return NULL;
695         }
696     } else {
697         return NULL;
698     }
699 }
700
701 function time_selectors($start_date, $min_date)
702 {
703     for($i=0;$i<24;$i++) {
704         if ($start_date+$i*60*60 >= $min_date) {
705             $selectors []= array("display" => "$i:00:00", "value"=>$i);
706         }
707     }
708
709     return $selectors;
710 }
711
712 function get_timezone()
713 {
714     if (isset($_GET['timezone_offset_minutes'])) {
715         $minutes = $_GET['timezone_offset_minutes'];
716 /*        echo "GMT offset (in minutes, from the browser): ". $minutes ."<br />\n";
717         echo "GMT: ". gmdate("Y-m-d H:i:s") ."<br />\n";
718
719         $local = gmmktime(gmdate("H"),gmdate("i")-$minutes); // adjust GMT by client's offset
720
721         echo "Calculated client's date/time: ". gmdate("Y-m-d h:i:s a",$local) ."<br />\n";*/
722
723         return $minutes;
724     } else {
725         if  (!strchr($_SERVER['REQUEST_URI'], "?")) {
726             $url = $_SERVER['REQUEST_URI'] . "?";
727         } else {
728             $url = $_SERVER['REQUEST_URI'] . "&";
729         }
730
731         echo "<script language='javascript'>\n";
732         echo "var d = new Date();\n";
733         echo "location.href=\"${url}timezone_offset_minutes=\" + (-d.getTimezoneOffset());\n";
734         echo "</script>\n";
735         exit();
736     }
737 }
738
739 function manage_slivers_tabs()
740 {
741     $tabs = array();
742
743     $tabs['Show Slivers'] = array('method'=>'GET',
744                                'url'=>l_gacks_nodelist(),
745                                'bubble'=>"Show slivers (also known as nodes or VMs) in your slice");
746
747     $tabs['Add Slivers'] = array('method'=>'GET',
748                                'url'=>l_gacks_wizard(),
749                                'bubble'=>"Add slivers (also known as nodes or VMs) to your slice");
750
751     $tabs['Configure Network'] = array('method'=>'GET',
752                                'url'=>l_gacks_network(),
753                                'bubble'=>"Configure a private network for your slivers to communicate with each other");
754
755     $tabs['Select Image'] = array('method'=>'GET',
756                                'url'=>l_gacks_image(),
757                                'bubble'=>"Select image to use in this slice");
758
759     $tabs['Shared Filesystem'] = array('method'=>'GET',
760                                 'url'=>l_gacks_syndicate(),
761                                 'bubble'=>"Enabled access to Syndicate shared filesystem");
762
763     return $tabs;
764 }
765
766 // This creates a centered div that sizes itself to fit the objects that are
767 // inside of it. Put it and some other stuff around a plekit table and it will
768 // make the contents all line up with the table.
769 //
770 // This fails in IE
771 function shrinkdiv_start()
772 {
773 //   print '<div style="width: 100px; margin: 0 auto;">';
774    print '<div style="text-align: center;">';
775    print '<div style="display: inline-block; text-align: left;">';
776 }
777
778 function shrinkdiv_end()
779 {
780     print '</div></div>';
781 }