3 # This file is a part of RackTables, a datacenter and server room management
4 # framework. See accompanying file "COPYING" for the full copyright and
5 # licensing information.
9 "Ophandler" in RackTables stands for "operation handler", or a function
10 that handles execution of "operation" (in the meaning explained in
11 navigation.php). Most of the ophandlers are meant to perform one specific
12 action, for example, to set a name of an object. Each such action often
13 requires a set of parameters (e. g. ID of the object and the new name),
14 and it is responsibility of each ophandler function to verify, that all
15 necessary parameters are provided by the user and have proper values. There
16 is a number of helper functions to make such verification simpler.
18 Errors occuring in ophandlers are typically indicated with exceptions of
19 assorted classes. Namely, an "InvalidRequestArgException" class means, that
20 at least one of the parameters provided by the user is not acceptable. This
21 is a "soft" error, which gets displayed in the standard message area of
22 otherwise usual interface. A different case is "InvalidArgException", which
23 means that one of the internal functions detected its argument(s) invalid
24 or corrupted, and that argument(s) did not come from user's input (and thus
25 cannot be fixed without fixing a bug in the code). Such "hard" errors don't
26 get special early handling and end up in the default catching block. The
27 latter may print a detailed stack trace instead of the interface HTML to
28 help a developer debug the issue.
30 As long as an ophandler makes through its request (extracting arguments,
31 performing validation and actually updating records in the database), it
32 may queue up messages (often referred to as "green" and "red" bars) by
33 means of showError() and showSuccess() functions. The messages are not
34 displayed immediately, because successfull ophandlers are expected to
35 return only the new URL, where the user will be immediately redirected to
36 (it is also possible to return an empty string to mean, that the current
37 logical location remains the same). The page at the "next" location is
38 supposed to translate message buffer into the standard message area.
40 A very special case of an ophandler is tableHandler(). This generic
41 function handles the most trivial actions, which map to a single INSERT,
42 UPDATE or DELETE SQL statement with a fixed number of arguments. The rules
43 of argument validation and mapping are listed in $opspec_list (operation
44 specifications list) array.
48 // This array is deprecated. Please do not add new message constants to it.
49 // use the new showError, showWarning, showSuccess functions instead
54 $opspec_list = array();
56 $opspec_list['object-edit-unlinkObjects'] = array
58 'table' => 'EntityLink',
62 array ('url_argname' => 'link_id', 'table_colname' => 'id', 'assertion' => 'uint'),
65 $opspec_list['object-ports-useup'] = array
69 'set_arglist' => array
71 array ('fix_argname' => 'reservation_comment', 'fix_argvalue' => NULL),
73 'where_arglist' => array
75 array ('url_argname' => 'port_id', 'table_colname' => 'id', 'assertion' => 'uint'),
76 array ('url_argname' => 'object_id', 'assertion' => 'uint'), # preserve context
79 $opspec_list['object-ports-delPort'] = array
85 array ('url_argname' => 'port_id', 'table_colname' => 'id', 'assertion' => 'uint'),
86 array ('url_argname' => 'object_id', 'assertion' => 'uint'),
89 $opspec_list['object-ports-deleteAll'] = array
95 array ('url_argname' => 'object_id', 'assertion' => 'uint'),
98 $opspec_list['location-log-del'] = array
100 'table' => 'ObjectLog',
101 'action' => 'DELETE',
104 array ('url_argname' => 'log_id', 'table_colname' => 'id', 'assertion' => 'uint'),
105 array ('url_argname' => 'location_id', 'table_colname' => 'object_id', 'assertion' => 'uint'),
108 $opspec_list['object-log-del'] = array
110 'table' => 'ObjectLog',
111 'action' => 'DELETE',
114 array ('url_argname' => 'log_id', 'table_colname' => 'id', 'assertion' => 'uint'),
115 array ('url_argname' => 'object_id', 'assertion' => 'uint'),
118 $opspec_list['rack-log-del'] = array
120 'table' => 'ObjectLog',
121 'action' => 'DELETE',
124 array ('url_argname' => 'log_id', 'table_colname' => 'id', 'assertion' => 'uint'),
125 array ('url_argname' => 'rack_id', 'table_colname' => 'object_id', 'assertion' => 'uint'),
128 $opspec_list['ipv4vs-editlblist-delLB'] =
129 $opspec_list['ipv4rspool-editlblist-delLB'] =
130 $opspec_list['object-editrspvs-delLB'] = array
133 'action' => 'DELETE',
136 array ('url_argname' => 'object_id', 'assertion' => 'uint'),
137 array ('url_argname' => 'pool_id', 'table_colname' => 'rspool_id', 'assertion' => 'uint'),
138 array ('url_argname' => 'vs_id', 'assertion' => 'uint'),
141 $opspec_list['ipv4vs-editlblist-updLB'] =
142 $opspec_list['ipv4rspool-editlblist-updLB'] =
143 $opspec_list['object-editrspvs-updLB'] = array
146 'action' => 'UPDATE',
147 'set_arglist' => array
149 array ('url_argname' => 'vsconfig', 'assertion' => 'string0', 'if_empty' => 'NULL'),
150 array ('url_argname' => 'rsconfig', 'assertion' => 'string0', 'if_empty' => 'NULL'),
151 array ('url_argname' => 'prio', 'assertion' => 'string0', 'if_empty' => 'NULL'),
153 'where_arglist' => array
155 array ('url_argname' => 'object_id', 'assertion' => 'uint'),
156 array ('url_argname' => 'pool_id', 'table_colname' => 'rspool_id', 'assertion' => 'uint'),
157 array ('url_argname' => 'vs_id', 'assertion' => 'uint'),
160 $opspec_list['object-cacti-add'] = array
162 'table' => 'CactiGraph',
163 'action' => 'INSERT',
166 array ('url_argname' => 'object_id', 'assertion' => 'uint'),
167 array ('url_argname' => 'server_id', 'assertion' => 'uint'),
168 array ('url_argname' => 'graph_id', 'assertion' => 'uint'),
169 array ('url_argname' => 'caption', 'assertion' => 'string0'),
172 $opspec_list['object-cacti-del'] = array
174 'table' => 'CactiGraph',
175 'action' => 'DELETE',
178 array ('url_argname' => 'object_id', 'assertion' => 'uint'),
179 array ('url_argname' => 'server_id', 'assertion' => 'uint'),
180 array ('url_argname' => 'graph_id', 'assertion' => 'uint'),
183 $opspec_list['object-munin-add'] = array
185 'table' => 'MuninGraph',
186 'action' => 'INSERT',
189 array ('url_argname' => 'object_id', 'assertion' => 'uint'),
190 array ('url_argname' => 'server_id', 'assertion' => 'uint'),
191 array ('url_argname' => 'graph', 'assertion' => 'string'),
192 array ('url_argname' => 'caption', 'assertion' => 'string0'),
195 $opspec_list['object-munin-del'] = array
197 'table' => 'MuninGraph',
198 'action' => 'DELETE',
201 array ('url_argname' => 'object_id', 'assertion' => 'uint'),
202 array ('url_argname' => 'server_id', 'assertion' => 'uint'),
203 array ('url_argname' => 'graph', 'assertion' => 'string'),
206 $opspec_list['ipv4rspool-editrslist-delRS'] = array
209 'action' => 'DELETE',
212 array ('url_argname' => 'id', 'assertion' => 'uint'),
215 $opspec_list['parentmap-edit-add'] = array
217 'table' => 'ObjectParentCompat',
218 'action' => 'INSERT',
221 array ('url_argname' => 'parent_objtype_id', 'assertion' => 'uint'),
222 array ('url_argname' => 'child_objtype_id', 'assertion' => 'uint'),
225 $opspec_list['parentmap-edit-del'] = array
227 'table' => 'ObjectParentCompat',
228 'action' => 'DELETE',
231 array ('url_argname' => 'parent_objtype_id', 'assertion' => 'uint'),
232 array ('url_argname' => 'child_objtype_id', 'assertion' => 'uint'),
235 $opspec_list['portmap-edit-add'] = array
237 'table' => 'PortCompat',
238 'action' => 'INSERT',
241 array ('url_argname' => 'type1', 'assertion' => 'uint'),
242 array ('url_argname' => 'type2', 'assertion' => 'uint'),
245 $opspec_list['portmap-edit-del'] = array
247 'table' => 'PortCompat',
248 'action' => 'DELETE',
251 array ('url_argname' => 'type1', 'assertion' => 'uint'),
252 array ('url_argname' => 'type2', 'assertion' => 'uint'),
255 $opspec_list['portifcompat-edit-del'] = array
257 'table' => 'PortInterfaceCompat',
258 'action' => 'DELETE',
261 array ('url_argname' => 'iif_id', 'assertion' => 'uint'),
262 array ('url_argname' => 'oif_id', 'assertion' => 'uint'),
265 $opspec_list['attrs-editmap-del'] = array
267 'table' => 'AttributeMap',
268 'action' => 'DELETE',
271 array ('url_argname' => 'attr_id', 'assertion' => 'uint'),
272 array ('url_argname' => 'objtype_id', 'assertion' => 'uint'),
275 $opspec_list['attrs-editattrs-add'] = array
277 'table' => 'Attribute',
278 'action' => 'INSERT',
281 array ('url_argname' => 'attr_type', 'table_colname' => 'type', 'assertion' => 'enum/attr_type'),
282 array ('url_argname' => 'attr_name', 'table_colname' => 'name', 'assertion' => 'string'),
285 $opspec_list['attrs-editattrs-del'] = array
287 'table' => 'Attribute',
288 'action' => 'DELETE',
291 array ('url_argname' => 'attr_id', 'table_colname' => 'id', 'assertion' => 'uint'),
294 $opspec_list['attrs-editattrs-upd'] = array
296 'table' => 'Attribute',
297 'action' => 'UPDATE',
298 'set_arglist' => array
300 array ('url_argname' => 'attr_name', 'table_colname' => 'name', 'assertion' => 'string'),
302 'where_arglist' => array
304 array ('url_argname' => 'attr_id', 'table_colname' => 'id', 'assertion' => 'uint'),
307 $opspec_list['dict-chapters-add'] = array
309 'table' => 'Chapter',
310 'action' => 'INSERT',
313 array ('url_argname' => 'chapter_name', 'table_colname' => 'name', 'assertion' => 'string')
316 $opspec_list['chapter-edit-add'] = array
318 'table' => 'Dictionary',
319 'action' => 'INSERT',
322 array ('url_argname' => 'chapter_no', 'table_colname' => 'chapter_id', 'assertion' => 'uint'),
323 array ('url_argname' => 'dict_value', 'assertion' => 'string'),
326 $opspec_list['chapter-edit-del'] = array
328 'table' => 'Dictionary',
329 'action' => 'DELETE',
332 // Technically dict_key is enough to delete, but including chapter_id into
333 // WHERE clause makes sure, that the action actually happends for the same
334 // chapter that authorization was granted for.
335 array ('url_argname' => 'chapter_no', 'table_colname' => 'chapter_id', 'assertion' => 'uint'),
336 array ('url_argname' => 'dict_key', 'assertion' => 'uint'),
337 array ('fix_argname' => 'dict_sticky', 'fix_argvalue' => 'no'), # protect system rows
340 $opspec_list['chapter-edit-upd'] = array
342 'table' => 'Dictionary',
343 'action' => 'UPDATE',
344 'set_arglist' => array
346 array ('url_argname' => 'dict_value', 'assertion' => 'string'),
348 'where_arglist' => array
350 # same as above for listing chapter_no
351 array ('url_argname' => 'chapter_no', 'table_colname' => 'chapter_id', 'assertion' => 'uint'),
352 array ('url_argname' => 'dict_key', 'assertion' => 'uint'),
353 array ('fix_argname' => 'dict_sticky', 'fix_argvalue' => 'no'), # protect system rows
356 $opspec_list['tagtree-edit-createTag'] = array
358 'table' => 'TagTree',
359 'action' => 'INSERT',
362 array ('url_argname' => 'tag_name', 'table_colname' => 'tag', 'assertion' => 'tag'),
363 array ('url_argname' => 'parent_id', 'assertion' => 'uint0', 'if_empty' => 'NULL'),
364 array ('url_argname' => 'is_assignable', 'assertion' => 'enum/yesno'),
367 $opspec_list['tagtree-edit-destroyTag'] = array
369 'table' => 'TagTree',
370 'action' => 'DELETE',
373 array ('url_argname' => 'tag_id', 'table_colname' => 'id', 'assertion' => 'uint'),
376 $opspec_list['8021q-vstlist-add'] = array
378 'table' => 'VLANSwitchTemplate',
379 'action' => 'INSERT',
382 array ('url_argname' => 'vst_descr', 'table_colname' => 'description', 'assertion' => 'string'),
385 $opspec_list['8021q-vstlist-del'] = array
387 'table' => 'VLANSwitchTemplate',
388 'action' => 'DELETE',
391 array ('url_argname' => 'vst_id', 'table_colname' => 'id', 'assertion' => 'uint'),
394 $opspec_list['8021q-vstlist-upd'] = array
396 'table' => 'VLANSwitchTemplate',
397 'action' => 'UPDATE',
398 'set_arglist' => array
400 array ('url_argname' => 'vst_descr', 'table_colname' => 'description', 'assertion' => 'string'),
402 'where_arglist' => array
404 array ('url_argname' => 'vst_id', 'table_colname' => 'id', 'assertion' => 'uint'),
407 $opspec_list['8021q-vdlist-del'] = array
409 'table' => 'VLANDomain',
410 'action' => 'DELETE',
413 array ('url_argname' => 'vdom_id', 'table_colname' => 'id', 'assertion' => 'uint'),
416 $opspec_list['8021q-vdlist-upd'] = array
418 'table' => 'VLANDomain',
419 'action' => 'UPDATE',
420 'set_arglist' => array
422 array ('url_argname' => 'vdom_descr', 'table_colname' => 'description', 'assertion' => 'string'),
424 'where_arglist' => array
426 array ('url_argname' => 'vdom_id', 'table_colname' => 'id', 'assertion' => 'uint'),
429 $opspec_list['vlandomain-vlanlist-add'] = array
431 'table' => 'VLANDescription',
432 'action' => 'INSERT',
435 array ('url_argname' => 'vdom_id', 'table_colname' => 'domain_id', 'assertion' => 'uint'),
436 array ('url_argname' => 'vlan_id', 'assertion' => 'vlan'),
437 array ('url_argname' => 'vlan_type', 'assertion' => 'enum/vlan_type'),
438 array ('url_argname' => 'vlan_descr', 'assertion' => 'string0', 'if_empty' => 'NULL'),
441 $opspec_list['vlandomain-vlanlist-del'] = array
443 'table' => 'VLANDescription',
444 'action' => 'DELETE',
447 array ('url_argname' => 'vdom_id', 'table_colname' => 'domain_id', 'assertion' => 'uint'),
448 array ('url_argname' => 'vlan_id', 'assertion' => 'vlan'),
451 $opspec_list['vlan-edit-upd'] = // both locations are using the same tableHandler op
452 $opspec_list['vlandomain-vlanlist-upd'] = array
454 'table' => 'VLANDescription',
455 'action' => 'UPDATE',
456 'set_arglist' => array
458 array ('url_argname' => 'vlan_type', 'assertion' => 'enum/vlan_type'),
459 array ('url_argname' => 'vlan_descr', 'assertion' => 'string0', 'if_empty' => 'NULL'),
461 'where_arglist' => array
463 array ('url_argname' => 'vdom_id', 'table_colname' => 'domain_id', 'assertion' => 'uint'),
464 array ('url_argname' => 'vlan_id', 'assertion' => 'vlan'),
467 $opspec_list['dict-chapters-upd'] = array
469 'table' => 'Chapter',
470 'action' => 'UPDATE',
471 'set_arglist' => array
473 array ('url_argname' => 'chapter_name', 'table_colname' => 'name', 'assertion' => 'string'),
475 'where_arglist' => array
477 array ('url_argname' => 'chapter_no', 'table_colname' => 'id', 'assertion' => 'uint'),
478 array ('fix_argname' => 'sticky', 'fix_argvalue' => 'no'), # protect system chapters
481 $opspec_list['dict-chapters-del'] = array
483 'table' => 'Chapter',
484 'action' => 'DELETE',
487 array ('url_argname' => 'chapter_no', 'table_colname' => 'id', 'assertion' => 'uint'),
488 array ('fix_argname' => 'sticky', 'fix_argvalue' => 'no'), # protect system chapters
491 $opspec_list['cacti-servers-add'] = array
493 'table' => 'CactiServer',
494 'action' => 'INSERT',
497 array ('url_argname' => 'base_url', 'assertion' => 'string'),
498 array ('url_argname' => 'username', 'assertion' => 'string0'),
499 array ('url_argname' => 'password', 'assertion' => 'string0'),
502 $opspec_list['cacti-servers-del'] = array
504 'table' => 'CactiServer',
505 'action' => 'DELETE',
508 array ('url_argname' => 'id', 'assertion' => 'uint'),
511 $opspec_list['cacti-servers-upd'] = array
513 'table' => 'CactiServer',
514 'action' => 'UPDATE',
515 'set_arglist' => array
517 array ('url_argname' => 'base_url', 'assertion' => 'string'),
518 array ('url_argname' => 'username', 'assertion' => 'string0'),
519 array ('url_argname' => 'password', 'assertion' => 'string0'),
521 'where_arglist' => array
523 array ('url_argname' => 'id', 'assertion' => 'uint'),
526 $opspec_list['munin-servers-add'] = array
528 'table' => 'MuninServer',
529 'action' => 'INSERT',
532 array ('url_argname' => 'base_url', 'assertion' => 'string')
535 $opspec_list['munin-servers-del'] = array
537 'table' => 'MuninServer',
538 'action' => 'DELETE',
541 array ('url_argname' => 'id', 'assertion' => 'uint'),
544 $opspec_list['munin-servers-upd'] = array
546 'table' => 'MuninServer',
547 'action' => 'UPDATE',
548 'set_arglist' => array
550 array ('url_argname' => 'base_url', 'assertion' => 'string'),
552 'where_arglist' => array
554 array ('url_argname' => 'id', 'assertion' => 'uint'),
558 $msgcode['addPortForwarding']['OK'] = 48;
559 function addPortForwarding ()
561 assertUIntArg ('object_id');
562 $localip_bin = assertIPv4Arg ('localip');
563 $remoteip_bin = assertIPv4Arg ('remoteip');
564 if ($_REQUEST['proto'] != 'ALL')
566 assertUIntArg ('localport');
567 assertUIntArg ('remoteport');
569 assertStringArg ('proto');
570 assertStringArg ('description', TRUE);
571 $remoteport = isset ($_REQUEST['remoteport']) ?
$_REQUEST['remoteport'] : '';
572 if (!strlen ($remoteport))
573 $remoteport = $_REQUEST['localport'];
577 $_REQUEST['object_id'],
579 $_REQUEST['localport'],
583 $_REQUEST['description']
586 showFuncMessage (__FUNCTION__
, 'OK');
589 $msgcode['delPortForwarding']['OK'] = 49;
590 function delPortForwarding ()
592 assertUIntArg ('object_id');
593 $localip_bin = assertIPv4Arg ('localip');
594 $remoteip_bin = assertIPv4Arg ('remoteip');
595 if ($_REQUEST['proto'] != 'ALL')
597 assertUIntArg ('localport');
598 assertUIntArg ('remoteport');
600 assertStringArg ('proto');
604 $_REQUEST['object_id'],
606 $_REQUEST['localport'],
608 $_REQUEST['remoteport'],
611 showFuncMessage (__FUNCTION__
, 'OK');
614 $msgcode['updPortForwarding']['OK'] = 51;
615 function updPortForwarding ()
617 assertUIntArg ('object_id');
618 $localip_bin = assertIPv4Arg ('localip');
619 $remoteip_bin = assertIPv4Arg ('remoteip');
620 if ($_REQUEST['proto'] != 'ALL')
622 assertUIntArg ('localport');
623 assertUIntArg ('remoteport');
625 assertStringArg ('proto');
626 assertStringArg ('description', TRUE);
630 $_REQUEST['object_id'],
632 $_REQUEST['localport'],
634 $_REQUEST['remoteport'],
636 $_REQUEST['description']
638 showFuncMessage (__FUNCTION__
, 'OK');
641 $msgcode['addPortForObject']['OK'] = 48;
642 function addPortForObject ()
644 assertStringArg ('port_name', TRUE);
645 genericAssertion ('port_l2address', 'l2address0');
646 genericAssertion ('port_name', 'string');
649 $_REQUEST['object_id'],
650 trim ($_REQUEST['port_name']),
651 $_REQUEST['port_type_id'],
652 trim ($_REQUEST['port_label']),
653 trim ($_REQUEST['port_l2address'])
655 showFuncMessage (__FUNCTION__
, 'OK', array ($_REQUEST['port_name']));
658 $msgcode['editPortForObject']['OK'] = 6;
659 function editPortForObject ()
662 assertUIntArg ('port_id');
663 assertUIntArg ('port_type_id');
664 assertStringArg ('reservation_comment', TRUE);
665 genericAssertion ('l2address', 'l2address0');
666 genericAssertion ('name', 'string');
667 commitUpdatePort ($sic['object_id'], $sic['port_id'], $sic['name'], $sic['port_type_id'], $sic['label'], $sic['l2address'], $sic['reservation_comment']);
668 if (array_key_exists ('cable', $_REQUEST))
669 commitUpdatePortLink ($sic['port_id'], $sic['cable']);
670 showFuncMessage (__FUNCTION__
, 'OK', array ($_REQUEST['name']));
673 $msgcode['addMultiPorts']['OK'] = 10;
674 function addMultiPorts ()
676 assertStringArg ('format');
677 assertStringArg ('input');
678 assertStringArg ('port_type');
679 $format = $_REQUEST['format'];
680 $port_type = $_REQUEST['port_type'];
681 $object_id = $_REQUEST['object_id'];
682 // Input lines are escaped, so we have to explode and to chop by 2-char
683 // \n and \r respectively.
684 $lines1 = explode ("\n", $_REQUEST['input']);
685 foreach ($lines1 as $line)
687 $parts = explode ('\r', $line);
689 if (!strlen ($parts[0]))
692 $lines2[] = rtrim ($parts[0]);
695 foreach ($lines2 as $line)
700 $words = explode (' ', preg_replace ('/[[:space:]]+/', ' ', $line));
701 list ($slot, $port) = explode ('/', $words[0]);
704 'name' => "e ${slot}/${port}",
705 'l2address' => $words[8],
706 'label' => "slot ${slot} port ${port}"
710 $words = explode (' ', preg_replace ('/[[:space:]]+/', ' ', trim (substr ($line, 3))));
712 How Async Lines are Numbered in Cisco 3600 Series Routers
713 http://www.cisco.com/en/US/products/hw/routers/ps274/products_tech_note09186a00801ca70b.shtml
715 Understanding 16- and 32-Port Async Network Modules
716 http://www.cisco.com/en/US/products/hw/routers/ps274/products_tech_note09186a00800a93f0.shtml
719 $slot = floor (($async - 1) / 32);
720 $octalgroup = floor (($async - 1 - $slot * 32) / 8);
721 $cable = $async - $slot * 32 - $octalgroup * 8;
722 $og_label[0] = 'async 0-7';
723 $og_label[1] = 'async 8-15';
724 $og_label[2] = 'async 16-23';
725 $og_label[3] = 'async 24-31';
728 'name' => "async ${async}",
730 'label' => "slot ${slot} " . $og_label[$octalgroup] . " cable ${cable}"
734 $words = explode (' ', preg_replace ('/[[:space:]]+/', ' ', $line));
735 $ifnumber = $words[0] * 1;
738 'name' => "e ${ifnumber}",
739 'l2address' => "${words[8]}",
740 'label' => "${ifnumber}"
744 $words = explode (' ', $line);
745 if (!strlen ($words[0]) or !strlen ($words[1]))
750 'l2address' => $words[1],
755 throw new InvalidRequestArgException ('format', $format);
759 // Create ports, if they don't exist.
760 $added_count = $updated_count = $error_count = 0;
761 foreach ($ports as $port)
763 $port_ids = getPortIDs ($object_id, $port['name']);
764 if (!count ($port_ids))
766 commitAddPort ($object_id, $port['name'], $port_type, $port['label'], $port['l2address']);
769 elseif (count ($port_ids) == 1) // update only single-socket ports
771 commitUpdatePort ($object_id, $port_ids[0], $port['name'], $port_type, $port['label'], $port['l2address']);
775 showFuncMessage (__FUNCTION__
, 'OK', array ($added_count, $updated_count, $error_count));
778 $msgcode['addBulkPorts']['OK'] = 82;
779 function addBulkPorts ()
781 assertStringArg ('port_type_id');
782 assertStringArg ('port_name', TRUE);
783 assertStringArg ('port_label', TRUE);
784 assertUIntArg ('port_numbering_start', TRUE);
785 assertUIntArg ('port_numbering_count');
787 $object_id = $_REQUEST['object_id'];
788 $port_name = $_REQUEST['port_name'];
789 $port_type_id = $_REQUEST['port_type_id'];
790 $port_label = $_REQUEST['port_label'];
791 $port_numbering_start = $_REQUEST['port_numbering_start'];
792 $port_numbering_count = $_REQUEST['port_numbering_count'];
794 $added_count = $error_count = 0;
795 if(strrpos($port_name, "%u") === false )
797 for ($i=0,$c=$port_numbering_start; $i<$port_numbering_count; $i++
,$c++
)
799 commitAddPort ($object_id, @sprintf
($port_name,$c), $port_type_id, @sprintf
($port_label,$c), '');
802 showFuncMessage (__FUNCTION__
, 'OK', array ($added_count, $error_count));
805 $msgcode['updIPAllocation']['OK'] = 51;
806 function updIPAllocation ()
808 $ip_bin = assertIPArg ('ip');
809 assertUIntArg ('object_id');
810 assertStringArg ('bond_name', TRUE);
811 genericAssertion ('bond_type', 'enum/alloc_type');
812 updateIPBond ($ip_bin, $_REQUEST['object_id'], $_REQUEST['bond_name'], $_REQUEST['bond_type']);
813 showFuncMessage (__FUNCTION__
, 'OK');
814 return buildRedirectURL (NULL, NULL, array ('hl_ip' => ip_format ($ip_bin)));
817 $msgcode['delIPAllocation']['OK'] = 49;
818 function delIPAllocation ()
820 $ip_bin = assertIPArg ('ip');
821 assertUIntArg ('object_id');
823 unbindIPFromObject ($ip_bin, $_REQUEST['object_id']);
824 showFuncMessage (__FUNCTION__
, 'OK');
827 $msgcode['addIPAllocation']['OK'] = 48;
828 $msgcode['addIPAllocation']['ERR1'] = 170;
829 function addIPAllocation ()
831 $ip_bin = assertIPArg ('ip');
832 assertUIntArg ('object_id');
833 assertStringArg ('bond_name', TRUE);
834 genericAssertion ('bond_type', 'enum/alloc_type');
836 if (getConfigVar ('IPV4_JAYWALK') != 'yes' and NULL === getIPAddressNetworkId ($ip_bin))
838 showFuncMessage (__FUNCTION__
, 'ERR1', array (ip_format ($ip_bin)));
842 bindIPToObject ($ip_bin, $_REQUEST['object_id'], $_REQUEST['bond_name'], $_REQUEST['bond_type']);
844 showFuncMessage (__FUNCTION__
, 'OK');
845 return buildRedirectURL (NULL, NULL, array ('hl_ip' => ip_format ($ip_bin)));
848 function addIPv4Prefix ()
850 assertStringArg ('range');
851 assertStringArg ('name', TRUE);
852 $taglist = genericAssertion ('taglist', 'array0');
854 $vlan_ck = empty ($sic['vlan_ck']) ?
NULL : genericAssertion ('vlan_ck', 'uint-vlan1');
855 $net_id = createIPv4Prefix ($_REQUEST['range'], $sic['name'], isCheckSet ('is_connected'), $taglist, $vlan_ck);
856 showSuccess ('IP network ' . mkA ($_REQUEST['range'], 'ipv4net', $net_id) . ' has been created');
859 function addIPv6Prefix ()
861 assertStringArg ('range');
862 assertStringArg ('name', TRUE);
863 $taglist = genericAssertion ('taglist', 'array0');
865 $vlan_ck = empty ($sic['vlan_ck']) ?
NULL : genericAssertion ('vlan_ck', 'uint-vlan1');
866 $net_id = createIPv6Prefix ($_REQUEST['range'], $sic['name'], isCheckSet ('is_connected'), $taglist, $vlan_ck);
867 showSuccess ('IP network ' . mkA ($_REQUEST['range'], 'ipv6net', $net_id) . ' has been created');
870 $msgcode['delIPv4Prefix']['OK'] = 49;
871 function delIPv4Prefix ()
873 assertUIntArg ('id');
874 $netinfo = spotEntity ('ipv4net', $_REQUEST['id']);
875 loadIPAddrList ($netinfo);
876 if (! isIPNetworkEmpty ($netinfo))
878 showError ("There are allocations within prefix, delete forbidden");
881 if (array_key_exists ($netinfo['ip_bin'], $netinfo['addrlist']))
882 updateV4Address ($netinfo['ip_bin'], '', 'no');
883 $last_ip = ip_last ($netinfo);
884 if (array_key_exists ($last_ip, $netinfo['addrlist']))
885 updateV4Address ($last_ip, '', 'no');
886 destroyIPv4Prefix ($_REQUEST['id']);
887 showFuncMessage (__FUNCTION__
, 'OK');
889 if ($pageno == 'ipv4net')
890 return buildRedirectURL ('index', 'default');
893 $msgcode['delIPv6Prefix']['OK'] = 49;
894 function delIPv6Prefix ()
896 assertUIntArg ('id');
897 $netinfo = spotEntity ('ipv6net', $_REQUEST['id']);
898 loadIPAddrList ($netinfo);
899 if (! isIPNetworkEmpty ($netinfo))
901 showError ("There are allocations within prefix, delete forbidden");
904 if (array_key_exists ($netinfo['ip_bin'], $netinfo['addrlist']))
905 updateV6Address ($netinfo['ip_bin'], '', 'no');
906 destroyIPv6Prefix ($_REQUEST['id']);
907 showFuncMessage (__FUNCTION__
, 'OK');
909 if ($pageno == 'ipv6net')
910 return buildRedirectURL ('index', 'default');
913 $msgcode['editAddress']['OK'] = 51;
914 function editAddress ()
916 assertStringArg ('name', TRUE);
917 assertStringArg ('comment', TRUE);
918 $ip_bin = assertIPArg ('ip');
919 updateAddress ($ip_bin, $_REQUEST['name'], isCheckSet ('reserved', 'yesno'), $_REQUEST['comment']);
920 showFuncMessage (__FUNCTION__
, 'OK');
923 $msgcode['createUser']['OK'] = 5;
924 function createUser ()
926 assertStringArg ('username');
927 assertStringArg ('realname', TRUE);
928 assertStringArg ('password');
929 $username = $_REQUEST['username'];
930 $password = sha1 ($_REQUEST['password']);
931 $user_id = commitCreateUserAccount ($username, $_REQUEST['realname'], $password);
932 if (isset ($_REQUEST['taglist']))
933 produceTagsForNewRecord ('user', $_REQUEST['taglist'], $user_id);
934 showFuncMessage (__FUNCTION__
, 'OK', array ($username));
937 $msgcode['updateUser']['OK'] = 6;
938 function updateUser ()
940 genericAssertion ('user_id', 'uint');
941 $username = assertStringArg ('username');
942 assertStringArg ('realname', TRUE);
943 $new_password = assertStringArg ('password');
944 $userinfo = spotEntity ('user', $_REQUEST['user_id']);
945 // Update user password only if provided password is not the same as current password hash.
946 if ($new_password != $userinfo['user_password_hash'])
947 $new_password = sha1 ($new_password);
948 commitUpdateUserAccount ($_REQUEST['user_id'], $username, $_REQUEST['realname'], $new_password);
949 // if user account renaming is being performed, change key value in UserConfig table
950 if ($userinfo['user_name'] !== $username)
951 usePreparedUpdateBlade ('UserConfig', array ('user' => $username), array('user' => $userinfo['user_name']));
952 showFuncMessage (__FUNCTION__
, 'OK', array ($username));
955 $msgcode['supplementAttrMap']['OK'] = 48;
956 $msgcode['supplementAttrMap']['ERR1'] = 154;
957 function supplementAttrMap ()
959 assertUIntArg ('attr_id');
960 assertUIntArg ('objtype_id');
961 $attrMap = getAttrMap();
962 if ($attrMap[$_REQUEST['attr_id']]['type'] != 'dict')
968 assertUIntArg ('chapter_no');
970 catch (InvalidRequestArgException
$e)
972 showFuncMessage (__FUNCTION__
, 'ERR1', array ('chapter not selected'));
975 $chapter_id = $_REQUEST['chapter_no'];
977 commitSupplementAttrMap ($_REQUEST['attr_id'], $_REQUEST['objtype_id'], $chapter_id);
978 showFuncMessage (__FUNCTION__
, 'OK');
981 $msgcode['clearSticker']['OK'] = 49;
982 function clearSticker ()
985 assertUIntArg ('attr_id');
986 if (permitted (NULL, NULL, NULL, array (array ('tag' => '$attr_' . $sic['attr_id']))))
987 commitUpdateAttrValue (getBypassValue(), $sic['attr_id']);
990 $oldvalues = getAttrValues (getBypassValue());
991 showError ('Permission denied, "' . $oldvalues[$sic['attr_id']]['name'] . '" left unchanged');
995 $msgcode['updateObjectAllocation']['OK'] = 63;
996 function updateObjectAllocation ()
998 global $remote_username, $sic;
999 if (!isset ($_REQUEST['got_atoms']))
1001 unset($_GET['page']);
1002 unset($_GET['tab']);
1004 unset($_POST['page']);
1005 unset($_POST['tab']);
1006 unset($_POST['op']);
1007 return buildRedirectURL (NULL, NULL, $_REQUEST);
1009 $object_id = getBypassValue();
1011 // Get a list of all of this object's parents,
1012 // then trim the list to only include parents that are racks
1013 $objectParents = getEntityRelatives('parents', 'object', $object_id);
1014 $parentRacks = array();
1015 foreach ($objectParents as $parentData)
1016 if ($parentData['entity_type'] == 'rack')
1017 $parentRacks[] = $parentData['entity_id'];
1018 $workingRacksData = array();
1019 foreach ($_REQUEST['rackmulti'] as $cand_id)
1021 if (!isset ($workingRacksData[$cand_id]))
1023 $rackData = spotEntity ('rack', $cand_id);
1024 amplifyCell ($rackData);
1025 $workingRacksData[$cand_id] = $rackData;
1027 // It's zero-U mounted to this rack on the form, but not in the DB. Mount it.
1028 if (isset($_REQUEST["zerou_${cand_id}"]) && !in_array($cand_id, $parentRacks))
1031 commitLinkEntities ('rack', $cand_id, 'object', $object_id);
1033 // It's not zero-U mounted to this rack on the form, but it is in the DB. Unmount it.
1034 if (!isset($_REQUEST["zerou_${cand_id}"]) && in_array($cand_id, $parentRacks))
1037 commitUnlinkEntities ('rack', $cand_id, 'object', $object_id);
1041 foreach ($workingRacksData as &$rd)
1042 applyObjectMountMask ($rd, $object_id);
1044 $oldMolecule = getMoleculeForObject ($object_id);
1045 foreach ($workingRacksData as $rack_id => $rackData)
1047 if (! processGridForm ($rackData, 'F', 'T', $object_id))
1050 // Reload our working copy after form processing.
1051 $rackData = spotEntity ('rack', $cand_id);
1052 amplifyCell ($rackData);
1053 applyObjectMountMask ($rackData, $object_id);
1054 $workingRacksData[$rack_id] = $rackData;
1059 $newMolecule = getMoleculeForObject ($object_id);
1060 usePreparedInsertBlade
1065 'object_id' => $object_id,
1066 'old_molecule_id' => count ($oldMolecule) ?
createMolecule ($oldMolecule) : NULL,
1067 'new_molecule_id' => count ($newMolecule) ?
createMolecule ($newMolecule) : NULL,
1068 'user_name' => $remote_username,
1069 'comment' => empty ($sic['comment']) ?
NULL : $sic['comment'],
1073 showFuncMessage (__FUNCTION__
, 'OK', array ($changecnt));
1076 $msgcode['updateObject']['OK'] = 51;
1077 function updateObject ()
1079 $taglist = genericAssertion ('taglist', 'array0');
1080 genericAssertion ('num_attrs', 'uint0');
1081 genericAssertion ('object_name', 'string0');
1082 genericAssertion ('object_label', 'string0');
1083 genericAssertion ('object_asset_no', 'string0');
1084 genericAssertion ('object_comment', 'string0');
1085 genericAssertion ('object_type_id', 'uint');
1086 $object_id = getBypassValue();
1088 global $dbxlink, $sic;
1089 $dbxlink->beginTransaction();
1093 $_REQUEST['object_name'],
1094 $_REQUEST['object_label'],
1095 isCheckSet ('object_has_problems', 'yesno'),
1096 $_REQUEST['object_asset_no'],
1097 $_REQUEST['object_comment']
1099 updateObjectAttributes ($object_id);
1100 $object = spotEntity ('object', $object_id);
1101 if ($sic['object_type_id'] != $object['objtype_id'])
1103 if (! array_key_exists ($sic['object_type_id'], getObjectTypeChangeOptions ($object_id)))
1104 throw new InvalidRequestArgException ('new type_id', $sic['object_type_id'], 'incompatible with requested attribute values');
1105 usePreparedUpdateBlade ('Object', array ('objtype_id' => $sic['object_type_id']), array ('id' => $object_id));
1107 // Invalidate thumb cache of all racks objects could occupy.
1108 foreach (getResidentRacksData ($object_id, FALSE) as $rack_id)
1109 usePreparedDeleteBlade ('RackThumbnail', array ('rack_id' => $rack_id));
1111 rebuildTagChainForEntity ('object', $object_id, buildTagChainFromIds ($taglist), TRUE);
1112 showFuncMessage (__FUNCTION__
, 'OK');
1115 // Used when updating an object, location or rack
1116 function updateObjectAttributes ($object_id)
1119 $type_id = getObjectType ($object_id);
1120 $oldvalues = getAttrValues ($object_id);
1121 $num_attrs = isset ($_REQUEST['num_attrs']) ?
$_REQUEST['num_attrs'] : 0;
1122 for ($i = 0; $i < $num_attrs; $i++
)
1124 genericAssertion ("${i}_attr_id", 'uint');
1125 $attr_id = $_REQUEST["${i}_attr_id"];
1126 if (! array_key_exists ($attr_id, $oldvalues))
1127 throw new InvalidRequestArgException ('attr_id', $attr_id, 'malformed request');
1128 $value = $_REQUEST["${i}_value"];
1130 // If the object is a rack, skip certain attributes as they are handled elsewhere
1131 // (height, sort_order)
1132 if ($type_id == 1560 and ($attr_id == 27 or $attr_id == 29))
1135 // Delete attribute and move on, when the field is empty or if the field
1136 // type is a dictionary and it is the "--NOT SET--" value of 0.
1137 if ($value == '' ||
($oldvalues[$attr_id]['type'] == 'dict' && $value == 0))
1139 if (permitted (NULL, NULL, NULL, array (array ('tag' => '$attr_' . $attr_id))))
1140 commitUpdateAttrValue ($object_id, $attr_id);
1142 showError ('Permission denied, "' . $oldvalues[$attr_id]['name'] . '" left unchanged');
1146 // The value could be uint/float, but we don't know ATM. Let SQL
1147 // server check this and complain.
1148 if ('date' == $oldvalues[$attr_id]['type'])
1149 $value = assertDateArg ("${i}_value");
1151 assertStringArg ("${i}_value");
1153 switch ($oldvalues[$attr_id]['type'])
1159 $oldvalue = $oldvalues[$attr_id]['value'];
1162 $oldvalue = $oldvalues[$attr_id]['key'];
1166 if ($value === $oldvalue) // ('' == 0), but ('' !== 0)
1168 if (permitted (NULL, NULL, NULL, array (array ('tag' => '$attr_' . $attr_id))))
1169 commitUpdateAttrValue ($object_id, $attr_id, $value);
1171 showError ('Permission denied, "' . $oldvalues[$attr_id]['name'] . '" left unchanged');
1175 function addMultipleObjects()
1177 $taglist = genericAssertion ('taglist', 'array0');
1178 $max = getConfigVar ('MASSCOUNT');
1179 for ($i = 0; $i < $max; $i++
)
1181 if (!isset ($_REQUEST["${i}_object_type_id"]))
1183 showError ('Submitted form is invalid at line ' . ($i +
1));
1187 assertUIntArg ("${i}_object_type_id", TRUE);
1188 assertStringArg ("${i}_object_name", TRUE);
1189 assertStringArg ("${i}_object_label", TRUE);
1190 assertStringArg ("${i}_object_asset_no", TRUE);
1191 $name = $_REQUEST["${i}_object_name"];
1193 // It's better to skip silently, than to print a notice.
1194 if ($_REQUEST["${i}_object_type_id"] == 0)
1198 $object_id = commitAddObject
1201 $_REQUEST["${i}_object_label"],
1202 $_REQUEST["${i}_object_type_id"],
1203 $_REQUEST["${i}_object_asset_no"],
1206 $info = spotEntity ('object', $object_id);
1207 amplifyCell ($info);
1208 showSuccess ("added object " . formatPortLink ($info['id'], $info['dname'], NULL, NULL));
1210 catch (RTDatabaseError
$e)
1212 showError ("Error creating object '$name': " . $e->getMessage());
1218 function addLotOfObjects()
1220 $taglist = genericAssertion ('taglist', 'array0');
1221 assertUIntArg ('global_type_id', TRUE);
1222 assertStringArg ('namelist', TRUE);
1223 $global_type_id = $_REQUEST['global_type_id'];
1224 if ($global_type_id == 0 or !strlen ($_REQUEST['namelist']))
1226 showError ('Incomplete form has been ignored. Cheers.');
1231 // The name extractor below was stolen from ophandlers.php:addMultiPorts()
1232 $names1 = explode ("\n", $_REQUEST['namelist']);
1234 foreach ($names1 as $line)
1236 $parts = explode ('\r', $line);
1238 if (!strlen ($parts[0]))
1241 $names2[] = rtrim ($parts[0]);
1243 foreach ($names2 as $name)
1246 $object_id = commitAddObject ($name, NULL, $global_type_id, '', $taglist);
1247 $info = spotEntity ('object', $object_id);
1248 amplifyCell ($info);
1249 showSuccess ("added object " . formatPortLink ($info['id'], $info['dname'], NULL, NULL));
1251 catch (RTDatabaseError
$e)
1253 showError ("Error creating object '$name': " . $e->getMessage());
1259 function linkObjects ()
1261 assertStringArg ('parent_entity_type');
1262 assertUIntArg ('parent_entity_id');
1263 assertStringArg ('child_entity_type');
1264 assertUIntArg ('child_entity_id');
1268 $_REQUEST['parent_entity_type'],
1269 $_REQUEST['parent_entity_id'],
1270 $_REQUEST['child_entity_type'],
1271 $_REQUEST['child_entity_id']
1273 showSuccess ('Container set successfully');
1276 $msgcode['deleteObject']['OK'] = 7;
1277 function deleteObject ()
1279 assertUIntArg ('object_id');
1280 $oinfo = spotEntity ('object', $_REQUEST['object_id']);
1282 $racklist = getResidentRacksData ($_REQUEST['object_id'], FALSE);
1283 commitDeleteObject ($_REQUEST['object_id']);
1284 foreach ($racklist as $rack_id)
1285 usePreparedDeleteBlade ('RackThumbnail', array ('rack_id' => $rack_id));
1286 showFuncMessage (__FUNCTION__
, 'OK', array ($oinfo['dname']));
1289 $msgcode['resetObject']['OK'] = 57;
1290 function resetObject ()
1292 $racklist = getResidentRacksData (getBypassValue(), FALSE);
1293 commitResetObject (getBypassValue());
1294 foreach ($racklist as $rack_id)
1295 usePreparedDeleteBlade ('RackThumbnail', array ('rack_id' => $rack_id));
1296 showFuncMessage (__FUNCTION__
, 'OK');
1299 $msgcode['updateUI']['OK'] = 51;
1300 function updateUI ()
1302 assertUIntArg ('num_vars');
1304 for ($i = 0; $i < $_REQUEST['num_vars']; $i++
)
1306 assertStringArg ("${i}_varname");
1307 assertStringArg ("${i}_varvalue", TRUE);
1308 $varname = $_REQUEST["${i}_varname"];
1309 $varvalue = $_REQUEST["${i}_varvalue"];
1311 // If form value = value in DB, don't bother updating DB
1312 if (!isConfigVarChanged($varname, $varvalue))
1314 // any exceptions will be handled by process.php
1315 setConfigVar ($varname, $varvalue, TRUE);
1317 showFuncMessage (__FUNCTION__
, 'OK');
1320 $msgcode['saveMyPreferences']['OK'] = 51;
1321 function saveMyPreferences ()
1323 assertUIntArg ('num_vars');
1325 for ($i = 0; $i < $_REQUEST['num_vars']; $i++
)
1327 assertStringArg ("${i}_varname");
1328 assertStringArg ("${i}_varvalue", TRUE);
1329 $varname = $_REQUEST["${i}_varname"];
1330 $varvalue = $_REQUEST["${i}_varvalue"];
1332 // If form value = value in DB, don't bother updating DB
1333 if (!isConfigVarChanged($varname, $varvalue))
1335 setUserConfigVar ($varname, $varvalue);
1337 showFuncMessage (__FUNCTION__
, 'OK');
1340 $msgcode['resetMyPreference']['OK'] = 51;
1341 function resetMyPreference ()
1343 assertStringArg ("varname");
1344 resetUserConfigVar ($_REQUEST["varname"]);
1345 showFuncMessage (__FUNCTION__
, 'OK');
1348 $msgcode['resetUIConfig']['OK'] = 57;
1349 function resetUIConfig()
1351 setConfigVar ('MASSCOUNT','8');
1352 setConfigVar ('MAXSELSIZE','30');
1353 setConfigVar ('ROW_SCALE','2');
1354 setConfigVar ('IPV4_ADDRS_PER_PAGE','256');
1355 setConfigVar ('DEFAULT_RACK_HEIGHT','42');
1356 setConfigVar ('DEFAULT_SLB_VS_PORT','');
1357 setConfigVar ('DEFAULT_SLB_RS_PORT','');
1358 setConfigVar ('DETECT_URLS','no');
1359 setConfigVar ('RACK_PRESELECT_THRESHOLD','1');
1360 setConfigVar ('DEFAULT_IPV4_RS_INSERVICE','no');
1361 setConfigVar ('AUTOPORTS_CONFIG','4 = 1*33*kvm + 2*24*eth%u;15 = 1*446*kvm');
1362 setConfigVar ('SHOW_EXPLICIT_TAGS','yes');
1363 setConfigVar ('SHOW_IMPLICIT_TAGS','yes');
1364 setConfigVar ('SHOW_AUTOMATIC_TAGS','no');
1365 setConfigVar ('DEFAULT_OBJECT_TYPE','4');
1366 setConfigVar ('IPV4_AUTO_RELEASE','1');
1367 setConfigVar ('SHOW_LAST_TAB', 'yes');
1368 setConfigVar ('EXT_IPV4_VIEW', 'yes');
1369 setConfigVar ('TREE_THRESHOLD', '25');
1370 setConfigVar ('IPV4_JAYWALK', 'no');
1371 setConfigVar ('ADDNEW_AT_TOP', 'yes');
1372 setConfigVar ('IPV4_TREE_SHOW_USAGE', 'no');
1373 setConfigVar ('PREVIEW_TEXT_MAXCHARS', '10240');
1374 setConfigVar ('PREVIEW_TEXT_ROWS', '25');
1375 setConfigVar ('PREVIEW_TEXT_COLS', '80');
1376 setConfigVar ('PREVIEW_IMAGE_MAXPXS', '320');
1377 setConfigVar ('VENDOR_SIEVE', '');
1378 setConfigVar ('IPV4LB_LISTSRC', 'false');
1379 setConfigVar ('IPV4OBJ_LISTSRC','not ({$typeid_3} or {$typeid_9} or {$typeid_10} or {$typeid_11})');
1380 setConfigVar ('IPV4NAT_LISTSRC','{$typeid_4} or {$typeid_7} or {$typeid_8} or {$typeid_798}');
1381 setConfigVar ('ASSETWARN_LISTSRC','{$typeid_4} or {$typeid_7} or {$typeid_8}');
1382 setConfigVar ('NAMEWARN_LISTSRC','{$typeid_4} or {$typeid_7} or {$typeid_8}');
1383 setConfigVar ('RACKS_PER_ROW','12');
1384 setConfigVar ('FILTER_PREDICATE_SIEVE','');
1385 setConfigVar ('FILTER_DEFAULT_ANDOR','and');
1386 setConfigVar ('FILTER_SUGGEST_ANDOR','yes');
1387 setConfigVar ('FILTER_SUGGEST_TAGS','yes');
1388 setConfigVar ('FILTER_SUGGEST_PREDICATES','yes');
1389 setConfigVar ('FILTER_SUGGEST_EXTRA','no');
1390 setConfigVar ('DEFAULT_SNMP_COMMUNITY','public');
1391 setConfigVar ('IPV4_ENABLE_KNIGHT','yes');
1392 setConfigVar ('TAGS_TOPLIST_SIZE','50');
1393 setConfigVar ('TAGS_QUICKLIST_SIZE','20');
1394 setConfigVar ('TAGS_QUICKLIST_THRESHOLD','50');
1395 setConfigVar ('ENABLE_MULTIPORT_FORM', 'no');
1396 setConfigVar ('DEFAULT_PORT_IIF_ID', '1');
1397 setConfigVar ('DEFAULT_PORT_OIF_IDS', '1=24; 3=1078; 4=1077; 5=1079; 6=1080; 8=1082; 9=1084; 10=1588; 11=1668');
1398 setConfigVar ('IPV4_TREE_RTR_AS_CELL', 'no');
1399 setConfigVar ('PROXIMITY_RANGE', 0);
1400 setConfigVar ('IPV4_TREE_SHOW_VLAN', 'yes');
1401 setConfigVar ('VLANSWITCH_LISTSRC', '');
1402 setConfigVar ('VLANIPV4NET_LISTSRC', '');
1403 setConfigVar ('DEFAULT_VDOM_ID', '');
1404 setConfigVar ('DEFAULT_VST_ID', '');
1405 setConfigVar ('STATIC_FILTER', 'yes');
1406 setConfigVar ('8021Q_DEPLOY_MINAGE', '300');
1407 setConfigVar ('8021Q_DEPLOY_MAXAGE', '3600');
1408 setConfigVar ('8021Q_DEPLOY_RETRY', '10800');
1409 setConfigVar ('8021Q_WRI_AFTER_CONFT_LISTSRC', 'false');
1410 setConfigVar ('8021Q_INSTANT_DEPLOY', 'no');
1411 setConfigVar ('CDP_RUNNERS_LISTSRC', '');
1412 setConfigVar ('LLDP_RUNNERS_LISTSRC', '');
1413 setConfigVar ('SHRINK_TAG_TREE_ON_CLICK', 'yes');
1414 setConfigVar ('MAX_UNFILTERED_ENTITIES', '0');
1415 setConfigVar ('SYNCDOMAIN_MAX_PROCESSES', '0');
1416 setConfigVar ('PORT_EXCLUSION_LISTSRC', '{$typeid_3} or {$typeid_10} or {$typeid_11} or {$typeid_1505} or {$typeid_1506}');
1417 setConfigVar ('FILTER_RACKLIST_BY_TAGS', 'yes');
1418 setConfigVar ('SSH_OBJS_LISTSRC', 'false');
1419 setConfigVar ('RDP_OBJS_LISTSRC', 'false');
1420 setConfigVar ('TELNET_OBJS_LISTSRC', 'false');
1421 setConfigVar ('SYNC_802Q_LISTSRC', '');
1422 setConfigVar ('QUICK_LINK_PAGES', 'depot,ipv4space,rackspace');
1423 setConfigVar ('CACTI_LISTSRC', 'false');
1424 setConfigVar ('MUNIN_LISTSRC', 'false');
1425 setConfigVar ('VIRTUAL_OBJ_LISTSRC', '1504,1505,1506,1507');
1426 setConfigVar ('DATETIME_ZONE', 'UTC');
1427 setConfigVar ('DATETIME_FORMAT', '%Y-%m-%d');
1428 setConfigVar ('SEARCH_DOMAINS', '');
1429 setConfigVar ('8021Q_EXTSYNC_LISTSRC', 'false');
1430 setConfigVar ('8021Q_MULTILINK_LISTSRC', 'false');
1431 setConfigVar ('REVERSED_RACKS_LISTSRC', 'false');
1432 setConfigVar ('NEAREST_RACKS_CHECKBOX', 'yes');
1433 showFuncMessage (__FUNCTION__
, 'OK');
1436 $msgcode['addRealServer']['OK'] = 48;
1437 // Add single record.
1438 function addRealServer ()
1441 $rsip_bin = assertIPArg ('rsip');
1442 assertStringArg ('rsport', TRUE);
1443 assertStringArg ('rsconfig', TRUE);
1444 assertStringArg ('comment', TRUE);
1449 $_REQUEST['rsport'],
1450 isCheckSet ('inservice', 'yesno'),
1454 showFuncMessage (__FUNCTION__
, 'OK');
1457 $msgcode['addRealServers']['OK'] = 37;
1458 $msgcode['addRealServers']['ERR1'] = 131;
1459 // Parse textarea submitted and try adding a real server for each line.
1460 function addRealServers ()
1463 assertStringArg ('format');
1464 assertStringArg ('rawtext');
1466 // Keep in mind, that the text will have HTML entities (namely '>') escaped.
1467 foreach (explode ("\n", dos2unix ($sic['rawtext'])) as $line)
1469 if (!strlen ($line))
1472 switch ($_REQUEST['format'])
1474 case 'ipvs_2': // address and port only
1475 if (!preg_match ('/^ -> ([0-9\.]+):([0-9]+) /', $line, $match))
1476 if (!preg_match ('/^ -> \[([0-9a-fA-F:]+)\]:([0-9]+) /', $line, $match))
1478 addRStoRSPool (getBypassValue(), ip_parse ($match[1]), $match[2], getConfigVar ('DEFAULT_IPV4_RS_INSERVICE'), '');
1480 case 'ipvs_3': // address, port and weight
1481 if (!preg_match ('/^ -> ([0-9\.]+):([0-9]+) +[a-zA-Z]+ +([0-9]+) /', $line, $match))
1482 if (!preg_match ('/^ -> \[([0-9a-fA-F:]+)\]:([0-9]+) +[a-zA-Z]+ +([0-9]+) /', $line, $match))
1484 addRStoRSPool (getBypassValue(), ip_parse ($match[1]), $match[2], getConfigVar ('DEFAULT_IPV4_RS_INSERVICE'), 'weight ' . $match[3]);
1486 case 'ssv_2': // IP address and port
1487 if (!preg_match ('/^([0-9\.a-fA-F:]+) ([0-9]+)$/', $line, $match))
1489 addRStoRSPool (getBypassValue(), ip_parse ($match[1]), $match[2], getConfigVar ('DEFAULT_IPV4_RS_INSERVICE'), '');
1491 case 'ssv_1': // IP address
1492 if (! $ip_bin = ip_checkparse ($line))
1494 addRStoRSPool (getBypassValue(), $ip_bin, 0, getConfigVar ('DEFAULT_IPV4_RS_INSERVICE'), '');
1497 showFuncMessage (__FUNCTION__
, 'ERR1');
1502 showFuncMessage (__FUNCTION__
, 'OK', array ($ngood));
1505 function addVService ()
1508 $vip_bin = assertIPArg ('vip');
1509 genericAssertion ('proto', 'enum/ipproto');
1510 assertStringArg ('name', TRUE);
1511 assertStringArg ('vsconfig', TRUE);
1512 assertStringArg ('rsconfig', TRUE);
1513 if ($_REQUEST['proto'] == 'MARK')
1517 assertUIntArg ('vport');
1518 $vport = $_REQUEST['vport'];
1520 usePreparedInsertBlade
1527 'proto' => $_REQUEST['proto'],
1528 'name' => !mb_strlen ($_REQUEST['name']) ?
NULL : $_REQUEST['name'],
1529 'vsconfig' => !strlen ($sic['vsconfig']) ?
NULL : $sic['vsconfig'],
1530 'rsconfig' => !strlen ($sic['rsconfig']) ?
NULL : $sic['rsconfig'],
1533 $vs_id = lastInsertID();
1534 if (isset ($_REQUEST['taglist']))
1535 produceTagsForNewRecord ('ipv4vs', $_REQUEST['taglist'], $vs_id);
1536 $vsinfo = spotEntity ('ipv4vs', $vs_id);
1537 showSuccess (mkCellA ($vsinfo) . ' created successfully');
1542 $name = assertStringArg ('name');
1543 usePreparedInsertBlade ('VS', array ('name' => $name));
1544 $vs_id = lastInsertID();
1545 if (isset ($_REQUEST['taglist']))
1546 produceTagsForNewRecord ('ipvs', $_REQUEST['taglist'], $vs_id);
1547 $vsinfo = spotEntity ('ipvs', $vs_id);
1548 showSuccess (mkCellA ($vsinfo) . ' created successfully');
1551 $msgcode['deleteVService']['OK'] = 49;
1552 function deleteVService ()
1554 assertUIntArg ('vs_id');
1555 $vsinfo = spotEntity ('ipv4vs', $_REQUEST['vs_id']);
1556 if ($vsinfo['refcnt'] != 0)
1558 showError ("Could not delete linked virtual service");
1561 commitDeleteVS ($vsinfo['id']);
1562 showFuncMessage (__FUNCTION__
, 'OK');
1563 return buildRedirectURL ('ipv4slb', 'default');
1568 $vsinfo = spotEntity ('ipvs', assertUIntArg ('vs_id'));
1569 if (count (getTriplets ($vsinfo)) != 0)
1571 showError ("Could not delete linked virtual service group");
1574 commitDeleteVSG ($vsinfo['id']);
1575 showSuccess (formatEntityName ($vsinfo) . ' deleted');
1576 return buildRedirectURL ('ipv4slb', 'vs');
1579 $msgcode['updateSLBDefConfig']['OK'] = 43;
1580 function updateSLBDefConfig ()
1583 commitUpdateSLBDefConf
1587 'vs' => $sic['vsconfig'],
1588 'rs' => $sic['rsconfig'],
1591 showFuncMessage (__FUNCTION__
, 'OK');
1594 $msgcode['updateRealServer']['OK'] = 51;
1595 function updateRealServer ()
1598 assertUIntArg ('rs_id');
1599 $rsip_bin = assertIPArg ('rsip');
1600 assertStringArg ('rsport', TRUE);
1601 assertStringArg ('rsconfig', TRUE);
1602 assertStringArg ('comment', TRUE);
1606 $_REQUEST['rsport'],
1607 isCheckSet ('inservice', 'yesno'),
1611 showFuncMessage (__FUNCTION__
, 'OK');
1614 $msgcode['updateVService']['OK'] = 51;
1615 function updateVService ()
1618 assertUIntArg ('vs_id');
1619 $taglist = genericAssertion ('taglist', 'array0');
1620 $vip_bin = assertIPArg ('vip');
1621 genericAssertion ('proto', 'enum/ipproto');
1622 if ($_REQUEST['proto'] == 'MARK')
1623 assertStringArg ('vport', TRUE);
1625 assertUIntArg ('vport');
1626 assertStringArg ('name', TRUE);
1627 assertStringArg ('vsconfig', TRUE);
1628 assertStringArg ('rsconfig', TRUE);
1638 rebuildTagChainForEntity ('ipvs', $_REQUEST['vs_id'], buildTagChainFromIds ($taglist), TRUE);
1639 showFuncMessage (__FUNCTION__
, 'OK');
1642 function updateVS ()
1644 $taglist = genericAssertion ('taglist', 'array0');
1645 $vs_id = assertUIntArg ('vs_id');
1646 $name = assertStringArg ('name');
1647 $vsconfig = nullEmptyStr (assertStringArg ('vsconfig', TRUE));
1648 $rsconfig = nullEmptyStr (assertStringArg ('rsconfig', TRUE));
1650 usePreparedUpdateBlade ('VS', array ('name' => $name, 'vsconfig' => $vsconfig, 'rsconfig' => $rsconfig), array ('id' => $vs_id));
1651 rebuildTagChainForEntity ('ipvs', $vs_id, buildTagChainFromIds ($taglist), TRUE);
1652 showSuccess ("Service updated successfully");
1655 function addIPToVS()
1657 $ip_bin = assertIPArg ('ip');
1658 $vsinfo = spotEntity ('ipvs', assertUIntArg ('vs_id'));
1659 amplifyCell ($vsinfo);
1660 $row = array ('vs_id' => $vsinfo['id'], 'vip' => $ip_bin, 'vsconfig' => NULL, 'rsconfig' => NULL);
1661 if ($vip = isVIPEnabled ($row, $vsinfo['vips']))
1663 showError ("Service already contains IP " . formatVSIP ($vip));
1666 usePreparedInsertBlade ('VSIPs', $row);
1667 showSuccess ("IP addded");
1670 function addPortToVS()
1673 $proto = assertStringArg ('proto');
1674 if (! in_array ($proto, $vs_proto))
1675 throw new InvalidRequestArgException ('proto', "Invalid VS protocol");
1676 $vport = assertUIntArg ('port', TRUE);
1677 if ($proto == 'MARK')
1679 if ($vport > 0xFFFFFFFF)
1681 showError ("fwmark value is too large");
1686 if ($vport == 0 ||
$vport >= 0xFFFF)
1688 showError ("Invalid $proto port value");
1692 $vsinfo = spotEntity ('ipvs', assertUIntArg ('vs_id'));
1693 amplifyCell ($vsinfo);
1694 $row = array ('vs_id' => $vsinfo['id'], 'proto' => $proto, 'vport' => $vport, 'vsconfig' => NULL, 'rsconfig' => NULL);
1695 if ($port = isPortEnabled ($row, $vsinfo['ports']))
1697 showError ("Service already contains port " . formatVSPort ($port));
1700 usePreparedInsertBlade ('VSPorts', $row);
1701 showSuccess ("port addded");
1704 function updateIPInVS()
1706 $vs_id = assertUIntArg ('vs_id');
1707 $ip_bin = assertIPArg ('ip');
1708 $vsconfig = nullEmptyStr (assertStringArg ('vsconfig', TRUE));
1709 $rsconfig = nullEmptyStr (assertStringArg ('rsconfig', TRUE));
1710 if (usePreparedUpdateBlade ('VSIPs', array ('vsconfig' => $vsconfig, 'rsconfig' => $rsconfig), array ('vs_id' => $vs_id, 'vip' => $ip_bin)))
1711 showSuccess ("IP configuration updated");
1713 showNotice ("Nothing changed");
1716 function updatePortInVS()
1718 $vs_id = assertUIntArg ('vs_id');
1719 $proto = assertStringArg ('proto');
1720 $vport = assertUIntArg ('port', TRUE);
1721 $vsconfig = nullEmptyStr (assertStringArg ('vsconfig', TRUE));
1722 $rsconfig = nullEmptyStr (assertStringArg ('rsconfig', TRUE));
1723 if (usePreparedUpdateBlade ('VSPorts', array ('vsconfig' => $vsconfig, 'rsconfig' => $rsconfig), array ('vs_id' => $vs_id, 'proto' => $proto, 'vport' => $vport)))
1724 showSuccess ("Port configuration updated");
1726 showNotice ("Nothing changed");
1729 function removeIPFromVS()
1731 $vip = array ('vip' => assertIPArg ('ip'));
1732 $vsinfo = spotEntity ('ipvs', assertUIntArg ('vs_id'));
1733 amplifyCell ($vsinfo);
1735 foreach (getTriplets ($vsinfo) as $triplet)
1736 if (isVIPEnabled ($vip, $triplet['vips']))
1738 if (usePreparedDeleteBlade ('VSIPs', array ('vs_id' => $vsinfo['id']) +
$vip))
1739 showSuccess ("IP removed" . ($used ?
", it was binded with $used SLBs" : ''));
1741 showNotice ("Nothing changed");
1744 function removePortFromVS()
1746 $port = array ('proto' => assertStringArg ('proto'), 'vport' => assertUIntArg ('port', TRUE));
1747 $vsinfo = spotEntity ('ipvs', assertUIntArg ('vs_id'));
1748 amplifyCell ($vsinfo);
1750 foreach (getTriplets ($vsinfo) as $triplet)
1751 if (isPortEnabled ($port, $triplet['ports']))
1753 if (usePreparedDeleteBlade ('VSPorts', array ('vs_id' => $vsinfo['id']) +
$port))
1754 showSuccess ("Port removed" . ($used ?
", it was binded with $used SLBs" : ''));
1756 showNotice ("Nothing changed");
1759 function updateTripletConfig()
1763 'object_id' => assertUIntArg ('object_id'),
1764 'vs_id' => assertUIntArg ('vs_id'),
1765 'rspool_id' => assertUIntArg ('rspool_id'),
1767 $config_fields = array
1769 'vsconfig' => nullEmptyStr (assertStringArg ('vsconfig', TRUE)),
1770 'rsconfig' => nullEmptyStr (assertStringArg ('rsconfig', TRUE)),
1773 $vsinfo = spotEntity ('ipvs', $key_fields['vs_id']);
1774 amplifyCell ($vsinfo);
1777 if ($_REQUEST['op'] == 'updPort')
1779 $table = 'VSEnabledPorts';
1780 $proto = assertStringArg ('proto');
1781 $vport = assertUIntArg ('port', TRUE);
1782 $key_fields['proto'] = $proto;
1783 $key_fields['vport'] = $vport;
1784 $key = "Port $proto-$vport";
1785 // check if such port exists in VS
1786 foreach ($vsinfo['ports'] as $vs_port)
1787 if ($vs_port['proto'] == $proto && $vs_port['vport'] == $vport)
1795 $table = 'VSEnabledIPs';
1796 $vip = assertIPArg ('vip');
1797 $config_fields['prio'] = nullEmptyStr (assertStringArg ('prio', TRUE));
1798 $key_fields['vip'] = $vip;
1799 $key = "IP " . ip_format ($vip);
1800 // check if such VIP exists in VS
1801 foreach ($vsinfo['vips'] as $vs_vip)
1802 if ($vs_vip['vip'] === $vip)
1810 showError ("$key not found in VS");
1815 if (! isCheckSet ('enabled'))
1817 if ($nchanged +
= usePreparedDeleteBlade ($table, $key_fields))
1819 showSuccess ("$key disabled");
1826 $dbxlink->beginTransaction();
1827 $q = "SELECT * FROM $table WHERE";
1830 foreach ($key_fields as $field => $value)
1832 $q .= " $sep $field = ?";
1836 $result = usePreparedSelectBlade ("$q FOR UPDATE", $params);
1837 $row = $result->fetch (PDO
::FETCH_ASSOC
);
1841 if ($nchanged +
= usePreparedUpdateBlade ($table, $config_fields, $key_fields))
1842 showSuccess ("$key config updated");
1847 $nchanged +
= ($table == 'VSEnabledIPs' ?
1848 addSLBIPLink ($key_fields +
$config_fields) :
1849 addSLBPortLink ($key_fields +
$config_fields)
1852 showSuccess ("$key enabled");
1857 showNotice ("No changes made");
1860 function removeTriplet()
1864 'object_id' => assertUIntArg ('object_id'),
1865 'vs_id' => assertUIntArg ('vs_id'),
1866 'rspool_id' => assertUIntArg ('rspool_id'),
1870 $dbxlink->beginTransaction();
1871 usePreparedDeleteBlade ('VSEnabledIPs', $key_fields);
1872 usePreparedDeleteBlade ('VSEnabledPorts', $key_fields);
1874 showSuccess ('Triplet deleted');
1877 function createTriplet()
1880 $object_id = assertUIntArg ('object_id');
1881 $vs_id = assertUIntArg ('vs_id');
1882 $rspool_id = assertUIntArg ('rspool_id');
1883 $vips = genericAssertion ('enabled_vips', 'array0');
1884 $ports = genericAssertion ('enabled_ports', 'array0');
1886 $vsinfo = spotEntity ('ipvs', $vs_id);
1887 amplifyCell ($vsinfo);
1890 $dbxlink->beginTransaction();
1891 foreach ($vsinfo['vips'] as $vip)
1892 if (in_array (ip_format ($vip['vip']), $vips))
1893 addSLBIPLink (array ('object_id' => $object_id, 'vs_id' => $vs_id, 'rspool_id' => $rspool_id, 'vip' => $vip['vip']));
1894 foreach ($vsinfo['ports'] as $port)
1895 if (in_array($port['proto'] . '-' . $port['vport'], $ports))
1896 addSLBPortLink (array ('object_id' => $object_id, 'vs_id' => $vs_id, 'rspool_id' => $rspool_id, 'proto' => $port['proto'], 'vport' => $port['vport']));
1899 catch (RTDatabaseError
$e)
1901 $dbxlink->rollBack();
1904 showSuccess ("SLB triplet created");
1907 $msgcode['addLoadBalancer']['OK'] = 48;
1908 function addLoadBalancer ()
1911 assertUIntArg ('pool_id');
1912 assertUIntArg ('object_id');
1913 assertUIntArg ('vs_id');
1914 assertStringArg ('vsconfig', TRUE);
1915 assertStringArg ('rsconfig', TRUE);
1916 assertStringArg ('prio', TRUE);
1919 $_REQUEST['pool_id'],
1920 $_REQUEST['object_id'],
1926 showFuncMessage (__FUNCTION__
, 'OK');
1929 function addRSPool ()
1932 assertStringArg ('name');
1933 assertStringArg ('vsconfig', TRUE);
1934 assertStringArg ('rsconfig', TRUE);
1935 $pool_id = commitCreateRSPool
1940 isset ($_REQUEST['taglist']) ?
$_REQUEST['taglist'] : array()
1942 showSuccess ('RS pool ' . mkA ($_REQUEST['name'], 'ipv4rspool', $pool_id) . ' created successfully');
1945 $msgcode['deleteRSPool']['OK'] = 49;
1946 function deleteRSPool ()
1948 assertUIntArg ('pool_id');
1949 $poolinfo = spotEntity ('ipv4rspool', $_REQUEST['pool_id']);
1950 if ($poolinfo['refcnt'] != 0)
1952 showError ("Could not delete linked RS pool");
1955 commitDeleteRSPool ($poolinfo['id']);
1956 showFuncMessage (__FUNCTION__
, 'OK');
1957 return buildRedirectURL ('ipv4slb', 'rspools');
1960 $msgcode['importPTRData']['OK'] = 26;
1961 $msgcode['importPTRData']['ERR'] = 141;
1962 function importPTRData ()
1964 $net = spotEntity ('ipv4net', getBypassValue());
1965 assertUIntArg ('addrcount');
1967 for ($i = 1; $i <= $_REQUEST['addrcount']; $i++
)
1969 $inputname = "import_${i}";
1970 if (! isCheckSet ($inputname))
1972 $ip_bin = assertIPv4Arg ("addr_${i}");
1973 assertStringArg ("descr_${i}", TRUE);
1974 assertStringArg ("rsvd_${i}");
1975 // Non-existent addresses will not have this argument set in request.
1977 if ($_REQUEST["rsvd_${i}"] == 'yes')
1981 if (! ip_in_range ($ip_bin, $net))
1982 throw new InvalidArgException ('ip_bin', $ip_bin);
1983 updateAddress ($ip_bin, $_REQUEST["descr_${i}"], $rsvd);
1986 catch (RackTablesError
$e)
1992 showFuncMessage (__FUNCTION__
, 'OK', array ($ngood));
1994 showFuncMessage (__FUNCTION__
, 'ERR', array ($nbad, $ngood));
1997 $msgcode['generateAutoPorts']['OK'] = 21;
1998 function generateAutoPorts ()
2000 $object = spotEntity ('object', getBypassValue());
2001 executeAutoPorts ($object['id'], $object['objtype_id']);
2002 showFuncMessage (__FUNCTION__
, 'OK');
2003 return buildRedirectURL (NULL, 'ports');
2006 function updateTag ()
2008 assertUIntArg ('tag_id');
2009 genericAssertion ('tag_name', 'tag');
2010 assertUIntArg ('parent_id', TRUE);
2011 genericAssertion ('is_assignable', 'enum/yesno');
2012 commitUpdateTag ($_REQUEST['tag_id'], $_REQUEST['tag_name'], $_REQUEST['parent_id'], $_REQUEST['is_assignable']);
2013 showSuccess ('Tag updated successfully');
2016 $msgcode['saveEntityTags']['OK'] = 43;
2017 function saveEntityTags ()
2019 global $pageno, $etype_by_pageno;
2020 if (!isset ($etype_by_pageno[$pageno]))
2021 throw new RackTablesError ('key not found in etype_by_pageno', RackTablesError
::INTERNAL
);
2022 $realm = $etype_by_pageno[$pageno];
2023 $entity_id = getBypassValue();
2024 $taglist = isset ($_REQUEST['taglist']) ?
$_REQUEST['taglist'] : array();
2025 rebuildTagChainForEntity ($realm, $entity_id, buildTagChainFromIds ($taglist), TRUE);
2026 showFuncMessage (__FUNCTION__
, 'OK');
2029 $msgcode['rollTags']['OK'] = 67;
2030 $msgcode['rollTags']['ERR'] = 149;
2031 function rollTags ()
2033 assertStringArg ('sum', TRUE);
2034 assertUIntArg ('realsum');
2035 if ($_REQUEST['sum'] != $_REQUEST['realsum'])
2037 showFuncMessage (__FUNCTION__
, 'ERR');
2040 // Even if the user requested an empty tag list, don't bail out, but process existing
2041 // tag chains with "zero" extra. This will make sure, that the stuff processed will
2042 // have its chains refined to "normal" form.
2043 $extratags = isset ($_REQUEST['taglist']) ?
$_REQUEST['taglist'] : array();
2045 // Minimizing the extra chain early, so that tag rebuilder doesn't have to
2046 // filter out the same tag again and again. It will have own noise to cancel.
2047 $extrachain = getExplicitTagsOnly (buildTagChainFromIds ($extratags));
2048 foreach (listCells ('rack', getBypassValue()) as $rack)
2050 if (rebuildTagChainForEntity ('rack', $rack['id'], $extrachain))
2052 amplifyCell ($rack);
2053 foreach ($rack['mountedObjects'] as $object_id)
2054 if (rebuildTagChainForEntity ('object', $object_id, $extrachain))
2057 showFuncMessage (__FUNCTION__
, 'OK', array ($n_ok));
2060 $msgcode['changeMyPassword']['OK'] = 51;
2061 $msgcode['changeMyPassword']['ERR1'] = 150;
2062 $msgcode['changeMyPassword']['ERR2'] = 151;
2063 $msgcode['changeMyPassword']['ERR3'] = 152;
2064 function changeMyPassword ()
2066 global $remote_username, $user_auth_src;
2067 if ($user_auth_src != 'database')
2069 showFuncMessage (__FUNCTION__
, 'ERR1');
2072 assertStringArg ('oldpassword');
2073 assertStringArg ('newpassword1');
2074 assertStringArg ('newpassword2');
2075 $remote_userid = getUserIDByUsername ($remote_username);
2076 $userinfo = spotEntity ('user', $remote_userid);
2077 if ($userinfo['user_password_hash'] != sha1 ($_REQUEST['oldpassword']))
2079 showFuncMessage (__FUNCTION__
, 'ERR2');
2082 if ($_REQUEST['newpassword1'] != $_REQUEST['newpassword2'])
2084 showFuncMessage (__FUNCTION__
, 'ERR3');
2087 commitUpdateUserAccount ($remote_userid, $userinfo['user_name'], $userinfo['user_realname'], sha1 ($_REQUEST['newpassword1']));
2088 showFuncMessage (__FUNCTION__
, 'OK');
2091 $msgcode['saveRackCode']['OK'] = 43;
2092 $msgcode['saveRackCode']['ERR1'] = 154;
2093 function saveRackCode ()
2095 assertStringArg ('rackcode');
2096 // For the test to succeed, unescape LFs, strip CRs.
2097 $newcode = dos2unix ($_REQUEST['rackcode']);
2098 $parseTree = getRackCode ($newcode);
2099 if ($parseTree['result'] != 'ACK')
2101 showFuncMessage (__FUNCTION__
, 'ERR1', array ($parseTree['load']));
2104 saveScript ('RackCode', $newcode);
2105 saveScript ('RackCodeCache', base64_encode (serialize ($parseTree)));
2106 showFuncMessage (__FUNCTION__
, 'OK');
2109 function submitSLBConfig ()
2111 showNotice ("You should redefine submitSLBConfig ophandler in your local extension to install SLB config");
2114 $msgcode['addLocation']['OK'] = 5;
2115 function addLocation ()
2117 assertUIntArg ('parent_id', TRUE);
2118 assertStringArg ('name');
2120 $location_id = commitAddObject ($_REQUEST['name'], NULL, 1562, NULL);
2121 if ($_REQUEST['parent_id'])
2122 commitLinkEntities ('location', $_REQUEST['parent_id'], 'location', $location_id);
2123 showSuccess ('added location ' . mkA ($_REQUEST['name'], 'location', $location_id));
2126 $msgcode['updateLocation']['OK'] = 6;
2127 // This function is used by two forms:
2128 // - renderEditLocationForm - all attributes may be modified
2129 // - renderRackspaceLocationEditor - only the name and parent may be modified
2130 function updateLocation ()
2133 assertUIntArg ('location_id');
2134 assertUIntArg ('parent_id', TRUE);
2135 assertStringArg ('name');
2137 if ($pageno == 'location')
2139 $taglist = genericAssertion ('taglist', 'array0');
2140 $has_problems = (isset ($_REQUEST['has_problems']) and $_REQUEST['has_problems'] == 'on') ?
'yes' : 'no';
2141 assertStringArg ('comment', TRUE);
2142 commitUpdateObject ($_REQUEST['location_id'], $_REQUEST['name'], NULL, $has_problems, NULL, $_REQUEST['comment']);
2143 updateObjectAttributes ($_REQUEST['location_id']);
2144 rebuildTagChainForEntity ('location', $_REQUEST['location_id'], buildTagChainFromIds ($taglist), TRUE);
2147 commitRenameObject ($_REQUEST['location_id'], $_REQUEST['name']);
2149 $locationData = spotEntity ('location', $_REQUEST['location_id']);
2151 // parent_id was submitted, but no link exists - create it
2152 if ($_REQUEST['parent_id'] > 0 && !$locationData['parent_id'])
2153 commitLinkEntities ('location', $_REQUEST['parent_id'], 'location', $_REQUEST['location_id']);
2155 // parent_id was submitted, but it doesn't match the existing link - update it
2156 if ($_REQUEST['parent_id'] > 0 && $_REQUEST['parent_id'] != $locationData['parent_id'])
2157 commitUpdateEntityLink
2159 'location', $locationData['parent_id'], 'location', $_REQUEST['location_id'],
2160 'location', $_REQUEST['parent_id'], 'location', $_REQUEST['location_id']
2163 // no parent_id was submitted, but a link exists - delete it
2164 if ($_REQUEST['parent_id'] == 0 && $locationData['parent_id'])
2165 commitUnlinkEntities ('location', $locationData['parent_id'], 'location', $_REQUEST['location_id']);
2167 showFuncMessage (__FUNCTION__
, 'OK', array ($_REQUEST['name']));
2170 $msgcode['deleteLocation']['OK'] = 7;
2171 $msgcode['deleteLocation']['ERR1'] = 206;
2172 function deleteLocation ()
2174 assertUIntArg ('location_id');
2175 $locationData = spotEntity ('location', $_REQUEST['location_id']);
2176 amplifyCell ($locationData);
2177 if (count ($locationData['locations']) ||
count ($locationData['rows']))
2179 showFuncMessage (__FUNCTION__
, 'ERR1', array ($locationData['name']));
2182 releaseFiles ('location', $_REQUEST['location_id']);
2183 destroyTagsForEntity ('location', $_REQUEST['location_id']);
2184 commitDeleteObject ($_REQUEST['location_id']);
2185 showFuncMessage (__FUNCTION__
, 'OK', array ($locationData['name']));
2186 return buildRedirectURL ('rackspace', 'editlocations');
2189 $msgcode['addRow']['OK'] = 5;
2192 assertUIntArg ('location_id', TRUE);
2193 assertStringArg ('name');
2194 $row_id = commitAddObject ($_REQUEST['name'], NULL, 1561, NULL);
2195 if ($_REQUEST['location_id'])
2196 commitLinkEntities ('location', $_REQUEST['location_id'], 'row', $row_id);
2197 showSuccess ('added row ' . mkA ($_REQUEST['name'], 'row', $row_id));
2200 $msgcode['updateRow']['OK'] = 6;
2201 // This function is used by two forms:
2202 // - renderEditRowForm - all attributes may be modified
2203 // - renderRackspaceRowEditor - only the name and location may be modified
2204 function updateRow ()
2206 assertUIntArg ('row_id');
2207 assertUIntArg ('location_id', TRUE);
2208 assertStringArg ('name');
2210 commitUpdateObject ($_REQUEST['row_id'], $_REQUEST['name'], NULL, NULL, NULL, NULL);
2213 if ($pageno == 'row')
2214 updateObjectAttributes ($_REQUEST['row_id']);
2216 $rowData = spotEntity ('row', $_REQUEST['row_id']);
2218 // location_id was submitted, but no link exists - create it
2219 if ($_REQUEST['location_id'] > 0 && !$rowData['location_id'])
2220 commitLinkEntities ('location', $_REQUEST['location_id'], 'row', $_REQUEST['row_id']);
2222 // location_id was submitted, but it doesn't match the existing link - update it
2223 if ($_REQUEST['location_id'] > 0 && $_REQUEST['location_id'] != $rowData['location_id'])
2224 commitUpdateEntityLink
2226 'location', $rowData['location_id'], 'row', $_REQUEST['row_id'],
2227 'location', $_REQUEST['location_id'], 'row', $_REQUEST['row_id']
2230 // no parent_id was submitted, but a link exists - delete it
2231 if ($_REQUEST['location_id'] == 0 && $rowData['location_id'])
2232 commitUnlinkEntities ('location', $rowData['location_id'], 'row', $_REQUEST['row_id']);
2234 showFuncMessage (__FUNCTION__
, 'OK', array ($_REQUEST['name']));
2237 $msgcode['deleteRow']['OK'] = 7;
2238 $msgcode['deleteRow']['ERR1'] = 206;
2239 function deleteRow ()
2241 assertUIntArg ('row_id');
2242 $rowData = spotEntity ('row', $_REQUEST['row_id']);
2243 amplifyCell ($rowData);
2244 if (count ($rowData['racks']))
2246 showFuncMessage (__FUNCTION__
, 'ERR1', array ($rowData['name']));
2249 commitDeleteObject ($_REQUEST['row_id']);
2250 showFuncMessage (__FUNCTION__
, 'OK', array ($rowData['name']));
2251 return buildRedirectURL ('rackspace', 'editrows');
2254 $msgcode['addRack']['ERR2'] = 172;
2257 $taglist = genericAssertion ('taglist', 'array0');
2259 // The new rack(s) should be placed on the bottom of the list, sort-wise
2260 $rowInfo = getRowInfo($_REQUEST['row_id']);
2261 $sort_order = $rowInfo['count']+
1;
2263 if (isset ($_REQUEST['got_data']))
2265 assertStringArg ('name');
2266 assertUIntArg ('height1');
2267 assertStringArg ('asset_no', TRUE);
2268 $rack_id = commitAddObject ($_REQUEST['name'], NULL, 1560, $_REQUEST['asset_no'], $taglist);
2269 produceTagsForNewRecord ('rack', $taglist, $rack_id);
2271 // Set the height and sort order
2272 commitUpdateAttrValue ($rack_id, 27, $_REQUEST['height1']);
2273 commitUpdateAttrValue ($rack_id, 29, $sort_order);
2275 // Link it to the row
2276 commitLinkEntities ('row', $_REQUEST['row_id'], 'rack', $rack_id);
2277 showSuccess ('added rack ' . mkA ($_REQUEST['name'], 'rack', $rack_id));
2279 elseif (isset ($_REQUEST['got_mdata']))
2281 assertUIntArg ('height2');
2282 assertStringArg ('names', TRUE);
2283 // copy-and-paste from renderAddMultipleObjectsForm()
2284 $names1 = explode ("\n", $_REQUEST['names']);
2286 foreach ($names1 as $line)
2288 $parts = explode ('\r', $line);
2290 if (!strlen ($parts[0]))
2293 $names2[] = rtrim ($parts[0]);
2295 foreach ($names2 as $cname)
2297 $rack_id = commitAddObject ($cname, NULL, 1560, NULL, $taglist);
2298 produceTagsForNewRecord ('rack', $taglist, $rack_id);
2300 // Set the height and sort order
2301 commitUpdateAttrValue ($rack_id, 27, $_REQUEST['height2']);
2302 commitUpdateAttrValue ($rack_id, 29, $sort_order);
2305 // Link it to the row
2306 commitLinkEntities ('row', $_REQUEST['row_id'], 'rack', $rack_id);
2307 showSuccess ('added rack ' . mkA ($cname, 'rack', $rack_id));
2311 showFuncMessage (__FUNCTION__
, 'ERR2');
2314 $msgcode['updateRack']['OK'] = 6;
2315 function updateRack ()
2317 assertUIntArg ('row_id');
2318 assertStringArg ('name');
2319 assertUIntArg ('height');
2320 assertStringArg ('asset_no', TRUE);
2321 assertStringArg ('comment', TRUE);
2322 $taglist = genericAssertion ('taglist', 'array0');
2323 $rack_id = getBypassValue();
2324 usePreparedDeleteBlade ('RackThumbnail', array ('rack_id' => $rack_id));
2328 $_REQUEST['row_id'],
2330 $_REQUEST['height'],
2331 isCheckSet ('has_problems', 'yesno'),
2332 $_REQUEST['asset_no'],
2333 $_REQUEST['comment']
2335 updateObjectAttributes ($rack_id);
2336 rebuildTagChainForEntity ('rack', $rack_id, buildTagChainFromIds ($taglist), TRUE);
2337 showFuncMessage (__FUNCTION__
, 'OK', array ($_REQUEST['name']));
2340 $msgcode['deleteRack']['OK'] = 7;
2341 $msgcode['deleteRack']['ERR1'] = 206;
2342 function deleteRack ()
2344 assertUIntArg ('rack_id');
2345 $rackData = spotEntity ('rack', $_REQUEST['rack_id']);
2346 amplifyCell ($rackData);
2347 if (count ($rackData['mountedObjects']))
2349 showFuncMessage (__FUNCTION__
, 'ERR1');
2352 releaseFiles ('rack', $_REQUEST['rack_id']);
2353 destroyTagsForEntity ('rack', $_REQUEST['rack_id']);
2354 usePreparedDeleteBlade ('RackSpace', array ('rack_id' => $_REQUEST['rack_id']));
2355 commitDeleteObject ($_REQUEST['rack_id']);
2356 resetRackSortOrder ($rackData['row_id']);
2357 showFuncMessage (__FUNCTION__
, 'OK', array ($rackData['name']));
2358 return buildRedirectURL ('rackspace', 'default');
2361 function updateRackDesign ()
2363 $rackData = spotEntity ('rack', getBypassValue());
2364 amplifyCell ($rackData);
2365 applyRackDesignMask($rackData);
2366 if (processGridForm ($rackData, 'A', 'F'))
2367 showSuccess ("Saved successfully");
2369 showNotice ("Nothing saved");
2372 function updateRackProblems ()
2374 $rackData = spotEntity ('rack', getBypassValue());
2375 amplifyCell ($rackData);
2376 applyRackProblemMask($rackData);
2377 if (processGridForm ($rackData, 'F', 'U'))
2378 showSuccess ("Saved successfully");
2380 showNotice ("Nothing saved");
2383 function querySNMPData ()
2385 genericAssertion ('ver', 'uint');
2386 $snmpsetup = array ();
2387 switch ($_REQUEST['ver'])
2391 genericAssertion ('community', 'string');
2392 $snmpsetup['community'] = $_REQUEST['community'];
2395 assertStringArg ('sec_name');
2396 assertStringArg ('sec_level');
2397 assertStringArg ('auth_protocol');
2398 assertStringArg ('auth_passphrase', TRUE);
2399 assertStringArg ('priv_protocol');
2400 assertStringArg ('priv_passphrase', TRUE);
2402 $snmpsetup['sec_name'] = $_REQUEST['sec_name'];
2403 $snmpsetup['sec_level'] = $_REQUEST['sec_level'];
2404 $snmpsetup['auth_protocol'] = $_REQUEST['auth_protocol'];
2405 $snmpsetup['auth_passphrase'] = $_REQUEST['auth_passphrase'];
2406 $snmpsetup['priv_protocol'] = $_REQUEST['priv_protocol'];
2407 $snmpsetup['priv_passphrase'] = $_REQUEST['priv_passphrase'];
2410 throw new InvalidRequestArgException ('ver', $_REQUEST['ver']);
2412 $snmpsetup['version'] = $_REQUEST['ver'];
2413 doSNMPmining (getBypassValue(), $snmpsetup); // shows message by itself
2416 $msgcode['addFileWithoutLink']['OK'] = 5;
2417 // File-related functions
2418 function addFileWithoutLink ()
2420 assertStringArg ('comment', TRUE);
2422 // Make sure the file can be uploaded
2423 if (get_cfg_var('file_uploads') != 1)
2424 throw new RackTablesError ('file uploads not allowed, change "file_uploads" parameter in php.ini', RackTablesError
::MISCONFIGURED
);
2426 $fp = fopen($_FILES['file']['tmp_name'], 'rb');
2428 $file_id = commitAddFile ($_FILES['file']['name'], $_FILES['file']['type'], $fp, $sic['comment']);
2429 if (isset ($_REQUEST['taglist']))
2430 produceTagsForNewRecord ('file', $_REQUEST['taglist'], $file_id);
2431 showFuncMessage (__FUNCTION__
, 'OK', array (htmlspecialchars ($_FILES['file']['name'])));
2434 $msgcode['addFileToEntity']['OK'] = 5;
2435 $msgcode['addFileToEntity']['ERR1'] = 207;
2436 function addFileToEntity ()
2438 global $pageno, $etype_by_pageno;
2439 if (!isset ($etype_by_pageno[$pageno]))
2440 throw new RackTablesError ('key not found in etype_by_pageno', RackTablesError
::INTERNAL
);
2441 $realm = $etype_by_pageno[$pageno];
2442 assertStringArg ('comment', TRUE);
2444 // Make sure the file can be uploaded
2445 if (get_cfg_var('file_uploads') != 1)
2446 throw new RackTablesError ('file uploads not allowed, change "file_uploads" parameter in php.ini', RackTablesError
::MISCONFIGURED
);
2448 // Exit if the upload failed
2449 if ($_FILES['file']['error'])
2451 showFuncMessage (__FUNCTION__
, 'ERR1', array ($_FILES['file']['error']));
2455 $fp = fopen($_FILES['file']['tmp_name'], 'rb');
2457 commitAddFile ($_FILES['file']['name'], $_FILES['file']['type'], $fp, $sic['comment']);
2458 usePreparedInsertBlade
2463 'file_id' => lastInsertID(),
2464 'entity_type' => $realm,
2465 'entity_id' => getBypassValue(),
2468 showFuncMessage (__FUNCTION__
, 'OK', array (htmlspecialchars ($_FILES['file']['name'])));
2471 $msgcode['linkFileToEntity']['OK'] = 71;
2472 function linkFileToEntity ()
2474 assertUIntArg ('file_id');
2475 global $pageno, $etype_by_pageno, $sic;
2476 if (!isset ($etype_by_pageno[$pageno]))
2477 throw new RackTablesError ('key not found in etype_by_pageno', RackTablesError
::INTERNAL
);
2479 usePreparedInsertBlade
2484 'file_id' => $sic['file_id'],
2485 'entity_type' => $etype_by_pageno[$pageno],
2486 'entity_id' => getBypassValue(),
2489 $fi = spotEntity ('file', $sic['file_id']);
2490 showFuncMessage (__FUNCTION__
, 'OK', array (htmlspecialchars ($fi['name'])));
2493 $msgcode['replaceFile']['OK'] = 7;
2494 $msgcode['replaceFile']['ERR2'] = 201;
2495 function replaceFile ()
2497 // Make sure the file can be uploaded
2498 if (get_cfg_var('file_uploads') != 1)
2499 throw new RackTablesError ('file uploads not allowed, change "file_uploads" parameter in php.ini', RackTablesError
::MISCONFIGURED
);
2500 $shortInfo = spotEntity ('file', getBypassValue());
2502 if (FALSE === $fp = fopen ($_FILES['file']['tmp_name'], 'rb'))
2504 showFuncMessage (__FUNCTION__
, 'ERR2');
2507 commitReplaceFile ($shortInfo['id'], $fp);
2509 showFuncMessage (__FUNCTION__
, 'OK', array (htmlspecialchars ($shortInfo['name'])));
2512 $msgcode['unlinkFile']['OK'] = 72;
2513 function unlinkFile ()
2515 assertUIntArg ('link_id');
2516 commitUnlinkFile ($_REQUEST['link_id']);
2517 showFuncMessage (__FUNCTION__
, 'OK');
2520 $msgcode['deleteFile']['OK'] = 7;
2521 function deleteFile ()
2523 assertUIntArg ('file_id');
2524 $shortInfo = spotEntity ('file', $_REQUEST['file_id']);
2525 commitDeleteFile ($_REQUEST['file_id']);
2526 showFuncMessage (__FUNCTION__
, 'OK', array (htmlspecialchars ($shortInfo['name'])));
2529 $msgcode['updateFileText']['OK'] = 6;
2530 $msgcode['updateFileText']['ERR1'] = 179;
2531 $msgcode['updateFileText']['ERR2'] = 155;
2532 function updateFileText ()
2534 assertStringArg ('mtime_copy');
2535 assertStringArg ('file_text', TRUE); // it's Ok to save empty
2536 $shortInfo = spotEntity ('file', getBypassValue());
2537 if ($shortInfo['mtime'] != $_REQUEST['mtime_copy'])
2539 showFuncMessage (__FUNCTION__
, 'ERR1');
2543 commitReplaceFile ($shortInfo['id'], $sic['file_text']);
2544 showFuncMessage (__FUNCTION__
, 'OK', array (htmlspecialchars ($shortInfo['name'])));
2547 $msgcode['addIIFOIFCompat']['OK'] = 48;
2548 function addIIFOIFCompat ()
2550 assertUIntArg ('iif_id');
2551 assertUIntArg ('oif_id');
2552 commitSupplementPIC ($_REQUEST['iif_id'], $_REQUEST['oif_id']);
2553 showFuncMessage (__FUNCTION__
, 'OK');
2556 $msgcode['addIIFOIFCompatPack']['OK'] = 37;
2557 function addIIFOIFCompatPack ()
2559 genericAssertion ('standard', 'enum/wdmstd');
2560 genericAssertion ('iif_id', 'iif');
2561 global $wdm_packs, $sic;
2563 foreach ($wdm_packs[$sic['standard']]['oif_ids'] as $oif_id)
2565 commitSupplementPIC ($sic['iif_id'], $oif_id);
2568 showFuncMessage (__FUNCTION__
, 'OK', array ($ngood));
2571 $msgcode['delIIFOIFCompatPack']['OK'] = 38;
2572 function delIIFOIFCompatPack ()
2574 genericAssertion ('standard', 'enum/wdmstd');
2575 genericAssertion ('iif_id', 'iif');
2576 global $wdm_packs, $sic;
2578 foreach ($wdm_packs[$sic['standard']]['oif_ids'] as $oif_id)
2580 usePreparedDeleteBlade ('PortInterfaceCompat', array ('iif_id' => $sic['iif_id'], 'oif_id' => $oif_id));
2583 showFuncMessage (__FUNCTION__
, 'OK', array ($ngood));
2586 $msgcode['addOIFCompatPack']['OK'] = 21;
2587 function addOIFCompatPack ()
2589 genericAssertion ('standard', 'enum/wdmstd');
2591 $oifs = $wdm_packs[$_REQUEST['standard']]['oif_ids'];
2592 foreach ($oifs as $oif_id_1)
2594 $args = $qmarks = array();
2595 $query = 'REPLACE INTO PortCompat (type1, type2) VALUES ';
2596 foreach ($oifs as $oif_id_2)
2598 $qmarks[] = '(?, ?)';
2599 $args[] = $oif_id_1;
2600 $args[] = $oif_id_2;
2602 $query .= implode (', ', $qmarks);
2603 usePreparedExecuteBlade ($query, $args);
2605 showFuncMessage (__FUNCTION__
, 'OK');
2608 $msgcode['delOIFCompatPack']['OK'] = 21;
2609 function delOIFCompatPack ()
2611 genericAssertion ('standard', 'enum/wdmstd');
2613 $oifs = $wdm_packs[$_REQUEST['standard']]['oif_ids'];
2614 foreach ($oifs as $oif_id_1)
2615 foreach ($oifs as $oif_id_2)
2616 if ($oif_id_1 != $oif_id_2) # leave narrow-band mapping intact
2617 usePreparedDeleteBlade ('PortCompat', array ('type1' => $oif_id_1, 'type2' => $oif_id_2));
2618 showFuncMessage (__FUNCTION__
, 'OK');
2621 $msgcode['add8021QOrder']['OK'] = 48;
2622 function add8021QOrder ()
2624 assertUIntArg ('vdom_id');
2625 assertUIntArg ('object_id');
2626 assertUIntArg ('vst_id');
2627 global $sic, $pageno;
2629 if ($pageno != 'object')
2630 spreadContext (spotEntity ('object', $sic['object_id']));
2631 if ($pageno != 'vst')
2632 spreadContext (spotEntity ('vst', $sic['vst_id']));
2634 usePreparedExecuteBlade
2636 'INSERT INTO VLANSwitch (domain_id, object_id, template_id, last_change, out_of_sync) ' .
2637 'VALUES (?, ?, ?, NOW(), "yes")',
2638 array ($sic['vdom_id'], $sic['object_id'], $sic['vst_id'])
2640 showFuncMessage (__FUNCTION__
, 'OK');
2643 $msgcode['del8021QOrder']['OK'] = 49;
2644 function del8021QOrder ()
2646 assertUIntArg ('object_id');
2647 assertUIntArg ('vdom_id');
2648 assertUIntArg ('vst_id');
2649 global $sic, $pageno;
2651 if ($pageno != 'object')
2652 spreadContext (spotEntity ('object', $sic['object_id']));
2653 if ($pageno != 'vst')
2654 spreadContext (spotEntity ('vst', $sic['vst_id']));
2656 usePreparedDeleteBlade ('VLANSwitch', array ('object_id' => $sic['object_id']));
2657 $focus_hints = array
2659 'prev_objid' => $_REQUEST['object_id'],
2660 'prev_vstid' => $_REQUEST['vst_id'],
2661 'prev_vdid' => $_REQUEST['vdom_id'],
2663 showFuncMessage (__FUNCTION__
, 'OK');
2664 return buildRedirectURL (NULL, NULL, $focus_hints);
2667 $msgcode['createVLANDomain']['OK'] = 48;
2668 function createVLANDomain ()
2670 assertStringArg ('vdom_descr');
2672 usePreparedInsertBlade
2677 'description' => $sic['vdom_descr'],
2680 usePreparedInsertBlade
2685 'domain_id' => lastInsertID(),
2686 'vlan_id' => VLAN_DFL_ID
,
2687 'vlan_type' => 'compulsory',
2688 'vlan_descr' => 'default',
2691 showFuncMessage (__FUNCTION__
, 'OK');
2694 function save8021QPorts ()
2697 assertUIntArg ('mutex_rev', TRUE); // counts from 0
2698 assertStringArg ('form_mode');
2699 if ($sic['form_mode'] != 'save' and $sic['form_mode'] != 'duplicate')
2700 throw new InvalidRequestArgException ('form_mode', $sic['form_mode']);
2703 // prepare the $changes array
2705 switch ($sic['form_mode'])
2708 assertUIntArg ('nports');
2709 if ($sic['nports'] == 1)
2711 assertStringArg ('pn_0');
2712 $extra = array ('port_name' => $sic['pn_0']);
2714 for ($i = 0; $i < $sic['nports']; $i++
)
2716 assertStringArg ('pn_' . $i);
2717 assertStringArg ('pm_' . $i);
2718 // An access port only generates form input for its native VLAN,
2719 // which we derive allowed VLAN list from.
2720 $native = isset ($sic['pnv_' . $i]) ?
$sic['pnv_' . $i] : 0;
2721 switch ($sic["pm_${i}"])
2724 # assertArrayArg ('pav_' . $i);
2725 $allowed = isset ($sic['pav_' . $i]) ?
$sic['pav_' . $i] : array();
2728 if ($native == 'same')
2730 assertUIntArg ('pnv_' . $i);
2731 $allowed = array ($native);
2734 throw new InvalidRequestArgException ("pm_${i}", $_REQUEST["pm_${i}"], 'unknown port mode');
2736 $changes[$sic['pn_' . $i]] = array
2738 'mode' => $sic['pm_' . $i],
2739 'allowed' => $allowed,
2740 'native' => $native,
2745 assertStringArg ('from_port');
2746 # assertArrayArg ('to_ports');
2747 $before = getStored8021QConfig ($sic['object_id'], 'desired');
2748 if (!array_key_exists ($sic['from_port'], $before))
2749 throw new InvalidArgException ('from_port', $sic['from_port'], 'this port does not exist');
2750 foreach ($sic['to_ports'] as $tpn)
2751 if (!array_key_exists ($tpn, $before))
2752 throw new InvalidArgException ('to_ports[]', $tpn, 'this port does not exist');
2753 elseif ($tpn != $sic['from_port'])
2754 $changes[$tpn] = $before[$sic['from_port']];
2757 apply8021qChangeRequest ($sic['object_id'], $changes, TRUE, $sic['mutex_rev']);
2758 return buildRedirectURL (NULL, NULL, $extra);
2761 $msgcode['bindVLANtoIPv4']['OK'] = 48;
2762 function bindVLANtoIPv4 ()
2764 genericAssertion ('id', 'uint');
2765 genericAssertion ('vlan_ck', 'uint-vlan1');
2767 commitSupplementVLANIPv4 ($sic['vlan_ck'], $sic['id']);
2768 showFuncMessage (__FUNCTION__
, 'OK');
2771 $msgcode['bindVLANtoIPv6']['OK'] = 48;
2772 function bindVLANtoIPv6 ()
2774 genericAssertion ('id', 'uint');
2775 genericAssertion ('vlan_ck', 'uint-vlan1');
2777 commitSupplementVLANIPv6 ($sic['vlan_ck'], $_REQUEST['id']);
2778 showFuncMessage (__FUNCTION__
, 'OK');
2781 $msgcode['unbindVLANfromIPv4']['OK'] = 49;
2782 function unbindVLANfromIPv4 ()
2784 genericAssertion ('id', 'uint');
2785 genericAssertion ('vlan_ck', 'uint-vlan1');
2787 commitReduceVLANIPv4 ($sic['vlan_ck'], $sic['id']);
2788 showFuncMessage (__FUNCTION__
, 'OK');
2791 $msgcode['unbindVLANfromIPv6']['OK'] = 49;
2792 function unbindVLANfromIPv6 ()
2794 genericAssertion ('id', 'uint');
2795 genericAssertion ('vlan_ck', 'uint-vlan1');
2797 commitReduceVLANIPv6 ($sic['vlan_ck'], $sic['id']);
2798 showFuncMessage (__FUNCTION__
, 'OK');
2801 $msgcode['process8021QSyncRequest']['OK'] = 63;
2802 $msgcode['process8021QSyncRequest']['ERR'] = 191;
2803 function process8021QSyncRequest ()
2805 // behave depending on current operation: exec8021QPull or exec8021QPush
2807 if (FALSE === $done = exec8021QDeploy ($sic['object_id'], $op == 'exec8021QPush'))
2808 showFuncMessage (__FUNCTION__
, 'ERR');
2810 showFuncMessage (__FUNCTION__
, 'OK', array ($done));
2813 $msgcode['process8021QRecalcRequest']['CHANGED'] = 87;
2814 function process8021QRecalcRequest ()
2816 assertPermission (NULL, NULL, NULL, array (array ('tag' => '$op_recalc8021Q')));
2817 $counters = recalc8021QPorts (getBypassValue());
2818 if ($counters['ports'])
2819 showFuncMessage (__FUNCTION__
, 'CHANGED', array ($counters['ports'], $counters['switches']));
2821 showNotice ('No changes were made');
2824 $msgcode['resolve8021QConflicts']['OK'] = 63;
2825 $msgcode['resolve8021QConflicts']['ERR1'] = 179;
2826 $msgcode['resolve8021QConflicts']['ERR2'] = 109;
2827 function resolve8021QConflicts ()
2829 global $sic, $dbxlink;
2830 assertUIntArg ('mutex_rev', TRUE); // counts from 0
2831 assertUIntArg ('nrows');
2832 // Divide submitted radio buttons into 3 groups:
2833 // left (saved version wins)
2835 // right (running version wins)
2837 for ($i = 0; $i < $sic['nrows']; $i++
)
2839 if (!array_key_exists ("i_${i}", $sic))
2841 // let's hope other inputs are in place
2842 switch ($sic["i_${i}"])
2846 $F[$sic["pn_${i}"]] = array
2848 'mode' => $sic["rm_${i}"],
2849 'allowed' => array_fetch ($sic, "ra_${i}", array()),
2850 'native' => $sic["rn_${i}"],
2851 'decision' => $sic["i_${i}"],
2858 $dbxlink->beginTransaction();
2861 if (NULL === $vswitch = getVLANSwitchInfo ($sic['object_id'], 'FOR UPDATE'))
2862 throw new InvalidArgException ('object_id', $sic['object_id'], 'VLAN domain is not set for this object');
2863 if ($vswitch['mutex_rev'] != $sic['mutex_rev'])
2864 throw new InvalidRequestArgException ('mutex_rev', $sic['mutex_rev'], 'expired form (table data has changed)');
2865 $D = getStored8021QConfig ($vswitch['object_id'], 'desired');
2866 $C = getStored8021QConfig ($vswitch['object_id'], 'cached');
2867 $R = getRunning8021QConfig ($vswitch['object_id']);
2868 $plan = get8021QSyncOptions ($vswitch, $D, $C, $R['portdata']);
2870 foreach ($F as $port_name => $port)
2872 if (!array_key_exists ($port_name, $plan))
2874 elseif ($plan[$port_name]['status'] == 'merge_conflict')
2876 // for R neither mutex nor revisions can be emulated, but revision change can be
2877 if (!same8021QConfigs ($port, $R['portdata'][$port_name]))
2878 throw new InvalidRequestArgException ("port ${port_name}", '(hidden)', 'expired form (switch data has changed)');
2879 if ($port['decision'] == 'right') // D wins, frame R by writing value of R to C
2880 $ndone +
= upd8021QPort ('cached', $vswitch['object_id'], $port_name, $port);
2881 elseif ($port['decision'] == 'left') // R wins, cross D up
2882 $ndone +
= upd8021QPort ('cached', $vswitch['object_id'], $port_name, $D[$port_name]);
2883 // otherwise there was no decision made
2887 $plan[$port_name]['status'] == 'delete_conflict' or
2888 $plan[$port_name]['status'] == 'martian_conflict'
2890 if ($port['decision'] == 'left')
2891 // confirm deletion of local copy
2892 $ndone +
= del8021QPort ($vswitch['object_id'], $port_name);
2893 // otherwise ignore a decision that doesn't address a conflict
2896 catch (InvalidRequestArgException
$e)
2898 $dbxlink->rollBack();
2899 showFuncMessage (__FUNCTION__
, 'ERR1');
2902 catch (Exception
$e)
2904 $dbxlink->rollBack();
2905 showFuncMessage (__FUNCTION__
, 'ERR2');
2909 showFuncMessage (__FUNCTION__
, 'OK', array ($ndone));
2912 function update8021QPortList()
2914 genericAssertion ('ports', 'array');
2915 $enabled = $disabled = 0;
2917 $default_port = array
2920 'allowed' => array (VLAN_DFL_ID
),
2921 'native' => VLAN_DFL_ID
,
2923 foreach ($sic['ports'] as $line)
2924 if (preg_match ('/^enable (.+)$/', $line, $m))
2925 $enabled +
= add8021QPort (getBypassValue(), $m[1], $default_port);
2926 elseif (preg_match ('/^disable (.+)$/', $line, $m))
2927 $disabled +
= del8021QPort (getBypassValue(), $m[1]);
2929 throw new InvalidRequestArgException ('ports[]', $line, 'malformed array item');
2930 # $enabled + $disabled > 0
2932 showSuccess ("enabled 802.1Q for ${enabled} port(s)");
2934 showSuccess ("disabled 802.1Q for ${disabled} port(s)");
2937 $msgcode['cloneVST']['OK'] = 48;
2940 assertUIntArg ('mutex_rev', TRUE);
2941 assertUIntArg ('from_id');
2942 $src_vst = spotEntity ('vst', $_REQUEST['from_id']);
2943 amplifyCell ($src_vst);
2944 commitUpdateVSTRules (getBypassValue(), $_REQUEST['mutex_rev'], $src_vst['rules']);
2945 showFuncMessage (__FUNCTION__
, 'OK');
2948 $msgcode['updVSTRule']['OK'] = 43;
2949 function updVSTRule()
2951 // this is used for making throwing an invalid argument exception easier.
2952 function updVSTRule_get_named_param ($name, $haystack, &$last_used_name)
2954 $last_used_name = $name;
2955 return isset ($haystack[$name]) ?
$haystack[$name] : NULL;