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