New version 0.4.0 of the reports plugin
[racktables-contribs] / reports / reports / plugin.php
1 <?php
2 // Custom Racktables Report v.0.4.1
3 // List a type of objects in a table and allow to export them via CSV
4
5 // 2016-02-04 - Mogilowski Sebastian <sebastian@mogilowski.net>
6 // 2018-09-10 - Lars Vogdt <lars@linux-schulserver.de>
7
8
9 require_once "reportExtensionLib.php";
10 require_once "custom-report.php";
11
12 function plugin_reports_info ()
13 {
14 return array
15 (
16 'name' => 'reports',
17 'longname' => 'Custom Reports',
18 'version' => '0.4.1',
19 'home_url' => 'https://github.com/lrupp/racktables-reports'
20 );
21 }
22
23 function plugin_reports_init ()
24 {
25 global $page, $tab;
26 $tab['reports']['custom'] = 'Custom';
27 $tab['reports']['server'] = 'Server';
28 $tab['reports']['switches'] = 'Switches';
29 $tab['reports']['vm'] = 'Virtual Machines';
30
31 $tabhandler['reports']['custom'] = 'renderCustomReport';
32 $tabhandler['reports']['server'] = 'renderServerReport';
33 $tabhandler['reports']['switches'] = 'renderSwitchReport';
34 $tabhandler['reports']['vm'] = 'renderVMReport';
35
36 registerTabHandler('reports', 'custom', 'renderCustomReport');
37 registerTabHandler('reports', 'server', 'renderServerReport');
38 registerTabHandler('reports', 'switches', 'renderSwitchReport');
39 registerTabHandler('reports', 'vm', 'renderVMReport');
40 }
41
42 function plugin_reports_install ()
43 {
44 addConfigVar('REPORTS_CSS_PATH', 'css/report', 'string', 'yes', 'no', 'no', 'Path to the CSS files of the Custom Reports plugin');
45 addConfigVar('REPORTS_JS_PATH', 'js/report', 'string', 'yes', 'no', 'no', 'Path to the Javascript files of the Custom Reports plugin');
46 addConfigVar('REPORTS_SHOW_MAC_FOR_SWITCHES', 'yes', 'string', 'no', 'no', 'yes', 'Show MAC addresses in Custom Switch Report' );
47 return TRUE;
48 }
49
50 function plugin_reports_uninstall ()
51 {
52 deleteConfigVar('REPORTS_CSS_PATH');
53 deleteConfigVar('REPORTS_JS_PATH');
54 deleteConfigVar('REPORTS_SHOW_MAC_FOR_SWITCHES');
55 return TRUE;
56 }
57
58 function plugin_reports_upgrade ()
59 {
60 return TRUE;
61 }
62
63 function renderServerReport()
64 {
65 $filter='{$typeid_4}'; # typeid_4 = Server
66 renderReport($filter);
67 }
68
69 function renderSwitchReport()
70 {
71 $filter='{$typeid_8}'; # typeid_8 = Switches
72 renderReport($filter);
73 }
74
75 function renderVMReport()
76 {
77 $filter='{$typeid_1504}'; # typeid_1504 = Virtual machines
78 renderReport($filter);
79 }
80
81
82 function renderReport($sFilter)
83 {
84 $aResult = array();
85 $iTotal = 0;
86
87 foreach (scanRealmByText ('object', $sFilter) as $Result)
88 {
89
90 $aResult[$Result['id']] = array();
91 $aResult[$Result['id']]['sName'] = $Result['name'];
92
93 // Asset Number
94 $aResult[$Result['id']]['sAsset'] = $Result['asset_no'];
95
96 // Load additional attributes:
97 $attributes = getAttrValues ($Result['id']);
98
99 // Contact information
100 $aResult[$Result['id']]['sContact'] = '';
101 if ( isset( $attributes['14']['a_value'] ) )
102 $aResult[$Result['id']]['sContact'] = $attributes['14']['a_value'];
103
104 // Create active links in comment
105 $aResult[$Result['id']]['sComment'] = $Result['comment'];
106
107 // Hardware Type
108 $aResult[$Result['id']]['HWtype'] = '';
109 if ( isset( $attributes['2']['a_value'] ) )
110 $aResult[$Result['id']]['HWtype'] = $attributes['2']['a_value'];
111
112 // OEM S/N
113 $aResult[$Result['id']]['OEMSN'] = '';
114 if ( isset( $attributes['1']['a_value'] ) )
115 $aResult[$Result['id']]['OEMSN'] = $attributes['1']['a_value'];
116
117 // HW Expire Date
118 $aResult[$Result['id']]['HWExpDate'] = '';
119 if ( isset( $attributes['22']['value'] ) )
120 $aResult[$Result['id']]['HWExpDate'] = date("Y-m-d",$attributes['22']['value']);
121
122 // Operating System (OS)
123 $aResult[$Result['id']]['sOS'] = '';
124 if ( isset( $attributes['4']['a_value'] ) )
125 $aResult[$Result['id']]['sOS'] = $attributes['4']['a_value'];
126
127 // OS Version (for Switches)
128 $aResult[$Result['id']]['sOSVersion'] = '';
129 if ( isset( $attributes['5']['a_value'] ) )
130 $aResult[$Result['id']]['sOSVersion'] = $attributes['5']['a_value'];
131
132
133 $aResult[$Result['id']]['sSlotNumber'] = 'unknown';
134 if ( isset( $attributes['28']['a_value'] ) && ( $attributes['28']['a_value'] != '' ) )
135 $aResult[$Result['id']]['sSlotNumber'] = $attributes['28']['a_value'];
136
137 // Location
138 $aResult[$Result['id']]['sLocation'] = getLocation($Result);
139
140 // IP Informations
141 $aResult[$Result['id']]['ipV4List'] = getObjectIPv4AllocationList($Result['id']);
142 $aResult[$Result['id']]['ipV6List'] = getObjectIPv6AllocationList($Result['id']);
143
144 // Port (MAC) Informations
145 $aResult[$Result['id']]['ports'] = getObjectPortsAndLinks($Result['id']);
146
147 // Container
148 $aResult[$Result['id']]['container'] = getObjectContainerList($Result['id']);
149
150 $iTotal++;
151 }
152
153 // define standard fields for all filters
154 $aCSVRow = array('Name','MAC(s)','IP(s)','Comment','Contact');
155 $title = 'Unnamed report';
156 // add specific fields depending on filter value
157 switch($sFilter)
158 {
159 case '{$typeid_4}': $title = 'Server report';
160 $report_type = 'server';
161 array_push($aCSVRow, 'Type','Asset No.','Location','OEM S/N','HW Expire Date','OS');
162 break;
163 case '{$typeid_8}': $title = 'Switch report';
164 $report_type = 'switches';
165 array_push($aCSVRow, 'Type','Asset No.','Location','OEM S/N','HW Expire Date','OS Version');
166 break;
167 case '{$typeid_1504}': $title = 'Virtual machines report';
168 $report_type = 'vm';
169 array_push($aCSVRow, 'OS','Hypervisor');
170 break;
171 default: echo '<h2>Unknown/No valid filter definition found</h2>';
172 break;
173 }
174
175 if ( isset($_GET['csv']) ) {
176
177 header('Content-type: text/csv');
178 header('Content-Disposition: attachment; filename=export_'.$report_type.'_'.date("Ymdhis").'.csv');
179 header('Pragma: no-cache');
180 header('Expires: 0');
181
182 $outstream = fopen("php://output", "w");
183
184 fputcsv( $outstream, $aCSVRow );
185
186 foreach ($aResult as $id => $aRow)
187 {
188 // 0 1 2 3 4 5 6 7 8 9 10
189 // Server: 'Name','MAC','IP(s)','Comment','Contact', 'Type','Asset No.','Location','OEM','HW Expire Date','OS'
190 // Switch: 'Name','MAC','IP(s)','Comment','Contact', 'Type','Asset No.','Location','OEM','HW Expire Date','OS Version'
191 // VM : 'Name','MAC','IP(s)','Comment','Contact', 'OS', 'Hypervisor'
192
193 $aCSVRow = array();
194 // Name
195 $aCSVRow[0] = $aRow['sName'];
196
197 // MAC
198 $aCSVRow[1] = '';
199 foreach ( $aRow['ports'] as $portNumber => $aPortDetails ) {
200 if (trim($aPortDetails['l2address']) != '')
201 $aCSVRow[1] .= $aPortDetails['l2address'] . ' ';
202 }
203 $aCSVRow[1] = trim($aCSVRow[1]);
204
205 // IP(s)
206 $aCSVRow[2] = '';
207 foreach ( $aRow['ipV4List'] as $key => $aDetails ) {
208 if ( function_exists('ip4_format') )
209 $key = ip4_format($key);
210 if ( trim($key) != '')
211 $aCSVRow[2] .= $key . ' ';
212 }
213 foreach ( $aRow['ipV6List'] as $key => $aDetails ) {
214 if ( function_exists('ip6_format') )
215 $key = ip6_format($key);
216 if ( trim($key) != '')
217 $aCSVRow[2] .= $key . ' ';
218 }
219 $aCSVRow[2] = trim($aCSVRow[2]);
220
221 // Comment
222 $aCSVRow[3] = str_replace('&quot;',"'",$aRow['sComment']);
223
224 // Contact
225 $aCSVRow[4] = $aRow['sContact'];
226
227 switch($sFilter)
228 {
229 case '{$typeid_4}':
230 case '{$typeid_8}':
231 // Type
232 $aCSVRow[5] = $aRow['HWtype'];
233 // Asset No
234 $aCSVRow[6] = $aRow['sAsset'];
235 // Location
236 $aCSVRow[7] = preg_replace('/<a[^>]*>(.*)<\/a>/iU', '$1', $aRow['sLocation']);
237 // OEM S/N
238 $aCSVRow[8] = $aRow['OEMSN'];
239 // HW Expire Date
240 $aCSVRow[9] = $aRow['HWExpDate'];
241 break;
242 case '{$typeid_1504}':
243 // OS
244 $aCSVRow[5] = $aRow['sOS'];
245 // Container
246 $aCSVRow[6] = '';
247 foreach ( $aRow['container'] as $key => $aDetails ) {
248 $aCSVRow[6] .= trim($aDetails['container_name']).' ';
249 }
250 break;
251 }
252 switch($sFilter)
253 {
254 case '{$typeid_4}': // OS
255 $aCSVRow[10] = $aRow['sOS'];
256 break;
257 case '{$typeid_8}': // OS Version
258 $aCSVRow[10] = $aRow['sOSVersion'];
259 break;
260 }
261
262 fputcsv( $outstream, $aCSVRow );
263 }
264
265 fclose($outstream);
266
267 exit(0); # Exit normally after send CSV to browser
268
269 }
270
271 // Load stylesheet and jquery sicripts
272 $css_path=getConfigVar('REPORTS_CSS_PATH');
273 $js_path=getConfigVar('REPORTS_JS_PATH');
274 addCSS ("$css_path/style.css");
275 addJS ("$js_path/jquery-latest.js");
276 addJS ("$js_path/jquery.tablesorter.js");
277 addJS ("$js_path/picnet.table.filter.min.js");
278
279 // Display the stat array
280 echo "\n<h2>$title (".$iTotal.")</h2><ul>";
281 echo "<a href='index.php?page=reports&tab=$report_type&csv'>CSV Export</a>\n";
282 echo "<table id=\"reportTable\" class=\"tablesorter\">\n <thead>\n <tr>\n";
283 foreach ($aCSVRow as $row)
284 {
285 echo " <th>$row</th>\n";
286 }
287 echo " </tr>\n </thead>\n<tbody>\n";
288
289 foreach ($aResult as $id => $aRow)
290 {
291 // 0 1 2 3 4 5 6 7 8 9 10
292 // Server: 'Name','MAC','IP(s)','Comment','Contact', 'Type','Asset No.','Location','OEM','HW Expire Date','OS'
293 // Switch: 'Name','MAC','IP(s)','Comment','Contact', 'Type','Asset No.','Location','OEM','HW Expire Date','OS Version'
294 // VM : 'Name','MAC','IP(s)','Comment','Contact', 'OS', 'Hypervisor'
295 //
296 // Name
297 echo "<tr>\n <td><a href=\"". makeHref ( array( 'page' => 'object', 'object_id' => $id) ) ."\">".$aRow['sName']."</a></td>\n <td>";
298 // MAC
299 if (getConfigVar ('REPORTS_SHOW_MAC_FOR_SWITCHES') == 'yes')
300 {
301 foreach ( $aRow['ports'] as $portNumber => $aPortDetails ) {
302 if (trim($aPortDetails['l2address']) != '')
303 echo $aPortDetails['l2address'] . "<br/>\n";
304 }
305 }
306 echo " </td>\n <td>";
307
308 // IP(s)
309 foreach ( $aRow['ipV4List'] as $key => $aDetails ) {
310 if ( function_exists('ip4_format') )
311 $key = ip4_format($key);
312 if ( trim($key) != '')
313 echo $key . "<br/>\n";
314 }
315
316 foreach ( $aRow['ipV6List'] as $key => $aDetails ) {
317 if ( function_exists('ip6_format') )
318 $key = ip6_format($key);
319 if ( trim($key) != '')
320 echo $key . "<br/>\n";
321 }
322
323 // Comment & Contact
324 echo " </td>\n <td>".makeLinksInText($aRow['sComment'])." </td>\n";
325 echo ' <td>'.makeLinksInText($aRow['sContact'])." </td>\n";
326
327 switch($sFilter)
328 {
329 case '{$typeid_4}':
330 case '{$typeid_8}':
331 // Type
332 echo ' <td>'.$aRow['HWtype']."</td>\n";
333 // Asset No
334 echo ' <td>'.$aRow['sAsset']."</td>\n";
335 // Location
336 echo ' <td>'.$aRow['sLocation']."</td>\n";
337 // OEM S/N
338 echo ' <td>'.$aRow['OEMSN']."</td>\n";
339 // HW Expire Date
340 echo ' <td>'.$aRow['HWExpDate']."</td>\n";
341 break;
342 case '{$typeid_1504}':
343 // OS
344 echo ' <td>'.$aRow['sOS']."</td>\n";
345 // Container
346 echo ' <td>';
347 foreach ( $aRow['container'] as $key => $aDetails ) {
348 echo trim($aDetails['container_name'])."<br/>\n";
349 }
350 echo " </td>\n";
351 break;
352 }
353 switch($sFilter)
354 {
355 case '{$typeid_4}': // OS
356 echo ' <td>'.$aRow['sOS']."</td>\n";
357 break;
358 case '{$typeid_8}': // OS Version
359 echo ' <td>'.$aRow['sOSVersion']."</td>\n";
360 break;
361 }
362 echo " </tr>\n";
363 }
364
365 echo " </tbody>\n</table>\n";
366
367 echo '<script type="text/javascript">
368 $(document).ready(function()
369 {
370 $.tablesorter.defaults.widgets = ["zebra"];
371 $("#reportTable").tablesorter(
372 { headers: {
373 2: { sorter: "ipAddress" },
374 }, sortList: [[0,0]] }
375 )
376 $("#reportTable").tableFilter();
377 });
378 </script>';
379 }
380
381 ?>