1#!/usr/bin/env perl 2############################################################################## 3# RackMonkey - Know Your Racks - http://www.rackmonkey.org # 4# Version 1.2.5-1 # 5# (C)2004-2009 Will Green (wgreen at users.sourceforge.net) # 6# Main RackMonkey CGI script # 7############################################################################## 8 9# This program is free software; you can redistribute it and/or modify it 10# under the terms of the GNU General Public License as published by the Free 11# Software Foundation; either version 2 of the License, or (at your option) 12# any later version. 13 14# This program is distributed in the hope that it will be useful, but WITHOUT 15# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17# more details. 18 19# You should have received a copy of the GNU General Public License along 20# with this program; if not, write to the Free Software Foundation, Inc., 21# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 22 23use strict; 24use warnings; 25 26use 5.006_001; 27 28use HTML::Template; 29use HTML::Entities; 30use Time::Local; 31use FindBin; 32use lib "$FindBin::Bin/"; 33 34use RackMonkey::CGI; 35use RackMonkey::Engine; 36use RackMonkey::Error; 37 38our $VERSION = '1.2.5-1'; 39our $AUTHOR = 'Will Green (wgreen at users.sourceforge.net)'; 40 41our ($template, $cgi, $conf, $backend); 42 43$cgi = new RackMonkey::CGI; 44 45eval { 46 $backend = RackMonkey::Engine->new; 47 $conf = $backend->getConfHash; 48 49 my $fullURL = $cgi->url; 50 my $baseURL = $cgi->baseUrl; 51 my $view = $cgi->view($$conf{'defaultview'}); 52 my $id = $cgi->viewId; 53 my $viewType = $cgi->viewType; 54 my $act = $cgi->act; 55 my $filterBy = $cgi->filterBy; 56 my $deviceSearch = $cgi->deviceSearch; 57 58 my $orderBy = $cgi->orderBy; 59 60 my $loggedInUser = $ENV{'REMOTE_USER'} || $ENV{'REMOTE_ADDR'}; 61 62 if ($act) # perform act, and return status: 303 (See Other) to redirect to a view 63 { 64 die "RMERR: You are logged in as 'guest'. Guest users can't update RackMonkey." if (lc($loggedInUser) eq 'guest'); 65 66 my $actData = $cgi->vars; 67 68 # Trim whitespace from the start and end of all submitted values 69 for (values %$actData) 70 { 71 s/^\s+//; 72 s/\s+$//; 73 } 74 75 # delete id, only act_ids should be used be used for acts, ids are used for views 76 delete $$actData{'id'}; 77 78 # convert act_id into a normal id for use by the engine 79 if ($$actData{'act_id'}) 80 { 81 $$actData{'id'} = $$actData{'act_id'}; 82 delete $$actData{'act_id'}; 83 } 84 85 my $lastCreatedId = $backend->performAct($cgi->actOn, $act, $loggedInUser, scalar($cgi->vars)); 86 $id = $lastCreatedId if (!$id); # use lastCreatedId if there isn't an id 87 my $redirectUrl = "$fullURL?view=$view&view_type=$viewType"; 88 $redirectUrl .= "&id=$id" if ($id); 89 $redirectUrl .= "&last_created_id=$lastCreatedId"; 90 $redirectUrl .= "&device_search=$deviceSearch" if ($deviceSearch); 91 92 $cgi->redirect303($redirectUrl); 93 } 94 else # display a view 95 { 96 unless ($view =~ /^(?:config|help|app|building|device|deviceApp|domain|hardware|network|power|org|os|rack|report|role|room|row|service|system)$/) 97 { 98 die "RMERR: '$view' is not a valid view. Did you type the URL manually? Note that view names are singular, for example device NOT devices."; 99 } 100 101 if ($view eq 'system') # check for this view first: it doesn't use templates 102 { 103 print $cgi->header('text/plain'); 104 my %sys = %{$backend->{'sys'}}; 105 print map "$_: $sys{$_}\n", sort keys %sys; 106 exit; 107 } 108 109 my $templatePath = $$conf{'tmplpath'} . "/${view}_${viewType}.tmpl"; 110 $template = HTML::Template->new('filename' => $templatePath, 'die_on_bad_params' => 0, 'global_vars' => 1, 'case_sensitive' => 1, 'loop_context_vars' => 1); 111 112 if (($view eq 'config') || ($view eq 'help') || ($view eq 'network') || ($view eq 'power')) 113 { 114 # do nothing - pages are static content 115 } 116 elsif ($view eq 'app') 117 { 118 if ($viewType =~ /^default/) 119 { 120 my $apps = $backend->appList($orderBy); 121 for my $a (@$apps) 122 { 123 $$a{'descript_short'} = shortStr($$a{'descript'}); 124 $$a{'notes'} = formatNotes($$a{'notes'}, 1); 125 $$a{'notes_short'} = shortStr($$a{'notes'}); 126 } 127 my $totalAppCount = $backend->itemCount('app'); 128 my $listedAppCount = @$apps; 129 $template->param('total_app_count' => $totalAppCount); 130 $template->param('listed_app_count' => $listedAppCount); 131 $template->param('all_apps_listed' => ($totalAppCount == $listedAppCount)); 132 $template->param('apps' => $apps); 133 } 134 elsif (($viewType =~ /^edit/) || ($viewType =~ /^single/)) 135 { 136 my $app = $backend->app($id); 137 138 if ($viewType =~ /^single/) 139 { 140 $$app{'notes'} = formatNotes($$app{'notes'}); 141 } 142 143 my $devices = $backend->appDevicesUsedList($id); 144 $$app{'app_devices'} = $devices; 145 $template->param($app); 146 } 147 } 148 elsif ($view eq 'building') 149 { 150 if ($viewType =~ /^default/) 151 { 152 my $buildings = $backend->buildingList($orderBy); 153 for my $b (@$buildings) 154 { 155 $$b{'notes'} = formatNotes($$b{'notes'}, 1); 156 $$b{'notes_short'} = shortStr($$b{'notes'}); 157 } 158 my $totalBuildingCount = $backend->itemCount('building'); 159 my $listedBuildingCount = @$buildings; 160 $template->param('total_building_count' => $totalBuildingCount); 161 $template->param('listed_building_count' => $listedBuildingCount); 162 $template->param('all_buildings_listed' => ($totalBuildingCount == $listedBuildingCount)); 163 $template->param('buildings' => $buildings); 164 } 165 elsif (($viewType =~ /^edit/) || ($viewType =~ /^single/)) 166 { 167 my $building = $backend->building($id); 168 if ($viewType =~ /^single/) 169 { 170 $$building{'rooms'} = $backend->roomListInBuilding($id); 171 $$building{'notes'} = formatNotes($$building{'notes'}); 172 } 173 $template->param($building); 174 } 175 } 176 elsif ($view eq 'device') 177 { 178 if ($viewType =~ /^default/) 179 { 180 my $devices; 181 182 if ($viewType =~ /^default_unracked/) 183 { 184 $devices = $backend->deviceListUnracked($orderBy, $filterBy, $deviceSearch); 185 } 186 else 187 { 188 $devices = $backend->deviceList($orderBy, $filterBy, $deviceSearch); 189 } 190 191 my $filterBy = $cgi->filterBy; 192 193 my $customers = $backend->customerWithDevice; 194 unshift @$customers, {'id' => '', name => 'All'}; 195 $template->param('customerlist' => $cgi->selectItem($customers, $$filterBy{'device.customer'})); 196 197 my $roles = $backend->roleWithDevice; 198 unshift @$roles, {'id' => '', name => 'All'}; 199 $template->param('rolelist' => $cgi->selectItem($roles, $$filterBy{'device.role'})); 200 201 my $hardware = $backend->hardwareWithDevice; 202 unshift @$hardware, {'id' => '', name => 'All'}; 203 $template->param('hardwarelist' => $cgi->selectItem($hardware, $$filterBy{'device.hardware'})); 204 205 my $os = $backend->osWithDevice; 206 unshift @$os, {'id' => '', name => 'All'}; 207 $template->param('oslist' => $cgi->selectItem($os, $$filterBy{'device.os'})); 208 209 for my $d (@$devices) 210 { 211 $$d{'age'} = calculateAge($$d{'purchased'}); # determine age in years from purchased date 212 $$d{'notes'} = formatNotes($$d{'notes'}, 1); 213 $$d{'notes_short'} = shortStr($$d{'notes'}); 214 } 215 216 $template->param('device_search' => $deviceSearch); 217 $template->param('devices' => $devices); 218 219 my $totalDeviceCount = $backend->itemCount('device'); 220 my $listedDeviceCount = @$devices; 221 $template->param('total_device_count' => $totalDeviceCount); 222 $template->param('listed_device_count' => $listedDeviceCount); 223 $template->param('all_devices_listed' => ($totalDeviceCount == $listedDeviceCount)); 224 } 225 else 226 { 227 my $selectedManufacturer = $cgi->lastCreatedId; 228 my $selectedHardwareModel = $cgi->lastCreatedId; 229 my $selectedOs = $cgi->lastCreatedId; 230 my $selectedRole = $cgi->lastCreatedId; 231 my $selectedCustomer = $cgi->lastCreatedId; 232 my $selectedService = $cgi->lastCreatedId; 233 my $selectedRack = $cgi->selectProperty('rack') || $cgi->lastCreatedId; 234 my $selectedDomain = $cgi->lastCreatedId; 235 236 if (($viewType =~ /^edit/) || ($viewType =~ /^single/) || ($viewType =~ /^create/)) 237 { 238 my $device = {}; 239 240 if ($id) 241 { 242 $device = $backend->device($id); 243 $$device{'age'} = calculateAge($$device{'purchased'}); 244 $$device{'apps'} = $backend->appOnDeviceList($id); 245 } 246 247 if ($viewType =~ /^single/) 248 { 249 $$device{'notes'} = formatNotes($$device{'notes'}); 250 251 if (lc($$device{'hardware_manufacturer_name'}) =~ /dell/) # not very extensible 252 { 253 $template->param('dell_query' => $$conf{'dellquery'}); 254 } 255 } 256 257 if ($viewType !~ /^single/) 258 { 259 # Use database value for selected if none in CGI 260 $selectedManufacturer = $$device{'hardware_manufacturer_id'} if (!$selectedManufacturer); 261 $selectedHardwareModel = $$device{'hardware'} if (!$selectedHardwareModel); 262 $selectedOs = $$device{'os'} if (!$selectedOs); 263 $selectedRole = $$device{'role'} if (!$selectedRole); 264 $selectedCustomer = $$device{'customer'} if (!$selectedCustomer); 265 $selectedService = $$device{'service'} if (!$selectedService); 266 $selectedRack = $$device{'rack'} if (!$selectedRack); 267 $selectedDomain = $$device{'domain'} if (!$selectedDomain); 268 } 269 270 # clear values unique to a device if we're copying an existing device 271 if ($viewType =~ /^create/) 272 { 273 $$device{'name'} = ''; 274 $$device{'rack_pos'} = ''; 275 $$device{'asset_no'} = ''; 276 $$device{'serial_no'} = ''; 277 $$device{'in_service'} = 1; # default is in service 278 $$device{'notes'} = ''; 279 $$device{'os_licence_key'} = ''; 280 } 281 282 $template->param($device); 283 } 284 if (($viewType =~ /^edit/) || ($viewType =~ /^create/)) 285 { 286 $template->param('selected_manufacturer' => $selectedManufacturer); 287 $template->param('selected_hardware_model' => $selectedHardwareModel); 288 # manufacturerlist: run selectItem to prefix - on meta_default items, should be separate sub from selectItem 289 $template->param('manufacturerlist' => $cgi->selectItem($backend->manufacturerWithHardwareList, 0)); 290 $template->param('modelList' => $backend->hardwareByManufacturer); # Todo: Need to add '-' prefix to meta default items 291 $template->param('oslist' => $cgi->selectItem($backend->simpleList('os', 1), $selectedOs)); 292 $template->param('rolelist' => $cgi->selectItem($backend->simpleList('role', 1), $selectedRole)); 293 $template->param('customerlist' => $cgi->selectItem($backend->simpleList('customer', 1), $selectedCustomer)); 294 $template->param('servicelist' => $cgi->selectItem($backend->simpleList('service', 1), $selectedService)); 295 $template->param('racklist' => $cgi->selectRack($backend->rackListBasic, $selectedRack)); 296 $template->param('domainlist' => $cgi->selectItem($backend->simpleList('domain', 1), $selectedDomain)); 297 $template->param('rack_pos' => $cgi->selectProperty('position')); 298 } 299 } 300 } 301 elsif ($view eq 'deviceApp') 302 { 303 if ($viewType =~ /^create/) 304 { 305 my $app = $backend->app($id); 306 $template->param($app); 307 308 my $devices = $backend->deviceList; 309 $template->param('devices' => $devices); 310 311 my $relations = $backend->simpleList('app_relation', 1); 312 $template->param('relations' => $relations); 313 } 314 } 315 elsif ($view eq 'domain') 316 { 317 if ($viewType =~ /^default/) 318 { 319 my $domains = $backend->domainList($orderBy); 320 for my $d (@$domains) 321 { 322 $$d{'notes'} = formatNotes($$d{'notes'}, 1); 323 $$d{'notes_short'} = shortStr($$d{'notes'}); 324 $$d{'descript_short'} = shortStr($$d{'descript'}); 325 } 326 my $totalDomainCount = $backend->itemCount('domain'); 327 my $listedDomainCount = @$domains; 328 $template->param('total_domain_count' => $totalDomainCount); 329 $template->param('listed_domain_count' => $listedDomainCount); 330 $template->param('all_domains_listed' => ($totalDomainCount == $listedDomainCount)); 331 $template->param('domains' => $domains); 332 } 333 elsif (($viewType =~ /^edit/) || ($viewType =~ /^single/)) 334 { 335 my $domain = $backend->domain($id); 336 if ($viewType =~ /^single/) 337 { 338 $$domain{'notes'} = formatNotes($$domain{'notes'}); 339 } 340 $template->param($domain); 341 } 342 } 343 elsif ($view eq 'hardware') 344 { 345 if ($viewType =~ /^default/) 346 { 347 my $hardware = $backend->hardwareList($orderBy); 348 for my $h (@$hardware) 349 { 350 $$h{'notes'} = formatNotes($$h{'notes'}, 1); 351 $$h{'notes_short'} = shortStr($$h{'notes'}); 352 } 353 my $totalHardwareCount = $backend->itemCount('hardware'); 354 my $listedHardwareCount = @$hardware; 355 $template->param('total_hardware_count' => $totalHardwareCount); 356 $template->param('listed_hardware_count' => $listedHardwareCount); 357 $template->param('all_hardware_listed' => ($totalHardwareCount == $listedHardwareCount)); 358 $template->param('hardware' => $hardware); 359 } 360 else 361 { 362 my $selectedManufacturer = $cgi->lastCreatedId; # need to sort out this mess of CGI vars and make clearer! 363 364 if (($viewType =~ /^edit/) || ($viewType =~ /^single/)) 365 { 366 my $hardware = $backend->hardware($id); 367 if ($viewType =~ /^single/) 368 { 369 $$hardware{'notes'} = formatNotes($$hardware{'notes'}); 370 } 371 $selectedManufacturer = $$hardware{'manufacturer'} if (!$selectedManufacturer); # Use database value for selected if none in CGI 372 $$hardware{'support_url_short'} = shortURL($$hardware{'support_url'}); # not actually needed by edit view 373 $$hardware{'spec_url_short'} = shortURL($$hardware{'spec_url'}); # not actually needed by edit view 374 $template->param($hardware); 375 } 376 377 if (($viewType =~ /^edit/) || ($viewType =~ /^create/)) 378 { 379 $template->param('manufacturerlist' => $cgi->selectItem($backend->simpleList('hardware_manufacturer', 1), $selectedManufacturer)); 380 } 381 } 382 } 383 elsif ($view eq 'org') 384 { 385 if ($viewType =~ /^default/) 386 { 387 my $orgs = $backend->orgList($orderBy); 388 389 my $totalOrgCount = $backend->itemCount('org'); 390 my $listedOrgCount = @$orgs; 391 $template->param('total_org_count' => $totalOrgCount); 392 $template->param('listed_org_count' => $listedOrgCount); 393 $template->param('all_org_listed' => ($totalOrgCount == $listedOrgCount)); 394 395 for my $o (@$orgs) 396 { 397 $$o{'notes'} = formatNotes($$o{'notes'}, 1); 398 $$o{'notes_short'} = shortStr($$o{'notes'}); 399 $$o{'descript_short'} = shortStr($$o{'descript'}); 400 } 401 $template->param('orgs' => $orgs); 402 } 403 elsif (($viewType =~ /^edit/) || ($viewType =~ /^single/)) 404 { 405 my $org = $backend->org($id); 406 if ($viewType =~ /^single/) 407 { 408 $$org{'notes'} = formatNotes($$org{'notes'}); 409 } 410 $template->param($org); 411 } 412 elsif ($viewType =~ /^create/) 413 { 414 $template->param({'customer' => $cgi->customer, 'software' => $cgi->software, 'hardware' => $cgi->hardware}); 415 } 416 } 417 elsif ($view eq 'os') 418 { 419 if ($viewType =~ /^default/) 420 { 421 my $os = $backend->osList($orderBy); 422 for my $o (@$os) 423 { 424 $$o{'notes'} = formatNotes($$o{'notes'}, 1); 425 $$o{'notes_short'} = shortStr($$o{'notes'}); 426 } 427 my $totalOSCount = $backend->itemCount('os'); 428 my $listedOSCount = @$os; 429 $template->param('total_os_count' => $totalOSCount); 430 $template->param('listed_os_count' => $listedOSCount); 431 $template->param('all_os_listed' => ($totalOSCount == $listedOSCount)); 432 $template->param('operatingsystems' => $os); 433 } 434 else 435 { 436 my $selectedManufacturer = $cgi->lastCreatedId; 437 438 if (($viewType =~ /^edit/) || ($viewType =~ /^single/)) 439 { 440 my $operatingSystem = $backend->os($id); 441 if ($viewType =~ /^single/) 442 { 443 $$operatingSystem{'notes'} = formatNotes($$operatingSystem{'notes'}); 444 } 445 $template->param($operatingSystem); 446 $selectedManufacturer = $$operatingSystem{'manufacturer'} if (!$selectedManufacturer); # Use database value for selected if none in CGI 447 } 448 449 if (($viewType =~ /^edit/) || ($viewType =~ /^create/)) 450 { 451 $template->param('manufacturerlist' => $cgi->selectItem($backend->simpleList('software_manufacturer', 1), $selectedManufacturer)); 452 } 453 } 454 } 455 elsif ($view eq 'rack') 456 { 457 if ($viewType =~ /^default/) 458 { 459 my $racks = $backend->rackList($orderBy); 460 for my $r (@$racks) 461 { 462 $$r{'notes'} = formatNotes($$r{'notes'}, 1); 463 $$r{'notes_short'} = shortStr($$r{'notes'}); 464 } 465 my $totalRackCount = $backend->itemCount('rack'); 466 my $listedRackCount = @$racks; 467 $template->param('total_rack_count' => $totalRackCount); 468 $template->param('listed_rack_count' => $listedRackCount); 469 $template->param('all_racks_listed' => ($totalRackCount == $listedRackCount)); 470 $template->param('racks' => $racks); 471 } 472 elsif ($viewType =~ /^physical/) 473 { 474 my @rackIdList = $cgi->rackList; 475 push(@rackIdList, $id) if (scalar(@rackIdList) == 0); # add current rack id if no list 476 die "RMERR: You need to select at least one rack to display. Use the checkboxes at the right of the rack table to select racks." 477 unless $rackIdList[0]; 478 my @racks; 479 my $selectDevice = $cgi->id('device'); 480 for my $rackId (@rackIdList) 481 { 482 my $rack = $backend->rack($rackId); 483 $$rack{'rack_layout'} = $backend->rackPhysical($rackId, $selectDevice, 1); 484 push @racks, $rack; 485 } 486 $template->param('rack_list' => \@racks); 487 $template->param('device_id' => $selectDevice); 488 } 489 else 490 { 491 my $selectedRoom = $cgi->lastCreatedId || $cgi->id('room'); 492 493 if (($viewType =~ /^edit/) || ($viewType =~ /^single/) || ($viewType =~ /^create/)) 494 { 495 my $rack = {}; 496 if ($id) # used if copying, editing or displaying single view, but not for a plain create 497 { 498 $rack = $backend->rack($id); 499 } 500 else 501 { 502 $$rack{'numbering_direction'} = $$conf{'number_from_top'}; 503 } 504 505 $selectedRoom = $$rack{'room'} if (!$selectedRoom); # Use database value for selected if none in CGI - not actually needed in single view 506 507 if ($viewType !~ /^single/) 508 { 509 $template->param('roomlist' => $cgi->selectRoom($backend->roomListBasic, $selectedRoom)); 510 } 511 else 512 { 513 $$rack{'notes'} = formatNotes($$rack{'notes'}); 514 } 515 516 # clear rack notes and name if we're creating a new device (so copy works) 517 if ($viewType =~ /^create/) 518 { 519 $$rack{'name'} = ''; 520 $$rack{'notes'} = ''; 521 } 522 523 $template->param($rack); 524 } 525 } 526 } 527 elsif ($view eq 'report') 528 { 529 if ($viewType =~ /^default/) 530 { 531 my $totalDevices = $backend->itemCount('device'); 532 my $unrackedDevices = $backend->deviceCountUnracked; 533 $template->param('device_count' => $totalDevices); 534 $template->param('unracked_device_count' => $unrackedDevices); 535 $template->param('racked_device_count' => $totalDevices - $unrackedDevices); 536 $template->param('rack_count' => $backend->itemCount('rack')); 537 my $rackSize = $backend->totalSizeRack; 538 my $deviceSize = $backend->totalSizeDevice; 539 $template->param('total_rack_space' => $rackSize); 540 $template->param('used_rack_space' => $deviceSize); 541 $template->param('free_rack_space' => $rackSize - $deviceSize); 542 } 543 elsif ($viewType =~ /^counts/) 544 { 545 $template->param('customer_device_count' => $backend->customerDeviceCount); 546 $template->param('role_device_count' => $backend->roleDeviceCount); 547 $template->param('hardware_device_count' => $backend->hardwareDeviceCount); 548 $template->param('os_device_count' => $backend->osDeviceCount); 549 } 550 elsif ($viewType =~ /^duplicates/) 551 { 552 $template->param('serials' => $backend->duplicateSerials); 553 $template->param('assets' => $backend->duplicateAssets); 554 $template->param('oslicence' => $backend->duplicateOSLicenceKey); 555 } 556 } 557 elsif ($view eq 'role') 558 { 559 if ($viewType =~ /^default/) 560 { 561 my $roles = $backend->roleList($orderBy); 562 563 my $totalRoleCount = $backend->itemCount('role'); 564 my $listedRoleCount = @$roles; 565 $template->param('total_role_count' => $totalRoleCount); 566 $template->param('listed_role_count' => $listedRoleCount); 567 $template->param('all_role_listed' => ($totalRoleCount == $listedRoleCount)); 568 569 for my $r (@$roles) 570 { 571 $$r{'notes'} = formatNotes($$r{'notes'}, 1); 572 $$r{'notes_short'} = shortStr($$r{'notes'}); 573 $$r{'descript_short'} = shortStr($$r{'descript'}); 574 } 575 $template->param('roles' => $roles); 576 } 577 elsif (($viewType =~ /^edit/) || ($viewType =~ /^single/)) 578 { 579 my $role = $backend->role($id); 580 if ($viewType =~ /^single/) 581 { 582 $$role{'notes'} = formatNotes($$role{'notes'}); 583 } 584 $template->param($role); 585 } 586 } 587 elsif ($view eq 'room') 588 { 589 if ($viewType =~ /^default/) 590 { 591 my $rooms = $backend->roomList($orderBy); 592 for my $r (@$rooms) 593 { 594 $$r{'notes'} = formatNotes($$r{'notes'}, 1); 595 $$r{'notes_short'} = shortStr($$r{'notes'}); 596 } 597 my $totalRoomCount = $backend->itemCount('room'); 598 my $listedRoomCount = @$rooms; 599 $template->param('total_room_count' => $totalRoomCount); 600 $template->param('listed_room_count' => $listedRoomCount); 601 $template->param('all_rooms_listed' => ($totalRoomCount == $listedRoomCount)); 602 $template->param('rooms' => $rooms); 603 } 604 else 605 { 606 my $selectedBuilding = $cgi->lastCreatedId || $cgi->id('building'); 607 608 if (($viewType =~ /^edit/) || ($viewType =~ /^single/)) 609 { 610 my $room = $backend->room($id); 611 if ($viewType =~ /^single/) 612 { 613 $$room{'notes'} = formatNotes($$room{'notes'}); 614 } 615 $$room{'row_count'} = $backend->rowCountInRoom($id); 616 $selectedBuilding = $$room{'building'} if (!$selectedBuilding); # Use database value for selected if none in CGI - not actually needed in single view 617 if ($viewType =~ /^single/) 618 { 619 $$room{'racks'} = $backend->rackListInRoom($id); # fix method then use 620 } 621 $template->param($room); 622 } 623 624 if (($viewType =~ /^edit/) || ($viewType =~ /^create/)) 625 { 626 $template->param('buildinglist' => $cgi->selectItem($backend->simpleList('building'), $selectedBuilding)); 627 } 628 } 629 } 630 elsif ($view eq 'row') 631 { 632 $template->param('rows' => $backend->rowListInRoom($cgi->id('room'))); 633 $template->param($backend->room($cgi->id('room'))); 634 } 635 elsif ($view eq 'service') 636 { 637 if ($viewType =~ /^default/) 638 { 639 my $serviceLevels = $backend->serviceList($orderBy); 640 641 my $totalServiceCount = $backend->itemCount('service'); 642 my $listedServiceCount = @$serviceLevels; 643 $template->param('total_service_count' => $totalServiceCount); 644 $template->param('listed_service_count' => $listedServiceCount); 645 $template->param('all_service_listed' => ($totalServiceCount == $listedServiceCount)); 646 647 for my $s (@$serviceLevels) 648 { 649 $$s{'notes'} = formatNotes($$s{'notes'}, 1); 650 $$s{'notes_short'} = shortStr($$s{'notes'}); 651 $$s{'descript_short'} = shortStr($$s{'descript'}); 652 } 653 $template->param('services' => $serviceLevels); 654 } 655 elsif (($viewType =~ /^edit/) || ($viewType =~ /^single/)) 656 { 657 my $service = $backend->service($id); 658 if ($viewType =~ /^single/) 659 { 660 $$service{'notes'} = formatNotes($$service{'notes'}); 661 } 662 $template->param($service); 663 } 664 } 665 else 666 { 667 die "RMERR: No such view. This error should not occur. Please report to developers."; 668 } 669 } 670 671 # create rack dropdown 672 my $selectedRack = 0; 673 $selectedRack = $id if (($viewType =~ /^physical/) && ($view eq 'rack')); 674 $template->param('racknavlist' => $cgi->selectRack($backend->rackListBasic(1), $selectedRack)); 675 676 # Get version, date and user for page footer 677 $template->param('version' => "$VERSION"); 678 my ($minute, $hour, $day, $month, $year) = (gmtime)[1, 2, 3, 4, 5]; 679 my $currentDate = sprintf("%04d-%02d-%02d %02d:%02d GMT", $year + 1900, $month + 1, $day, $hour, $minute); 680 $template->param('date' => $currentDate); 681 $template->param('logged_in_user' => $ENV{'REMOTE_USER'}); 682 $template->param('user_ip' => $ENV{'REMOTE_ADDR'}); 683 684 # Make the current view and view_type available in the template 685 $template->param('view' => $cgi->view); 686 $template->param('view_type' => $cgi->viewType); 687 688 # Support overriding the next view of the template 689 $template->param('return_view' => $cgi->returnView || $view); 690 $template->param('return_view_type' => $cgi->returnViewType || ''); 691 $template->param('return_view_id' => $cgi->returnViewId || 0); 692 693 # support hiding and showing of filters 694 $template->param('show_filters' => $cgi->showFilters); 695 $template->param('filter_string' => $cgi->filterString); 696 697 # XLS Plugin 698 if ($$conf{'plugin_xls'}) 699 { 700 my $rack2XLSURL = $baseURL; 701 my $rackXLSName = $$conf{'plugin_xls'}; 702 703 if ($rack2XLSURL =~ /rackmonkey\.pl/) 704 { 705 $rack2XLSURL =~ s/\/(.*?)\.pl/$rackXLSName/; 706 } 707 else 708 { 709 $rack2XLSURL .= $rackXLSName; 710 } 711 $template->param('rack2xls_url' => $rack2XLSURL); 712 } 713 714 # DNS Plugin 715 if ($$conf{'plugin_dns'}) 716 { 717 my $rackDNSURL = $baseURL; 718 my $rackDNSName = $$conf{'plugin_dns'}; 719 720 if ($rackDNSURL =~ /rackmonkey\.pl/) 721 { 722 $rackDNSURL =~ s/\/(.*?)\.pl/$rackDNSName/; 723 } 724 else 725 { 726 $rackDNSURL .= $rackDNSName; 727 } 728 $template->param('rackdns_url' => $rackDNSURL); 729 } 730 731 $template->param('base_url' => $baseURL); 732 $template->param('web_root' => $$conf{'wwwpath'}); 733 $template->param('size_of_u' => $$conf{'size_of_u'}); 734 735 $template->param('order_by' => $orderBy); 736 737 print $cgi->header; 738 print $template->output; 739}; 740if ($@) 741{ 742 my $errMsg = $@; 743 print $cgi->header; 744 my $friendlyErrMsg = RackMonkey::Error::enlighten($errMsg); 745 RackMonkey::Error::display($errMsg, $friendlyErrMsg, $backend->{'sys'}); 746} 747 748sub shortStr 749{ 750 my $str = shift; 751 return unless defined $str; 752 if (length($str) > $$conf{'shorttextlen'}) 753 { 754 return substr($str, 0, $$conf{'shorttextlen'}) . '...'; 755 } 756 return ''; 757} 758 759sub shortURL 760{ 761 my $url = shift; 762 return unless defined $url; 763 if (length($url) > $$conf{'shorturllen'}) 764 { 765 return substr($url, 0, $$conf{'shorturllen'}) . '...'; 766 } 767 return ''; 768} 769 770sub calculateAge 771{ 772 my $date = shift; 773 return unless defined $date; 774 my ($year, $month, $day) = $date =~ /(\d{4})-(\d{2})-(\d{2})/; 775 if ($year) 776 { 777 $month--; # perl months start at 0 778 my $startTime = timelocal(0, 0, 12, $day, $month, $year); 779 my $age = (time - $startTime) / (86400 * 365.24); # Age in years 780 return sprintf("%.1f", $age); 781 } 782 return ''; 783} 784 785sub formatNotes 786{ 787 my $note = shift; 788 my $inline = shift || 0; 789 $note = encode_entities($note); # we don't use HTML::Template escape so have to encode here 790 791 unless ($inline) 792 { 793 $note =~ s/\n/<br>/sg; # turn newlines into break tags 794 $note =~ s/\[(.*?)\|(.*?)\]/<a href="$1">$2<\/a>/sg; # create hyperlinks 795 $note =~ s/\*\*\*(.*?)\*\*\*/<strong>$1<\/strong>/sg; # strong using *** 796 $note =~ s/\*\*(.*?)\*\*/<em>$1<\/em>/sg; # emphasis using ** 797 } 798 else 799 { 800 $note =~ s/\[(.*?)\|(.*?)\]/$2 ($1)/sg; # can't make proper hyperlinks inline as they may be truncated 801 $note =~ s/\*\*\*(.*?)\*\*\*/$1/sg; # remove *** 802 $note =~ s/\*\*(.*?)\*\*/$1/sg; # remove ** 803 } 804 805 return $note; 806} 807