r1800 + introduce getExplicitTagsOnly() and buildTrailFromIds()
[racktables] / inc / ophandlers.php
1 <?php
2 /*
3 *
4 * This file is a library of operation handlers for RackTables.
5 *
6 */
7
8 function addPortForwarding ()
9 {
10 global $root, $pageno, $tabno;
11
12 assertUIntArg ('object_id');
13 assertIPv4Arg ('localip');
14 assertIPv4Arg ('remoteip');
15 assertUIntArg ('localport');
16 assertUIntArg ('proto');
17 assertStringArg ('description', TRUE);
18 $object_id = $_REQUEST['object_id'];
19 $localip = $_REQUEST['localip'];
20 $remoteip = $_REQUEST['remoteip'];
21 $localport = $_REQUEST['localport'];
22 $remoteport = $_REQUEST['remoteport'];
23 $proto = $_REQUEST['proto'];
24 $description = $_REQUEST['description'];
25 if (empty ($remoteport))
26 $remoteport = $localport;
27
28 $retpage="${root}?page=${pageno}&tab=${tabno}&object_id=$object_id";
29
30
31 $error=newPortForwarding($object_id, $localip, $localport, $remoteip, $remoteport, $proto, $description);
32
33 if ($error == '')
34 return "${retpage}&message=".urlencode('Port forwarding successfully added.');
35 else
36 {
37 return "${retpage}&error=".urlencode($error);
38 }
39
40 }
41
42 function delPortForwarding ()
43 {
44 global $root, $pageno, $tabno;
45
46 $object_id = $_REQUEST['object_id'];
47 $localip = $_REQUEST['localip'];
48 $remoteip = $_REQUEST['remoteip'];
49 $localport = $_REQUEST['localport'];
50 $remoteport = $_REQUEST['remoteport'];
51 $proto = $_REQUEST['proto'];
52
53 $retpage="${root}?page=${pageno}&tab=${tabno}&object_id=$object_id";
54
55 $error=deletePortForwarding($object_id, $localip, $localport, $remoteip, $remoteport, $proto);
56 if ($error == '')
57 return "${retpage}&message=".urlencode('Port forwarding successfully deleted.');
58 else
59 {
60 return "${retpage}&error=".urlencode($error);
61 }
62
63 }
64
65 function updPortForwarding ()
66 {
67 global $root, $pageno, $tabno;
68
69 $object_id = $_REQUEST['object_id'];
70 $localip = $_REQUEST['localip'];
71 $remoteip = $_REQUEST['remoteip'];
72 $localport = $_REQUEST['localport'];
73 $remoteport = $_REQUEST['remoteport'];
74 $proto = $_REQUEST['proto'];
75 $description = $_REQUEST['description'];
76
77 $retpage="${root}?page=${pageno}&tab=${tabno}&object_id=$object_id";
78
79 $error=updatePortForwarding($object_id, $localip, $localport, $remoteip, $remoteport, $proto, $description);
80 if ($error == '')
81 return "${retpage}&message=".urlencode('Port forwarding successfully updated.');
82 else
83 {
84 return "${retpage}&error=".urlencode($error);
85 }
86
87 }
88
89 function addPortForObject ()
90 {
91 global $root, $pageno, $tabno;
92
93 $object_id = $_REQUEST['object_id'];
94 $port_name = $_REQUEST['port_name'];
95 $port_l2address = $_REQUEST['port_l2address'];
96 $port_label = $_REQUEST['port_label'];
97 $port_type_id = $_REQUEST['port_type_id'];
98
99
100 if ($port_name == '')
101 return "${root}?page=${pageno}&tab=${tabno}&object_id=${object_id}&error=".urlencode('Port name cannot be empty');
102 else
103 {
104 $error = commitAddPort ($object_id, $port_name, $port_type_id, $port_label, $port_l2address);
105 if ($error != '')
106 {
107 return "${root}?page=${pageno}&tab=${tabno}&object_id=${object_id}&error=".urlencode($error);
108 }
109 else
110 {
111 return "${root}?page=${pageno}&tab=${tabno}&object_id=${object_id}&message=".urlencode("Port $port_name added successfully");
112 }
113 }
114
115 }
116
117 function editPortForObject ()
118 {
119 global $root, $pageno, $tabno;
120
121 assertUIntArg ('port_id');
122 assertUIntArg ('object_id');
123 assertStringArg ('name');
124 $port_id = $_REQUEST['port_id'];
125 $object_id = $_REQUEST['object_id'];
126 $port_name = $_REQUEST['name'];
127 $port_l2address = $_REQUEST['l2address'];
128 $port_label = $_REQUEST['label'];
129 if (isset ($_REQUEST['reservation_comment']) and !empty ($_REQUEST['reservation_comment']))
130 $port_rc = '"' . $_REQUEST['reservation_comment'] . '"';
131 else
132 $port_rc = 'NULL';
133
134 if ($port_name == '')
135 return "${root}?page=${pageno}&tab=${tabno}&object_id=${object_id}&error=".urlencode('Port name cannot be empty');
136 else
137 {
138 $error = commitUpdatePort ($port_id, $port_name, $port_label, $port_l2address, $port_rc);
139 if ($error != '')
140 {
141 return "${root}?page=${pageno}&tab=${tabno}&object_id=${object_id}&error=".urlencode($error);
142 }
143 else
144 {
145 return "${root}?page=${pageno}&tab=${tabno}&object_id=${object_id}&message=".urlencode("Port $port_name updated successfully");
146 }
147 }
148
149 }
150
151 function delPortFromObject ()
152 {
153 global $root, $pageno, $tabno;
154
155 $port_id = $_REQUEST['port_id'];
156 $port_name = $_REQUEST['port_name'];
157 $object_id = $_REQUEST['object_id'];
158 $error = delObjectPort($port_id);
159
160 if ($error != '')
161 {
162 return "${root}?page=${pageno}&tab=${tabno}&object_id=${object_id}&error=".urlencode($error);
163 }
164 else
165 {
166 return "${root}?page=${pageno}&tab=${tabno}&object_id=${object_id}&message=".urlencode("Port $port_name deleted successfully");
167 }
168 }
169
170 function linkPortForObject ()
171 {
172 global $root, $pageno, $tabno;
173
174 $port_id = $_REQUEST['port_id'];
175 $remote_port_id = $_REQUEST['remote_port_id'];
176 $object_id = $_REQUEST['object_id'];
177 $port_name = $_REQUEST['port_name'];
178 $remote_port_name = $_REQUEST['remote_port_name'];
179 $remote_object_name = $_REQUEST['remote_object_name'];
180
181 $error = linkPorts($port_id, $remote_port_id);
182 if ($error != '')
183 {
184 return "${root}?page=${pageno}&tab=${tabno}&object_id=${object_id}&error=".urlencode($error);
185 }
186 else
187 {
188 return "${root}?page=${pageno}&tab=${tabno}&object_id=${object_id}&message=".urlencode("Port $port_name successfully linked with port $remote_port_name at object $remote_object_name");
189 }
190 }
191
192 function unlinkPortForObject ()
193 {
194 global $root, $pageno, $tabno;
195
196 $port_id = $_REQUEST['port_id'];
197 $object_id = $_REQUEST['object_id'];
198 $port_name = $_REQUEST['port_name'];
199 $remote_port_name = $_REQUEST['remote_port_name'];
200 $remote_object_name = $_REQUEST['remote_object_name'];
201
202 $error = unlinkPort($port_id);
203 if ($error != '')
204 {
205 return "${root}?page=${pageno}&tab=${tabno}&object_id=${object_id}&error=".urlencode($error);
206 }
207 else
208 {
209 return "${root}?page=${pageno}&tab=${tabno}&object_id=${object_id}&message=".urlencode("Port $port_name successfully unlinked from port $remote_port_name at object $remote_object_name");
210 }
211 }
212
213 function addMultiPorts ()
214 {
215 global $root, $pageno, $tabno;
216 // Parse data.
217 assertStringArg ('format');
218 assertStringArg ('input');
219 assertUIntArg ('port_type');
220 assertUIntArg ('object_id');
221 $format = $_REQUEST['format'];
222 $port_type = $_REQUEST['port_type'];
223 $object_id = $_REQUEST['object_id'];
224 // Input lines are escaped, so we have to explode and to chop by 2-char
225 // \n and \r respectively.
226 $lines1 = explode ('\n', $_REQUEST['input']);
227 foreach ($lines1 as $line)
228 {
229 $parts = explode ('\r', $line);
230 reset ($parts);
231 if (empty ($parts[0]))
232 continue;
233 else
234 $lines2[] = rtrim ($parts[0]);
235 }
236 $ports = array();
237 foreach ($lines2 as $line)
238 {
239 switch ($format)
240 {
241 case 'fisxii':
242 $words = explode (' ', ereg_replace ('[[:space:]]+', ' ', $line));
243 list ($slot, $port) = explode ('/', $words[0]);
244 $ports[] = array
245 (
246 'name' => "e ${slot}/${port}",
247 'l2address' => $words[8],
248 'label' => "slot ${slot} port ${port}"
249 );
250 break;
251 case 'c3600asy':
252 $words = explode (' ', ereg_replace ('[[:space:]]+', ' ', trim (substr ($line, 3))));
253 /*
254 How Async Lines are Numbered in Cisco 3600 Series Routers
255 http://www.cisco.com/en/US/products/hw/routers/ps274/products_tech_note09186a00801ca70b.shtml
256
257 Understanding 16- and 32-Port Async Network Modules
258 http://www.cisco.com/en/US/products/hw/routers/ps274/products_tech_note09186a00800a93f0.shtml
259 */
260 $async = $words[0];
261 $slot = floor (($async - 1) / 32);
262 $octalgroup = floor (($async - 1 - $slot * 32) / 8);
263 $cable = $async - $slot * 32 - $octalgroup * 8;
264 $og_label[0] = 'async 0-7';
265 $og_label[1] = 'async 8-15';
266 $og_label[2] = 'async 16-23';
267 $og_label[3] = 'async 24-31';
268 $ports[] = array
269 (
270 'name' => "async ${async}",
271 'l2address' => '',
272 'label' => "slot ${slot} " . $og_label[$octalgroup] . " cable ${cable}"
273 );
274 break;
275 case 'fiwg':
276 $words = explode (' ', ereg_replace ('[[:space:]]+', ' ', $line));
277 $ifnumber = $words[0] * 1;
278 $ports[] = array
279 (
280 'name' => "e ${ifnumber}",
281 'l2address' => "${words[8]}",
282 'label' => "${ifnumber}"
283 );
284 break;
285 case 'ssv1':
286 $words = explode (' ', $line);
287 if (empty ($words[0]) or empty ($words[1]))
288 continue;
289 $ports[] = array
290 (
291 'name' => $words[0],
292 'l2address' => $words[1],
293 'label' => ''
294 );
295 break;
296 default:
297 return
298 "${root}?page=${pageno}&tab=${tabno}&object_id=${object_id}&error=" .
299 urlencode('Cannot process submitted data: unknown format code.');
300 break;
301 }
302 }
303 // Create ports, if they don't exist.
304 $added_count = $updated_count = $error_count = 0;
305 foreach ($ports as $port)
306 {
307 $port_id = getPortID ($object_id, $port['name']);
308 if ($port_id === NULL)
309 {
310 $result = commitAddPort ($object_id, $port['name'], $port_type, $port['label'], $port['l2address']);
311 if ($result == '')
312 $added_count++;
313 else
314 $error_count++;
315 }
316 else
317 {
318 $result = commitUpdatePort ($port_id, $port['name'], $port['label'], $port['l2address']);
319 if ($result == '')
320 $updated_count++;
321 else
322 $error_count++;
323 }
324 }
325 return
326 "${root}?page=${pageno}&tab=${tabno}&object_id=${object_id}&message=" .
327 urlencode("Added ${added_count} ports, updated ${updated_count} ports, encountered ${error_count} errors.");
328 }
329
330 function editAddressFromObject ()
331 {
332 global $root;
333
334 $ip = $_REQUEST['ip'];
335 $object_id = $_REQUEST['object_id'];
336 $name = $_REQUEST['bond_name'];
337 $type = $_REQUEST['bond_type'];
338 $error = updateBond($ip, $object_id, $name, $type);
339 if ($error != '')
340 {
341 return "${root}?page=object&tab=network&object_id=$object_id&error=".urlencode($error);
342 }
343 else
344 {
345 return "${root}?page=object&tab=network&object_id=$object_id&message=".urlencode("Interface successfully updated");
346 }
347 }
348
349 function delAddressFromObject ()
350 {
351 global $root;
352
353 $ip = $_REQUEST['ip'];
354 $object_id = $_REQUEST['object_id'];
355 $error = unbindIpFromObject($ip, $object_id);
356 if ($error != '')
357 {
358 return "${root}?page=object&tab=network&object_id=$object_id&error=".urlencode($error);
359 }
360 else
361 {
362 return "${root}?page=object&tab=network&object_id=$object_id&message=".urlencode("Interface successfully deleted");
363 }
364 }
365
366 function delIpAssignment ()
367 {
368 global $root;
369
370 $ip = $_REQUEST['ip'];
371 $object_id = $_REQUEST['object_id'];
372 $error = unbindIpFromObject($ip, $object_id);
373 if ($error != '')
374 {
375 return "${root}?page=ipaddress&tab=assignment&ip=$ip&error=".urlencode($error);
376 }
377 else
378 {
379 return "${root}?page=ipaddress&tab=assignment&ip=$ip&message=".urlencode("Interface successfully deleted");
380 }
381 }
382
383 function editIpAssignment ()
384 {
385 global $root;
386
387 $ip = $_REQUEST['ip'];
388 $object_id = $_REQUEST['object_id'];
389 $name = $_REQUEST['bond_name'];
390 $type = $_REQUEST['bond_type'];
391 $error = updateBond($ip, $object_id, $name, $type);
392
393 if ($error != '')
394 {
395 return "${root}?page=ipaddress&tab=assignment&ip=$ip&error=".urlencode($error);
396 }
397 else
398 {
399 return "${root}?page=ipaddress&tab=assignment&ip=$ip&message=".urlencode("Interface successfully updated");
400 }
401 }
402
403 function addIpAssignment ()
404 {
405 global $root;
406
407 $ip = $_REQUEST['ip'];
408 $object_id = $_REQUEST['object_id'];
409 $name = $_REQUEST['bond_name'];
410 $type = $_REQUEST['bond_type'];
411 $error = bindIpToObject($ip, $object_id, $name, $type);
412 if ($error != '')
413 {
414 return "${root}?page=ipaddress&tab=assignment&ip=$ip&error=".urlencode($error);
415 }
416 else
417 {
418 return "${root}?page=ipaddress&tab=assignment&ip=$ip&message=".urlencode("Interface successfully added");
419 }
420 }
421
422 function addNewRange ()
423 {
424 global $root, $pageno, $tabno;
425
426 $range = $_REQUEST['range'];
427 $name = $_REQUEST['name'];
428 $is_bcast = $_REQUEST['is_bcast'];
429 $error = addRange($range, $name, $is_bcast == 'on');
430 if ($error != '')
431 {
432 return "${root}?page=${pageno}&tab=${tabno}&error=".urlencode($error);
433 }
434 else
435 {
436 return "${root}?page=${pageno}&tab=${tabno}&message=".urlencode("Range successfully added");
437 }
438 }
439
440 function editRange ()
441 {
442 global $root, $pageno, $tabno;
443
444 $id = $_REQUEST['id'];
445 $name = $_REQUEST['name'];
446 $error = updateRange($id, $name);
447 if ($error != '')
448 {
449 return "${root}?page=${pageno}&tab=${tabno}&id=$id&error=".urlencode($error);
450 }
451 else
452 {
453 return "${root}?page=${pageno}&tab=${tabno}&id=$id&message=".urlencode("Range updated");
454 }
455
456 }
457
458 function delRange ()
459 {
460 global $root, $pageno, $tabno;
461
462 $id = $_REQUEST['id'];
463 $error = commitDeleteRange ($id);
464 if ($error != '')
465 {
466 return "${root}?page=${pageno}&tab=${tabno}&error=".urlencode($error);
467 }
468 else
469 {
470 return "${root}?page=${pageno}&tab=${tabno}&message=".urlencode("Range deleted");
471 }
472
473 }
474
475 function editAddress ()
476 {
477 global $root, $pageno, $tabno;
478
479 $ip = $_REQUEST['ip'];
480 $name = $_REQUEST['name'];
481 if (isset ($_REQUEST['reserved']))
482 $reserved = $_REQUEST['reserved'];
483 else
484 $reserved = 'off';
485 $error = updateAddress($ip, $name, $reserved=='on'?'yes':'no');
486 if ($error != '')
487 {
488 return "${root}?page=${pageno}&tab=${tabno}&ip=$ip&error=".urlencode($error);
489 }
490 else
491 {
492 return "${root}?page=${pageno}&tab=${tabno}&ip=$ip&message=".urlencode("Address updated");
493 }
494
495 }
496
497 function addAddressToObject ()
498 {
499 global $root, $pageno, $tabno;
500
501 assertStringArg ('ip');
502 assertUIntArg ('object_id');
503 assertStringArg ('name', TRUE);
504 assertStringArg ('type');
505 // Strip masklen.
506 $ip = ereg_replace ('/[[:digit:]]+$', '', $_REQUEST['ip']);
507 $object_id = $_REQUEST['object_id'];
508 $error = bindIpToObject($ip, $object_id, $_REQUEST['name'], $_REQUEST['type']);
509 if ($error != '')
510 return "${root}?page=${pageno}&tab=${tabno}&object_id=${object_id}&error=".urlencode($error);
511 else
512 return "${root}?page=$pageno&tab=${tabno}&object_id=${object_id}&message=".
513 urlencode("Address ${ip} was added successfully.");
514 }
515
516 function createUserAccount ()
517 {
518 global $root, $pageno, $tabno;
519 assertStringArg ('username');
520 assertStringArg ('realname', TRUE);
521 assertStringArg ('password');
522 $username = $_REQUEST['username'];
523 $password = hash (PASSWORD_HASH, $_REQUEST['password']);
524 $result = commitCreateUserAccount ($username, $_REQUEST['realname'], $password);
525 if ($result == TRUE)
526 return "${root}?page=${pageno}&tab=${tabno}&message=" . urlencode ("User account ${username} created.");
527 else
528 return "${root}?page=${pageno}&tab=${tabno}&error=" . urlencode ("Error creating user account ${username}.");
529 }
530
531 function updateUserAccount ()
532 {
533 global $root, $pageno, $tabno;
534 assertUIntArg ('id');
535 assertStringArg ('username');
536 assertStringArg ('realname', TRUE);
537 assertStringArg ('password');
538 // We might be asked to change username, so use user ID only.
539 $id = $_REQUEST['id'];
540 $username = $_REQUEST['username'];
541 $new_password = $_REQUEST['password'];
542 $old_hash = getHashByID ($id);
543 if ($old_hash == NULL)
544 {
545 showError ('getHashByID() failed', __FUNCTION__);
546 return;
547 }
548 // Update user password only if provided password is not the same as current password hash.
549 if ($new_password != $old_hash)
550 $new_password = hash (PASSWORD_HASH, $new_password);
551 $result = commitUpdateUserAccount ($_REQUEST['id'], $username, $_REQUEST['realname'], $new_password);
552 if ($result == TRUE)
553 return "${root}?page=${pageno}&tab=${tabno}&message=" . urlencode ("User account ${username} updated.");
554 else
555 return "${root}?page=${pageno}&tab=${tabno}&error=" . urlencode ("Error updating user account ${username}.");
556 }
557
558 function enableUserAccount ()
559 {
560 global $root, $pageno, $tabno;
561 assertUIntArg ('id');
562 $id = $_REQUEST['id'];
563 $result = commitEnableUserAccount ($id, 'yes');
564 if ($result == TRUE)
565 return "${root}?page=${pageno}&tab=${tabno}&message=" . urlencode ("User account enabled.");
566 else
567 return "${root}?page=${pageno}&tab=${tabno}&error=" . urlencode ("Error enabling user account.");
568 }
569
570 function disableUserAccount ()
571 {
572 global $root, $pageno, $tabno;
573 assertUIntArg ('id');
574 $id = $_REQUEST['id'];
575 if ($id == 1)
576 $result = FALSE;
577 else
578 $result = commitEnableUserAccount ($id, 'no');
579 if ($result == TRUE)
580 return "${root}?page=${pageno}&tab=${tabno}&message=" . urlencode ("User account disabled.");
581 else
582 return "${root}?page=${pageno}&tab=${tabno}&error=" . urlencode ("Error disabling user account.");
583 }
584
585 function revokePermission ()
586 {
587 global $root, $pageno, $tabno;
588 assertUIntArg ('access_userid', TRUE);
589 assertStringArg ('access_page');
590 assertStringArg ('access_tab');
591 $result = commitRevokePermission
592 (
593 $_REQUEST['access_userid'],
594 $_REQUEST['access_page'],
595 $_REQUEST['access_tab']
596 );
597 if ($result == TRUE)
598 return "${root}?page=${pageno}&tab=${tabno}&message=" . urlencode ("Revoke successfull.");
599 else
600 return "${root}?page=${pageno}&tab=${tabno}&error=" . urlencode ("Error revoking permission.");
601 }
602
603 function grantPermission ()
604 {
605 global $root, $pageno, $tabno;
606 assertUIntArg ('access_userid', TRUE);
607 assertStringArg ('access_page');
608 assertStringArg ('access_tab');
609 assertStringArg ('access_value');
610 $result = commitGrantPermission
611 (
612 $_REQUEST['access_userid'],
613 $_REQUEST['access_page'],
614 $_REQUEST['access_tab'],
615 $_REQUEST['access_value']
616 );
617 if ($result == TRUE)
618 return "${root}?page=${pageno}&tab=${tabno}&message=" . urlencode ("Grant successfull.");
619 else
620 return "${root}?page=${pageno}&tab=${tabno}&error=" . urlencode ("Error granting permission.");
621 }
622
623 // This function find differences in users's submit and PortCompat table
624 // and modifies database accordingly.
625 function savePortMap ()
626 {
627 global $root, $pageno, $tabno;
628 $ptlist = getPortTypes();
629 $oldCompat = getPortCompat();
630 $newCompat = array();
631 foreach (array_keys ($ptlist) as $leftKey)
632 foreach (array_keys ($ptlist) as $rightKey)
633 if (isset ($_REQUEST["atom_${leftKey}_${rightKey}"]))
634 $newCompat[] = array ('type1' => $leftKey, 'type2' => $rightKey);
635 // Build the new matrix from user's submit and compare it to
636 // the old matrix. Those pairs which appear on
637 // new matrix only, have to be stored in PortCompat table. Those who appear
638 // on the old matrix only, should be removed from PortCompat table.
639 // Those present in both matrices should be skipped.
640 $oldCompatTable = buildPortCompatMatrixFromList ($ptlist, $oldCompat);
641 $newCompatTable = buildPortCompatMatrixFromList ($ptlist, $newCompat);
642 $error_count = $success_count = 0;
643 foreach (array_keys ($ptlist) as $type1)
644 foreach (array_keys ($ptlist) as $type2)
645 if ($oldCompatTable[$type1][$type2] != $newCompatTable[$type1][$type2])
646 switch ($oldCompatTable[$type1][$type2])
647 {
648 case TRUE: // new value is FALSE
649 if (removePortCompat ($type1, $type2) === TRUE)
650 $success_count++;
651 else
652 $error_count++;
653 break;
654 case FALSE: // new value is TRUE
655 if (addPortCompat ($type1, $type2) === TRUE)
656 $success_count++;
657 else
658 $error_count++;
659 break;
660 default:
661 showError ('oldCompatTable is invalid', __FUNCTION__);
662 break;
663 }
664 return
665 "${root}?page=${pageno}&tab=${tabno}&" .
666 ($error_count == 0 ? 'message' : 'error') .
667 "=" . urlencode ("${error_count} failures and ${success_count} successfull changes.");
668 }
669
670 function deleteDictWord ()
671 {
672 global $root, $pageno, $tabno;
673 return
674 "${root}?page=${pageno}&tab=${tabno}&" .
675 "error=" . urlencode ('Dragon ate this word!');
676 }
677
678 function updateDictionary ()
679 {
680 global $root, $pageno, $tabno;
681 assertUIntArg ('chapter_no');
682 assertUIntArg ('dict_key');
683 assertStringArg ('dict_value');
684 if (commitUpdateDictionary ($_REQUEST['chapter_no'], $_REQUEST['dict_key'], $_REQUEST['dict_value']) === TRUE)
685 return "${root}?page=${pageno}&tab=${tabno}&message=" . urlencode ('Update succeeded.');
686 else
687 return "${root}?page=${pageno}&tab=${tabno}&error=" . urlencode ("Update failed!");
688 }
689
690 function supplementDictionary ()
691 {
692 global $root, $pageno, $tabno;
693 assertUIntArg ('chapter_no');
694 assertStringArg ('dict_value');
695 if (commitSupplementDictionary ($_REQUEST['chapter_no'], $_REQUEST['dict_value']) === TRUE)
696 return "${root}?page=${pageno}&tab=${tabno}&message=" . urlencode ('Supplement succeeded.');
697 else
698 return "${root}?page=${pageno}&tab=${tabno}&error=" . urlencode ("Supplement failed!");
699 }
700
701 function reduceDictionary ()
702 {
703 global $root, $pageno, $tabno;
704 assertUIntArg ('chapter_no');
705 assertUIntArg ('dict_key');
706 if (commitReduceDictionary ($_REQUEST['chapter_no'], $_REQUEST['dict_key']) === TRUE)
707 return "${root}?page=${pageno}&tab=${tabno}&message=" . urlencode ('Reduction succeeded.');
708 else
709 return "${root}?page=${pageno}&tab=${tabno}&error=" . urlencode ("Reduction failed!");
710 }
711
712 function addChapter ()
713 {
714 global $root, $pageno, $tabno;
715 assertStringArg ('chapter_name');
716 if (commitAddChapter ($_REQUEST['chapter_name']) === TRUE)
717 return "${root}?page=${pageno}&tab=${tabno}&message=" . urlencode ('Chapter was added.');
718 else
719 return "${root}?page=${pageno}&tab=${tabno}&error=" . urlencode ('Error adding chapter.');
720 }
721
722 function updateChapter ()
723 {
724 global $root, $pageno, $tabno;
725 assertUIntArg ('chapter_no');
726 assertStringArg ('chapter_name');
727 if (commitUpdateChapter ($_REQUEST['chapter_no'], $_REQUEST['chapter_name']) === TRUE)
728 return "${root}?page=${pageno}&tab=${tabno}&message=" . urlencode ('Chapter was updated.');
729 else
730 return "${root}?page=${pageno}&tab=${tabno}&error=" . urlencode ('Error updating chapter.');
731 }
732
733 function delChapter ()
734 {
735 global $root, $pageno, $tabno;
736 assertUIntArg ('chapter_no');
737 if (commitDeleteChapter ($_REQUEST['chapter_no']))
738 return "${root}?page=${pageno}&tab=${tabno}&message=" . urlencode ('Chapter was deleted.');
739 else
740 return "${root}?page=${pageno}&tab=${tabno}&error=" . urlencode ('Error deleting chapter.');
741 }
742
743 function changeAttribute ()
744 {
745 global $root, $pageno, $tabno;
746 assertUIntArg ('attr_id');
747 assertStringArg ('attr_name');
748 if (commitUpdateAttribute ($_REQUEST['attr_id'], $_REQUEST['attr_name']))
749 return "${root}?page=${pageno}&tab=${tabno}&message=" . urlencode ('Rename successful.');
750 else
751 return "${root}?page=${pageno}&tab=${tabno}&error=" . urlencode ('Error renaming attribute.');
752 }
753
754 function createAttribute ()
755 {
756 global $root, $pageno, $tabno;
757 assertStringArg ('attr_name');
758 assertStringArg ('attr_type');
759 if (commitAddAttribute ($_REQUEST['attr_name'], $_REQUEST['attr_type']))
760 return "${root}?page=${pageno}&tab=${tabno}&message=" . urlencode ("Attribute '${_REQUEST['attr_name']}' created.");
761 else
762 return "${root}?page=${pageno}&tab=${tabno}&error=" . urlencode ('Error creating attribute.');
763 }
764
765 function deleteAttribute ()
766 {
767 global $root, $pageno, $tabno;
768 assertUIntArg ('attr_id');
769 if (commitDeleteAttribute ($_REQUEST['attr_id']))
770 return "${root}?page=${pageno}&tab=${tabno}&message=" . urlencode ('Attribute was deleted.');
771 else
772 return "${root}?page=${pageno}&tab=${tabno}&error=" . urlencode ('Error deleting attribute.');
773 }
774
775 function supplementAttrMap ()
776 {
777 global $root, $pageno, $tabno;
778 assertUIntArg ('attr_id');
779 assertUIntArg ('objtype_id');
780 assertUIntArg ('chapter_no');
781 if (commitSupplementAttrMap ($_REQUEST['attr_id'], $_REQUEST['objtype_id'], $_REQUEST['chapter_no']) === TRUE)
782 return "${root}?page=${pageno}&tab=${tabno}&message=" . urlencode ('Supplement succeeded.');
783 else
784 return "${root}?page=${pageno}&tab=${tabno}&error=" . urlencode ("Supplement failed!");
785 }
786
787 function reduceAttrMap ()
788 {
789 global $root, $pageno, $tabno;
790 assertUIntArg ('attr_id');
791 assertUIntArg ('objtype_id');
792 if (commitReduceAttrMap ($_REQUEST['attr_id'], $_REQUEST['objtype_id']) === TRUE)
793 return "${root}?page=${pageno}&tab=${tabno}&message=" . urlencode ('Reduction succeeded.');
794 else
795 return "${root}?page=${pageno}&tab=${tabno}&error=" . urlencode ("Reduction failed!");
796 }
797
798 function resetAttrValue ()
799 {
800 global $root, $pageno, $tabno;
801 assertUIntArg ('attr_id');
802 assertUIntArg ('object_id');
803 $object_id = $_REQUEST['object_id'];
804 if (commitResetAttrValue ($object_id, $_REQUEST['attr_id']) === TRUE)
805 return "${root}?page=${pageno}&tab=${tabno}&object_id=${object_id}&message=" . urlencode ('Reset succeeded.');
806 else
807 return "${root}?page=${pageno}&tab=${tabno}&object_id=${object_id}&error=" . urlencode ("Reset failed!");
808 }
809
810 function updateAttrValues ()
811 {
812 global $root, $pageno, $tabno;
813 assertUIntArg ('object_id');
814 $object_id = $_REQUEST['object_id'];
815 $oldvalues = getAttrValues ($object_id);
816
817 assertUIntArg ('num_attrs');
818 $num_attrs = $_REQUEST['num_attrs'];
819 $result = array();
820
821 for ($i = 0; $i < $num_attrs; $i++)
822 {
823 assertUIntArg ("${i}_attr_id");
824 $attr_id = $_REQUEST["${i}_attr_id"];
825
826 // Field is empty, delete attribute and move on.
827 if (empty($_REQUEST["${i}_value"]))
828 {
829 commitResetAttrValue ($object_id, $attr_id);
830 continue;
831 }
832
833 // The value could be uint/float, but we don't know ATM. Let SQL
834 // server check this and complain.
835 assertStringArg ("${i}_value");
836 $value = $_REQUEST["${i}_value"];
837 switch ($oldvalues[$attr_id]['type'])
838 {
839 case 'uint':
840 case 'float':
841 case 'string':
842 $oldvalue = $oldvalues[$attr_id]['value'];
843 break;
844 case 'dict':
845 $oldvalue = $oldvalues[$attr_id]['key'];
846 break;
847 default:
848 showError ('Internal structure error', __FUNCTION__);
849 die;
850 }
851 if ($value == $oldvalue)
852 continue;
853
854 // Note if the queries succeed or not, it determines which page they see.
855 $result[] = commitUpdateAttrValue ($object_id, $attr_id, $value);
856 }
857
858 if (in_array(false, $result))
859 return "${root}?page=${pageno}&tab=${tabno}&object_id=${object_id}&error=" . urlencode ("Update failed!");
860
861 return "${root}?page=${pageno}&tab=${tabno}&object_id=${object_id}&message=" . urlencode ('Update succeeded.');
862 }
863
864 function useupPort ()
865 {
866 global $root, $pageno, $tabno;
867 assertUIntArg ('port_id');
868 assertUIntArg ('object_id');
869 $object_id = $_REQUEST['object_id'];
870 if (commitUseupPort ($_REQUEST['port_id']) === TRUE)
871 return "${root}?page=${pageno}&tab=${tabno}&object_id=${object_id}&message=" . urlencode ('Reservation removed.');
872 else
873 return "${root}?page=${pageno}&tab=${tabno}&object_id=${object_id}&error=" . urlencode ("Error removing reservation!");
874 }
875
876 function updateUI ()
877 {
878 global $root, $pageno, $tabno;
879 $oldvalues = loadConfigCache();
880
881 assertUIntArg ('num_vars');
882 $num_vars = $_REQUEST['num_vars'];
883 $error = '';
884
885 for ($i = 0; $i < $num_vars; $i++)
886 {
887 assertStringArg ("${i}_varname");
888 assertStringArg ("${i}_varvalue", TRUE);
889 $varname = $_REQUEST["${i}_varname"];
890 $varvalue = $_REQUEST["${i}_varvalue"];
891
892 // If form value = value in DB, don't bother updating DB
893 if ($varvalue == getConfigVar ($varname))
894 continue;
895
896 // Note if the queries succeed or not, it determines which page they see.
897 $error = setConfigVar ($varname, $varvalue, TRUE);
898 if (!empty ($error))
899 break;
900 }
901
902 if ($error != '')
903 return "${root}?page=${pageno}&tab=${tabno}&error=" . urlencode ("Update failed with error: " . $error);
904
905 return "${root}?page=${pageno}&tab=${tabno}&message=" . urlencode ("Update succeeded.");
906 }
907
908 function resetUIConfig()
909 {
910 global $root, $pageno, $tabno;
911 setConfigVar ('default_port_type','24');
912 setConfigVar ('MASSCOUNT','15');
913 setConfigVar ('MAXSELSIZE','30');
914 setConfigVar ('NAMEFUL_OBJTYPES','4,7,8');
915 setConfigVar ('ROW_SCALE','2');
916 setConfigVar ('PORTS_PER_ROW','12');
917 setConfigVar ('IPV4_ADDRS_PER_PAGE','256');
918 setConfigVar ('DEFAULT_RACK_HEIGHT','42');
919 setConfigVar ('REQUIRE_ASSET_TAG_FOR','4,7,8');
920 setConfigVar ('USER_AUTH_SRC','database');
921 setConfigVar ('DEFAULT_SLB_VS_PORT','');
922 setConfigVar ('DEFAULT_SLB_RS_PORT','');
923 setConfigVar ('IPV4_PERFORMERS','1,4,7,8,12,14,445,447');
924 setConfigVar ('NATV4_PERFORMERS','4,7,8');
925 setConfigVar ('DETECT_URLS','no');
926 setConfigVar ('RACK_PRESELECT_THRESHOLD','1');
927 setConfigVar ('DEFAULT_IPV4_RS_INSERVICE','no');
928 setConfigVar ('AUTOPORTS_CONFIG','4 = 1*33*kvm + 2*24*eth%u;15 = 1*446*kvm');
929 setConfigVar ('DEFAULT_OBJECT_TYPE','4');
930 return "${root}?page=${pageno}&tab=default&message=" . urlencode ("Reset complete");
931 }
932
933 // Add single record.
934 function addRealServer ()
935 {
936 global $root, $pageno, $tabno;
937
938 assertUIntArg ('id');
939 assertIPv4Arg ('remoteip');
940 assertUIntArg ('rsport');
941 assertStringArg ('rsconfig', TRUE);
942 $pool_id = $_REQUEST['id'];
943 if (!addRStoRSPool ($pool_id, $_REQUEST['remoteip'], $_REQUEST['rsport'], getConfigVar ('DEFAULT_IPV4_RS_INSERVICE'), $_REQUEST['rsconfig']))
944 return "${root}?page=${pageno}&tab=${tabno}&id=${pool_id}&error=" . urlencode ('addRStoRSPool() failed');
945 else
946 return "${root}?page=${pageno}&tab=${tabno}&id=${pool_id}&message=" . urlencode ("Real server was successfully added");
947 }
948
949 // Parse textarea submitted and try adding a real server for each line.
950 function addRealServers ()
951 {
952 global $root, $pageno, $tabno;
953
954 assertUIntArg ('id');
955 assertStringArg ('format');
956 assertStringArg ('rawtext');
957 $pool_id = $_REQUEST['id'];
958 $rawtext = str_replace ('\r', '', $_REQUEST['rawtext']);
959 $ngood = $nbad = 0;
960 $rsconfig = '';
961 // Keep in mind, that the text will have HTML entities (namely '>') escaped.
962 foreach (explode ('\n', $rawtext) as $line)
963 {
964 if (empty ($line))
965 continue;
966 $match = array ();
967 switch ($_REQUEST['format'])
968 {
969 case 'ipvs_2': // address and port only
970 if (!preg_match ('/^ -&gt; ([0-9\.]+):([0-9]+) /', $line, $match))
971 continue;
972 if (addRStoRSPool ($pool_id, $match[1], $match[2], getConfigVar ('DEFAULT_IPV4_RS_INSERVICE'), ''))
973 $ngood++;
974 else
975 $nbad++;
976 break;
977 case 'ipvs_3': // address, port and weight
978 if (!preg_match ('/^ -&gt; ([0-9\.]+):([0-9]+) +[a-zA-Z]+ +([0-9]+) /', $line, $match))
979 continue;
980 if (addRStoRSPool ($pool_id, $match[1], $match[2], getConfigVar ('DEFAULT_IPV4_RS_INSERVICE'), 'weight ' . $match[3]))
981 $ngood++;
982 else
983 $nbad++;
984 break;
985 case 'ssv_2': // IP address and port
986 if (!preg_match ('/^([0-9\.]+) ([0-9]+)$/', $line, $match))
987 continue;
988 if (addRStoRSPool ($pool_id, $match[1], $match[2], getConfigVar ('DEFAULT_IPV4_RS_INSERVICE'), ''))
989 $ngood++;
990 else
991 $nbad++;
992 break;
993 default:
994 return "${root}?page=${pageno}&tab=${tabno}&id=${pool_id}&error=" . urlencode (__FUNCTION__ . ': invalid format requested');
995 break;
996 }
997 }
998 if ($nbad == 0 and $ngood > 0)
999 return "${root}?page=${pageno}&tab=${tabno}&id=${pool_id}&message=" . urlencode ("Successfully added ${ngood} real servers");
1000 else
1001 return "${root}?page=${pageno}&tab=${tabno}&id=${pool_id}&error=" . urlencode ("Added ${ngood} real servers and encountered ${nbad} errors");
1002 }
1003
1004 function addVService ()
1005 {
1006 global $root, $pageno, $tabno;
1007
1008 assertIPv4Arg ('vip');
1009 assertUIntArg ('vport');
1010 assertStringArg ('proto');
1011 $proto = $_REQUEST['proto'];
1012 if ($proto != 'TCP' and $proto != 'UDP')
1013 return "${root}?page=${pageno}&tab=${tabno}&error=" . urlencode (__FUNCTION__ . ': invalid protocol');
1014 assertStringArg ('name', TRUE);
1015 assertStringArg ('vsconfig', TRUE);
1016 assertStringArg ('rsconfig', TRUE);
1017 $pool_id = $_REQUEST['id'];
1018 if (!commitCreateVS ($_REQUEST['vip'], $_REQUEST['vport'], $proto, $_REQUEST['name'], $_REQUEST['vsconfig'], $_REQUEST['rsconfig']))
1019 return "${root}?page=${pageno}&tab=${tabno}&error=" . urlencode ('commitCreateVS() failed');
1020 else
1021 return "${root}?page=${pageno}&tab=${tabno}&message=" . urlencode ("Virtual service was successfully created");
1022 }
1023
1024 function deleteRealServer ()
1025 {
1026 global $root, $pageno, $tabno;
1027
1028 assertUIntArg ('pool_id');
1029 assertUIntArg ('id');
1030 $pool_id = $_REQUEST['pool_id'];
1031 if (!commitDeleteRS ($_REQUEST['id']))
1032 return "${root}?page=${pageno}&tab=${tabno}&id=${pool_id}&error=" . urlencode ('commitDeleteRS() failed');
1033 else
1034 return "${root}?page=${pageno}&tab=${tabno}&id=${pool_id}&message=" . urlencode ("Real server was successfully deleted");
1035 }
1036
1037 function deleteLoadBalancer ()
1038 {
1039 global $root, $pageno, $tabno;
1040
1041 assertUIntArg ('object_id');
1042 assertUIntArg ('pool_id');
1043 assertUIntArg ('vs_id');
1044 $pool_id = $_REQUEST['pool_id'];
1045 if (!commitDeleteLB ($_REQUEST['object_id'], $pool_id, $_REQUEST['vs_id']))
1046 return "${root}?page=${pageno}&tab=${tabno}&id=${pool_id}&error=" . urlencode ('commitDeleteLB() failed');
1047 else
1048 return "${root}?page=${pageno}&tab=${tabno}&id=${pool_id}&message=" . urlencode ("Load balancer was successfully deleted");
1049 }
1050
1051 function deleteVService ()
1052 {
1053 global $root, $pageno, $tabno;
1054
1055 assertUIntArg ('id');
1056 if (!commitDeleteVS ($_REQUEST['id']))
1057 return "${root}?page=${pageno}&tab=${tabno}&error=" . urlencode ('commitDeleteVS() failed');
1058 else
1059 return "${root}?page=${pageno}&tab=${tabno}&message=" . urlencode ("Virtual service was successfully deleted");
1060 }
1061
1062 function updateRealServer ()
1063 {
1064 global $root, $pageno, $tabno;
1065
1066 assertUIntArg ('id');
1067 assertUIntArg ('rs_id');
1068 assertIPv4Arg ('rsip');
1069 assertUIntArg ('rsport');
1070 assertStringArg ('rsconfig', TRUE);
1071 // only necessary for generating next URL
1072 $pool_id = $_REQUEST['id'];
1073 if (!commitUpdateRS ($_REQUEST['rs_id'], $_REQUEST['rsip'], $_REQUEST['rsport'], $_REQUEST['rsconfig']))
1074 return "${root}?page=${pageno}&tab=${tabno}&id=${pool_id}&error=" . urlencode ('commitUpdateRS() failed');
1075 else
1076 return "${root}?page=${pageno}&tab=${tabno}&id=${pool_id}&message=" . urlencode ("Real server was successfully updated");
1077 }
1078
1079 function updateLoadBalancer ()
1080 {
1081 global $root, $pageno, $tabno;
1082
1083 assertUIntArg ('object_id');
1084 assertUIntArg ('pool_id');
1085 assertUIntArg ('vs_id');
1086 assertStringArg ('vsconfig', TRUE);
1087 assertStringArg ('rsconfig', TRUE);
1088 $pool_id = $_REQUEST['pool_id'];
1089 if (!commitUpdateLB ($_REQUEST['object_id'], $pool_id, $_REQUEST['vs_id'], $_REQUEST['vsconfig'], $_REQUEST['rsconfig']))
1090 return "${root}?page=${pageno}&tab=${tabno}&id=${pool_id}&error=" . urlencode ('commitUpdateLB() failed');
1091 else
1092 return "${root}?page=${pageno}&tab=${tabno}&id=${pool_id}&message=" . urlencode ("Load balancer info was successfully updated");
1093 }
1094
1095 function updateVService ()
1096 {
1097 global $root, $pageno, $tabno;
1098
1099 assertUIntArg ('id');
1100 assertIPv4Arg ('vip');
1101 assertUIntArg ('vport');
1102 assertStringArg ('proto');
1103 assertStringArg ('name', TRUE);
1104 assertStringArg ('vsconfig', TRUE);
1105 assertStringArg ('rsconfig', TRUE);
1106 if (!commitUpdateVS ($_REQUEST['id'], $_REQUEST['vip'], $_REQUEST['vport'], $_REQUEST['proto'], $_REQUEST['name'], $_REQUEST['vsconfig'], $_REQUEST['rsconfig']))
1107 return "${root}?page=${pageno}&tab=${tabno}&error=" . urlencode ('commitUpdateVS() failed');
1108 else
1109 return "${root}?page=${pageno}&tab=${tabno}&message=" . urlencode ("Virtual service was successfully updated");
1110 }
1111
1112 function addLoadBalancer ()
1113 {
1114 global $root, $pageno, $tabno;
1115
1116 assertUIntArg ('pool_id');
1117 assertUIntArg ('object_id');
1118 assertUIntArg ('vs_id');
1119 assertStringArg ('vsconfig', TRUE);
1120 assertStringArg ('rsconfig', TRUE);
1121 $pool_id = $_REQUEST['pool_id'];
1122 if (!addLBtoRSPool ($pool_id, $_REQUEST['object_id'], $_REQUEST['vs_id'], $_REQUEST['vsconfig'], $_REQUEST['rsconfig']))
1123 return "${root}?page=${pageno}&tab=${tabno}&id=${pool_id}&error=" . urlencode ('addLBtoRSPool() failed');
1124 else
1125 return "${root}?page=${pageno}&tab=${tabno}&id=${pool_id}&message=" . urlencode ("Load balancer was successfully added");
1126 }
1127
1128 function addRSPool ()
1129 {
1130 global $root, $pageno, $tabno;
1131
1132 assertStringArg ('name', TRUE);
1133 assertStringArg ('vsconfig', TRUE);
1134 assertStringArg ('rsconfig', TRUE);
1135 if (!commitCreateRSPool ($_REQUEST['name'], $_REQUEST['vsconfig'], $_REQUEST['rsconfig']))
1136 return "${root}?page=${pageno}&tab=${tabno}&error=" . urlencode ('commitCreateRSPool() failed');
1137 else
1138 return "${root}?page=${pageno}&tab=${tabno}&message=" . urlencode ("Real server pool was successfully created");
1139 }
1140
1141 function deleteRSPool ()
1142 {
1143 global $root, $pageno, $tabno;
1144
1145 assertUIntArg ('id');
1146 if (!commitDeleteRSPool ($_REQUEST['id']))
1147 return "${root}?page=${pageno}&tab=${tabno}&error=" . urlencode ('commitDeleteRSPool() failed');
1148 else
1149 return "${root}?page=${pageno}&tab=${tabno}&message=" . urlencode ("Real server pool was successfully deleted");
1150 }
1151
1152 function updateRSPool ()
1153 {
1154 global $root, $pageno, $tabno;
1155
1156 assertUIntArg ('id');
1157 assertStringArg ('name', TRUE);
1158 assertStringArg ('vsconfig', TRUE);
1159 assertStringArg ('rsconfig', TRUE);
1160 if (!commitUpdateRSPool ($_REQUEST['id'], $_REQUEST['name'], $_REQUEST['vsconfig'], $_REQUEST['rsconfig']))
1161 return "${root}?page=${pageno}&tab=${tabno}&error=" . urlencode ('commitUpdateRSPool() failed');
1162 else
1163 return "${root}?page=${pageno}&tab=${tabno}&message=" . urlencode ("Real server pool was successfully updated");
1164 }
1165
1166 function updateRSInService ()
1167 {
1168 global $root, $pageno, $tabno;
1169 assertUIntArg ('id');
1170 assertUIntArg ('rscount');
1171 $pool_id = $_REQUEST['id'];
1172 $orig = getRSPoolInfo ($pool_id);
1173 $nbad = $ngood = 0;
1174 for ($i = 1; $i <= $_REQUEST['rscount']; $i++)
1175 {
1176 $rs_id = $_REQUEST["rsid_${i}"];
1177 if (isset ($_REQUEST["inservice_${i}"]) and $_REQUEST["inservice_${i}"] == 'on')
1178 $newval = 'yes';
1179 else
1180 $newval = 'no';
1181 if ($newval != $orig['rslist'][$rs_id]['inservice'])
1182 {
1183 if (commitSetInService ($rs_id, $newval))
1184 $ngood++;
1185 else
1186 $nbad++;
1187 }
1188 }
1189 if (!$nbad)
1190 return "${root}?page=${pageno}&tab=${tabno}&id=${pool_id}&message=" . urlencode ($ngood . " real server(s) were successfully (de)activated");
1191 else
1192 return "${root}?page=${pageno}&tab=${tabno}&id=${pool_id}&error=" . urlencode ("Encountered ${nbad} errors, (de)activated ${ngood} real servers");
1193 }
1194
1195 function importPTRData ()
1196 {
1197 global $root, $pageno, $tabno;
1198 assertUIntArg ('id');
1199 assertUIntArg ('addrcount');
1200 $nbad = $ngood = 0;
1201 $id = $_REQUEST['id'];
1202 for ($i = 0; $i < $_REQUEST['addrcount']; $i++)
1203 {
1204 $inputname = "import_${i}";
1205 if (!isset ($_REQUEST[$inputname]) or $_REQUEST[$inputname] != 'on')
1206 continue;
1207 assertIPv4Arg ("addr_${i}");
1208 assertStringArg ("descr_${i}", TRUE);
1209 assertStringArg ("rsvd_${i}");
1210 // Non-existent addresses will not have this argument set in request.
1211 $rsvd = 'no';
1212 if ($_REQUEST["rsvd_${i}"] == 'yes')
1213 $rsvd = 'yes';
1214 if (updateAddress ($_REQUEST["addr_${i}"], $_REQUEST["descr_${i}"], $rsvd) == '')
1215 $ngood++;
1216 else
1217 $nbad++;
1218 }
1219 if (!$nbad)
1220 return "${root}?page=${pageno}&tab=${tabno}&id=${id}&message=" . urlencode ($ngood . " IP address(es) were successfully updated");
1221 else
1222 return "${root}?page=${pageno}&tab=${tabno}&id=${id}&error=" . urlencode ("Encountered ${nbad} errors, updated ${ngood} IP address(es)");
1223 }
1224
1225 function generateAutoPorts ()
1226 {
1227 global $root, $pageno, $tabno;
1228 assertUIntArg ('object_id');
1229 $object_id = $_REQUEST['object_id'];
1230 $info = getObjectInfo ($object_id);
1231 // Navigate away in case of success, stay at the place otherwise.
1232 if (executeAutoPorts ($object_id, $info['objtype_id']))
1233 return "${root}?page=${pageno}&tab=ports&object_id=${object_id}&message=" . urlencode ('Generation complete');
1234 else
1235 return "${root}?page=${pageno}&tab=${tabno}&object_id=${object_id}&error=" . urlencode ('executeAutoPorts() failed');
1236 }
1237
1238 // Filter out implicit tags before storing the new tag set.
1239 function saveObjectTags ()
1240 {
1241 global $root, $pageno, $tabno, $explicit_tags, $implicit_tags;
1242 assertUIntArg ('object_id');
1243 $object_id = $_REQUEST['object_id'];
1244 // Build a trail from the submitted data, minimize it,
1245 // then wipe existing records and store the new set instead.
1246 useDeleteBlade ('RackObjectTags', 'object_id', $object_id);
1247 $newtrail = getExplicitTagsOnly (buildTrailFromIds ($_REQUEST['taglist']));
1248 $n_succeeds = $n_errors = 0;
1249 foreach ($newtrail as $taginfo)
1250 {
1251 if (useInsertBlade ('RackObjectTags', array ('object_id' => $object_id, 'tag_id' => $taginfo['id'])))
1252 $n_succeeds++;
1253 else
1254 $n_errors++;
1255 }
1256 if ($n_errors)
1257 return "${root}?page=${pageno}&tab=${tabno}&object_id=${object_id}&error=" . urlencode ("Replaced trail with ${n_succeeds} tags, but experienced ${n_errors} errors.");
1258 else
1259 return "${root}?page=${pageno}&tab=${tabno}&object_id=${object_id}&message=" . urlencode ("New trail is ${n_succeeds} tags long");
1260 }
1261
1262 ?>