Last active
March 16, 2018 07:37
-
-
Save asimpkin/8047575 to your computer and use it in GitHub Desktop.
Dynamic Rack Generation from ServiceNow CMDB Rack Sys_ID
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
include('../common.inc.php'); // Contains defintions for INSTANCE, USER, PASS | |
////////////////////////////////// | |
// GET THE RACK FROM sys_id in URL | |
$q='sys_id='.$_GET[sys_id]; | |
$query=urlencode($q); | |
$ch = curl_init(); | |
curl_setopt($ch, CURLOPT_URL, 'https://'.INSTANCE.'.service-now.com/cmdb_ci_rack_list.do?XML&useUnloadFormat=true&sysparm_query='.$query); | |
curl_setopt($ch, CURLOPT_HEADER, 0); | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); | |
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); | |
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); | |
curl_setopt($ch, CURLOPT_USERPWD, USER.':'.PASS); // locate in common.inc.php | |
$data = curl_exec($ch); | |
curl_close($ch); | |
$xmlIterator = new SimpleXMLIterator($data); | |
for( $xmlIterator->rewind(); $xmlIterator->valid(); $xmlIterator->next() ) { | |
foreach($xmlIterator->getChildren() as $name => $data) { | |
$RACK[(string)$name]=(string)$data; | |
} // end foreach | |
} // end for | |
////////////////////////////// | |
// GET ALL THE CIS IN THE RACK | |
$q='u_in_rack.sys_id='.$RACK[sys_id]; | |
$query=urlencode($q); | |
$ch = curl_init(); | |
curl_setopt($ch, CURLOPT_URL, 'https://'.INSTANCE.'.service-now.com/cmdb_ci_hardware_list.do?XML&useUnloadFormat=true&sysparm_query='.$query); | |
curl_setopt($ch, CURLOPT_HEADER, 0); | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); | |
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); | |
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); | |
curl_setopt($ch, CURLOPT_USERPWD, USER.':'.PASS); | |
$data = curl_exec($ch); | |
curl_close($ch); | |
$xmlIterator = new SimpleXMLIterator($data); | |
for( $xmlIterator->rewind(); $xmlIterator->valid(); $xmlIterator->next() ) { $K++; | |
foreach($xmlIterator->getChildren() as $name => $data) { | |
if ($name=="u_rack_position") $CIS[$K][$name]=(string)$data; | |
if ($name=="sys_id") $CIS[$K][$name]=(string)$data; | |
if ($name=="name") $CIS[$K][$name]=(string)$data; | |
if ($name=="u_rack_units") $CIS[$K][$name]=(string)$data; | |
} // end for each | |
} // end for | |
unset($K); | |
///////////////////////////////////// | |
// SORT THE CI ARRAY BY RACK POSITION | |
function aasort (&$array, $key) { | |
$sorter=array(); | |
$ret=array(); | |
reset($array); | |
foreach ($array as $ii => $va) { | |
$sorter[$ii]=$va[$key]; | |
} | |
asort($sorter); | |
foreach ($sorter as $ii => $va) { | |
$ret[$ii]=$array[$ii]; | |
} | |
$array=$ret; | |
} | |
aasort($CIS,"u_rack_position"); | |
/////////////////////////////// | |
// BUILD THE RACK DISPLAY ARRAY | |
# Populate with device label, and how many rack units of space it takes up | |
# Two special cases... 'rackname' gets applied to the top nameplate area | |
# 'blankXX' append random strings or numbers to avoid a name collision in php arrays | |
$rack['rackname']=$RACK[name]; | |
for($i=$RACK[rack_units]; $i>=1; $i--){ | |
foreach($CIS as $v) { | |
if($i==$v[u_rack_position]+$v[u_rack_units]-1) { | |
$F = array( 'name'=>$v[name], 'units'=>$v[u_rack_units] ); | |
$i=$i-$v[u_rack_units]+1; | |
} | |
}// end foreach | |
if($F) { | |
$rack[$F[name]]=$F[units]; | |
} else { | |
$rack['blank'.$i]=1; | |
} // end if | |
unset($F); | |
} // end for | |
////////////////////////////////////////////////////////////////////////////////// | |
// DRAW THE RACK | |
// http://www.jaredwatkins.com/2011/10/dynamic-rack-face-diagrams-with-php-and-gd/ | |
// DOWNLOAD :: http://www.jaredwatkins.com/uploads/DynamicRackFaces1.zip | |
// All drawRack() code below this point courtesy of Jared Watkins | |
drawRack($rack, 'BlankRack'.$RACK[rack_units].'u.png'); | |
function drawRack($r, $racktemplate) { | |
$template = imagecreatefrompng($racktemplate); | |
# Initial offset from the top left corner to begin placing 'servers' | |
$dstX = 27; | |
$dstY = 22; | |
foreach ($r as $name => $u) { | |
# This defines the nameplate at the top of the rack | |
if ($name == 'rackname') { | |
$nameplate = imagecreate(150,20); | |
$background = imagecolorallocate( $nameplate, 255, 255, 255 ); | |
$text_colour = imagecolorallocate( $nameplate, 0, 0, 0 ); | |
imageCenterString($nameplate, 5, $u, $text_colour); | |
imagecopy ($template, $nameplate, 52, 1, 0, 0, 150, 20); | |
continue; | |
} // end if | |
$deviceimg = imagecreate (200, (20*$u)); | |
drawRackDevice(&$deviceimg,$name); | |
imagecopy($template, $deviceimg, $dstX, $dstY, 0, 0, 200, (20*$u)); | |
$dstY += (20*$u); | |
imagedestroy($deviceimg); | |
} // end foreach | |
# You could also save it to a file on disk | |
header( "Content-type: image/png" ); | |
imagepng( $template ); | |
imagedestroy($template); | |
} | |
function drawRackDevice ($img, $text) { | |
// sys_class_name color picked from ServiceNow | |
// extended by AJ Simpkin 2013.12.19 hohoho! | |
if($sys_class_name=='cmdb_ci_linux_server') { // blue | |
$background = imagecolorallocate( $img, 100, 150, 200 ); | |
} elseif($sys_class_name=='cmdb_ci_win_server') { // red | |
$background = imagecolorallocate( $img, 200, 100, 100 ); | |
} else { | |
$background = imagecolorallocate( $img, 200, 200, 200 ); | |
} | |
$text_colour = imagecolorallocate( $img, 0, 0, 0 ); | |
$line_colour = imagecolorallocate( $img, 0, 0, 0 ); | |
# If this should be a blank space.. make a transparent 'server' to fill the gap | |
if ((strlen($text) == 0) or strstr($text, 'blank')) { | |
imagecolortransparent ($img, $background); | |
} else { | |
imageCenterString($img, 5, $text, $text_colour); | |
imageline ($img, 0,0,200,0, $line_colour); | |
imageline ($img, 0,imagesy($img)-1,200,imagesy($img)-1, $line_colour); | |
} // end if | |
} // end function | |
function imageCenterString(&$img, $font, $text, $color) { | |
if($font < 0 || $font > 5){ $font = 0; } | |
$num = array(array(4.6, 6), | |
array(4.6, 6), | |
array(5.6, 12), | |
array(6.5, 12), | |
array(7.6, 16), | |
array(8.5, 16)); | |
$width = ceil(strlen($text) * $num[$font][0]); | |
$x = imagesx($img) - $width - 8; | |
$y = Imagesy($img) - ($num[$font][1] + 2); | |
imagestring($img, $font, $x/2, $y/2, $text, $color); | |
} // end function | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment