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