r4496 createIPv6Prefix(): add handling of additional parameter
[racktables] / wwwroot / inc / ophandlers.php
1 <?php
2 /*
3
4 "Ophandler" in RackTables stands for "operation handler", or a function,
5 which handles execution of "operation" (in the meaning explained in
6 navigation.php). Most of the ophandlers are meant to perform one specific
7 action, for example, to set a name of an object. Each such action often
8 requires a set of parameters (e. g. ID of the object and the new name),
9 and it is responsibility of each ophandler function to verify, that all
10 necessary parameters are provided by the user and have proper values. There
11 is a number of helper functions to make such verification simple.
12
13 Errors occuring in ophandlers are typically indicated with exceptions of
14 assorted classes. Namely, an "InvalidRequestArgException" class means, that
15 at least one of the parameters provided by the user is not acceptable. This
16 is a "soft" error, which gets displayed in the standard message area of
17 otherwise usual interface. A different case is "InvalidArgException", which
18 means, that one of the internal functions detected its argument(s) invalid
19 or currupted, and that argument(s) did not come from user's input (and thus
20 cannot be fixed without fixing a bug in the code). Such "hard" errors don't
21 get special early handling and end up in the default catching block. The
22 latter may print a detailed stack trace instead of the interface HTML to
23 help a developer debug the issue.
24
25 As long as an ophandler makes through its request (extracting arguments,
26 performing validation and actually updating records in the database), it
27 may queue up messages (often referred to as "green" and "red" bars) by
28 means of showError() and showSuccess() function. The messages are not
29 displayed immediately, because successfull ophandlers are expected to
30 return only the new URL, where the user will be immediately redirected to
31 (it is also possible to return an empty string to mean, that the current
32 logical location remains the same). The page at the "next" location is
33 supposed to translate message buffer into the standard message area.
34
35 A very special case of an ophandler is tableHandler(). This generic
36 function handles the most trivial actions, which map to a single INSERT,
37 UPDATE or DELETE SQL statement with a fixed number of arguments. The rules
38 of argument validation and mapping are listed in $opspec_list (operation
39 specifications list) array.
40
41 */
42
43 // This array is deprecated. Please do not add new message constants to it.
44 // use the new showError, showWarning, showSuccess functions instead
45 global $msgcode;
46 $msgcode = array();
47
48 global $opspec_list;
49 $opspec_list = array();
50
51 $opspec_list['rackspace-edit-addRow'] = array
52 (
53 'table' => 'RackRow',
54 'action' => 'INSERT',
55 'arglist' => array
56 (
57 array ('url_argname' => 'name', 'assertion' => 'string')
58 ),
59 );
60 $opspec_list['rackspace-edit-delete'] = array
61 (
62 'table' => 'RackRow',
63 'action' => 'DELETE',
64 'arglist' => array
65 (
66 array ('url_argname' => 'row_id', 'table_colname' => 'id', 'assertion' => 'uint')
67 ),
68 );
69 $opspec_list['rackspace-edit-updateRow'] = array
70 (
71 'table' => 'RackRow',
72 'action' => 'UPDATE',
73 'set_arglist' => array
74 (
75 array ('url_argname' => 'name', 'assertion' => 'string')
76 ),
77 'where_arglist' => array
78 (
79 array ('url_argname' => 'row_id', 'table_colname' => 'id', 'assertion' => 'uint')
80 ),
81 );
82 $opspec_list['object-ports-delPort'] = array
83 (
84 'table' => 'Port',
85 'action' => 'DELETE',
86 'arglist' => array
87 (
88 array ('url_argname' => 'port_id', 'table_colname' => 'id', 'assertion' => 'uint'),
89 array ('url_argname' => 'object_id', 'assertion' => 'uint'),
90 ),
91 );
92 $opspec_list['object-ports-deleteAll'] = array
93 (
94 'table' => 'Port',
95 'action' => 'DELETE',
96 'arglist' => array
97 (
98 array ('url_argname' => 'object_id', 'assertion' => 'uint'),
99 ),
100 );
101 $opspec_list['object-log-del'] = array
102 (
103 'table' => 'ObjectLog',
104 'action' => 'DELETE',
105 'arglist' => array
106 (
107 array ('url_argname' => 'logid', 'table_colname' => 'id', 'assertion' => 'uint'),
108 array ('url_argname' => 'object_id', 'assertion' => 'uint'),
109 ),
110 );
111 $opspec_list['ipv4vs-editlblist-delLB'] =
112 $opspec_list['ipv4rspool-editlblist-delLB'] =
113 $opspec_list['object-editrspvs-delLB'] = array
114 (
115 'table' => 'IPv4LB',
116 'action' => 'DELETE',
117 'arglist' => array
118 (
119 array ('url_argname' => 'object_id', 'assertion' => 'uint'),
120 array ('url_argname' => 'pool_id', 'table_colname' => 'rspool_id', 'assertion' => 'uint'),
121 array ('url_argname' => 'vs_id', 'assertion' => 'uint'),
122 ),
123 );
124 $opspec_list['ipv4vs-editlblist-updLB'] =
125 $opspec_list['ipv4rspool-editlblist-updLB'] =
126 $opspec_list['object-editrspvs-updLB'] = array
127 (
128 'table' => 'IPv4LB',
129 'action' => 'UPDATE',
130 'set_arglist' => array
131 (
132 array ('url_argname' => 'vsconfig', 'assertion' => 'string0', 'if_empty' => 'NULL'),
133 array ('url_argname' => 'rsconfig', 'assertion' => 'string0', 'if_empty' => 'NULL'),
134 array ('url_argname' => 'prio', 'assertion' => 'uint0', 'if_empty' => 'NULL'),
135 ),
136 'where_arglist' => array
137 (
138 array ('url_argname' => 'object_id', 'assertion' => 'uint'),
139 array ('url_argname' => 'pool_id', 'table_colname' => 'rspool_id', 'assertion' => 'uint'),
140 array ('url_argname' => 'vs_id', 'assertion' => 'uint'),
141 ),
142 );
143 $opspec_list['ipv4net-properties-editRange'] = array
144 (
145 'table' => 'IPv4Network',
146 'action' => 'UPDATE',
147 'set_arglist' => array
148 (
149 array ('url_argname' => 'name', 'assertion' => 'string0'),
150 array ('url_argname' => 'comment', 'assertion' => 'string0'),
151 ),
152 'where_arglist' => array
153 (
154 array ('url_argname' => 'id', 'assertion' => 'uint')
155 ),
156 );
157 $opspec_list['ipv6net-properties-editRange'] = array
158 (
159 'table' => 'IPv6Network',
160 'action' => 'UPDATE',
161 'set_arglist' => array
162 (
163 array ('url_argname' => 'name', 'assertion' => 'string0'),
164 array ('url_argname' => 'comment', 'assertion' => 'string0'),
165 ),
166 'where_arglist' => array
167 (
168 array ('url_argname' => 'id', 'assertion' => 'uint')
169 ),
170 );
171 $opspec_list['ipv4rspool-editrslist-delRS'] = array
172 (
173 'table' => 'IPv4RS',
174 'action' => 'DELETE',
175 'arglist' => array
176 (
177 array ('url_argname' => 'id', 'assertion' => 'uint'),
178 ),
179 );
180 $opspec_list['ipv4rspool-edit-updIPv4RSP'] = array
181 (
182 'table' => 'IPv4RSPool',
183 'action' => 'UPDATE',
184 'set_arglist' => array
185 (
186 array ('url_argname' => 'name', 'assertion' => 'string0', 'if_empty' => 'NULL'),
187 array ('url_argname' => 'vsconfig', 'assertion' => 'string0', 'if_empty' => 'NULL'),
188 array ('url_argname' => 'rsconfig', 'assertion' => 'string0', 'if_empty' => 'NULL'),
189 ),
190 'where_arglist' => array
191 (
192 array ('url_argname' => 'pool_id', 'table_colname' => 'id', 'assertion' => 'uint')
193 ),
194 );
195 $opspec_list['file-edit-updateFile'] = array
196 (
197 'table' => 'File',
198 'action' => 'UPDATE',
199 'set_arglist' => array
200 (
201 array ('url_argname' => 'file_name', 'table_colname' => 'name', 'assertion' => 'string'),
202 array ('url_argname' => 'file_type', 'table_colname' => 'type', 'assertion' => 'string'),
203 array ('url_argname' => 'file_comment', 'table_colname' => 'comment', 'assertion' => 'string0', 'if_empty' => 'NULL'),
204 ),
205 'where_arglist' => array
206 (
207 array ('url_argname' => 'file_id', 'table_colname' => 'id', 'assertion' => 'uint')
208 ),
209 );
210 $opspec_list['parentmap-edit-add'] = array
211 (
212 'table' => 'ObjectParentCompat',
213 'action' => 'INSERT',
214 'arglist' => array
215 (
216 array ('url_argname' => 'parent_objtype_id', 'assertion' => 'uint'),
217 array ('url_argname' => 'child_objtype_id', 'assertion' => 'uint'),
218 ),
219 );
220 $opspec_list['parentmap-edit-del'] = array
221 (
222 'table' => 'ObjectParentCompat',
223 'action' => 'DELETE',
224 'arglist' => array
225 (
226 array ('url_argname' => 'parent_objtype_id', 'assertion' => 'uint'),
227 array ('url_argname' => 'child_objtype_id', 'assertion' => 'uint'),
228 ),
229 );
230 $opspec_list['portmap-edit-add'] = array
231 (
232 'table' => 'PortCompat',
233 'action' => 'INSERT',
234 'arglist' => array
235 (
236 array ('url_argname' => 'type1', 'assertion' => 'uint'),
237 array ('url_argname' => 'type2', 'assertion' => 'uint'),
238 ),
239 );
240 $opspec_list['portmap-edit-del'] = array
241 (
242 'table' => 'PortCompat',
243 'action' => 'DELETE',
244 'arglist' => array
245 (
246 array ('url_argname' => 'type1', 'assertion' => 'uint'),
247 array ('url_argname' => 'type2', 'assertion' => 'uint'),
248 ),
249 );
250 $opspec_list['portifcompat-edit-del'] = array
251 (
252 'table' => 'PortInterfaceCompat',
253 'action' => 'DELETE',
254 'arglist' => array
255 (
256 array ('url_argname' => 'iif_id', 'assertion' => 'uint'),
257 array ('url_argname' => 'oif_id', 'assertion' => 'uint'),
258 ),
259 );
260 $opspec_list['attrs-editmap-del'] = array
261 (
262 'table' => 'AttributeMap',
263 'action' => 'DELETE',
264 'arglist' => array
265 (
266 array ('url_argname' => 'attr_id', 'assertion' => 'uint'),
267 array ('url_argname' => 'objtype_id', 'assertion' => 'uint'),
268 ),
269 );
270 $opspec_list['attrs-editattrs-add'] = array
271 (
272 'table' => 'Attribute',
273 'action' => 'INSERT',
274 'arglist' => array
275 (
276 array ('url_argname' => 'attr_type', 'table_colname' => 'type', 'assertion' => 'enum/attr_type'),
277 array ('url_argname' => 'attr_name', 'table_colname' => 'name', 'assertion' => 'string'),
278 ),
279 );
280 $opspec_list['attrs-editattrs-del'] = array
281 (
282 'table' => 'Attribute',
283 'action' => 'DELETE',
284 'arglist' => array
285 (
286 array ('url_argname' => 'attr_id', 'table_colname' => 'id', 'assertion' => 'uint'),
287 ),
288 );
289 $opspec_list['attrs-editattrs-upd'] = array
290 (
291 'table' => 'Attribute',
292 'action' => 'UPDATE',
293 'set_arglist' => array
294 (
295 array ('url_argname' => 'attr_name', 'table_colname' => 'name', 'assertion' => 'string'),
296 ),
297 'where_arglist' => array
298 (
299 array ('url_argname' => 'attr_id', 'table_colname' => 'id', 'assertion' => 'uint'),
300 ),
301 );
302 $opspec_list['dict-chapters-add'] = array
303 (
304 'table' => 'Chapter',
305 'action' => 'INSERT',
306 'arglist' => array
307 (
308 array ('url_argname' => 'chapter_name', 'table_colname' => 'name', 'assertion' => 'string')
309 ),
310 );
311 $opspec_list['chapter-edit-add'] = array
312 (
313 'table' => 'Dictionary',
314 'action' => 'INSERT',
315 'arglist' => array
316 (
317 array ('url_argname' => 'chapter_no', 'table_colname' => 'chapter_id', 'assertion' => 'uint'),
318 array ('url_argname' => 'dict_value', 'assertion' => 'string'),
319 ),
320 );
321 $opspec_list['chapter-edit-del'] = array
322 (
323 'table' => 'Dictionary',
324 'action' => 'DELETE',
325 'arglist' => array
326 (
327 // Technically dict_key is enough to delete, but including chapter_id into
328 // WHERE clause makes sure, that the action actually happends for the same
329 // chapter, which authorization was granted for.
330 array ('url_argname' => 'chapter_no', 'table_colname' => 'chapter_id', 'assertion' => 'uint'),
331 array ('url_argname' => 'dict_key', 'assertion' => 'uint'),
332 ),
333 );
334 $opspec_list['tagtree-edit-createTag'] = array
335 (
336 'table' => 'TagTree',
337 'action' => 'INSERT',
338 'arglist' => array
339 (
340 array ('url_argname' => 'tag_name', 'table_colname' => 'tag', 'assertion' => 'tag'),
341 array ('url_argname' => 'parent_id', 'assertion' => 'uint0', 'if_empty' => 'NULL'),
342 ),
343 );
344 $opspec_list['tagtree-edit-destroyTag'] = array
345 (
346 'table' => 'TagTree',
347 'action' => 'DELETE',
348 'arglist' => array
349 (
350 array ('url_argname' => 'tag_id', 'table_colname' => 'id', 'assertion' => 'uint'),
351 ),
352 );
353 $opspec_list['tagtree-edit-updateTag'] = array
354 (
355 'table' => 'TagTree',
356 'action' => 'UPDATE',
357 'set_arglist' => array
358 (
359 array ('url_argname' => 'tag_name', 'table_colname' => 'tag', 'assertion' => 'tag'),
360 array ('url_argname' => 'parent_id', 'assertion' => 'uint0', 'if_empty' => 'NULL'),
361 ),
362 'where_arglist' => array
363 (
364 array ('url_argname' => 'tag_id', 'table_colname' => 'id', 'assertion' => 'uint'),
365 ),
366 );
367 $opspec_list['8021q-vstlist-upd'] = array
368 (
369 'table' => 'VLANSwitchTemplate',
370 'action' => 'UPDATE',
371 'set_arglist' => array
372 (
373 array ('url_argname' => 'vst_descr', 'table_colname' => 'description', 'assertion' => 'string'),
374 ),
375 'where_arglist' => array
376 (
377 array ('url_argname' => 'vst_id', 'table_colname' => 'id', 'assertion' => 'uint'),
378 ),
379 );
380 $opspec_list['8021q-vdlist-upd'] = array
381 (
382 'table' => 'VLANDomain',
383 'action' => 'UPDATE',
384 'set_arglist' => array
385 (
386 array ('url_argname' => 'vdom_descr', 'table_colname' => 'description', 'assertion' => 'string'),
387 ),
388 'where_arglist' => array
389 (
390 array ('url_argname' => 'vdom_id', 'table_colname' => 'id', 'assertion' => 'uint'),
391 ),
392 );
393 $opspec_list['vlandomain-vlanlist-add'] = array
394 (
395 'table' => 'VLANDescription',
396 'action' => 'INSERT',
397 'arglist' => array
398 (
399 array ('url_argname' => 'vdom_id', 'table_colname' => 'domain_id', 'assertion' => 'uint'),
400 array ('url_argname' => 'vlan_id', 'assertion' => 'vlan'),
401 array ('url_argname' => 'vlan_type', 'assertion' => 'enum/vlan_type'),
402 array ('url_argname' => 'vlan_descr', 'assertion' => 'string0', 'if_empty' => 'NULL'),
403 ),
404 );
405 $opspec_list['vlandomain-vlanlist-del'] = array
406 (
407 'table' => 'VLANDescription',
408 'action' => 'DELETE',
409 'arglist' => array
410 (
411 array ('url_argname' => 'vdom_id', 'table_colname' => 'domain_id', 'assertion' => 'uint'),
412 array ('url_argname' => 'vlan_id', 'assertion' => 'vlan'),
413 ),
414 );
415 $opspec_list['vlandomain-vlanlist-upd'] = array
416 (
417 'table' => 'VLANDescription',
418 'action' => 'UPDATE',
419 'set_arglist' => array
420 (
421 array ('url_argname' => 'vlan_type', 'assertion' => 'enum/vlan_type'),
422 array ('url_argname' => 'vlan_descr', 'assertion' => 'string0', 'if_empty' => 'NULL'),
423 ),
424 'where_arglist' => array
425 (
426 array ('url_argname' => 'vdom_id', 'table_colname' => 'domain_id', 'assertion' => 'uint'),
427 array ('url_argname' => 'vlan_id', 'assertion' => 'vlan'),
428 ),
429 );
430
431 function buildRedirectURL ($nextpage = NULL, $nexttab = NULL, $moreArgs = array())
432 {
433 global $page, $pageno, $tabno;
434 if ($nextpage === NULL)
435 $nextpage = $pageno;
436 if ($nexttab === NULL)
437 $nexttab = $tabno;
438 $url = "index.php?page=${nextpage}&tab=${nexttab}";
439 if (isset ($page[$nextpage]['bypass']))
440 $url .= '&' . $page[$nextpage]['bypass'] . '=' . $_REQUEST[$page[$nextpage]['bypass']];
441
442 if (count ($moreArgs) > 0)
443 foreach ($moreArgs as $arg => $value)
444 if (is_array ($value))
445 foreach ($value as $v)
446 $url .= '&' . urlencode ($arg . '[]') . '=' . urlencode ($v);
447 elseif ($arg != 'module')
448 $url .= '&' . urlencode ($arg) . '=' . urlencode ($value);
449 return $url;
450 }
451
452 $msgcode['addPortForwarding']['OK'] = 48;
453 function addPortForwarding ()
454 {
455 assertUIntArg ('object_id');
456 assertIPv4Arg ('localip');
457 assertIPv4Arg ('remoteip');
458 assertUIntArg ('localport');
459 assertStringArg ('proto');
460 assertStringArg ('description', TRUE);
461 $remoteport = isset ($_REQUEST['remoteport']) ? $_REQUEST['remoteport'] : '';
462 if (!strlen ($remoteport))
463 $remoteport = $_REQUEST['localport'];
464
465 newPortForwarding
466 (
467 $_REQUEST['object_id'],
468 $_REQUEST['localip'],
469 $_REQUEST['localport'],
470 $_REQUEST['remoteip'],
471 $remoteport,
472 $_REQUEST['proto'],
473 $_REQUEST['description']
474 );
475
476 return showFuncMessage (__FUNCTION__, 'OK');
477 }
478
479 $msgcode['delPortForwarding']['OK'] = 49;
480 function delPortForwarding ()
481 {
482 assertUIntArg ('object_id');
483 assertIPv4Arg ('localip');
484 assertIPv4Arg ('remoteip');
485 assertUIntArg ('localport');
486 assertUIntArg ('remoteport');
487 assertStringArg ('proto');
488
489 deletePortForwarding
490 (
491 $_REQUEST['object_id'],
492 $_REQUEST['localip'],
493 $_REQUEST['localport'],
494 $_REQUEST['remoteip'],
495 $_REQUEST['remoteport'],
496 $_REQUEST['proto']
497 );
498 return showFuncMessage (__FUNCTION__, 'OK');
499 }
500
501 $msgcode['updPortForwarding']['OK'] = 51;
502 function updPortForwarding ()
503 {
504 assertUIntArg ('object_id');
505 assertIPv4Arg ('localip');
506 assertIPv4Arg ('remoteip');
507 assertUIntArg ('localport');
508 assertUIntArg ('remoteport');
509 assertStringArg ('proto');
510 assertStringArg ('description');
511
512 updatePortForwarding
513 (
514 $_REQUEST['object_id'],
515 $_REQUEST['localip'],
516 $_REQUEST['localport'],
517 $_REQUEST['remoteip'],
518 $_REQUEST['remoteport'],
519 $_REQUEST['proto'],
520 $_REQUEST['description']
521 );
522 return showFuncMessage (__FUNCTION__, 'OK');
523 }
524
525 $msgcode['addPortForObject']['OK'] = 48;
526 function addPortForObject ()
527 {
528 assertStringArg ('port_name', TRUE);
529 genericAssertion ('port_l2address', 'l2address0');
530 genericAssertion ('port_name', 'string');
531 commitAddPort
532 (
533 $_REQUEST['object_id'],
534 trim ($_REQUEST['port_name']),
535 $_REQUEST['port_type_id'],
536 trim ($_REQUEST['port_label']),
537 trim ($_REQUEST['port_l2address'])
538 );
539 return showFuncMessage (__FUNCTION__, 'OK', array ($_REQUEST['port_name']));
540 }
541
542 $msgcode['editPortForObject']['OK'] = 6;
543 function editPortForObject ()
544 {
545 global $sic;
546 assertUIntArg ('port_id');
547 assertUIntArg ('port_type_id');
548 assertStringArg ('reservation_comment', TRUE);
549 genericAssertion ('l2address', 'l2address0');
550 genericAssertion ('name', 'string');
551 commitUpdatePort ($sic['object_id'], $sic['port_id'], $sic['name'], $sic['port_type_id'], $sic['label'], $sic['l2address'], $sic['reservation_comment']);
552 return showFuncMessage (__FUNCTION__, 'OK', array ($_REQUEST['name']));
553 }
554
555 $msgcode['linkPortForObject']['OK'] = 8;
556 function linkPortForObject ()
557 {
558 assertUIntArg ('port_id');
559 assertUIntArg ('remote_port_id');
560 assertStringArg ('cable', TRUE);
561
562 // FIXME: ensure, that at least one of these ports belongs to the current object
563 linkPorts ($_REQUEST['port_id'], $_REQUEST['remote_port_id'], $_REQUEST['cable']);
564 $port_info = getPortInfo ($_REQUEST['port_id']);
565 return showFuncMessage
566 (
567 __FUNCTION__,
568 'OK',
569 array
570 (
571 formatPortLink ($port_info['id'], $port_info['name'], NULL, NULL),
572 formatLinkedPort ($port_info),
573 )
574 );
575 }
576
577 $msgcode['addMultiPorts']['OK'] = 10;
578 function addMultiPorts ()
579 {
580 assertStringArg ('format');
581 assertStringArg ('input');
582 assertStringArg ('port_type');
583 $format = $_REQUEST['format'];
584 $port_type = $_REQUEST['port_type'];
585 $object_id = $_REQUEST['object_id'];
586 // Input lines are escaped, so we have to explode and to chop by 2-char
587 // \n and \r respectively.
588 $lines1 = explode ("\n", $_REQUEST['input']);
589 foreach ($lines1 as $line)
590 {
591 $parts = explode ('\r', $line);
592 reset ($parts);
593 if (!strlen ($parts[0]))
594 continue;
595 else
596 $lines2[] = rtrim ($parts[0]);
597 }
598 $ports = array();
599 foreach ($lines2 as $line)
600 {
601 switch ($format)
602 {
603 case 'fisxii':
604 $words = explode (' ', preg_replace ('/[[:space:]]+/', ' ', $line));
605 list ($slot, $port) = explode ('/', $words[0]);
606 $ports[] = array
607 (
608 'name' => "e ${slot}/${port}",
609 'l2address' => $words[8],
610 'label' => "slot ${slot} port ${port}"
611 );
612 break;
613 case 'c3600asy':
614 $words = explode (' ', preg_replace ('/[[:space:]]+/', ' ', trim (substr ($line, 3))));
615 /*
616 How Async Lines are Numbered in Cisco 3600 Series Routers
617 http://www.cisco.com/en/US/products/hw/routers/ps274/products_tech_note09186a00801ca70b.shtml
618
619 Understanding 16- and 32-Port Async Network Modules
620 http://www.cisco.com/en/US/products/hw/routers/ps274/products_tech_note09186a00800a93f0.shtml
621 */
622 $async = $words[0];
623 $slot = floor (($async - 1) / 32);
624 $octalgroup = floor (($async - 1 - $slot * 32) / 8);
625 $cable = $async - $slot * 32 - $octalgroup * 8;
626 $og_label[0] = 'async 0-7';
627 $og_label[1] = 'async 8-15';
628 $og_label[2] = 'async 16-23';
629 $og_label[3] = 'async 24-31';
630 $ports[] = array
631 (
632 'name' => "async ${async}",
633 'l2address' => '',
634 'label' => "slot ${slot} " . $og_label[$octalgroup] . " cable ${cable}"
635 );
636 break;
637 case 'fiwg':
638 $words = explode (' ', preg_replace ('/[[:space:]]+/', ' ', $line));
639 $ifnumber = $words[0] * 1;
640 $ports[] = array
641 (
642 'name' => "e ${ifnumber}",
643 'l2address' => "${words[8]}",
644 'label' => "${ifnumber}"
645 );
646 break;
647 case 'ssv1':
648 $words = explode (' ', $line);
649 if (!strlen ($words[0]) or !strlen ($words[1]))
650 continue;
651 $ports[] = array
652 (
653 'name' => $words[0],
654 'l2address' => $words[1],
655 'label' => ''
656 );
657 break;
658 default:
659 throw new InvalidRequestArgException ('format', $format);
660 break;
661 }
662 }
663 // Create ports, if they don't exist.
664 $added_count = $updated_count = $error_count = 0;
665 foreach ($ports as $port)
666 {
667 $port_ids = getPortIDs ($object_id, $port['name']);
668 if (!count ($port_ids))
669 {
670 commitAddPort ($object_id, $port['name'], $port_type, $port['label'], $port['l2address']);
671 $added_count++;
672 }
673 elseif (count ($port_ids) == 1) // update only single-socket ports
674 {
675 commitUpdatePort ($object_id, $port_ids[0], $port['name'], $port_type, $port['label'], $port['l2address']);
676 $updated_count++;
677 }
678 }
679 return showFuncMessage (__FUNCTION__, 'OK', array ($added_count, $updated_count, $error_count));
680 }
681
682 $msgcode['addBulkPorts']['OK'] = 82;
683 function addBulkPorts ()
684 {
685 assertStringArg ('port_type_id');
686 assertStringArg ('port_name');
687 assertStringArg ('port_label', TRUE);
688 assertUIntArg ('port_numbering_start', TRUE);
689 assertUIntArg ('port_numbering_count');
690
691 $object_id = $_REQUEST['object_id'];
692 $port_name = $_REQUEST['port_name'];
693 $port_type_id = $_REQUEST['port_type_id'];
694 $port_label = $_REQUEST['port_label'];
695 $port_numbering_start = $_REQUEST['port_numbering_start'];
696 $port_numbering_count = $_REQUEST['port_numbering_count'];
697
698 $added_count = $error_count = 0;
699 if(strrpos($port_name, "%u") === false )
700 $port_name .= '%u';
701 for ($i=0,$c=$port_numbering_start; $i<$port_numbering_count; $i++,$c++)
702 {
703 commitAddPort ($object_id, @sprintf($port_name,$c), $port_type_id, @sprintf($port_label,$c), '');
704 $added_count++;
705 }
706 return showFuncMessage (__FUNCTION__, 'OK', array ($added_count, $error_count));
707 }
708
709 $msgcode['updIPv4Allocation']['OK'] = 51;
710 function updIPv4Allocation ()
711 {
712 assertIPv4Arg ('ip');
713 assertUIntArg ('object_id');
714 assertStringArg ('bond_name', TRUE);
715 genericAssertion ('bond_type', 'enum/inet4alloc');
716
717 updateBond ($_REQUEST['ip'], $_REQUEST['object_id'], $_REQUEST['bond_name'], $_REQUEST['bond_type']);
718 return showFuncMessage (__FUNCTION__, 'OK');
719 }
720
721 $msgcode['updIPv6Allocation']['OK'] = 51;
722 function updIPv6Allocation ()
723 {
724 $ipv6 = assertIPv6Arg ('ip');
725 assertUIntArg ('object_id');
726 assertStringArg ('bond_name', TRUE);
727 genericAssertion ('bond_type', 'enum/inet6alloc');
728
729 updateIPv6Bond ($ipv6, $_REQUEST['object_id'], $_REQUEST['bond_name'], $_REQUEST['bond_type']);
730 return showFuncMessage (__FUNCTION__, 'OK');
731 }
732
733 $msgcode['delIPv4Allocation']['OK'] = 49;
734 function delIPv4Allocation ()
735 {
736 assertIPv4Arg ('ip');
737 assertUIntArg ('object_id');
738
739 unbindIpFromObject ($_REQUEST['ip'], $_REQUEST['object_id']);
740 return showFuncMessage (__FUNCTION__, 'OK');
741 }
742
743 $msgcode['delIPv6Allocation']['OK'] = 49;
744 function delIPv6Allocation ()
745 {
746 assertUIntArg ('object_id');
747 $ipv6 = assertIPv6Arg ('ip');
748 unbindIPv6FromObject ($ipv6, $_REQUEST['object_id']);
749 return showFuncMessage (__FUNCTION__, 'OK');
750 }
751
752 $msgcode['addIPv4Allocation']['OK'] = 48;
753 $msgcode['addIPv4Allocation']['ERR1'] = 170;
754 function addIPv4Allocation ()
755 {
756 assertIPv4Arg ('ip');
757 assertUIntArg ('object_id');
758 assertStringArg ('bond_name', TRUE);
759 genericAssertion ('bond_type', 'enum/inet4alloc');
760
761 // Strip masklen.
762 $ip = preg_replace ('@/[[:digit:]]+$@', '', $_REQUEST['ip']);
763 if (getConfigVar ('IPV4_JAYWALK') != 'yes' and NULL === getIPv4AddressNetworkId ($ip))
764 return showFuncMessage (__FUNCTION__, 'ERR1', array ($ip));
765
766 bindIpToObject ($ip, $_REQUEST['object_id'], $_REQUEST['bond_name'], $_REQUEST['bond_type']);
767 $address = getIPv4Address ($ip);
768 if ($address['reserved'] == 'yes' or strlen ($address['name']))
769 {
770 $release = getConfigVar ('IPV4_AUTO_RELEASE');
771 if ($release >= 1)
772 $address['reserved'] = 'no';
773 if ($release >= 2)
774 $address['name'] = '';
775 updateAddress ($ip, $address['name'], $address['reserved']);
776 }
777 return showFuncMessage (__FUNCTION__, 'OK');
778 }
779
780 $msgcode['addIPv6Allocation']['OK'] = 48;
781 $msgcode['addIPv6Allocation']['ERR1'] = 170;
782 function addIPv6Allocation ()
783 {
784 assertUIntArg ('object_id');
785 assertStringArg ('bond_name', TRUE);
786 genericAssertion ('bond_type', 'enum/inet6alloc');
787
788 // Strip masklen.
789 $ipv6 = new IPv6Address;
790 if (! $ipv6->parse (preg_replace ('@/\d+$@', '', $_REQUEST['ip'])))
791 throw new InvalidRequestArgException('ip', $_REQUEST['ip'], 'parameter is not a valid ipv6 address');
792
793 if (getConfigVar ('IPV4_JAYWALK') != 'yes' and NULL === getIPv6AddressNetworkId ($ipv6))
794 return showFuncMessage (__FUNCTION__, 'ERR1', array ($ip));
795
796 bindIPv6ToObject ($ipv6, $_REQUEST['object_id'], $_REQUEST['bond_name'], $_REQUEST['bond_type']);
797 $address = getIPv6Address ($ipv6);
798 if ($address['reserved'] == 'yes' or strlen ($address['name']))
799 {
800 $release = getConfigVar ('IPV4_AUTO_RELEASE');
801 if ($release >= 1)
802 $address['reserved'] = 'no';
803 if ($release >= 2)
804 $address['name'] = '';
805 updateAddress ($ipv6, $address['name'], $address['reserved']);
806 }
807 return showFuncMessage (__FUNCTION__, 'OK');
808 }
809
810 $msgcode['addIPv4Prefix']['OK'] = 48;
811 function addIPv4Prefix ()
812 {
813 assertStringArg ('range');
814 assertStringArg ('name', TRUE);
815
816 $is_bcast = isset ($_REQUEST['is_bcast']) ? $_REQUEST['is_bcast'] : 'off';
817 $taglist = isset ($_REQUEST['taglist']) ? $_REQUEST['taglist'] : array();
818 global $sic;
819 createIPv4Prefix ($_REQUEST['range'], $sic['name'], $is_bcast == 'on', $taglist);
820 return showFuncMessage (__FUNCTION__, 'OK');
821 }
822
823 $msgcode['addIPv6Prefix']['OK'] = 48;
824 function addIPv6Prefix ()
825 {
826 assertStringArg ('range');
827 assertStringArg ('name', TRUE);
828
829 $taglist = isset ($_REQUEST['taglist']) ? $_REQUEST['taglist'] : array();
830 $is_connected = isset ($_REQUEST['is_connected']) ? ($_REQUEST['is_connected'] == 'on') : FALSE;
831 global $sic;
832 createIPv6Prefix ($_REQUEST['range'], $sic['name'], $is_connected, $taglist);
833 return showFuncMessage (__FUNCTION__, 'OK');
834 }
835
836 $msgcode['delIPv4Prefix']['OK'] = 49;
837 function delIPv4Prefix ()
838 {
839 assertUIntArg ('id');
840 destroyIPv4Prefix ($_REQUEST['id']);
841 return showFuncMessage (__FUNCTION__, 'OK');
842 }
843
844 $msgcode['delIPv6Prefix']['OK'] = 49;
845 function delIPv6Prefix ()
846 {
847 assertUIntArg ('id');
848 destroyIPv6Prefix ($_REQUEST['id']);
849 return showFuncMessage (__FUNCTION__, 'OK');
850 }
851
852 $msgcode['editAddress']['OK'] = 51;
853 function editAddress ()
854 {
855 assertStringArg ('name', TRUE);
856
857 if (isset ($_REQUEST['reserved']))
858 $reserved = $_REQUEST['reserved'];
859 else
860 $reserved = 'off';
861 updateAddress ($_REQUEST['ip'], $_REQUEST['name'], $reserved == 'on' ? 'yes' : 'no');
862 return showFuncMessage (__FUNCTION__, 'OK');
863 }
864
865 $msgcode['editv6Address']['OK'] = 51;
866 function editv6Address ()
867 {
868 $ipv6 = assertIPArg ('ip');
869 assertStringArg ('name', TRUE);
870
871 if (isset ($_REQUEST['reserved']))
872 $reserved = $_REQUEST['reserved'];
873 else
874 $reserved = 'off';
875 updateAddress ($ipv6, $_REQUEST['name'], $reserved == 'on' ? 'yes' : 'no');
876 return showFuncMessage (__FUNCTION__, 'OK');
877 }
878
879 $msgcode['createUser']['OK'] = 5;
880 function createUser ()
881 {
882 assertStringArg ('username');
883 assertStringArg ('realname', TRUE);
884 assertStringArg ('password');
885 $username = $_REQUEST['username'];
886 $password = sha1 ($_REQUEST['password']);
887 commitCreateUserAccount ($username, $_REQUEST['realname'], $password);
888 if (isset ($_REQUEST['taglist']))
889 produceTagsForLastRecord ('user', $_REQUEST['taglist']);
890 return showFuncMessage (__FUNCTION__, 'OK', array ($username));
891 }
892
893 $msgcode['updateUser']['OK'] = 6;
894 function updateUser ()
895 {
896 genericAssertion ('user_id', 'uint');
897 assertStringArg ('username');
898 assertStringArg ('realname', TRUE);
899 assertStringArg ('password');
900 $username = $_REQUEST['username'];
901 $new_password = $_REQUEST['password'];
902 $userinfo = spotEntity ('user', $_REQUEST['user_id']);
903 // Update user password only if provided password is not the same as current password hash.
904 if ($new_password != $userinfo['user_password_hash'])
905 $new_password = sha1 ($new_password);
906 commitUpdateUserAccount ($_REQUEST['user_id'], $username, $_REQUEST['realname'], $new_password);
907 return showFuncMessage (__FUNCTION__, 'OK', array ($username));
908 }
909
910 $msgcode['updateDictionary']['OK'] = 51;
911 function updateDictionary ()
912 {
913 assertUIntArg ('dict_key');
914 assertStringArg ('dict_value');
915 // this request must be built with chapter_no
916 usePreparedUpdateBlade
917 (
918 'Dictionary',
919 array ('dict_value' => $sic['dict_value']),
920 array
921 (
922 'chapter_id' => $sic['chapter_no'],
923 'dict_key' => $sic['dict_key'],
924 )
925 );
926 return showFuncMessage (__FUNCTION__, 'OK');
927 }
928
929 $msgcode['updateChapter']['OK'] = 51;
930 function updateChapter ()
931 {
932 assertUIntArg ('chapter_no');
933 assertStringArg ('chapter_name');
934 usePreparedUpdateBlade
935 (
936 'Chapter',
937 array
938 (
939 'name' => $chapter_name,
940 ),
941 array
942 (
943 'id' => $chapter_no,
944 'sticky' => 'no', // note this constant, it protects system chapters
945 )
946 );
947 return showFuncMessage (__FUNCTION__, 'OK');
948 }
949
950 $msgcode['delChapter']['OK'] = 49;
951 function delChapter ()
952 {
953 assertUIntArg ('chapter_no');
954 commitDeleteChapter ($_REQUEST['chapter_no']);
955 return showFuncMessage (__FUNCTION__, 'OK');
956 }
957
958 $msgcode['supplementAttrMap']['OK'] = 48;
959 $msgcode['supplementAttrMap']['ERR1'] = 154;
960 function supplementAttrMap ()
961 {
962 assertUIntArg ('attr_id');
963 assertUIntArg ('objtype_id');
964 $attrMap = getAttrMap();
965 if ($attrMap[$_REQUEST['attr_id']]['type'] != 'dict')
966 $chapter_id = NULL;
967 else
968 {
969 try
970 {
971 assertUIntArg ('chapter_no');
972 }
973 catch (InvalidRequestArgException $e)
974 {
975 return showFuncMessage (__FUNCTION__, 'ERR1', array ('chapter not selected'));
976 }
977 $chapter_id = $_REQUEST['chapter_no'];
978 }
979 commitSupplementAttrMap ($_REQUEST['attr_id'], $_REQUEST['objtype_id'], $chapter_id);
980 return showFuncMessage (__FUNCTION__, 'OK');
981 }
982
983 $msgcode['clearSticker']['OK'] = 49;
984 function clearSticker ()
985 {
986 global $sic;
987 assertUIntArg ('attr_id');
988 commitUpdateAttrValue (getBypassValue(), $sic['attr_id']);
989 }
990
991 $msgcode['updateObjectAllocation']['OK'] = 63;
992 function updateObjectAllocation ()
993 {
994 global $remote_username, $sic;
995 if (!isset ($_REQUEST['got_atoms']))
996 {
997 unset($_GET['page']);
998 unset($_GET['tab']);
999 unset($_GET['op']);
1000 unset($_POST['page']);
1001 unset($_POST['tab']);
1002 unset($_POST['op']);
1003 return buildRedirectURL (NULL, NULL, $_REQUEST);
1004 }
1005 $object_id = getBypassValue();
1006 $workingRacksData = array();
1007 foreach ($_REQUEST['rackmulti'] as $cand_id)
1008 {
1009 if (!isset ($workingRacksData[$cand_id]))
1010 {
1011 $rackData = spotEntity ('rack', $cand_id);
1012 amplifyCell ($rackData);
1013 $workingRacksData[$cand_id] = $rackData;
1014 }
1015 }
1016
1017 foreach ($workingRacksData as &$rd)
1018 applyObjectMountMask ($rd, $object_id);
1019
1020 $oldMolecule = getMoleculeForObject ($object_id);
1021 $changecnt = 0;
1022 foreach ($workingRacksData as $rack_id => $rackData)
1023 {
1024 if (! processGridForm ($rackData, 'F', 'T', $object_id))
1025 continue;
1026 $changecnt++;
1027 // Reload our working copy after form processing.
1028 $rackData = spotEntity ('rack', $cand_id);
1029 amplifyCell ($rackData);
1030 applyObjectMountMask ($rackData, $object_id);
1031 $workingRacksData[$rack_id] = $rackData;
1032 }
1033 if ($changecnt)
1034 {
1035 // Log a record.
1036 $newMolecule = getMoleculeForObject ($object_id);
1037 usePreparedInsertBlade
1038 (
1039 'MountOperation',
1040 array
1041 (
1042 'object_id' => $object_id,
1043 'old_molecule_id' => count ($oldMolecule) ? createMolecule ($oldMolecule) : NULL,
1044 'new_molecule_id' => count ($newMolecule) ? createMolecule ($newMolecule) : NULL,
1045 'user_name' => $remote_username,
1046 'comment' => empty ($sic['comment']) ? NULL : $sic['comment'],
1047 )
1048 );
1049 }
1050 return showFuncMessage (__FUNCTION__, 'OK', array ($changecnt));
1051 }
1052
1053 $msgcode['updateObject']['OK'] = 51;
1054 function updateObject ()
1055 {
1056 genericAssertion ('num_attrs', 'uint0');
1057 genericAssertion ('object_name', 'string0');
1058 genericAssertion ('object_label', 'string0');
1059 genericAssertion ('object_asset_no', 'string0');
1060 genericAssertion ('object_comment', 'string0');
1061 genericAssertion ('object_type_id', 'uint');
1062 if (array_key_exists ('object_has_problems', $_REQUEST) and $_REQUEST['object_has_problems'] == 'on')
1063 $has_problems = 'yes';
1064 else
1065 $has_problems = 'no';
1066 $object_id = getBypassValue();
1067
1068 global $dbxlink, $sic;
1069 $dbxlink->beginTransaction();
1070 commitUpdateObject
1071 (
1072 $object_id,
1073 $_REQUEST['object_name'],
1074 $_REQUEST['object_label'],
1075 $has_problems,
1076 $_REQUEST['object_asset_no'],
1077 $_REQUEST['object_comment']
1078 );
1079 // Update optional attributes
1080 $oldvalues = getAttrValues ($object_id);
1081 for ($i = 0; $i < $_REQUEST['num_attrs']; $i++)
1082 {
1083 genericAssertion ("${i}_attr_id", 'uint');
1084 $attr_id = $_REQUEST["${i}_attr_id"];
1085 if (! array_key_exists ($attr_id, $oldvalues))
1086 throw new InvalidRequestArgException ('attr_id', $attr_id, 'malformed request');
1087 $value = $_REQUEST["${i}_value"];
1088
1089 # Delete attribute and move on, when the field is empty or if the field
1090 # type is a dictionary and it is the "--NOT SET--" value of 0.
1091 if ($value == '' || ($oldvalues[$attr_id]['type'] == 'dict' && $value == 0))
1092 {
1093 commitUpdateAttrValue ($object_id, $attr_id);
1094 continue;
1095 }
1096
1097 // The value could be uint/float, but we don't know ATM. Let SQL
1098 // server check this and complain.
1099 assertStringArg ("${i}_value");
1100 switch ($oldvalues[$attr_id]['type'])
1101 {
1102 case 'uint':
1103 case 'float':
1104 case 'string':
1105 $oldvalue = $oldvalues[$attr_id]['value'];
1106 break;
1107 case 'dict':
1108 $oldvalue = $oldvalues[$attr_id]['key'];
1109 break;
1110 default:
1111 }
1112 if ($value === $oldvalue) // ('' == 0), but ('' !== 0)
1113 continue;
1114 commitUpdateAttrValue ($object_id, $attr_id, $value);
1115 }
1116 $object = spotEntity ('object', $object_id);
1117 if ($sic['object_type_id'] != $object['objtype_id'])
1118 {
1119 if (! array_key_exists ($sic['object_type_id'], getObjectTypeChangeOptions ($object_id)))
1120 throw new InvalidRequestArgException ('new type_id', $sic['object_type_id'], 'incompatible with requested attribute values');
1121 usePreparedUpdateBlade ('RackObject', array ('objtype_id' => $sic['object_type_id']), array ('id' => $object_id));
1122 }
1123 // Invalidate thumb cache of all racks objects could occupy.
1124 foreach (getResidentRacksData ($object_id, FALSE) as $rack_id)
1125 usePreparedUpdateBlade ('Rack', array ('thumb_data' => NULL), array ('id' => $rack_id));
1126 $dbxlink->commit();
1127 return showFuncMessage (__FUNCTION__, 'OK');
1128 }
1129
1130 function addMultipleObjects()
1131 {
1132 $taglist = isset ($_REQUEST['taglist']) ? $_REQUEST['taglist'] : array();
1133 $max = getConfigVar ('MASSCOUNT');
1134 for ($i = 0; $i < $max; $i++)
1135 {
1136 if (!isset ($_REQUEST["${i}_object_type_id"]))
1137 return showError ('Submitted form is invalid at line ' . ($i + 1));
1138
1139 // set to empty values for virtual objects
1140 if (isset ($_REQUEST['virtual_objects']))
1141 {
1142 $_REQUEST["${i}_object_label"] = '';
1143 $_REQUEST["${i}_object_asset_no"] = '';
1144 }
1145
1146 assertUIntArg ("${i}_object_type_id", TRUE);
1147 assertStringArg ("${i}_object_name", TRUE);
1148 assertStringArg ("${i}_object_label", TRUE);
1149 assertStringArg ("${i}_object_asset_no", TRUE);
1150 $name = $_REQUEST["${i}_object_name"];
1151
1152 // It's better to skip silently, than to print a notice.
1153 if ($_REQUEST["${i}_object_type_id"] == 0)
1154 continue;
1155 try
1156 {
1157 $object_id = commitAddObject
1158 (
1159 $name,
1160 $_REQUEST["${i}_object_label"],
1161 $_REQUEST["${i}_object_type_id"],
1162 $_REQUEST["${i}_object_asset_no"],
1163 $taglist
1164 );
1165 $info = spotEntity ('object', $object_id);
1166 // FIXME: employ amplifyCell() instead of calling loader functions directly
1167 amplifyCell ($info);
1168 showSuccess ("added object " . formatPortLink ($info['id'], $info['dname'], NULL, NULL));
1169 }
1170 catch (RTDatabaseError $e)
1171 {
1172 showError ("Error creating object '$name': " . $e->getMessage());
1173 continue;
1174 }
1175 }
1176 }
1177
1178 function addLotOfObjects()
1179 {
1180 $taglist = isset ($_REQUEST['taglist']) ? $_REQUEST['taglist'] : array();
1181 assertUIntArg ('global_type_id', TRUE);
1182 assertStringArg ('namelist', TRUE);
1183 $global_type_id = $_REQUEST['global_type_id'];
1184 if ($global_type_id == 0 or !strlen ($_REQUEST['namelist']))
1185 return showError ('Incomplete form has been ignored. Cheers.');
1186 else
1187 {
1188 // The name extractor below was stolen from ophandlers.php:addMultiPorts()
1189 $names1 = explode ("\n", $_REQUEST['namelist']);
1190 $names2 = array();
1191 foreach ($names1 as $line)
1192 {
1193 $parts = explode ('\r', $line);
1194 reset ($parts);
1195 if (!strlen ($parts[0]))
1196 continue;
1197 else
1198 $names2[] = rtrim ($parts[0]);
1199 }
1200 foreach ($names2 as $name)
1201 try
1202 {
1203 $object_id = commitAddObject ($name, '', $global_type_id, '', $taglist);
1204 $info = spotEntity ('object', $object_id);
1205 amplifyCell ($info);
1206 showSuccess ("added object " . formatPortLink ($info['id'], $info['dname'], NULL, NULL));
1207 }
1208 catch (RTDatabaseError $e)
1209 {
1210 showError ("Error creating object '$name': " . $e->getMessage());
1211 continue;
1212 }
1213 }
1214 }
1215
1216 $msgcode['deleteObject']['OK'] = 6;
1217 function deleteObject ()
1218 {
1219 assertUIntArg ('object_id');
1220 $oinfo = spotEntity ('object', $_REQUEST['object_id']);
1221
1222 $racklist = getResidentRacksData ($_REQUEST['object_id'], FALSE);
1223 commitDeleteObject ($_REQUEST['object_id']);
1224 foreach ($racklist as $rack_id)
1225 usePreparedUpdateBlade ('Rack', array ('thumb_data' => NULL), array ('id' => $rack_id));
1226 return showFuncMessage (__FUNCTION__, 'OK', array ($oinfo['dname']));
1227 }
1228
1229 $msgcode['resetObject']['OK'] = 57;
1230 function resetObject ()
1231 {
1232 $racklist = getResidentRacksData (getBypassValue(), FALSE);
1233 commitResetObject (getBypassValue());
1234 foreach ($racklist as $rack_id)
1235 usePreparedUpdateBlade ('Rack', array ('thumb_data' => NULL), array ('id' => $rack_id));
1236 return showFuncMessage (__FUNCTION__, 'OK');
1237 }
1238
1239 $msgcode['useupPort']['OK'] = 49;
1240 function useupPort ()
1241 {
1242 assertUIntArg ('port_id');
1243 commitUpdatePortComment ($_REQUEST['port_id'], '');
1244 return showFuncMessage (__FUNCTION__, 'OK');
1245 }
1246
1247 $msgcode['updateUI']['OK'] = 51;
1248 function updateUI ()
1249 {
1250 assertUIntArg ('num_vars');
1251
1252 for ($i = 0; $i < $_REQUEST['num_vars']; $i++)
1253 {
1254 assertStringArg ("${i}_varname");
1255 assertStringArg ("${i}_varvalue", TRUE);
1256 $varname = $_REQUEST["${i}_varname"];
1257 $varvalue = $_REQUEST["${i}_varvalue"];
1258
1259 // If form value = value in DB, don't bother updating DB
1260 if (!isConfigVarChanged($varname, $varvalue))
1261 continue;
1262 // any exceptions will be handled by process.php
1263 setConfigVar ($varname, $varvalue, TRUE);
1264 }
1265 return showFuncMessage (__FUNCTION__, 'OK');
1266 }
1267
1268 $msgcode['saveMyPreferences']['OK'] = 51;
1269 function saveMyPreferences ()
1270 {
1271 assertUIntArg ('num_vars');
1272
1273 for ($i = 0; $i < $_REQUEST['num_vars']; $i++)
1274 {
1275 assertStringArg ("${i}_varname");
1276 assertStringArg ("${i}_varvalue", TRUE);
1277 $varname = $_REQUEST["${i}_varname"];
1278 $varvalue = $_REQUEST["${i}_varvalue"];
1279
1280 // If form value = value in DB, don't bother updating DB
1281 if (!isConfigVarChanged($varname, $varvalue))
1282 continue;
1283 setUserConfigVar ($varname, $varvalue);
1284 }
1285 return showFuncMessage (__FUNCTION__, 'OK');
1286 }
1287
1288 $msgcode['resetMyPreference']['OK'] = 51;
1289 function resetMyPreference ()
1290 {
1291 assertStringArg ("varname");
1292 resetUserConfigVar ($_REQUEST["varname"]);
1293 return showFuncMessage (__FUNCTION__, 'OK');
1294 }
1295
1296 $msgcode['resetUIConfig']['OK'] = 57;
1297 function resetUIConfig()
1298 {
1299 setConfigVar ('MASSCOUNT','8');
1300 setConfigVar ('MAXSELSIZE','30');
1301 setConfigVar ('ROW_SCALE','2');
1302 setConfigVar ('PORTS_PER_ROW','12');
1303 setConfigVar ('IPV4_ADDRS_PER_PAGE','256');
1304 setConfigVar ('DEFAULT_RACK_HEIGHT','42');
1305 setConfigVar ('DEFAULT_SLB_VS_PORT','');
1306 setConfigVar ('DEFAULT_SLB_RS_PORT','');
1307 setConfigVar ('DETECT_URLS','no');
1308 setConfigVar ('RACK_PRESELECT_THRESHOLD','1');
1309 setConfigVar ('DEFAULT_IPV4_RS_INSERVICE','no');
1310 setConfigVar ('AUTOPORTS_CONFIG','4 = 1*33*kvm + 2*24*eth%u;15 = 1*446*kvm');
1311 setConfigVar ('SHOW_EXPLICIT_TAGS','yes');
1312 setConfigVar ('SHOW_IMPLICIT_TAGS','yes');
1313 setConfigVar ('SHOW_AUTOMATIC_TAGS','no');
1314 setConfigVar ('DEFAULT_OBJECT_TYPE','4');
1315 setConfigVar ('IPV4_AUTO_RELEASE','1');
1316 setConfigVar ('SHOW_LAST_TAB', 'no');
1317 setConfigVar ('EXT_IPV4_VIEW', 'yes');
1318 setConfigVar ('TREE_THRESHOLD', '25');
1319 setConfigVar ('IPV4_JAYWALK', 'no');
1320 setConfigVar ('ADDNEW_AT_TOP', 'yes');
1321 setConfigVar ('IPV4_TREE_SHOW_USAGE', 'yes');
1322 setConfigVar ('PREVIEW_TEXT_MAXCHARS', '10240');
1323 setConfigVar ('PREVIEW_TEXT_ROWS', '25');
1324 setConfigVar ('PREVIEW_TEXT_COLS', '80');
1325 setConfigVar ('PREVIEW_IMAGE_MAXPXS', '320');
1326 setConfigVar ('VENDOR_SIEVE', '');
1327 setConfigVar ('IPV4LB_LISTSRC', '{$typeid_4}');
1328 setConfigVar ('IPV4OBJ_LISTSRC','{$typeid_4} or {$typeid_7} or {$typeid_8} or {$typeid_12} or {$typeid_445} or {$typeid_447} or {$typeid_798} or {$typeid_1504}');
1329 setConfigVar ('IPV4NAT_LISTSRC','{$typeid_4} or {$typeid_7} or {$typeid_8} or {$typeid_798}');
1330 setConfigVar ('ASSETWARN_LISTSRC','{$typeid_4} or {$typeid_7} or {$typeid_8}');
1331 setConfigVar ('NAMEWARN_LISTSRC','{$typeid_4} or {$typeid_7} or {$typeid_8}');
1332 setConfigVar ('RACKS_PER_ROW','12');
1333 setConfigVar ('FILTER_PREDICATE_SIEVE','');
1334 setConfigVar ('FILTER_DEFAULT_ANDOR','or');
1335 setConfigVar ('FILTER_SUGGEST_ANDOR','yes');
1336 setConfigVar ('FILTER_SUGGEST_TAGS','yes');
1337 setConfigVar ('FILTER_SUGGEST_PREDICATES','yes');
1338 setConfigVar ('FILTER_SUGGEST_EXTRA','no');
1339 setConfigVar ('DEFAULT_SNMP_COMMUNITY','public');
1340 setConfigVar ('IPV4_ENABLE_KNIGHT','yes');
1341 setConfigVar ('TAGS_TOPLIST_SIZE','50');
1342 setConfigVar ('TAGS_QUICKLIST_SIZE','20');
1343 setConfigVar ('TAGS_QUICKLIST_THRESHOLD','50');
1344 setConfigVar ('ENABLE_MULTIPORT_FORM', 'no');
1345 setConfigVar ('DEFAULT_PORT_IIF_ID', '1');
1346 setConfigVar ('DEFAULT_PORT_OIF_IDS', '1=24; 3=1078; 4=1077; 5=1079; 6=1080; 8=1082; 9=1084');
1347 setConfigVar ('IPV4_TREE_RTR_AS_CELL', 'yes');
1348 setConfigVar ('PROXIMITY_RANGE', 0);
1349 setConfigVar ('IPV4_TREE_SHOW_VLAN', 'yes');
1350 setConfigVar ('VLANSWITCH_LISTSRC', '');
1351 setConfigVar ('VLANIPV4NET_LISTSRC', '');
1352 setConfigVar ('DEFAULT_VDOM_ID', '');
1353 setConfigVar ('DEFAULT_VST_ID', '');
1354 setConfigVar ('STATIC_FILTER', 'yes');
1355 setConfigVar ('8021Q_DEPLOY_MINAGE', '300');
1356 setConfigVar ('8021Q_DEPLOY_MAXAGE', '3600');
1357 setConfigVar ('8021Q_DEPLOY_RETRY', '10800');
1358 setConfigVar ('8021Q_WRI_AFTER_CONFT_LISTSRC', 'false');
1359 setConfigVar ('8021Q_INSTANT_DEPLOY', 'no');
1360 setConfigVar ('CDP_RUNNERS_LISTSRC', '');
1361 setConfigVar ('LLDP_RUNNERS_LISTSRC', '');
1362 setConfigVar ('SHRINK_TAG_TREE_ON_CLICK', 'yes');
1363 setConfigVar ('MAX_UNFILTERED_ENTITIES', '0');
1364 setConfigVar ('SYNCDOMAIN_MAX_PROCESSES', '0');
1365 setConfigVar ('PORT_EXCLUSION_LISTSRC', '{$typeid_3} or {$typeid_10} or {$typeid_11} or {$typeid_1505} or {$typeid_1506}');
1366 setConfigVar ('FILTER_RACKLIST_BY_TAGS', 'yes');
1367 setConfigVar ('SSH_OBJS_LISTSRC', 'none');
1368 setConfigVar ('TELNET_OBJS_LISTSRC', 'none');
1369 return showFuncMessage (__FUNCTION__, 'OK');
1370 }
1371
1372 $msgcode['addRealServer']['OK'] = 48;
1373 // Add single record.
1374 function addRealServer ()
1375 {
1376 assertIPv4Arg ('remoteip');
1377 assertStringArg ('rsport', TRUE);
1378 assertStringArg ('rsconfig', TRUE);
1379 addRStoRSPool
1380 (
1381 getBypassValue(),
1382 $_REQUEST['remoteip'],
1383 $_REQUEST['rsport'],
1384 getConfigVar ('DEFAULT_IPV4_RS_INSERVICE'),
1385 $_REQUEST['rsconfig']
1386 );
1387 return showFuncMessage (__FUNCTION__, 'OK');
1388 }
1389
1390 $msgcode['addRealServers']['OK'] = 37;
1391 $msgcode['addRealServers']['ERR1'] = 131;
1392 // Parse textarea submitted and try adding a real server for each line.
1393 function addRealServers ()
1394 {
1395 assertStringArg ('format');
1396 assertStringArg ('rawtext');
1397 $ngood = 0;
1398 $rsconfig = '';
1399 // Keep in mind, that the text will have HTML entities (namely '>') escaped.
1400 foreach (explode ("\n", dos2unix ($_REQUEST['rawtext'])) as $line)
1401 {
1402 if (!strlen ($line))
1403 continue;
1404 $match = array ();
1405 switch ($_REQUEST['format'])
1406 {
1407 case 'ipvs_2': // address and port only
1408 if (!preg_match ('/^ -&gt; ([0-9\.]+):([0-9]+) /', $line, $match))
1409 continue;
1410 addRStoRSPool (getBypassValue(), $match[1], $match[2], getConfigVar ('DEFAULT_IPV4_RS_INSERVICE'), '');
1411 break;
1412 case 'ipvs_3': // address, port and weight
1413 if (!preg_match ('/^ -&gt; ([0-9\.]+):([0-9]+) +[a-zA-Z]+ +([0-9]+) /', $line, $match))
1414 continue;
1415 addRStoRSPool (getBypassValue(), $match[1], $match[2], getConfigVar ('DEFAULT_IPV4_RS_INSERVICE'), 'weight ' . $match[3]);
1416 break;
1417 case 'ssv_2': // IP address and port
1418 if (!preg_match ('/^([0-9\.]+) ([0-9]+)$/', $line, $match))
1419 continue;
1420 addRStoRSPool (getBypassValue(), $match[1], $match[2], getConfigVar ('DEFAULT_IPV4_RS_INSERVICE'), '');
1421 break;
1422 case 'ssv_1': // IP address
1423 if (!preg_match ('/^([0-9\.]+)$/', $line, $match))
1424 continue;
1425 addRStoRSPool (getBypassValue(), $match[1], 0, getConfigVar ('DEFAULT_IPV4_RS_INSERVICE'), '');
1426 break;
1427 default:
1428 return showFuncMessage (__FUNCTION__, 'ERR1');
1429 }
1430 $ngood++;
1431 }
1432 return showFuncMessage (__FUNCTION__, 'OK', array ($ngood));
1433 }
1434
1435 $msgcode['addVService']['OK'] = 48;
1436 function addVService ()
1437 {
1438 assertIPv4Arg ('vip');
1439 assertUIntArg ('vport');
1440 genericAssertion ('proto', 'enum/ipproto');
1441 assertStringArg ('name', TRUE);
1442 assertStringArg ('vsconfig', TRUE);
1443 assertStringArg ('rsconfig', TRUE);
1444 usePreparedExecuteBlade
1445 (
1446 'INSERT INTO IPv4VS (vip, vport, proto, name, vsconfig, rsconfig) VALUES (INET_ATON(?), ?, ?, ?, ?, ?)',
1447 array
1448 (
1449 $_REQUEST['vip'],
1450 $_REQUEST['vport'],
1451 $_REQUEST['proto'],
1452 !mb_strlen ($_REQUEST['name']) ? NULL : $_REQUEST['name'],
1453 !strlen ($_REQUEST['vsconfig']) ? NULL : $_REQUEST['vsconfig'],
1454 !strlen ($_REQUEST['rsconfig']) ? NULL : $_REQUEST['rsconfig'],
1455 )
1456 );
1457 produceTagsForLastRecord ('ipv4vs', isset ($_REQUEST['taglist']) ? $_REQUEST['taglist'] : array());
1458 return showFuncMessage (__FUNCTION__, 'OK');
1459 }
1460
1461 $msgcode['deleteVService']['OK'] = 49;
1462 function deleteVService ()
1463 {
1464 assertUIntArg ('vs_id');
1465 commitDeleteVS ($_REQUEST['vs_id']);
1466 return showFuncMessage (__FUNCTION__, 'OK');
1467 }
1468
1469 $msgcode['updateSLBDefConfig']['OK'] = 43;
1470 function updateSLBDefConfig ()
1471 {
1472 commitUpdateSLBDefConf
1473 (
1474 array
1475 (
1476 'vs' => $_REQUEST['vsconfig'],
1477 'rs' => $_REQUEST['rsconfig'],
1478 )
1479 );
1480 return showFuncMessage (__FUNCTION__, 'OK');
1481 }
1482
1483 $msgcode['updateRealServer']['OK'] = 51;
1484 function updateRealServer ()
1485 {
1486 assertUIntArg ('rs_id');
1487 assertIPv4Arg ('rsip');
1488 assertStringArg ('rsport', TRUE);
1489 assertStringArg ('rsconfig', TRUE);
1490 commitUpdateRS (
1491 $_REQUEST['rs_id'],
1492 $_REQUEST['rsip'],
1493 $_REQUEST['rsport'],
1494 $_REQUEST['rsconfig']
1495 );
1496 return showFuncMessage (__FUNCTION__, 'OK');
1497 }
1498
1499 $msgcode['updateVService']['OK'] = 51;
1500 function updateVService ()
1501 {
1502 assertUIntArg ('vs_id');
1503 assertIPv4Arg ('vip');
1504 assertUIntArg ('vport');
1505 genericAssertion ('proto', 'enum/ipproto');
1506 assertStringArg ('name', TRUE);
1507 assertStringArg ('vsconfig', TRUE);
1508 assertStringArg ('rsconfig', TRUE);
1509 commitUpdateVS (
1510 $_REQUEST['vs_id'],
1511 $_REQUEST['vip'],
1512 $_REQUEST['vport'],
1513 $_REQUEST['proto'],
1514 $_REQUEST['name'],
1515 $_REQUEST['vsconfig'],
1516 $_REQUEST['rsconfig']
1517 );
1518 return showFuncMessage (__FUNCTION__, 'OK');
1519 }
1520
1521 $msgcode['addLoadBalancer']['OK'] = 48;
1522 function addLoadBalancer ()
1523 {
1524 assertUIntArg ('pool_id');
1525 assertUIntArg ('object_id');
1526 assertUIntArg ('vs_id');
1527 assertStringArg ('vsconfig', TRUE);
1528 assertStringArg ('rsconfig', TRUE);
1529 if (! empty($_REQUEST['prio']))
1530 assertUIntArg('prio', TRUE);
1531
1532 addLBtoRSPool (
1533 $_REQUEST['pool_id'],
1534 $_REQUEST['object_id'],
1535 $_REQUEST['vs_id'],
1536 $_REQUEST['vsconfig'],
1537 $_REQUEST['rsconfig'],
1538 $_REQUEST['prio']
1539 );
1540 return showFuncMessage (__FUNCTION__, 'OK');
1541 }
1542
1543 $msgcode['addRSPool']['OK'] = 48;
1544 function addRSPool ()
1545 {
1546 assertStringArg ('name');
1547 assertStringArg ('vsconfig', TRUE);
1548 assertStringArg ('rsconfig', TRUE);
1549 commitCreateRSPool
1550 (
1551 $_REQUEST['name'],
1552 $_REQUEST['vsconfig'],
1553 $_REQUEST['rsconfig'],
1554 isset ($_REQUEST['taglist']) ? $_REQUEST['taglist'] : array()
1555 );
1556 return showFuncMessage (__FUNCTION__, 'OK');
1557 }
1558
1559 $msgcode['deleteRSPool']['OK'] = 49;
1560 function deleteRSPool ()
1561 {
1562 assertUIntArg ('pool_id');
1563 commitDeleteRSPool ($_REQUEST['pool_id']);
1564 return showFuncMessage (__FUNCTION__, 'OK');
1565 }
1566
1567 $msgcode['updateRSInService']['OK'] = 26;
1568 function updateRSInService ()
1569 {
1570 assertUIntArg ('rscount');
1571 $orig = spotEntity ('ipv4rspool', getBypassValue());
1572 amplifyCell ($orig);
1573 $ngood = 0;
1574 for ($i = 1; $i <= $_REQUEST['rscount']; $i++)
1575 {
1576 $rs_id = $_REQUEST["rsid_${i}"];
1577 if (isset ($_REQUEST["inservice_${i}"]) and $_REQUEST["inservice_${i}"] == 'on')
1578 $newval = 'yes';
1579 else
1580 $newval = 'no';
1581 if ($newval != $orig['rslist'][$rs_id]['inservice'])
1582 {
1583 commitSetInService ($rs_id, $newval);
1584 $ngood++;
1585 }
1586 }
1587 return showFuncMessage (__FUNCTION__, 'OK', array ($ngood));
1588 }
1589
1590 $msgcode['importPTRData']['OK'] = 26;
1591 $msgcode['importPTRData']['ERR'] = 141;
1592 // FIXME: check, that each submitted address belongs to the prefix we
1593 // are operating on.
1594 function importPTRData ()
1595 {
1596 assertUIntArg ('addrcount');
1597 $nbad = $ngood = 0;
1598 for ($i = 0; $i < $_REQUEST['addrcount']; $i++)
1599 {
1600 $inputname = "import_${i}";
1601 if (!isset ($_REQUEST[$inputname]) or $_REQUEST[$inputname] != 'on')
1602 continue;
1603 assertIPv4Arg ("addr_${i}");
1604 assertStringArg ("descr_${i}", TRUE);
1605 assertStringArg ("rsvd_${i}");
1606 // Non-existent addresses will not have this argument set in request.
1607 $rsvd = 'no';
1608 if ($_REQUEST["rsvd_${i}"] == 'yes')
1609 $rsvd = 'yes';
1610 if (updateAddress ($_REQUEST["addr_${i}"], $_REQUEST["descr_${i}"], $rsvd) == '')
1611 $ngood++;
1612 else
1613 $nbad++;
1614 }
1615 if (!$nbad)
1616 return showFuncMessage (__FUNCTION__, 'OK', array ($ngood));
1617 else
1618 return showFuncMessage (__FUNCTION__, 'ERR', array ($nbad, $ngood));
1619 }
1620
1621 $msgcode['generateAutoPorts']['OK'] = 21;
1622 function generateAutoPorts ()
1623 {
1624 $object = spotEntity ('object', getBypassValue());
1625 executeAutoPorts ($object['id'], $object['objtype_id']);
1626 showOneLiner (__FUNCTION__, 'OK');
1627 return buildRedirectURL (NULL, 'ports');
1628 }
1629
1630 $msgcode['saveEntityTags']['OK'] = 43;
1631 function saveEntityTags ()
1632 {
1633 global $pageno, $etype_by_pageno;
1634 if (!isset ($etype_by_pageno[$pageno]))
1635 throw new RackTablesError ('key not found in etype_by_pageno', RackTablesError::INTERNAL);
1636 $realm = $etype_by_pageno[$pageno];
1637 $entity_id = getBypassValue();
1638 $taglist = isset ($_REQUEST['taglist']) ? $_REQUEST['taglist'] : array();
1639 rebuildTagChainForEntity ($realm, $entity_id, buildTagChainFromIds ($taglist), TRUE);
1640 return showFuncMessage (__FUNCTION__, 'OK');
1641 }
1642
1643 $msgcode['rollTags']['OK'] = 67;
1644 $msgcode['rollTags']['ERR'] = 149;
1645 function rollTags ()
1646 {
1647 assertStringArg ('sum', TRUE);
1648 assertUIntArg ('realsum');
1649 if ($_REQUEST['sum'] != $_REQUEST['realsum'])
1650 return showFuncMessage (__FUNCTION__, 'ERR');
1651 // Even if the user requested an empty tag list, don't bail out, but process existing
1652 // tag chains with "zero" extra. This will make sure, that the stuff processed will
1653 // have its chains refined to "normal" form.
1654 $extratags = isset ($_REQUEST['taglist']) ? $_REQUEST['taglist'] : array();
1655 $n_ok = 0;
1656 // Minimizing the extra chain early, so that tag rebuilder doesn't have to
1657 // filter out the same tag again and again. It will have own noise to cancel.
1658 $extrachain = getExplicitTagsOnly (buildTagChainFromIds ($extratags));
1659 foreach (listCells ('rack', getBypassValue()) as $rack)
1660 {
1661 if (rebuildTagChainForEntity ('rack', $rack['id'], $extrachain))
1662 $n_ok++;
1663 amplifyCell ($rack);
1664 foreach ($rack['mountedObjects'] as $object_id)
1665 if (rebuildTagChainForEntity ('object', $object_id, $extrachain))
1666 $n_ok++;
1667 }
1668 return showFuncMessage (__FUNCTION__, 'OK', array ($n_ok));
1669 }
1670
1671 $msgcode['changeMyPassword']['OK'] = 51;
1672 $msgcode['changeMyPassword']['ERR1'] = 150;
1673 $msgcode['changeMyPassword']['ERR2'] = 151;
1674 $msgcode['changeMyPassword']['ERR3'] = 152;
1675 function changeMyPassword ()
1676 {
1677 global $remote_username, $user_auth_src;
1678 if ($user_auth_src != 'database')
1679 return showFuncMessage (__FUNCTION__, 'ERR1');
1680 assertStringArg ('oldpassword');
1681 assertStringArg ('newpassword1');
1682 assertStringArg ('newpassword2');
1683 $remote_userid = getUserIDByUsername ($remote_username);
1684 $userinfo = spotEntity ('user', $remote_userid);
1685 if ($userinfo['user_password_hash'] != sha1 ($_REQUEST['oldpassword']))
1686 return showFuncMessage (__FUNCTION__, 'ERR2');
1687 if ($_REQUEST['newpassword1'] != $_REQUEST['newpassword2'])
1688 return showFuncMessage (__FUNCTION__, 'ERR3');
1689 commitUpdateUserAccount ($remote_userid, $userinfo['user_name'], $userinfo['user_realname'], sha1 ($_REQUEST['newpassword1']));
1690 return showFuncMessage (__FUNCTION__, 'OK');
1691 }
1692
1693 $msgcode['saveRackCode']['OK'] = 43;
1694 $msgcode['saveRackCode']['ERR1'] = 154;
1695 function saveRackCode ()
1696 {
1697 assertStringArg ('rackcode');
1698 // For the test to succeed, unescape LFs, strip CRs.
1699 $newcode = dos2unix ($_REQUEST['rackcode']);
1700 $parseTree = getRackCode ($newcode);
1701 if ($parseTree['result'] != 'ACK')
1702 return showFuncMessage (__FUNCTION__, 'ERR1', array ($parseTree['load']));
1703 saveScript ('RackCode', $newcode);
1704 saveScript ('RackCodeCache', base64_encode (serialize ($parseTree)));
1705 return showFuncMessage (__FUNCTION__, 'OK');
1706 }
1707
1708 $msgcode['setPortVLAN']['ERR'] = 164;
1709 // This handler's context is pre-built, but not authorized. It is assumed, that the
1710 // handler will take existing context and before each commit check authorization
1711 // on the base chain plus necessary context added.
1712 function setPortVLAN ()
1713 {
1714 assertUIntArg ('portcount');
1715 try
1716 {
1717 $data = getSwitchVLANs ($_REQUEST['object_id']);
1718 }
1719 catch (RTGatewayError $re)
1720 {
1721 return showFuncMessage (__FUNCTION__, 'ERR', array ($re->getMessage()));
1722 }
1723 list ($vlanlist, $portlist) = $data;
1724 // Here we just build up 1 set command for the gateway with all of the ports
1725 // included. The gateway is expected to filter unnecessary changes silently
1726 // and to provide a list of responses with either error or success message
1727 // for each of the rest.
1728 $nports = $_REQUEST['portcount'];
1729 $prefix = 'set ';
1730 $setcmd = '';
1731 for ($i = 0; $i < $nports; $i++)
1732 {
1733 genericAssertion ('portname_' . $i, 'string');
1734 genericAssertion ('vlanid_' . $i, 'string');
1735 if ($_REQUEST['portname_' . $i] != $portlist[$i]['portname'])
1736 throw new InvalidRequestArgException ('portname_' . $i, $_REQUEST['portname_' . $i], 'expected to be ' . $portlist[$i]['portname']);
1737 if
1738 (
1739 $_REQUEST['vlanid_' . $i] == $portlist[$i]['vlanid'] ||
1740 $portlist[$i]['vlanid'] == 'TRUNK'
1741 )
1742 continue;
1743 $portname = $_REQUEST['portname_' . $i];
1744 $oldvlanid = $portlist[$i]['vlanid'];
1745 $newvlanid = $_REQUEST['vlanid_' . $i];
1746 if
1747 (
1748 !permitted (NULL, NULL, NULL, array (array ('tag' => '$fromvlan_' . $oldvlanid), array ('tag' => '$vlan_' . $oldvlanid))) or
1749 !permitted (NULL, NULL, NULL, array (array ('tag' => '$tovlan_' . $newvlanid), array ('tag' => '$vlan_' . $newvlanid)))
1750 )
1751 {
1752 showOneLiner (159, array ($portname, $oldvlanid, $newvlanid));
1753 continue;
1754 }
1755 $setcmd .= $prefix . $portname . '=' . $newvlanid;
1756 $prefix = ';';
1757 }
1758 // Feed the gateway and interpret its (non)response.
1759 if ($setcmd == '')
1760 showOneLiner (201);
1761 else
1762 {
1763 try
1764 {
1765 setSwitchVLANs ($_REQUEST['object_id'], $setcmd); // shows messages by itself
1766 }
1767 catch (RTGatewayError $e)
1768 {
1769 showOneLiner (164, $e->getMessage());
1770 }
1771 }
1772 }
1773
1774 $msgcode['submitSLBConfig']['OK'] = 66;
1775 $msgcode['submitSLBConfig']['ERR'] = 164;
1776 function submitSLBConfig ()
1777 {
1778 $newconfig = buildLVSConfig (getBypassValue());
1779 try
1780 {
1781 gwSendFileToObject (getBypassValue(), 'slbconfig', html_entity_decode ($newconfig, ENT_QUOTES, 'UTF-8'));
1782 }
1783 catch (RTGatewayError $e)
1784 {
1785 return showFuncMessage (__FUNCTION__, 'ERR', array ($e->getMessage()));
1786 }
1787 return showFuncMessage (__FUNCTION__, 'OK', array ('slbconfig'));
1788 }
1789
1790 $msgcode['addRack']['OK'] = 48;
1791 $msgcode['addRack']['ERR2'] = 172;
1792 function addRack ()
1793 {
1794 $taglist = isset ($_REQUEST['taglist']) ? $_REQUEST['taglist'] : array();
1795 if (isset ($_REQUEST['got_data']))
1796 {
1797 assertStringArg ('rack_name');
1798 assertUIntArg ('rack_height1');
1799 assertStringArg ('rack_comment', TRUE);
1800 commitAddRack ($_REQUEST['rack_name'], $_REQUEST['rack_height1'], $_REQUEST['row_id'], $_REQUEST['rack_comment'], $taglist);
1801 return showFuncMessage (__FUNCTION__, 'OK', array ($_REQUEST['rack_name']));
1802 }
1803 elseif (isset ($_REQUEST['got_mdata']))
1804 {
1805 assertUIntArg ('rack_height2');
1806 assertStringArg ('rack_names', TRUE);
1807 // copy-and-paste from renderAddMultipleObjectsForm()
1808 $names1 = explode ("\n", $_REQUEST['rack_names']);
1809 $names2 = array();
1810 foreach ($names1 as $line)
1811 {
1812 $parts = explode ('\r', $line);
1813 reset ($parts);
1814 if (!strlen ($parts[0]))
1815 continue;
1816 else
1817 $names2[] = rtrim ($parts[0]);
1818 }
1819 foreach ($names2 as $cname)
1820 {
1821 commitAddRack ($cname, $_REQUEST['rack_height2'], $_REQUEST['row_id'], '', $taglist);
1822 showFuncMessage (__FUNCTION__, 'OK', array ($cname));
1823 }
1824 }
1825 else
1826 return showFuncMessage (__FUNCTION__, 'ERR2');
1827 }
1828
1829 $msgcode['deleteRack']['OK'] = 6;
1830 $msgcode['deleteRack']['ERR1'] = 206;
1831 function deleteRack ()
1832 {
1833 assertUIntArg ('rack_id');
1834 $rackData = spotEntity ('rack', $_REQUEST['rack_id']);
1835 amplifyCell ($rackData);
1836 if (count ($rackData['mountedObjects']))
1837 return showFuncMessage (__FUNCTION__, 'ERR1');
1838 commitDeleteRack ($_REQUEST['rack_id']);
1839 showOneLiner (__FUNCTION__, 'OK', array ($rackData['name']));
1840 return buildRedirectURL ('rackspace', 'default');
1841 }
1842
1843 $msgcode['updateRack']['OK'] = 6;
1844 function updateRack ()
1845 {
1846 assertUIntArg ('rack_row_id');
1847 assertUIntArg ('rack_height');
1848 assertStringArg ('rack_name');
1849 assertStringArg ('rack_comment', TRUE);
1850
1851 $rack_id = getBypassValue();
1852 usePreparedUpdateBlade ('Rack', array ('thumb_data' => NULL), array ('id' => $rack_id));
1853 commitUpdateRack ($rack_id, $_REQUEST['rack_name'], $_REQUEST['rack_height'], $_REQUEST['rack_row_id'], $_REQUEST['rack_comment']);
1854 return showFuncMessage (__FUNCTION__, 'OK', array ($_REQUEST['rack_name']));
1855 }
1856
1857 function updateRackDesign ()
1858 {
1859 $rackData = spotEntity ('rack', getBypassValue());
1860 amplifyCell ($rackData);
1861 applyRackDesignMask($rackData);
1862 markupObjectProblems ($rackData);
1863 if (processGridForm ($rackData, 'A', 'F'))
1864 showSuccess ("Saved successfully");
1865 else
1866 showNotice ("Nothing saved");
1867 }
1868
1869 function updateRackProblems ()
1870 {
1871 $rackData = spotEntity ('rack', getBypassValue());
1872 amplifyCell ($rackData);
1873 applyRackProblemMask($rackData);
1874 markupObjectProblems ($rackData);
1875 if (processGridForm ($rackData, 'F', 'U'))
1876 showSuccess ("Saved successfully");
1877 else
1878 showNotice ("Nothing saved");
1879 }
1880
1881 function querySNMPData ()
1882 {
1883 assertStringArg ('community', TRUE);
1884
1885 $snmpsetup = array ();
1886 if ($_REQUEST['community'] != '')
1887 $snmpsetup['community'] = $_REQUEST['community'];
1888 else
1889 {
1890 assertStringArg ('sec_name');
1891 assertStringArg ('sec_level');
1892 assertStringArg ('auth_protocol');
1893 assertStringArg ('auth_passphrase', TRUE);
1894 assertStringArg ('priv_protocol');
1895 assertStringArg ('priv_passphrase', TRUE);
1896
1897 $snmpsetup['sec_name'] = $_REQUEST['sec_name'];
1898 $snmpsetup['sec_level'] = $_REQUEST['sec_level'];
1899 $snmpsetup['auth_protocol'] = $_REQUEST['auth_protocol'];
1900 $snmpsetup['auth_passphrase'] = $_REQUEST['auth_passphrase'];
1901 $snmpsetup['priv_protocol'] = $_REQUEST['priv_protocol'];
1902 $snmpsetup['priv_passphrase'] = $_REQUEST['priv_passphrase'];
1903 }
1904 doSNMPmining (getBypassValue(), $snmpsetup); // shows message by itself
1905 }
1906
1907 $msgcode['linkEntities']['OK'] = 51;
1908 function linkEntities ()
1909 {
1910 assertStringArg ('parent_entity_type');
1911 assertUIntArg ('parent_entity_id');
1912 assertStringArg ('child_entity_type');
1913 assertUIntArg ('child_entity_id');
1914 usePreparedInsertBlade
1915 (
1916 'EntityLink',
1917 array
1918 (
1919 'parent_entity_type' => $_REQUEST['parent_entity_type'],
1920 'parent_entity_id' => $_REQUEST['parent_entity_id'],
1921 'child_entity_type' => $_REQUEST['child_entity_type'],
1922 'child_entity_id' => $_REQUEST['child_entity_id'],
1923 )
1924 );
1925 return showFuncMessage (__FUNCTION__, 'OK');
1926 }
1927
1928 $msgcode['unlinkEntities']['OK'] = 49;
1929 function unlinkEntities ()
1930 {
1931 assertUIntArg ('link_id');
1932 commitUnlinkEntities ($_REQUEST['link_id']);
1933 return showFuncMessage (__FUNCTION__, 'OK');
1934 }
1935
1936 $msgcode['addFileWithoutLink']['OK'] = 5;
1937 // File-related functions
1938 function addFileWithoutLink ()
1939 {
1940 assertStringArg ('comment', TRUE);
1941
1942 // Make sure the file can be uploaded
1943 if (get_cfg_var('file_uploads') != 1)
1944 throw new RackTablesError ('file uploads not allowed, change "file_uploads" parameter in php.ini', RackTablesError::MISCONFIGURED);
1945
1946 $fp = fopen($_FILES['file']['tmp_name'], 'rb');
1947 global $sic;
1948 commitAddFile ($_FILES['file']['name'], $_FILES['file']['type'], $fp, $sic['comment']);
1949 if (isset ($_REQUEST['taglist']))
1950 produceTagsForLastRecord ('file', $_REQUEST['taglist']);
1951 return showFuncMessage (__FUNCTION__, 'OK', array (htmlspecialchars ($_FILES['file']['name'])));
1952 }
1953
1954 $msgcode['addFileToEntity']['OK'] = 5;
1955 function addFileToEntity ()
1956 {
1957 global $pageno, $etype_by_pageno;
1958 if (!isset ($etype_by_pageno[$pageno]))
1959 throw new RackTablesError ('key not found in etype_by_pageno', RackTablesError::INTERNAL);
1960 $realm = $etype_by_pageno[$pageno];
1961 assertStringArg ('comment', TRUE);
1962
1963 // Make sure the file can be uploaded
1964 if (get_cfg_var('file_uploads') != 1)
1965 throw new RackTablesError ('file uploads not allowed, change "file_uploads" parameter in php.ini', RackTablesError::MISCONFIGURED);
1966
1967 $fp = fopen($_FILES['file']['tmp_name'], 'rb');
1968 global $sic;
1969 commitAddFile ($_FILES['file']['name'], $_FILES['file']['type'], $fp, $sic['comment']);
1970 usePreparedInsertBlade
1971 (
1972 'FileLink',
1973 array
1974 (
1975 'file_id' => lastInsertID(),
1976 'entity_type' => $realm,
1977 'entity_id' => getBypassValue(),
1978 )
1979 );
1980 return showFuncMessage (__FUNCTION__, 'OK', array (htmlspecialchars ($_FILES['file']['name'])));
1981 }
1982
1983 $msgcode['linkFileToEntity']['OK'] = 71;
1984 function linkFileToEntity ()
1985 {
1986 assertUIntArg ('file_id');
1987 global $pageno, $etype_by_pageno, $sic;
1988 if (!isset ($etype_by_pageno[$pageno]))
1989 throw new RackTablesError ('key not found in etype_by_pageno', RackTablesError::INTERNAL);
1990
1991 $fi = spotEntity ('file', $sic['file_id']);
1992 usePreparedInsertBlade
1993 (
1994 'FileLink',
1995 array
1996 (
1997 'file_id' => $sic['file_id'],
1998 'entity_type' => $etype_by_pageno[$pageno],
1999 'entity_id' => getBypassValue(),
2000 )
2001 );
2002 return showFuncMessage (__FUNCTION__, 'OK', array (htmlspecialchars ($fi['name'])));
2003 }
2004
2005 $msgcode['replaceFile']['OK'] = 7;
2006 $msgcode['replaceFile']['ERR2'] = 201;
2007 function replaceFile ()
2008 {
2009 // Make sure the file can be uploaded
2010 if (get_cfg_var('file_uploads') != 1)
2011 throw new RackTablesError ('file uploads not allowed, change "file_uploads" parameter in php.ini', RackTablesError::MISCONFIGURED);
2012 $shortInfo = spotEntity ('file', getBypassValue());
2013
2014 if (FALSE === $fp = fopen ($_FILES['file']['tmp_name'], 'rb'))
2015 return showFuncMessage (__FUNCTION__, 'ERR2');
2016 commitReplaceFile ($shortInfo['id'], $fp);
2017
2018 return showFuncMessage (__FUNCTION__, 'OK', array (htmlspecialchars ($shortInfo['name'])));
2019 }
2020
2021 $msgcode['unlinkFile']['OK'] = 72;
2022 function unlinkFile ()
2023 {
2024 assertUIntArg ('link_id');
2025 commitUnlinkFile ($_REQUEST['link_id']);
2026 return showFuncMessage (__FUNCTION__, 'OK');
2027 }
2028
2029 $msgcode['deleteFile']['OK'] = 7;
2030 function deleteFile ()
2031 {
2032 assertUIntArg ('file_id');
2033 $shortInfo = spotEntity ('file', $_REQUEST['file_id']);
2034 commitDeleteFile ($_REQUEST['file_id']);
2035 return showFuncMessage (__FUNCTION__, 'OK', array (htmlspecialchars ($shortInfo['name'])));
2036 }
2037
2038 $msgcode['updateFileText']['OK'] = 6;
2039 $msgcode['updateFileText']['ERR1'] = 179;
2040 $msgcode['updateFileText']['ERR2'] = 155;
2041 function updateFileText ()
2042 {
2043 assertStringArg ('mtime_copy');
2044 assertStringArg ('file_text', TRUE); // it's Ok to save empty
2045 $shortInfo = spotEntity ('file', getBypassValue());
2046 if ($shortInfo['mtime'] != $_REQUEST['mtime_copy'])
2047 return showFuncMessage (__FUNCTION__, 'ERR1');
2048 global $sic;
2049 commitReplaceFile ($shortInfo['id'], $sic['file_text']);
2050 return showFuncMessage (__FUNCTION__, 'OK', array (htmlspecialchars ($shortInfo['name'])));
2051 }
2052
2053 $msgcode['addIIFOIFCompat']['OK'] = 48;
2054 function addIIFOIFCompat ()
2055 {
2056 assertUIntArg ('iif_id');
2057 assertUIntArg ('oif_id');
2058 commitSupplementPIC ($_REQUEST['iif_id'], $_REQUEST['oif_id']);
2059 return showFuncMessage (__FUNCTION__, 'OK');
2060 }
2061
2062 $msgcode['addIIFOIFCompatPack']['OK'] = 37;
2063 function addIIFOIFCompatPack ()
2064 {
2065 genericAssertion ('standard', 'enum/wdmstd');
2066 genericAssertion ('iif_id', 'iif');
2067 global $wdm_packs, $sic;
2068 $ngood = 0;
2069 foreach ($wdm_packs[$sic['standard']]['oif_ids'] as $oif_id)
2070 {
2071 commitSupplementPIC ($sic['iif_id'], $oif_id);
2072 $ngood++;
2073 }
2074 return showFuncMessage (__FUNCTION__, 'OK', array ($ngood));
2075 }
2076
2077 $msgcode['delIIFOIFCompatPack']['OK'] = 38;
2078 function delIIFOIFCompatPack ()
2079 {
2080 genericAssertion ('standard', 'enum/wdmstd');
2081 genericAssertion ('iif_id', 'iif');
2082 global $wdm_packs, $sic;
2083 $ngood = 0;
2084 foreach ($wdm_packs[$sic['standard']]['oif_ids'] as $oif_id)
2085 {
2086 usePreparedDeleteBlade ('PortInterfaceCompat', array ('iif_id' => $sic['iif_id'], 'oif_id' => $oif_id));
2087 $ngood++;
2088 }
2089 return showFuncMessage (__FUNCTION__, 'OK', array ($ngood));
2090 }
2091
2092 $msgcode['addOIFCompatPack']['OK'] = 21;
2093 function addOIFCompatPack ()
2094 {
2095 genericAssertion ('standard', 'enum/wdmstd');
2096 global $wdm_packs;
2097 $oifs = $wdm_packs[$_REQUEST['standard']]['oif_ids'];
2098 foreach ($oifs as $oif_id_1)
2099 {
2100 $args = $qmarks = array();
2101 $query = 'REPLACE INTO PortCompat (type1, type2) VALUES ';
2102 foreach ($oifs as $oif_id_2)
2103 {
2104 $qmarks[] = '(?, ?)';
2105 $args[] = $oif_id_1;
2106 $args[] = $oif_id_2;
2107 }
2108 $query .= implode (', ', $qmarks);
2109 usePreparedExecuteBlade ($query, $args);
2110 }
2111 return showFuncMessage (__FUNCTION__, 'OK');
2112 }
2113
2114 $msgcode['delOIFCompatPack']['OK'] = 21;
2115 function delOIFCompatPack ()
2116 {
2117 genericAssertion ('standard', 'enum/wdmstd');
2118 global $wdm_packs;
2119 $oifs = $wdm_packs[$_REQUEST['standard']]['oif_ids'];
2120 foreach ($oifs as $oif_id_1)
2121 foreach ($oifs as $oif_id_2)
2122 if ($oif_id_1 != $oif_id_2) # leave narrow-band mapping intact
2123 usePreparedDeleteBlade ('PortCompat', array ('type1' => $oif_id_1, 'type2' => $oif_id_2));
2124 return showFuncMessage (__FUNCTION__, 'OK');
2125 }
2126
2127 $msgcode['add8021QOrder']['OK'] = 48;
2128 function add8021QOrder ()
2129 {
2130 assertUIntArg ('vdom_id');
2131 assertUIntArg ('object_id');
2132 assertUIntArg ('vst_id');
2133 global $sic, $pageno;
2134 fixContext();
2135 if ($pageno != 'object')
2136 spreadContext (spotEntity ('object', $sic['object_id']));
2137 if ($pageno != 'vst')
2138 spreadContext (spotEntity ('vst', $sic['vst_id']));
2139 assertPermission();
2140 usePreparedExecuteBlade
2141 (
2142 'INSERT INTO VLANSwitch (domain_id, object_id, template_id, last_change, out_of_sync) ' .
2143 'VALUES (?, ?, ?, NOW(), "yes")',
2144 array ($sic['vdom_id'], $sic['object_id'], $sic['vst_id'])
2145 );
2146 return showFuncMessage (__FUNCTION__, 'OK');
2147 }
2148
2149 $msgcode['del8021QOrder']['OK'] = 49;
2150 function del8021QOrder ()
2151 {
2152 assertUIntArg ('object_id');
2153 assertUIntArg ('vdom_id');
2154 assertUIntArg ('vst_id');
2155 global $sic, $pageno;
2156 fixContext();
2157 if ($pageno != 'object')
2158 spreadContext (spotEntity ('object', $sic['object_id']));
2159 if ($pageno != 'vst')
2160 spreadContext (spotEntity ('vst', $sic['vst_id']));
2161 assertPermission();
2162 usePreparedDeleteBlade ('VLANSwitch', array ('object_id' => $sic['object_id']));
2163 $focus_hints = array
2164 (
2165 'prev_objid' => $_REQUEST['object_id'],
2166 'prev_vstid' => $_REQUEST['vst_id'],
2167 'prev_vdid' => $_REQUEST['vdom_id'],
2168 );
2169 showOneLiner (__FUNCTION__, 'OK');
2170 return buildRedirectURL (NULL, NULL, $focus_hints);
2171 }
2172
2173 $msgcode['createVLANDomain']['OK'] = 48;
2174 function createVLANDomain ()
2175 {
2176 assertStringArg ('vdom_descr');
2177 global $sic;
2178 usePreparedInsertBlade
2179 (
2180 'VLANDomain',
2181 array
2182 (
2183 'description' => $sic['vdom_descr'],
2184 )
2185 );
2186 usePreparedInsertBlade
2187 (
2188 'VLANDescription',
2189 array
2190 (
2191 'domain_id' => lastInsertID(),
2192 'vlan_id' => VLAN_DFL_ID,
2193 'vlan_type' => 'compulsory',
2194 'vlan_descr' => 'default',
2195 )
2196 );
2197 return showFuncMessage (__FUNCTION__, 'OK');
2198 }
2199
2200 $msgcode['destroyVLANDomain']['OK'] = 49;
2201 function destroyVLANDomain ()
2202 {
2203 assertUIntArg ('vdom_id');
2204 global $sic;
2205 usePreparedDeleteBlade ('VLANDomain', array ('id' => $sic['vdom_id']));
2206 return showFuncMessage (__FUNCTION__, 'OK');
2207 }
2208
2209 $msgcode['save8021QPorts']['OK1'] = 63;
2210 $msgcode['save8021QPorts']['OK2'] = 41;
2211 $msgcode['save8021QPorts']['ERR2'] = 109;
2212 function save8021QPorts ()
2213 {
2214 global $sic, $dbxlink;
2215 assertUIntArg ('mutex_rev', TRUE); // counts from 0
2216 assertStringArg ('form_mode');
2217 if ($sic['form_mode'] != 'save' and $sic['form_mode'] != 'duplicate')
2218 throw new InvalidRequestArgException ('form_mode', $sic['form_mode']);
2219 $extra = array();
2220 $dbxlink->beginTransaction();
2221 try
2222 {
2223 if (NULL === $vswitch = getVLANSwitchInfo ($sic['object_id'], 'FOR UPDATE'))
2224 throw new InvalidArgException ('object_id', $object_id, 'VLAN domain is not set for this object');
2225 if ($vswitch['mutex_rev'] != $sic['mutex_rev'])
2226 throw new InvalidRequestArgException ('mutex_rev', $sic['mutex_rev'], 'expired form data');
2227 $after = $before = apply8021QOrder ($vswitch['template_id'], getStored8021QConfig ($sic['object_id'], 'desired'));
2228 $changes = array();
2229 switch ($sic['form_mode'])
2230 {
2231 case 'save':
2232 assertUIntArg ('nports');
2233 if ($sic['nports'] == 1)
2234 {
2235 assertStringArg ('pn_0');
2236 $extra = array ('port_name' => $sic['pn_0']);
2237 }
2238 for ($i = 0; $i < $sic['nports']; $i++)
2239 {
2240 assertStringArg ('pn_' . $i);
2241 assertStringArg ('pm_' . $i);
2242 // An access port only generates form input for its native VLAN,
2243 // which we derive allowed VLAN list from.
2244 $native = isset ($sic['pnv_' . $i]) ? $sic['pnv_' . $i] : 0;
2245 switch ($sic["pm_${i}"])
2246 {
2247 case 'trunk':
2248 # assertArrayArg ('pav_' . $i);
2249 $allowed = isset ($sic['pav_' . $i]) ? $sic['pav_' . $i] : array();
2250 break;
2251 case 'access':
2252 if ($native == 'same')
2253 continue 2;
2254 assertUIntArg ('pnv_' . $i);
2255 $allowed = array ($native);
2256 break;
2257 default:
2258 throw new InvalidRequestArgException ("pm_${i}", $_REQUEST["pm_${i}"], 'unknown port mode');
2259 }
2260 $changes[$sic['pn_' . $i]] = array
2261 (
2262 'mode' => $sic['pm_' . $i],
2263 'allowed' => $allowed,
2264 'native' => $native,
2265 );
2266 }
2267 break;
2268 case 'duplicate':
2269 assertStringArg ('from_port');
2270 # assertArrayArg ('to_ports');
2271 if (!array_key_exists ($sic['from_port'], $before))
2272 throw new InvalidArgException ('from_port', $sic['from_port'], 'this port does not exist');
2273 foreach ($sic['to_ports'] as $tpn)
2274 if (!array_key_exists ($tpn, $before))
2275 throw new InvalidArgException ('to_ports[]', $tpn, 'this port does not exist');
2276 elseif ($tpn != $sic['from_port'])
2277 $changes[$tpn] = $before[$sic['from_port']];
2278 break;
2279 }
2280 $domain_vlanlist = getDomainVLANs ($vswitch['domain_id']);
2281 $changes = filter8021QChangeRequests
2282 (
2283 $domain_vlanlist,
2284 $before,
2285 apply8021QOrder ($vswitch['template_id'], $changes)
2286 );
2287 $changes = authorize8021QChangeRequests ($before, $changes);
2288 foreach ($changes as $port_name => $port)
2289 $after[$port_name] = $port;
2290 $new_uplinks = filter8021QChangeRequests ($domain_vlanlist, $after, produceUplinkPorts ($domain_vlanlist, $after, $vswitch['object_id']));
2291 $npulled = replace8021QPorts ('desired', $vswitch['object_id'], $before, $changes);
2292 $nsaved_uplinks = replace8021QPorts ('desired', $vswitch['object_id'], $before, $new_uplinks);
2293 }
2294 catch (Exception $e)
2295 {
2296 $dbxlink->rollBack();
2297 showOneLiner (__FUNCTION__, 'ERR2');
2298 return buildRedirectURL (NULL, NULL, $extra);
2299 }
2300 if ($npulled + $nsaved_uplinks)
2301 usePreparedExecuteBlade
2302 (
2303 'UPDATE VLANSwitch SET mutex_rev=mutex_rev+1, last_change=NOW(), out_of_sync="yes" WHERE object_id=?',
2304 array ($sic['object_id'])
2305 );
2306 $dbxlink->commit();
2307 showOneLiner (63, array ($npulled + $nsaved_uplinks));
2308 if ($nsaved_uplinks)
2309 {
2310 initiateUplinksReverb ($vswitch['object_id'], $new_uplinks);
2311 showOneLiner (41);
2312 }
2313 if ($npulled + $nsaved_uplinks > 0 and getConfigVar ('8021Q_INSTANT_DEPLOY') == 'yes')
2314 {
2315 try
2316 {
2317 if (FALSE === $done = exec8021QDeploy ($sic['object_id'], TRUE))
2318 showOneLiner (191);
2319 else
2320 showOneLiner (63, array ($done));
2321 }
2322 catch (Exception $e)
2323 {
2324 showOneLiner (109);
2325 }
2326 }
2327 return buildRedirectURL (NULL, NULL, $extra);
2328 }
2329
2330 $msgcode['bindVLANtoIPv4']['OK'] = 48;
2331 function bindVLANtoIPv4 ()
2332 {
2333 assertUIntArg ('id'); // network id
2334 global $sic;
2335 commitSupplementVLANIPv4 ($sic['vlan_ck'], $sic['id']);
2336 return showFuncMessage (__FUNCTION__, 'OK');
2337 }
2338
2339 $msgcode['bindVLANtoIPv6']['OK'] = 48;
2340 function bindVLANtoIPv6 ()
2341 {
2342 assertUIntArg ('id'); // network id
2343 global $sic;
2344 commitSupplementVLANIPv6 ($sic['vlan_ck'], $_REQUEST['id']);
2345 return showFuncMessage (__FUNCTION__, 'OK');
2346 }
2347
2348 $msgcode['unbindVLANfromIPv4']['OK'] = 49;
2349 function unbindVLANfromIPv4 ()
2350 {
2351 assertUIntArg ('id'); // network id
2352 global $sic;
2353 commitReduceVLANIPv4 ($sic['vlan_ck'], $sic['id']);
2354 return showFuncMessage (__FUNCTION__, 'OK');
2355 }
2356
2357 $msgcode['unbindVLANfromIPv6']['OK'] = 49;
2358 function unbindVLANfromIPv6 ()
2359 {
2360 assertUIntArg ('id'); // network id
2361 global $sic;
2362 commitReduceVLANIPv6 ($sic['vlan_ck'], $sic['id']);
2363 return showFuncMessage (__FUNCTION__, 'OK');
2364 }
2365
2366 $msgcode['process8021QSyncRequest']['OK'] = 63;
2367 $msgcode['process8021QSyncRequest']['ERR'] = 191;
2368 function process8021QSyncRequest ()
2369 {
2370 // behave depending on current operation: exec8021QPull or exec8021QPush
2371 global $sic, $op;
2372 if (FALSE === $done = exec8021QDeploy ($sic['object_id'], $op == 'exec8021QPush'))
2373 return showFuncMessage (__FUNCTION__, 'ERR');
2374 return showFuncMessage (__FUNCTION__, 'OK', array ($done));
2375 }
2376
2377 $msgcode['process8021QRecalcRequest']['CHANGED'] = 87;
2378 function process8021QRecalcRequest ()
2379 {
2380 assertPermission (NULL, NULL, NULL, array (array ('tag' => '$op_recalc8021Q')));
2381 $counters = recalc8021QPorts (getBypassValue());
2382 if ($counters['ports'])
2383 return showFuncMessage (__FUNCTION__, 'CHANGED', array ($counters['ports'], $counters['switches']));
2384 else
2385 return showNotice ('No changes were made');
2386 }
2387
2388 $msgcode['resolve8021QConflicts']['OK'] = 63;
2389 $msgcode['resolve8021QConflicts']['ERR1'] = 179;
2390 $msgcode['resolve8021QConflicts']['ERR2'] = 109;
2391 function resolve8021QConflicts ()
2392 {
2393 global $sic, $dbxlink;
2394 assertUIntArg ('mutex_rev', TRUE); // counts from 0
2395 assertUIntArg ('nrows');
2396 // Divide submitted radio buttons into 3 groups:
2397 // left (saved version wins)
2398 // asis (ignore)
2399 // right (running version wins)
2400 $F = array();
2401 for ($i = 0; $i < $sic['nrows']; $i++)
2402 {
2403 if (!array_key_exists ("i_${i}", $sic))
2404 continue;
2405 // let's hope other inputs are in place
2406 switch ($sic["i_${i}"])
2407 {
2408 case 'left':
2409 case 'right':
2410 $F[$sic["pn_${i}"]] = array
2411 (
2412 'mode' => $sic["rm_${i}"],
2413 'allowed' => $sic["ra_${i}"],
2414 'native' => $sic["rn_${i}"],
2415 'decision' => $sic["i_${i}"],
2416 );
2417 break;
2418 default:
2419 // don't care
2420 }
2421 }
2422 $dbxlink->beginTransaction();
2423 try
2424 {
2425 if (NULL === $vswitch = getVLANSwitchInfo ($sic['object_id'], 'FOR UPDATE'))
2426 throw new InvalidArgException ('object_id', $sic['object_id'], 'VLAN domain is not set for this object');
2427 if ($vswitch['mutex_rev'] != $sic['mutex_rev'])
2428 throw new InvalidRequestArgException ('mutex_rev', $sic['mutex_rev'], 'expired form (table data has changed)');
2429 $D = getStored8021QConfig ($vswitch['object_id'], 'desired');
2430 $C = getStored8021QConfig ($vswitch['object_id'], 'cached');
2431 $R = getRunning8021QConfig ($vswitch['object_id']);
2432 $plan = get8021QSyncOptions ($vswitch, $D, $C, $R['portdata']);
2433 $ndone = 0;
2434 foreach ($F as $port_name => $port)
2435 {
2436 if (!array_key_exists ($port_name, $plan))
2437 continue;
2438 elseif ($plan[$port_name]['status'] == 'merge_conflict')
2439 {
2440 // for R neither mutex nor revisions can be emulated, but revision change can be
2441 if (!same8021QConfigs ($port, $R['portdata'][$port_name]))
2442 throw new InvalidRequestArgException ("port ${port_name}", '(hidden)', 'expired form (switch data has changed)');
2443 if ($port['decision'] == 'right') // D wins, frame R by writing value of R to C
2444 {
2445 upd8021QPort ('cached', $vswitch['object_id'], $port_name, $port);
2446 $ndone++;
2447 }
2448 elseif ($port['decision'] == 'left') // R wins, cross D up
2449 {
2450 upd8021QPort ('cached', $vswitch['object_id'], $port_name, $D[$port_name]);
2451 $ndone++;
2452 }
2453 // otherwise there was no decision made
2454 }
2455 elseif
2456 (
2457 $plan[$port_name]['status'] == 'delete_conflict' or
2458 $plan[$port_name]['status'] == 'martian_conflict'
2459 )
2460 if ($port['decision'] == 'left')
2461 {
2462 // confirm deletion of local copy
2463 del8021QPort ($vswitch['object_id'], $port_name);
2464 $ndone++;
2465 }
2466 // otherwise ignore a decision, which doesn't address a conflict
2467 }
2468 }
2469 catch (InvalidRequestArgException $e)
2470 {
2471 $dbxlink->rollBack();
2472 return showFuncMessage (__FUNCTION__, 'ERR1');
2473 }
2474 catch (Exception $e)
2475 {
2476 $dbxlink->rollBack();
2477 return showFuncMessage (__FUNCTION__, 'ERR2');
2478 }
2479 $dbxlink->commit();
2480 return showFuncMessage (__FUNCTION__, 'OK', array ($ndone));
2481 }
2482
2483 $msgcode['addVLANSwitchTemplate']['OK'] = 48;
2484 function addVLANSwitchTemplate()
2485 {
2486 assertStringArg ('vst_descr');
2487 global $sic;
2488 usePreparedInsertBlade
2489 (
2490 'VLANSwitchTemplate',
2491 array
2492 (
2493 'description' => $sic['vst_descr'],
2494 )
2495 );
2496 return showFuncMessage (__FUNCTION__, 'OK');
2497 }
2498
2499 $msgcode['delVLANSwitchTemplate']['OK'] = 49;
2500 function delVLANSwitchTemplate()
2501 {
2502 assertUIntArg ('vst_id');
2503 global $sic;
2504 usePreparedDeleteBlade ('VLANSwitchTemplate', array ('id' => $sic['vst_id']));
2505 return showFuncMessage (__FUNCTION__, 'OK');
2506 }
2507
2508 $msgcode['cloneVST']['OK'] = 48;
2509 function cloneVST()
2510 {
2511 assertUIntArg ('mutex_rev', TRUE);
2512 assertUIntArg ('from_id');
2513 $src_vst = spotEntity ('vst', $_REQUEST['from_id']);
2514 amplifyCell ($src_vst);
2515 commitUpdateVSTRules (getBypassValue(), $_REQUEST['mutex_rev'], $src_vst['rules']);
2516 return showFuncMessage (__FUNCTION__, 'OK');
2517 }
2518
2519 $msgcode['updVSTRule']['OK'] = 43;
2520 function updVSTRule()
2521 {
2522 // this is used for making throwing an invalid argument exception easier.
2523 function updVSTRule_get_named_param ($name, $haystack, &$last_used_name)
2524 {
2525 $last_used_name = $name;
2526 return isset ($haystack[$name]) ? $haystack[$name] : NULL;
2527 }
2528
2529 global $port_role_options, $sic;
2530 assertUIntArg ('mutex_rev', TRUE);
2531 genericAssertion ('template_json', 'json');
2532 $data = json_decode ($sic['template_json'], TRUE);
2533 $rule_no = 0;
2534 try
2535 {
2536 $last_field = '';
2537 foreach ($data as $rule)
2538 {
2539 $rule_no++;
2540 if
2541 (
2542 ! isInteger (updVSTRule_get_named_param ('rule_no', $rule, $last_field))
2543 or ! isPCRE (updVSTRule_get_named_param ('port_pcre', $rule, $last_field))
2544 or NULL === updVSTRule_get_named_param ('port_role', $rule, $last_field)
2545 or ! array_key_exists (updVSTRule_get_named_param ('port_role', $rule, $last_field), $port_role_options)
2546 or NULL === updVSTRule_get_named_param ('wrt_vlans', $rule, $last_field)
2547 or ! preg_match ('/^[ 0-9\-,]*$/', updVSTRule_get_named_param ('wrt_vlans', $rule, $last_field))
2548 or NULL === updVSTRule_get_named_param ('description', $rule, $last_field)
2549 )
2550 throw new InvalidRequestArgException ($last_field, $rule[$last_field], "rule #$rule_no");
2551 }
2552 commitUpdateVSTRules ($_REQUEST['vst_id'], $_REQUEST['mutex_rev'], $data);
2553 }
2554 catch (Exception $e)
2555 {
2556 // Every case, which is soft-processed in process.php, will have the working copy available for a retry.
2557 if ($e instanceof InvalidRequestArgException or $e instanceof RTDatabaseError)
2558 $_SESSION['vst_edited'] = $data;
2559 throw $e;
2560 }
2561 return showFuncMessage (__FUNCTION__, 'OK');
2562 }
2563
2564 $msgcode['importDPData']['OK'] = 44;
2565 function importDPData()
2566 {
2567 global $sic, $dbxlink;
2568 assertUIntArg ('nports');
2569 $nignored = $ndone = 0;
2570 $POIFC = getPortOIFCompat();
2571 for ($i = 0; $i < $sic['nports']; $i++)
2572 if (array_key_exists ("do_${i}", $sic))
2573 {
2574 $params = array();
2575 assertStringArg ("ports_${i}");
2576 foreach (explode (',', $_REQUEST["ports_${i}"]) as $item)
2577 {
2578 $pair = explode (':', $item);
2579 if (count ($pair) != 2)
2580 continue;
2581 $params[$pair[0]] = $pair[1];
2582 }
2583 if (! isset ($params['a_id']) || ! isset ($params['b_id']) ||
2584 ! intval ($params['a_id']) || ! intval ($params['b_id']))
2585 throw new InvalidArgException ("ports_${i}", $_REQUEST["ports_${i}"], "can not unpack port ids");
2586
2587 $porta = getPortInfo ($params['a_id']);
2588 $portb = getPortInfo ($params['b_id']);
2589 if
2590 (
2591 $porta['linked'] or
2592 $portb['linked'] or
2593 ($porta['object_id'] != $sic['object_id'] and $portb['object_id'] != $sic['object_id'])
2594 )
2595 {
2596 $nignored++;
2597 continue;
2598 }
2599 $oif_a = intval (@$params['a_oif']); // these parameters are optional
2600 $oif_b = intval (@$params['b_oif']);
2601
2602 $dbxlink->beginTransaction();
2603 if ($oif_a || $oif_b)
2604 try
2605 {
2606 if ($oif_a)
2607 {
2608 commitUpdatePortOIF ($params['a_id'], $oif_a);
2609 $porta['oif_id'] = $oif_a;
2610 }
2611 if ($oif_b)
2612 {
2613 commitUpdatePortOIF ($params['b_id'], $oif_b);
2614 $portb['oif_id'] = $oif_b;
2615 }
2616 }
2617 catch (RTDatabaseError $e)
2618 {
2619 $dbxlink->rollBack();
2620 $nignored++;
2621 continue;
2622 }
2623
2624 foreach ($POIFC as $item)
2625 if ($item['type1'] == $porta['oif_id'] and $item['type2'] == $portb['oif_id'])
2626 {
2627 linkPorts ($params['a_id'], $params['b_id']);
2628 $ndone++;
2629 $dbxlink->commit();
2630 continue 2; //next port
2631 }
2632 $dbxlink->rollback();
2633 }
2634 return showFuncMessage (__FUNCTION__, 'OK', array ($nignored, $ndone));
2635 }
2636
2637 function addObjectlog ()
2638 {
2639 assertStringArg ('logentry');
2640 global $remote_username, $sic;
2641 $oi = spotEntity ('object', $sic['object_id']);
2642 usePreparedExecuteBlade ('INSERT INTO ObjectLog SET object_id=?, user=?, date=NOW(), content=?', array ($sic['object_id'], $remote_username, $sic['logentry']));
2643 showSuccess ('Log entry for ' . mkA ($oi['dname'], 'object', $sic['object_id'], 'log') . " added by ${remote_username}");
2644 }
2645
2646 function getOpspec()
2647 {
2648 global $pageno, $tabno, $op, $opspec_list;
2649 if (!array_key_exists ($pageno . '-' . $tabno . '-' . $op, $opspec_list))
2650 throw new RackTablesError ('key not found in opspec_list', RackTablesError::INTERNAL);
2651 $ret = $opspec_list[$pageno . '-' . $tabno . '-' . $op];
2652 if
2653 (
2654 !array_key_exists ('table', $ret)
2655 or !array_key_exists ('action', $ret)
2656 // add further checks here
2657 )
2658 throw new RackTablesError ('malformed array structure in opspec_list', RackTablesError::INTERNAL);
2659 return $ret;
2660 }
2661
2662 function unlinkPort ()
2663 {
2664 assertUIntArg ('port_id');
2665 commitUnlinkPort ($_REQUEST['port_id']);
2666 showSuccess ("Port unlinked successfully");
2667 }
2668
2669 function tableHandler()
2670 {
2671 $opspec = getOpspec();
2672 global $sic;
2673 $columns = array();
2674 foreach (array ('arglist', 'set_arglist', 'where_arglist') as $listname)
2675 {
2676 if (! array_key_exists ($listname, $opspec))
2677 continue;
2678 foreach ($opspec[$listname] as $argspec)
2679 {
2680 genericAssertion ($argspec['url_argname'], $argspec['assertion']);
2681 // "table_colname" is normally used for an override, if it is not
2682 // set, use the URL argument name
2683 $table_colname = array_key_exists ('table_colname', $argspec) ?
2684 $argspec['table_colname'] :
2685 $argspec['url_argname'];
2686 $arg_value = $sic[$argspec['url_argname']];
2687 if
2688 (
2689 ($argspec['assertion'] == 'uint0' and $arg_value == 0)
2690 or ($argspec['assertion'] == 'string0' and $arg_value == '')
2691 )
2692 switch (TRUE)
2693 {
2694 case !array_key_exists ('if_empty', $argspec): // no action requested
2695 break;
2696 case $argspec['if_empty'] == 'NULL':
2697 $arg_value = NULL;
2698 break;
2699 default:
2700 throw new InvalidArgException ('opspec', '(malformed array structure)', '"if_empty" not recognized');
2701 }
2702 $columns[$listname][$table_colname] = $arg_value;
2703 }
2704 }
2705 switch ($opspec['action'])
2706 {
2707 case 'INSERT':
2708 usePreparedInsertBlade ($opspec['table'], $columns['arglist']);
2709 break;
2710 case 'DELETE':
2711 $conjunction = array_key_exists ('conjunction', $opspec) ? $opspec['conjunction'] : 'AND';
2712 usePreparedDeleteBlade ($opspec['table'], $columns['arglist'], $conjunction);
2713 break;
2714 case 'UPDATE':
2715 usePreparedUpdateBlade
2716 (
2717 $opspec['table'],
2718 $columns['set_arglist'],
2719 $columns['where_arglist'],
2720 array_key_exists ('conjunction', $opspec) ? $opspec['conjunction'] : 'AND'
2721 );
2722 break;
2723 default:
2724 throw new InvalidArgException ('opspec/action', $opspec['action']);
2725 }
2726 showOneLiner (51);
2727 }
2728
2729 ?>