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