Change Mail Address
[racktables-contribs] / local_copy_object.php
1 <?php
2
3 /*
4 (c) 2014 Maximilian Mensing <max@maximilian-mensing.de>
5 (c) 2011 Manon Goo <manon@dg-i.net>
6 */
7
8 defineIfNotDefined ('TABLE_BORDER', 0);
9
10 $tab['object']['objectcopier'] = 'Object Copier ';
11 $tabhandler['object']['objectcopier'] = 'localfunc_ObjectCopier';
12 $ophandler['object']['objectcopier']['copyLotOfObjects'] = 'copyLotOfObjects';
13
14 function amplifyCell_object_Backend_Port (&$record, $dummy = NULL)
15 {
16 switch ($record['realm'])
17 {
18 case 'object':
19 $record['BackendPorts'] = getObjectBackendPortsAndLinks ($record['id']);
20 break;
21 default:
22 }
23 }
24
25 function getObjectBackendPortsAndLinks ($object_id)
26 {
27 $ret = fetchBackendPortList ("Port.object_id = ?", array ($object_id));
28 return sortPortList ($ret, TRUE);
29 }
30
31 function fetchBackendPortList ($sql_where_clause, $query_params = array())
32 {
33 $query = <<<END
34 SELECT
35 Port.id,
36 Port.name,
37 Port.object_id,
38 Object.name AS object_name,
39 Port.l2address,
40 Port.label,
41 Port.reservation_comment,
42 Port.iif_id,
43 Port.type AS oif_id,
44 (SELECT PortInnerInterface.iif_name FROM PortInnerInterface WHERE PortInnerInterface.id = Port.iif_id) AS iif_name,
45 (SELECT Dictionary.dict_value FROM Dictionary WHERE Dictionary.dict_key = Port.type) AS oif_name,
46 IF(lba.porta, lba.cable, lbb.cable) AS cableid,
47 IF(lba.porta, pa.id, pb.id) AS remote_id,
48 IF(lba.porta, pa.name, pb.name) AS remote_name,
49 IF(lba.porta, pa.object_id, pb.object_id) AS remote_object_id,
50 IF(lba.porta, oa.name, ob.name) AS remote_object_name,
51 (SELECT COUNT(*) FROM PortLog WHERE PortLog.port_id = Port.id) AS log_count,
52 PortLog.user,
53 UNIX_TIMESTAMP(PortLog.date) as time
54 FROM
55 Port
56 INNER JOIN Object ON Port.object_id = Object.id
57 LEFT JOIN LinkBackend AS lba ON lba.porta = Port.id
58 LEFT JOIN Port AS pa ON pa.id = lba.portb
59 LEFT JOIN Object AS oa ON pa.object_id = oa.id
60 LEFT JOIN LinkBackend AS lbb on lbb.portb = Port.id
61 LEFT JOIN Port AS pb ON pb.id = lbb.porta
62 LEFT JOIN Object AS ob ON pb.object_id = ob.id
63 LEFT JOIN PortLog ON PortLog.id = (SELECT id FROM PortLog WHERE PortLog.port_id = Port.id ORDER BY date DESC LIMIT 1)
64 WHERE
65 $sql_where_clause
66 END;
67
68 $result = usePreparedSelectBlade ($query, $query_params);
69 $ret = array();
70 while ($row = $result->fetch (PDO::FETCH_ASSOC))
71 {
72 $row['l2address'] = l2addressFromDatabase ($row['l2address']);
73 $row['linked'] = isset ($row['remote_id']) ? 1 : 0;
74
75 // last changed log
76 $row['last_log'] = array();
77 if ($row['log_count'])
78 {
79 $row['last_log']['user'] = $row['user'];
80 $row['last_log']['time'] = $row['time'];
81 }
82 unset ($row['user']);
83 unset ($row['time']);
84
85 $ret[] = $row;
86 }
87 return $ret;
88 }
89
90
91 function varDumpToString ($var)
92 {
93 ob_start();
94 var_dump($var);
95 $result = ob_get_clean();
96 return $result;
97 }
98
99 function localfunc_ObjectCopier($object_id)
100 {
101 $object = spotEntity ('object', $object_id );
102 amplifyCell($object);
103 global $virtual_obj_types, $taglist, $target_given_tags;
104 $typelist = readChapter (CHAP_OBJTYPE, 'o');
105 $typelist[0] = 'select type...';
106 $typelist = cookOptgroups ($typelist);
107 $max = getConfigVar ('MASSCOUNT');
108 $tabindex = 100;
109
110 echo "\n";
111 echo "\n<!-- printOpFormIntro ('copyLotOfObjects') -->\n";
112 printOpFormIntro ('copyLotOfObjects');
113 echo "\n";
114 startPortlet ('Make many copies of this object');
115 echo "\n" . sprintf('<table border=%s align=center>', TABLE_BORDER);
116 echo "\n" . '<tr><th align=left>name or "name","label","asset_no" (no csv escaping)<br><br>';
117 echo 'Example:<br> "server.example.com","server.example.com","12345"<br>www.example.com<br>testmachine<br>';
118 echo '</th><th>Copy Tags</th></tr>';
119 //echo "<tr><td><input type=submit name=got_very_fast_data value='Go!'></td><td></td></tr>\n";
120 echo "\n" . "<tr><td valign=top ><textarea name=namelist cols=60 rows=35>\n</textarea></td>";
121 echo "<td valign=top>";
122 printf ("<input type=hidden name=global_type_id value='%s'>\n", $object['objtype_id']);
123 //renderCopyEntityTagsPortlet ('Tag tree', getTagTree(), $target_given_tags, $etype_by_pageno[$pageno]);
124 renderCopyEntityTags($object);
125 echo "</td></tr>";
126 echo "<tr><td colspan=2><input type=submit name=got_very_fast_data value='Go!'></td></tr></table>\n";
127 echo "</form>\n";
128 finishPortlet();
129
130 }
131
132 function copyLotOfObjects()//$template_object)
133 {
134 global $dbxlink;
135 $dbrollback = 0;
136 if (! $dbxlink->beginTransaction() )
137 throw new RTDatabaseError ("can not start transaction");
138 // do we need this ?
139 $log = emptyLog();
140 $taglist = isset ($_REQUEST['taglist']) ? $_REQUEST['taglist'] : array();
141 assertUIntArg ('global_type_id', TRUE);
142 assertStringArg ('namelist', TRUE);
143 $global_type_id = $_REQUEST['global_type_id'];
144 $source_object_id = $_REQUEST['object_id'];
145 $source_object = spotEntity ('object', $source_object_id);
146 amplifyCell($source_object);
147 // only call amplifyCell_object_Backend_Port if we have function linkmgmt_linkPorts from linkmgmt.php
148 if ( function_exists ( 'amplifyCell_object_Backend_Port' ) && function_exists ('linkmgmt_linkPorts') )
149 {
150 amplifyCell_object_Backend_Port($source_object);
151 }
152 if ($global_type_id == 0 or !strlen ($_REQUEST['namelist']))
153 {
154 // Log something reasonable with showError Here
155 // We do not have names to copy our object to !
156 // Pls check what makes $global_type_id == 0 an error
157 $log = mergeLogs ($log, oneLiner (186));
158 return ;
159 }
160 // The name extractor below was stolen from ophandlers.php:addMultiPorts()
161 $names1 = explode ("\n", $_REQUEST['namelist']);
162 $names2 = array();
163 foreach ($names1 as $line)
164 {
165 $parts = explode ('\r', $line);
166 reset ($parts);
167 if (!strlen ($parts[0]))
168 continue;
169 else
170 $names2[] = rtrim ($parts[0]);
171 }
172 foreach ($names2 as $name_or_csv)
173 {
174 $label = '';
175 $asset_no = '';
176 $object_name = '';
177 $regexp='/^\"([^\"]*)\","([^\"]*)\","([^\"]*)\"/';
178 $object_name_or_csv = htmlspecialchars_decode($name_or_csv, ENT_QUOTES);
179 // error_log( "$regexp $object_name" );
180 if (preg_match($regexp, $object_name_or_csv, $matches) )
181 {
182 $object_name = $matches[1];
183 $label = $matches[2];
184 $asset_no = $matches[3];
185 }
186 else
187 $object_name = $name_or_csv;
188 try
189 {
190 $object_id = commitAddObject ($object_name, $label, $global_type_id, $asset_no, $taglist);
191 if (!$object_id)
192 throw new RTDatabaseError("could not create $object_name");
193 $info = spotEntity ('object', $object_id);
194 amplifyCell ($info);
195 foreach ($source_object['ports'] as $source_port)
196 {
197 $update_port=0;
198 foreach ($info['ports'] as $new_port)
199 {
200 if ($new_port['name'] == $source_port['name'] )
201 {
202 commitUpdatePort ($object_id, $new_port['id'], $new_port['name'], $new_port['oif_id'], $source_port['label'], "" );
203 $update_port=1;
204 }
205 }
206 if ($update_port)
207 true;
208 else
209 commitAddPort ( $object_id, $source_port['name'], sprintf("%s-%s", $source_port['iif_id'], $source_port['oif_id']), $source_port['label'], "" );
210 }
211 // Copy Backendlinks only start if we ghave function linkmgmt_linkPorts from linkmgmt.php
212 if ( function_exists ( 'amplifyCell_object_Backend_Port' ) && function_exists ('linkmgmt_linkPorts') )
213 {
214 $info = spotEntity ('object', $object_id);
215 amplifyCell ($info);
216 amplifyCell_object_Backend_Port($info);
217
218 /* showError( '<div align="left"><pre>\n===== Source Object ======\n\n' .
219 varDumpToString ( $source_object ) .
220 '\n\n===== New Object ======\n\n' .
221 varDumpToString ( $info ) . '</pre></div>' );
222 */
223 $name_by_id = array();
224 foreach ($info['BackendPorts'] as $new_be_port)
225 {
226 $name_by_id[$new_be_port['name']] = $new_be_port['id'];
227 }
228
229 $linked_ports = array();
230 foreach ($source_object['BackendPorts'] as $source_be_port)
231 {
232 if ( $source_be_port['object_id'] == $source_be_port['remote_object_id'] )
233 {
234 // We have a Port that has the own object as remote object we want to copy this type of Linko
235 // We have backend Links
236 $new_be_port_a = $name_by_id[$source_be_port['name']] ;
237 $new_be_port_b = $name_by_id[$source_be_port['remote_name']] ;
238 if ( $new_be_port_a && $new_be_port_b && ! array_key_exists($new_be_port_a, $linked_ports ) && ! array_key_exists($new_be_port_b, $linked_ports ) )
239 {
240 // error_log ( sprintf ('new_be_port_a %s // new_be_port_b %s // cableid %s', $new_be_port_a , $new_be_port_b, $source_be_port['cableid'] ));
241 $ret_val = linkmgmt_linkPorts( $new_be_port_a , $new_be_port_b , 'back', $source_be_port['cableid'] );
242 // error_log ( sprintf (' linkmgmt_linkPorts ret val: "%s" ', $ret_val)) ;
243 if ($ret_val)
244 {
245 throw new RTDatabaseError("could not copy Backend Links for $object_name because: $ret_val");
246 }
247 else
248 {
249 $linked_ports[$new_be_port_a] = True;
250 $linked_ports[$new_be_port_b] = True;
251 }
252 }
253 }
254 }
255 }
256 // Copy attributes
257 foreach (getAttrValues ($source_object_id) as $record)
258 {
259 $value = $record['value'];
260 switch ($record['type'])
261 {
262 case 'uint':
263 case 'float':
264 case 'string':
265 $value = $record['value'];
266 break;
267 case 'dict':
268 $value = $record['key'];
269 break;
270 default:
271 }
272
273 if (permitted (NULL, NULL, NULL, array (array ('tag' => '$attr_' . $record['id'] ))))
274 if (empty($value))
275 commitUpdateAttrValue ($object_id, $record['id'] );
276 else
277 commitUpdateAttrValue ($object_id, $record['id'], $value ) ;
278 else
279 showError ('Permission denied, "' . $record['name'] . '" can not be set');
280
281 }
282
283 //$log = mergeLogs ($log, oneLiner (5, array ('<a href="' .
284 // makeHref (array ('page' => 'object', 'tab' => 'default', 'object_id' => $object_id)) .
285 // '">' . $info['dname'] . '</a>'))
286 //);
287 showSuccess (sprintf ("Copied Object %s ; new Object: %s", $source_object['name'] , formatPortLink($object_id, $info['dname'], 1, '', '')) );
288 }
289 catch (RTDatabaseError $e)
290 {
291 error_log("rolling back DB");
292 $dbrollback = 1;
293 $dbxlink->rollBack();
294 $log = mergeLogs ($log, oneLiner (147, array ($object_name)));
295 throw new RTDatabaseError ( $e->getMessage() . sprintf(' (%s)', $name_or_csv ));
296 }
297 }
298 if (! $dbrollback )
299 $dbxlink->commit();
300 // return buildWideRedirectURL ($log);
301 }
302
303 //MOD
304 //MOD
305 //MOD
306 function renderCopyEntityTagsPortlet ($title, $tags, $preselect, $realm)
307 {
308 startPortlet ($title);
309 echo '<a class="toggleTreeMode" style="display:none" href="#"></a>';
310 echo '<table border=0 cellspacing=0 cellpadding=1 align=center class="tagtree">';
311 printTagCheckboxTable ('taglist', $preselect, array(), $tags, $realm);
312 echo '<tr><td class=tdleft>';
313 //echo "</form></td><td class=tdright>";
314 echo '</td></tr></table>';
315 finishPortlet();
316 }
317
318 function renderCopyEntityTags ($entity_id)
319 {
320 global $taglist, $target_given_tags, $pageno, $etype_by_pageno;
321 echo '<table border=0 width="10%"><tr>';
322
323 if (count ($taglist) > getConfigVar ('TAGS_QUICKLIST_THRESHOLD'))
324 {
325 $minilist = getTagChart (getConfigVar ('TAGS_QUICKLIST_SIZE'), $etype_by_pageno[$pageno], $target_given_tags);
326 // It could happen, that none of existing tags have been used in the current realm.
327 if (count ($minilist))
328 {
329 $js_code = "tag_cb.setTagShortList ({";
330 $is_first = TRUE;
331 foreach ($minilist as $tag)
332 {
333 if (! $is_first)
334 $js_code .= ",";
335 $is_first = FALSE;
336 $js_code .= "\n\t${tag['id']} : 1";
337 }
338 $js_code .= "\n});\n$(document).ready(tag_cb.compactTreeMode);";
339 addJS ('js/tag-cb.js');
340 addJS ($js_code, TRUE);
341 }
342 }
343
344 // do not do anything about empty tree, trigger function ought to work this out
345 echo '<td class=pcright>';
346 renderCopyEntityTagsPortlet ('', getTagTree(), $target_given_tags, $etype_by_pageno[$pageno]);
347 echo '</td>';
348
349 echo '</tr></table>';
350 }
351 function mergeLogs ($log1, $log2)
352 {
353 $ret = emptyLog();
354 $ret['m'] = array_merge ($log1['m'], $log2['m']);
355 return $ret;
356 }
357
358
359
360 function emptyLog ()
361 {
362 return array
363 (
364 'v' => 2,
365 'm' => array()
366 );
367 }
368 function oneLiner ($code, $args = array())
369 {
370 $ret = emptyLog();
371 $ret['m'][] = count ($args) ? array ('c' => $code, 'a' => $args) : array ('c' => $code);
372 return $ret;
373 }