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