Manage Virtual Hosts\n"; $profiles = getVMProfiles(); if($viewmode == ADMIN_DEVELOPER) { print "
\n"; print "
\n"; } print "
\n"; print ""; print "\n"; print "\n"; print "
\n"; $newmsg = "To create a new Virtual Host, change the state of a computer to
\n" . "'vmhostinuse' under Manage Computers->Computer Utilities.

\n"; $vmhosts = getVMHostData(); $resources = getUserResources(array("computerAdmin"), array("administer")); foreach($vmhosts as $key => $value) { if(! array_key_exists($value['computerid'], $resources['computer'])) unset($vmhosts[$key]); } if(empty($vmhosts)) { print "You do not have access to manage any existing virtual hosts.

\n"; print $newmsg; return; } print $newmsg; print "Select a Virtual Host:
\n"; printSelectInput("vmhostid", $vmhosts, -1, 0, 0, 'vmhostid'); $cont = addContinuationsEntry('vmhostdata'); print "

\n"; print "

\n"; /*print "
\n"; print "You have selected to change the VM Profile for this host.
\n"; print "Doing this will attempt to move any future reservations on the
\n"; print "host's VMs to other VMs and will submit a reload reservation for this
\n"; print "host after any active reservations on its VMs.

\n"; print "Are you sure you want to do this?

\n"; print "\n"; print "\n"; print "\n"; print "
\n";*/ print "
\n"; if($viewmode != ADMIN_DEVELOPER) return; print "
\n"; print "
Select a profile to configure:
\n"; print "\n"; $cont = addContinuationsEntry('AJprofiledata'); print ""; $cont = addContinuationsEntry('AJnewProfile'); print ""; print "

\n"; print "\n"; print "
\n"; print "
\n"; } //////////////////////////////////////////////////////////////////////////////// /// /// \fn vmhostdata() /// /// \brief prints json formatted data with information about the submitted VM /// host /// //////////////////////////////////////////////////////////////////////////////// function vmhostdata() { $vmhostid = processInputVar('vmhostid', ARG_NUMERIC); $ret = ''; $data = getVMHostData($vmhostid); $resources = getUserResources(array("computerAdmin"), array("administer")); if(! array_key_exists($data[$vmhostid]['computerid'], $resources['computer'])) { sendJSON(array('failed' => 'noaccess')); return; } # get vms assigned to vmhost $query = "SELECT c.id, " . "c.hostname, " . "s.name AS state, " . "c.vmhostid " . "FROM computer c, " . "state s " . "WHERE c.type = 'virtualmachine' AND " . "c.stateid = s.id AND " . "(vmhostid IS NULL OR " . "vmhostid NOT IN (SELECT id FROM vmhost) OR " . "c.vmhostid = $vmhostid) " . "ORDER BY c.hostname"; $qh = doQuery($query, 101); $ids = array(); $allvms = array(); $currvms = array(); $freevms = array(); while($row = mysql_fetch_assoc($qh)) { if($row['vmhostid'] == $vmhostid) { $ids[$row['id']] = $row['hostname']; $currvms[$row['id']] = array('id' => $row['id'], 'name' => $row['hostname'], 'state' => $row['state']); $allvms[] = array('id' => $row['id'], 'name' => $row['hostname'], 'inout' => 1); } else { $freevms[] = array('id' => $row['id'], 'name' => $row['hostname']); $allvms[] = array('id' => $row['id'], 'name' => $row['hostname'], 'inout' => 0); } } uasort($allvms, "sortKeepIndex"); uasort($currvms, "sortKeepIndex"); uasort($freevms, "sortKeepIndex"); $keys = array_keys($ids); $movevms = array(); if(! empty($keys)) { $keys = join(',', $keys); $query = "SELECT rq.id, " . "DATE_FORMAT(rq.start, '%l:%i%p %c/%e/%y') AS start, " . "rs.computerid " . "FROM request rq, " . "reservation rs " . "WHERE rs.requestid = rq.id AND " . "rs.computerid IN ($keys) AND " . "(rq.stateid = 18 OR " . "rq.laststateid = 18) AND " . "rq.start > NOW()"; $qh = doQuery($query, 101); while($row = mysql_fetch_assoc($qh)) { $movevms[] = array('id' => $row['id'], 'time' => strtolower($row['start']), 'hostname' => $currvms[$row['computerid']]['name']); unset($currvms[$row['computerid']]); } uasort($movevms, "sortKeepIndex"); $movevms = array_merge($movevms); } $allvms = array_merge($allvms); $currvms = array_merge($currvms); $freevms = array_merge($freevms); $cont = addContinuationsEntry('AJchangeVMprofile', array(), 3600, 1, 0); $arr = array('vmlimit' => $data[$vmhostid]['vmlimit'], 'profile' => $data[$vmhostid]['vmprofiledata'], 'continuation' => $cont, 'allvms' => $allvms, 'currvms' => $currvms, 'freevms' => $freevms, 'movevms' => $movevms); sendJSON($arr); } //////////////////////////////////////////////////////////////////////////////// /// /// \fn getVMHostData($id) /// /// \param $id - (optional) a host id about which to get data /// /// \return an array where each key is a vmhost id and each element is an array /// with these values:\n /// \b computerid - id of computer\n /// \b name - hostname of computer\n /// \b hostname - hostname of computer\n /// \b vmlimit - maximum number of vm's host can handle\n /// \b vmprofileid - id of vm profile\n /// \b vmkernalnic - name of kernel nic\n /// \b vmprofiledata - array of data about the vm's profile as returned from /// getVMProfiles /// /// \brief builds a array of information about the vmhosts /// //////////////////////////////////////////////////////////////////////////////// function getVMHostData($id='') { $profiles = getVMProfiles(); $query = "SELECT vh.id, " . "vh.computerid, " . "c.hostname AS name, " . "c.hostname, " . "vh.vmlimit, " . "vh.vmprofileid, " . "vh.vmkernalnic " . "FROM vmhost vh, " . "computer c " . "WHERE vh.computerid = c.id"; if(! empty($id)) $query .= " AND vh.id = $id"; $qh = doQuery($query, 101); $ret = array(); while($row = mysql_fetch_assoc($qh)) { $ret[$row['id']] = $row; $ret[$row['id']]['vmprofiledata'] = $profiles[$row['vmprofileid']]; } uasort($ret, 'sortKeepIndex'); return $ret; } //////////////////////////////////////////////////////////////////////////////// /// /// \fn updateVMlimit() /// /// \brief updates the vmlimit for the submitted vmhostid /// //////////////////////////////////////////////////////////////////////////////// function updateVMlimit() { global $mysql_link_vcl; $vmhostid = processInputVar('vmhostid', ARG_NUMERIC); $data = getVMHostData($vmhostid); $resources = getUserResources(array("computerAdmin"), array("administer")); if(! array_key_exists($data[$vmhostid]['computerid'], $resources['computer'])) { print 'You do not have access to manage this host.'; return; } $newlimit = processInputVar('newlimit', ARG_NUMERIC); if($newlimit < 0 || $newlimit > MAXVMLIMIT) { print "ERROR: newlimit out of range"; return; } $query = "UPDATE vmhost SET vmlimit = $newlimit WHERE id = $vmhostid"; $qh = doQuery($query, 101); if(mysql_affected_rows($mysql_link_vcl)) print "SUCCESS"; else print "ERROR: failed to update vmlimit"; } //////////////////////////////////////////////////////////////////////////////// /// /// \fn AJvmToHost() /// /// \brief adds vm's to a vmhost; prints json data with:\n /// \b vms - array of vm's successfully added\n /// \b fails - array of vm's that couldn't be added for some reason\n /// \b addrem - 1 /// //////////////////////////////////////////////////////////////////////////////// function AJvmToHost() { $hostid = processInputVar('hostid', ARG_NUMERIC); $hostdata = getVMHostData($hostid); $resources = getUserResources(array("computerAdmin"), array("administer")); if(! array_key_exists($hostdata[$hostid]['computerid'], $resources['computer'])) { sendJSON(array('failed' => 'nohostaccess')); return; } # find out how many vms are currently on the host $query = "SELECT COUNT(id) " . "FROM computer " . "WHERE vmhostid = $hostid"; $qh = doQuery($query, 101); $row = mysql_fetch_row($qh); if($row[0] >= $hostdata[$hostid]['vmlimit']) { sendJSON(array('failed' => 'vmlimit')); return; } $adds = array(); $fails = array(); $vmlistids = processInputVar('listids', ARG_STRING); $vmids = explode(',', $vmlistids); # get data about submitted vms to add $query = "SELECT id, hostname, vmhostid " . "FROM computer " . "WHERE id in ($vmlistids)"; $qh = doQuery($query, 101); $vmdata = array(); while($row = mysql_fetch_assoc($qh)) { if(! array_key_exists($row['id'], $resources['computer'])) { $fails[] = array('id' => $row['id'], 'name' => $row['hostname'], 'reason' => 'noaccess'); unset_by_val($row['id'], $vmids); continue; } $vmdata[$row['id']] = $row; } # build list of vm hosts $query = "SELECT id FROM vmhost"; $vmhosts = array(); $qh = doQuery($query, 101); while($row = mysql_fetch_assoc($qh)) $vmhosts[$row['id']] = 1; # check to see if there any submitted vms have a hostid of an existing vm host foreach($vmids as $compid) { if(! array_key_exists($vmdata[$compid]['vmhostid'], $vmhosts)) { $query = "UPDATE computer " . "SET vmhostid = $hostid, " . "stateid = 2 " . "WHERE id = $compid"; doQuery($query, 101); $adds[] = array('id' => $compid, 'name' => $vmdata[$compid]['hostname'], 'state' => 'available'); } else $fails[] = array('id' => $compid, 'name' => $vmdata[$compid]['hostname'], 'reason' => 'otherhost'); } $arr = array('vms' => $adds, 'fails' => $fails, 'addrem' => 1); sendJSON($arr); } //////////////////////////////////////////////////////////////////////////////// /// /// \fn AJvmFromHost() /// /// \brief removes vm's from a host by adding reservations for them in the /// tomaintenance state; prints json data with:\n /// \b vms - vm's that successfully had reservastions created to move them off\n /// \b checks - vm's that have reservations on them that can be removed in the /// future by adding a future tomaintenance reservation\n /// \b addrem - 0\n /// \b cont - a new continuation for submitting the future tomaintenance /// reservations /// //////////////////////////////////////////////////////////////////////////////// function AJvmFromHost() { $hostid = processInputVar('hostid', ARG_NUMERIC); $hostdata = getVMHostData($hostid); $resources = getUserResources(array("computerAdmin"), array("administer")); if(! array_key_exists($hostdata[$hostid]['computerid'], $resources['computer'])) { sendJSON(array('failed' => 'nohostaccess')); return; } $fails = array(); $vmlistids = processInputVar('listids', ARG_STRING); $vmids = explode(',', $vmlistids); $rems = array(); $checks = array(); $vclreloadid = getUserlistID('vclreload@Local'); $imageid = getImageId('noimage'); $imagerevisionid = getProductionRevisionid($imageid); $start = getReloadStartTime(); $end = $start + SECINMONTH; $start = unixToDatetime($start); $end = unixToDatetime($end); foreach($vmids as $compid) { $compdata = getComputers(0, 0, $compid); if(! array_key_exists($compid, $resources['computer'])) { $fails[] = array('id' => $compid, 'name' => $compdata[$compid]['hostname'], 'reason' => 'noaccess'); continue; } # try to remove reservations off of computer if(($compdata[$compid]['state'] == 'available' || $compdata[$compid]['state'] == 'maintenance' || $compdata[$compid]['state'] == 'failed') && moveReservationsOffComputer($compid)) { // if no reservations on computer, submit reload # reservation so vm gets stopped on host $reqid = simpleAddRequest($compid, $imageid, $imagerevisionid, $start, $end, 18, $vclreloadid); if($reqid == 0) { $fails[] = array('id' => $compid, 'name' => $compdata[$compid]['hostname'], 'reason' => 'nomgtnode'); } else { $rems[] = array('id' => $compid, 'hostname' => $compdata[$compid]['hostname'], 'reqid' => $reqid, 'time' => 'immediately'); } } else { # existing reservation on computer, find end time and prompt user # if ok to wait until then to move it $query = "SELECT DATE_FORMAT(rq.end, '%l:%i%p %c/%e/%y') AS end, " . "rq.end AS end2 " . "FROM request rq, " . "reservation rs " . "WHERE rs.requestid = rq.id AND " . "rs.computerid = $compid AND " . "rq.stateid NOT IN (1,5,12) " . "ORDER BY end DESC " . "LIMIT 1"; $qh = doQuery($query, 101); if($row = mysql_fetch_assoc($qh)) { $checks[] = array('id' => $compid, 'hostname' => $compdata[$compid]['hostname'], 'end' => strtolower($row['end']), 'end2' => $row['end2']); } else $rems[] = array('id' => $compid); } } if(count($checks)) $cont = addContinuationsEntry('AJvmFromHostDelayed', $checks, 120, 1, 0); else $cont = ''; $arr = array('vms' => $rems, 'checks' => $checks, 'fails' => $fails, 'addrem' => 0, 'cont' => $cont); sendJSON($arr); } //////////////////////////////////////////////////////////////////////////////// /// /// \fn AJvmFromHostDelayed() /// /// \brief submits future tomaintenance reservations for vm's saved in the /// continuation /// //////////////////////////////////////////////////////////////////////////////// function AJvmFromHostDelayed() { $data = getContinuationVar(); $vclreloadid = getUserlistID('vclreload@Local'); $imageid = getImageId('noimage'); $imagerevisionid = getProductionRevisionid($imageid); $fails = array(); foreach($data as $comp) { $end = datetimeToUnix($comp['end2']) + SECINMONTH; $end = unixToDatetime($end); if(! simpleAddRequest($comp['id'], $imageid, $imagerevisionid, $comp['end2'], $end, 18, $vclreloadid)) $fails[] = array('name' => $comp['hostname'], 'reason' => 'nomgtnode'); } $cont = addContinuationsEntry('vmhostdata'); $arr = array('msg' => 'SUCCESS', 'cont' => $cont, 'fails' => $fails); sendJSON($arr); } //////////////////////////////////////////////////////////////////////////////// /// /// \fn AJchangeVMprofile() /// /// \brief stub function for changing the vm profile of a vm host /// //////////////////////////////////////////////////////////////////////////////// function AJchangeVMprofile() { $hostid = processInputVar('hostid', ARG_NUMERIC); $oldprofileid = processInputVar('oldprofileid', ARG_NUMERIC); $newprofileid = processInputVar('newprofileid', ARG_NUMERIC); # add security checks # try to remove reservations off of each vm // if no reservations on any vms, create reload reservation # else try to create reservation to handle in future # else return error message $cont = addContinuationsEntry('AJchangeVMprofile', array(), 3600, 1, 0); $arr = array('msg' => 'function not implemented', 'continuation' => $cont); sendJSON($arr); } //////////////////////////////////////////////////////////////////////////////// /// /// \fn AJcancelVMmove() /// /// \brief cancels tomaintenance reservations that had been submitted to move /// a vm off of a vmhost /// //////////////////////////////////////////////////////////////////////////////// function AJcancelVMmove() { $hostid = processInputVar('hostid', ARG_NUMERIC); $hostdata = getVMHostData($hostid); $resources = getUserResources(array("computerAdmin"), array("administer")); if(! array_key_exists($hostdata[$hostid]['computerid'], $resources['computer'])) { sendJSON(array('failed' => 'nohostaccess')); return; } $fails = array(); $requestids = processInputVar('listids', ARG_STRING); $now = time(); $msg = 'FAIL'; foreach(explode(',', $requestids) AS $reqid) { $request = getRequestInfo($reqid); if(! array_key_exists($request['reservations'][0]['computerid'], $resources['computer'])) { $fails[] = array('id' => $request['reservations'][0]['computerid'], 'name' => $request['reservations'][0]['hostname'], 'reason' => 'noaccess'); continue; } if(datetimeToUnix($request["start"]) < $now) { # set stateid and laststateid for each request to deleted $query = "UPDATE request " . "SET stateid = 1, " . "laststateid = 1 " . "WHERE id = $reqid"; doQuery($query, 101); } else { $query = "DELETE FROM request WHERE id = $reqid"; doQuery($query, 101); $query = "DELETE FROM reservation WHERE requestid = $reqid"; doQuery($query, 101); } $msg = 'SUCCESS'; } $cont = addContinuationsEntry('vmhostdata'); $arr = array('msg' => $msg, 'cont' => $cont, 'fails' => $fails); sendJSON($arr); } //////////////////////////////////////////////////////////////////////////////// /// /// \fn AJprofileData() /// /// \param $profileid - (optional) id of a vm profile /// /// \brief prints json data about a submitted or passed in vm profile with these /// fields:\n /// \b profile - array returned from getVMProfiles\n /// \b types - array of vm types\n /// \b vmdisk - array of vm disk options\n /// \b images - array of images /// //////////////////////////////////////////////////////////////////////////////// function AJprofileData($profileid="") { global $viewmode; if($viewmode != ADMIN_DEVELOPER) { sendJSON(array('failed' => 'noaccess')); return; } $profileid = processInputVar('profileid', ARG_NUMERIC, $profileid); $profiledata = getVMProfiles($profileid); foreach($profiledata[$profileid] AS $key => $value) { if(is_null($value)) $profiledata[$profileid][$key] = ''; } $types = getVMtypes(); $allimages = getImages(); $images = array(); foreach($allimages as $key => $image) $images[] = array('id' => $key, 'name' => $image['prettyname']); $imagedata = array('identifier' => 'id', 'items' => $images); $types2 = array(); foreach($types as $id => $val) { $types2[] = array('id' => $id, 'name' => $val); } $typedata = array('identifier' => 'id', 'items' => $types2); $vmdiskitems = array(); $vmdiskitems[] = array('id' => 'localdisk', 'name' => 'localdisk'); $vmdiskitems[] = array('id' => 'networkdisk', 'name' => 'networkdisk'); $vmdisk = array('identifier' => 'id', 'items' => $vmdiskitems); $arr = array('profile' => $profiledata[$profileid], 'types' => $typedata, 'vmdisk' => $vmdisk, 'images' => $imagedata); sendJSON($arr); } //////////////////////////////////////////////////////////////////////////////// /// /// \fn AJupdateVMprofileItem() /// /// \brief updates the submitted item for the submitted vm profile and prints /// javascript to keep the global curprofile object updated /// //////////////////////////////////////////////////////////////////////////////// function AJupdateVMprofileItem() { global $viewmode; if($viewmode != ADMIN_DEVELOPER) { print "alert('You do not have access to manage this vm profile.');"; return; } $profileid = processInputVar('profileid', ARG_NUMERIC); $item = processInputVar('item', ARG_STRING); if(! preg_match('/^(profilename|vmtypeid|imageid|repositorypath|datastorepath|vmpath|virtualswitch0|virtualswitch1|vmdisk|username|password|vmware_mac_eth0_generated|vmware_mac_eth1_generated)$/', $item)) { print "alert('Invalid data submitted.');"; return; } if(preg_match('/^vmware_mac_eth[01]_generated$/', $item)) { $newvalue = processInputVar('newvalue', ARG_NUMERIC); if($newvalue != 0 && $newvalue != 1) $newvalue = 0; } elseif($item == 'password') $newvalue = $_POST['newvalue']; else $newvalue = processInputVar('newvalue', ARG_STRING); if($newvalue == '') $newvalue2 = 'NULL'; else { if(get_magic_quotes_gpc()) $newvalue = stripslashes($newvalue); $newvalue2 = mysql_real_escape_string($newvalue); $newvalue2 = "'$newvalue2'"; } $item = mysql_real_escape_string($item); $profile = getVMProfiles($profileid); if($profile[$profileid][$item] == $newvalue) return; $query = "UPDATE vmprofile " . "SET `$item` = $newvalue2 " . "WHERE id = $profileid"; doQuery($query, 101); if($item == 'password') { print "document.getElementById('savestatus').innerHTML = 'Saved'; "; print "setTimeout(function() {document.getElementById('savestatus').innerHTML = '';}, 3000); "; } $newvalue = preg_replace("/'/", "\\'", $newvalue); print "curprofile.$item = '$newvalue';"; } //////////////////////////////////////////////////////////////////////////////// /// /// \fn AJnewProfile() /// /// \brief creates a new vmprofile entry using just the submitted new name and /// the defaults for the rest of the fields; calls AJprofileData /// //////////////////////////////////////////////////////////////////////////////// function AJnewProfile() { $newprofile = processInputVar('newname', ARG_STRING); if(get_magic_quotes_gpc()) { $newprofile = stripslashes($newprofile); $newprofile = mysql_real_escape_string($newprofile); } # TODO add check for existing name $query = "SELECT id FROM vmprofile WHERE profilename = '$newprofile'"; $qh = doQuery($query, 101); if($row = mysql_fetch_assoc($qh)) { sendJSON(array('failed' => 'exists')); return; } $query = "INSERT INTO vmprofile (profilename) VALUES ('$newprofile')"; doQuery($query, 101); $qh = doQuery("SELECT LAST_INSERT_ID() FROM vmprofile", 101); $row = mysql_fetch_row($qh); $newid = $row[0]; AJprofileData($newid); } //////////////////////////////////////////////////////////////////////////////// /// /// \fn AJdelProfile() /// /// \brief deletes the submitted vm profile /// //////////////////////////////////////////////////////////////////////////////// function AJdelProfile() { global $viewmode; if($viewmode != ADMIN_DEVELOPER) { sendJSON(array('failed' => 'noaccess')); return; } $profileid = processInputVar('profileid', ARG_NUMERIC); # check to see if profile is in use $query = "SELECT vh.computerid, " . "s.name " . "FROM vmhost vh, " . "computer c, " . "state s " . "WHERE vh.computerid = c.id AND " . "c.stateid = s.id AND " . "s.name IN ('vmhostinuse', 'tovmhostinuse') AND " . "vh.vmprofileid = $profileid"; $qh = doQuery($query, 101); if($row = mysql_fetch_assoc($qh)) { sendJSON(array('failed' => 'inuse')); return; } $query = "DELETE FROM vmprofile WHERE id = $profileid"; doQuery($query, 101); sendJSON(array('SUCCESS')); } ?>