| <?php |
| /* |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| |
| require_once(".ht-inc/secrets.php"); |
| require_once(".ht-inc/authentication.php"); |
| require_once(".ht-inc/spyc-0.5.1/Spyc.php"); |
| if(file_exists(".ht-inc/vcldocs.php")) |
| require_once(".ht-inc/vcldocs.php"); |
| |
| /** |
| * \file |
| */ |
| |
| /// used for processInputVar, means the input variable should be numeric |
| define("ARG_NUMERIC", 1); |
| /// used for processInputVar, means the input variable should be a string |
| define("ARG_STRING", 1 << 1); |
| /// used for processInputVar, means the input variable should be an array of numbers |
| define("ARG_MULTINUMERIC", 1 << 2); |
| /// used for processInputVar, means the input variable should be an array of strings |
| define("ARG_MULTISTRING", 1 << 3); |
| |
| /// global array used to hold request information between calling isAvailable |
| /// and addRequest |
| $requestInfo = array(); |
| |
| /// global array to cache arrays of node parents for getNodeParents |
| $nodeparents = array(); |
| /// global array to cache various data |
| $cache = array(); |
| /// global variable to store what needs to be printed in printHTMLHeader |
| $HTMLheader = ""; |
| /// global variable to store if header has been printed |
| $printedHTMLheader = 0; |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn initGlobals() |
| /// |
| /// \brief this is where globals get initialized |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function initGlobals() { |
| global $mode, $user, $remoteIP, $authed, $oldmode, $semid; |
| global $days, $phpVer, $keys, $pemkey, $AUTHERROR; |
| global $passwdArray, $skin, $contdata, $lastmode, $inContinuation; |
| global $ERRORS, $actions; |
| global $affilValFunc, $addUserFunc, $updateUserFunc, $addUserFuncArgs; |
| global $uniqid, $cryptkey, $ivsize; |
| |
| define("SECINDAY", 86400); |
| define("SECINWEEK", 604800); |
| define("SECINMONTH", 2678400); |
| define("SECINYEAR", 31536000); |
| |
| define("SYMALGO", "AES"); |
| define("SYMOPT", "CBC"); |
| define("SYMLEN", 256); |
| |
| define("ASYMALGO", "RSA"); |
| define("ASYMOPT", "OAEP"); |
| define("ASYMLEN", 4096); |
| |
| if(! defined('QUERYLOGGING')) |
| define('QUERYLOGGING', 1); |
| # TODO validate security of this |
| if(array_key_exists("PATH_INFO", $_SERVER)) { |
| $pathdata = explode("/", $_SERVER["PATH_INFO"]); |
| $tmp = explode('.', $pathdata[1]); |
| $_GET["mode"] = $tmp[0]; |
| } |
| |
| if(function_exists('openssl_encrypt')) { |
| define('USE_PHPSECLIB', 0); |
| $crytpkey = base64_decode($cryptkey); |
| } |
| else { |
| define('USE_PHPSECLIB', 1); |
| require_once(".ht-inc/phpseclib/Crypt/Base.php"); |
| require_once(".ht-inc/phpseclib/Crypt/Rijndael.php"); |
| require_once(".ht-inc/phpseclib/Crypt/AES.php"); |
| require_once(".ht-inc/phpseclib/Crypt/Random.php"); |
| } |
| $ivsize = 16; |
| |
| $mode = processInputVar("mode", ARG_STRING, 'main'); |
| $inContinuation = 0; |
| $contdata = array(); |
| $contuserid = ''; |
| $continuation = processInputVar('continuation', ARG_STRING); |
| if(! empty($continuation)) { |
| $tmp = getContinuationsData($continuation); |
| if(empty($tmp)) |
| abort(11); |
| elseif(array_key_exists('error', $tmp)) { |
| $mode = "continuationsError"; |
| $contdata = $tmp; |
| } |
| else { |
| $inContinuation = 1; |
| $contuserid = $tmp['userid']; |
| $lastmode = $tmp['frommode']; |
| $mode = $tmp['nextmode']; |
| $contdata = $tmp['data']; |
| } |
| } |
| $submitErr = 0; |
| $submitErrMsg = array(); |
| $remoteIP = $_SERVER["REMOTE_ADDR"]; |
| $days = array(i('Sunday'), i('Monday'), i('Tuesday'), i('Wednesday'), i('Thursday'), i('Friday'), i('Saturday')); |
| $phpVerArr = explode('.', phpversion()); |
| $phpVer = $phpVerArr[0]; |
| $uniqid = uniqid($_SERVER['HTTP_HOST'] . "-" . getmypid() . "-"); |
| |
| $passwdArray = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', |
| 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', |
| 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', |
| 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', |
| 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', |
| '4', '5', '6', '7', '8', '9', '0'); |
| |
| if(array_key_exists('VCLAUTH', $_COOKIE) || $mode == 'submitLogin') { |
| // open keys |
| $fp = fopen(".ht-inc/keys.pem", "r"); |
| $key = fread($fp, 8192); |
| fclose($fp); |
| $keys["private"] = openssl_pkey_get_private($key, $pemkey); |
| if(! $keys['private']) |
| abort(6); |
| $fp = fopen(".ht-inc/pubkey.pem", "r"); |
| $key = fread($fp, 8192); |
| fclose($fp); |
| $keys["public"] = openssl_pkey_get_public($key); |
| if(! $keys['public']) |
| abort(7); |
| } |
| |
| # USING A SINGLE USER WITHOUT LOGGING IN: |
| # to automatically log in to vcl with the same user |
| # every time, comment out from this comment block to |
| # the 'end auth check' comment, then, right after |
| # that, set $authed = 1 and $userid to the id from |
| # the user table corresponding to the user you want |
| # logged in |
| |
| # start auth check |
| $authed = 0; |
| if(array_key_exists("VCLAUTH", $_COOKIE)) { |
| $userid = readAuthCookie(); |
| if(! is_null($userid)) |
| $authed = 1; |
| } |
| elseif(preg_match('/_shibsession/', join(',', array_keys($_COOKIE)))) { |
| # redirect to shibauth directory |
| header('Location: ' . BASEURL . "/shibauth/"); |
| dbDisconnect(); |
| exit; |
| } |
| # end auth check |
| |
| if($authed && $mode == 'selectauth') |
| $mode = 'main'; |
| |
| # check that mode is valid |
| if(! array_key_exists($mode, $actions['pages'])) |
| $mode = 'main'; |
| |
| if(! $authed) { |
| # set $skin based on cookie (so it gets set before user logs in |
| # later, we set it by affiliation (helps with 'view as user') |
| if(array_key_exists('VCLSKIN', $_COOKIE)) { |
| switch($_COOKIE['VCLSKIN']) { |
| case 'EXAMPLE2': |
| $skin = 'example2'; |
| break; |
| default: |
| $skin = getAffiliationTheme(0); |
| break; |
| } |
| } |
| # set skin based on IP address, useful to ensure anyone coming |
| # from a certain organization automatically gets a different skin |
| /*elseif(preg_match('/^152\.9\./', $_SERVER['REMOTE_ADDR']) || |
| (array_key_exists('VCLSKIN', $_COOKIE) && $_COOKIE['VCLSKIN'] == 'EXAMPLE1')) { |
| $skin = 'example1'; |
| }*/ |
| else |
| $skin = getAffiliationTheme(0); |
| if($mode != 'selectauth' && $mode != 'submitLogin') |
| require_once("themes/$skin/page.php"); |
| |
| require_once(".ht-inc/requests.php"); |
| if($mode != "logout" && |
| $mode != "shiblogout" && |
| $mode != "xmlrpccall" && |
| $mode != "xmlrpcaffiliations" && |
| $mode != "selectauth" && |
| $mode != "submitLogin" && |
| $mode != "changeLocale") { |
| $oldmode = $mode; |
| $mode = "auth"; |
| } |
| if($mode == 'xmlrpccall' || $mode == 'xmlrpcaffiliations') { |
| require_once(".ht-inc/xmlrpcWrappers.php"); |
| require_once(".ht-inc/requests.php"); |
| #require_once(".ht-inc/serverprofiles.php"); |
| require_once(".ht-inc/groups.php"); |
| setupSession(); |
| } |
| return; |
| } |
| setupSession(); |
| if(array_key_exists('user', $_SESSION)) { |
| $user = $_SESSION['user']; |
| if(! empty($contuserid) && |
| $user['id'] != $contuserid) |
| abort(51); |
| } |
| else { |
| # get info about user |
| if(! $user = getUserInfo($userid)) { |
| // if first call to getUserInfo fails, try calling with $noupdate set |
| if(! $user = getUserInfo($userid, 1)) { |
| $ERRORS[1] = i("Failed to get user info from database. userid was ") . "$userid"; |
| abort(1); |
| } |
| } |
| if(! empty($contuserid) && |
| $user['id'] != $contuserid) |
| abort(51); |
| $_SESSION['user'] = $user; |
| } |
| |
| # setskin |
| $skin = getAffiliationTheme($user['affiliationid']); |
| require_once("themes/$skin/page.php"); |
| |
| $_SESSION['mode'] = $mode; |
| |
| // check for and possibly clear dirty permission cache |
| $dontClearModes = array('AJchangeUserPrivs', 'AJchangeUserGroupPrivs', 'AJchangeResourcePrivs'); |
| if(! in_array($mode, $dontClearModes) && |
| array_key_exists('dirtyprivs', $_SESSION) && |
| $_SESSION['dirtyprivs']) { |
| clearPrivCache(); |
| $_SESSION['dirtyprivs'] = 0; |
| } |
| |
| # set up $affilValFunc, $addUserFunc, $updateUserFunc for any shibonly affiliations |
| $query = "SELECT id FROM affiliation WHERE shibonly = 1"; |
| $qh = doQuery($query); |
| while($row = mysql_fetch_assoc($qh)) { |
| $id = $row['id']; |
| if(! array_key_exists($id, $affilValFunc)) { |
| if(ALLOWADDSHIBUSERS) |
| $affilValFunc[$id] = create_function('', 'return 1;'); |
| else |
| $affilValFunc[$id] = create_function('', 'return 0;'); |
| } |
| if(! array_key_exists($id, $addUserFunc)) { |
| if(ALLOWADDSHIBUSERS) { |
| $addUserFunc[$id] = 'addShibUserStub'; |
| $addUserFuncArgs[$id] = $id; |
| } |
| else |
| $addUserFunc[$id] = create_function('', 'return 0;'); |
| } |
| if(! array_key_exists($id, $updateUserFunc)) |
| $updateUserFunc[$id] = create_function('', 'return NULL;'); |
| } |
| |
| # include appropriate files |
| switch($actions['pages'][$mode]) { |
| case 'blockAllocations': |
| require_once(".ht-inc/blockallocations.php"); |
| break; |
| case 'help': |
| require_once(".ht-inc/help.php"); |
| break; |
| case 'userPreferences': |
| require_once(".ht-inc/userpreferences.php"); |
| break; |
| case 'statistics': |
| require_once(".ht-inc/statistics.php"); |
| break; |
| case 'manageGroups': |
| require_once(".ht-inc/groups.php"); |
| break; |
| case 'privileges': |
| case 'userLookup': |
| require_once(".ht-inc/privileges.php"); |
| break; |
| case 'sitemaintenance': |
| require_once(".ht-inc/sitemaintenance.php"); |
| break; |
| case 'vm': |
| require_once(".ht-inc/vm.php"); |
| break; |
| case 'dashboard': |
| require_once(".ht-inc/dashboard.php"); |
| break; |
| case 'siteconfig': |
| require_once(".ht-inc/siteconfig.php"); |
| break; |
| case 'resource': |
| case 'config': |
| case 'image': |
| case 'computer': |
| case 'managementnode': |
| case 'schedule': |
| case 'addomain': |
| require_once(".ht-inc/resource.php"); |
| break; |
| case 'storebackend': |
| require_once(".ht-inc/storebackend.php"); |
| break; |
| /*case 'serverProfiles': |
| require_once(".ht-inc/serverprofiles.php"); |
| require_once(".ht-inc/requests.php"); |
| break;*/ |
| case 'oneClicks': |
| require_once(".ht-inc/oneclick.php"); |
| break; |
| default: |
| require_once(".ht-inc/requests.php"); |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn __autoload($class) |
| /// |
| /// \param $class - name of a class |
| /// |
| /// \brief handles loading class implementation file for a specified class |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function __autoload($class) { |
| global $actions; |
| $class = strtolower($class); |
| if(array_key_exists($class, $actions['classmapping'])) { |
| require_once(".ht-inc/{$actions['classmapping'][$class]}.php"); |
| return; |
| } |
| require_once(".ht-inc/resource.php"); |
| require_once(".ht-inc/$class.php"); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn checkAccess() |
| /// |
| /// \brief gets the user's access level to the locker from the ptsowner_admin |
| /// table |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function checkAccess() { |
| global $mode, $user, $actionFunction, $authMechs; |
| global $itecsauthkey, $ENABLE_ITECSAUTH, $actions, $noHTMLwrappers; |
| global $inContinuation, $docreaders, $apiValidateFunc; |
| if($mode == 'xmlrpccall') { |
| // double check for SSL |
| if(! isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on") { |
| printXMLRPCerror(4); # must have SSL enabled |
| dbDisconnect(); |
| exit; |
| } |
| $xmluser = processInputData($_SERVER['HTTP_X_USER'], ARG_STRING, 1); |
| if(! $user = getUserInfo($xmluser)) { |
| // if first call to getUserInfo fails, try calling with $noupdate set |
| if(! $user = getUserInfo($xmluser, 1)) { |
| $testid = $xmluser; |
| $affilid = DEFAULT_AFFILID; |
| getAffilidAndLogin($testid, $affilid); |
| addLoginLog($testid, 'unknown', $affilid, 0); |
| printXMLRPCerror(3); # access denied |
| dbDisconnect(); |
| exit; |
| } |
| } |
| if(! array_key_exists('HTTP_X_PASS', $_SERVER) || strlen($_SERVER['HTTP_X_PASS']) == 0) { |
| addLoginLog($xmluser, 'unknown', $user['affilid'], 0); |
| printXMLRPCerror(3); # access denied |
| dbDisconnect(); |
| exit; |
| } |
| $xmlpass = $_SERVER['HTTP_X_PASS']; |
| if(get_magic_quotes_gpc()) |
| $xmlpass = stripslashes($xmlpass); |
| $apiver = processInputData($_SERVER['HTTP_X_APIVERSION'], ARG_NUMERIC, 1); |
| if($apiver == 1) { |
| addLoginLog($xmluser, 'unknown', $user['affilid'], 0); |
| printXMLRPCerror(8); # unsupported API version |
| dbDisconnect(); |
| exit; |
| } |
| elseif($apiver == 2) { |
| $authtype = ""; |
| foreach($authMechs as $key => $authmech) { |
| if($authmech['affiliationid'] == $user['affiliationid']) { |
| $authtype = $key; |
| break; |
| } |
| } |
| if(empty($authtype)) { |
| print "No authentication mechanism found for passed in X-User"; |
| addLoginLog($xmluser, 'unknown', $user['affilid'], 0); |
| dbDisconnect(); |
| exit; |
| } |
| if($authMechs[$authtype]['type'] == 'ldap') { |
| $auth = $authMechs[$authtype]; |
| $ds = ldap_connect("ldaps://{$auth['server']}/"); |
| if(! $ds) { |
| addLoginLog($xmluser, $authtype, $user['affilid'], 0); |
| printXMLRPCerror(5); # failed to connect to auth server |
| dbDisconnect(); |
| exit; |
| } |
| ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3); |
| ldap_set_option($ds, LDAP_OPT_REFERRALS, 0); |
| if($auth['lookupuserbeforeauth']) { |
| # in this case, we have to look up what part of the tree the user is in |
| # before we can actually look up the user |
| if(array_key_exists('masterlogin', $auth) && strlen($auth['masterlogin'])) |
| $res = ldap_bind($ds, $auth['masterlogin'], $auth['masterpwd']); |
| else |
| $res = ldap_bind($ds); |
| if(! $res) { |
| addLoginLog($user['unityid'], $authtype, $user['affiliationid'], 0); |
| printXMLRPCerror(5); # failed to connect to auth server |
| dbDisconnect(); |
| exit; |
| } |
| $search = ldap_search($ds, |
| $auth['binddn'], |
| "{$auth['lookupuserfield']}={$user['unityid']}", |
| array('dn'), 0, 3, 15); |
| if($search) { |
| $tmpdata = ldap_get_entries($ds, $search); |
| if(! $tmpdata['count'] || ! array_key_exists('dn', $tmpdata[0])) { |
| addLoginLog($user['unityid'], $authtype, $user['affiliationid'], 0); |
| printXMLRPCerror(3); # access denied |
| dbDisconnect(); |
| exit; |
| } |
| $ldapuser = $tmpdata[0]['dn']; |
| } |
| else { |
| addLoginLog($user['unityid'], $authtype, $user['affiliationid'], 0); |
| printXMLRPCerror(3); # access denied |
| dbDisconnect(); |
| exit; |
| } |
| } |
| else |
| $ldapuser = sprintf($auth['userid'], $user['unityid']); |
| $res = ldap_bind($ds, $ldapuser, $xmlpass); |
| if(! $res) { |
| addLoginLog($user['unityid'], $authtype, $user['affiliationid'], 0); |
| printXMLRPCerror(3); # access denied |
| dbDisconnect(); |
| exit; |
| } |
| addLoginLog($user['unityid'], $authtype, $user['affiliationid'], 1); |
| } |
| elseif($ENABLE_ITECSAUTH && |
| $authMechs[$authtype]['affiliationid'] == getAffiliationID('ITECS')) { |
| $rc = ITECSAUTH_validateUser($itecsauthkey, $user['unityid'], $xmlpass); |
| if(empty($rc) || $rc['passfail'] == 'fail') { |
| printXMLRPCerror(3); # access denied |
| dbDisconnect(); |
| exit; |
| } |
| } |
| elseif($authMechs[$authtype]['type'] == 'local') { |
| if(! validateLocalAccount($user['unityid'], $xmlpass)) { |
| printXMLRPCerror(3); # access denied |
| dbDisconnect(); |
| exit; |
| } |
| } |
| elseif($authMechs[$authtype]['type'] == 'redirect') { |
| $affilid = $authMechs[$authtype]['affiliationid']; |
| if(!(isset($apiValidateFunc) && is_array($apiValidateFunc) && |
| array_key_exists($affilid, $apiValidateFunc) && |
| $apiValidateFunc[$affilid]($xmluser, $xmlpass))) { |
| printXMLRPCerror(3); # access denied |
| dbDisconnect(); |
| exit; |
| } |
| } |
| else { |
| printXMLRPCerror(6); # unable to auth passed in X-User |
| dbDisconnect(); |
| exit; |
| } |
| } |
| else { |
| printXMLRPCerror(7); # unknown API version |
| dbDisconnect(); |
| exit; |
| } |
| } |
| elseif($mode == 'xmlrpcaffiliations') { |
| // double check for SSL, not really required for this mode, but it keeps things consistant |
| if(! isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on") { |
| printXMLRPCerror(4); # must have SSL enabled |
| dbDisconnect(); |
| exit; |
| } |
| $apiver = processInputData($_SERVER['HTTP_X_APIVERSION'], ARG_NUMERIC, 1); |
| if($apiver == 1) { |
| printXMLRPCerror(8); # unsupported API version |
| dbDisconnect(); |
| exit; |
| } |
| elseif($apiver != 2) { |
| printXMLRPCerror(7); # unknown API version |
| dbDisconnect(); |
| exit; |
| } |
| } |
| elseif(! empty($mode)) { |
| if(! in_array($mode, $actions['entry']) && |
| ! $inContinuation) { |
| $mode = "main"; |
| $actionFunction = "main"; |
| return; |
| } |
| else { |
| if(! $inContinuation) { |
| # check that user has access to this area |
| switch($mode) { |
| case 'viewGroups': |
| if(! in_array("groupAdmin", $user["privileges"])) { |
| $mode = ""; |
| $actionFunction = "main"; |
| return; |
| } |
| break; |
| /*case 'serverProfiles': |
| if(! in_array("serverProfileAdmin", $user["privileges"]) && |
| ! in_array("serverCheckOut", $user["privileges"])) { |
| $mode = ""; |
| $actionFunction = "main"; |
| return; |
| } |
| break;*/ |
| case 'pickTimeTable': |
| $computermetadata = getUserComputerMetaData(); |
| if(! count($computermetadata["platforms"]) || |
| ! count($computermetadata["schedules"])) { |
| $mode = ""; |
| $actionFunction = "main"; |
| return; |
| } |
| break; |
| case 'viewNodes': |
| if(! in_array("userGrant", $user["privileges"]) && |
| ! in_array("resourceGrant", $user["privileges"]) && |
| ! in_array("nodeAdmin", $user["privileges"])) { |
| $mode = ""; |
| $actionFunction = "main"; |
| return; |
| } |
| break; |
| case 'userLookup': |
| if(! checkUserHasPerm('User Lookup (global)') && |
| ! checkUserHasPerm('User Lookup (affiliation only)')) { |
| $mode = ""; |
| $actionFunction = "main"; |
| return; |
| } |
| break; |
| case 'editVMInfo': |
| if(! in_array("computerAdmin", $user["privileges"])) { |
| $mode = ""; |
| $actionFunction = "main"; |
| return; |
| } |
| break; |
| case 'siteMaintenance': |
| if(! checkUserHasPerm('Schedule Site Maintenance')) { |
| $mode = ""; |
| $actionFunction = "main"; |
| return; |
| } |
| break; |
| case 'dashboard': |
| if(! checkUserHasPerm('View Dashboard (global)') && |
| ! checkUserHasPerm('View Dashboard (affiliation only)')) { |
| $mode = ""; |
| $actionFunction = "main"; |
| return; |
| } |
| break; |
| } |
| } |
| } |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn checkCryptkey() |
| /// |
| /// \brief checks for an entry in cryptkey; if missing, generates keys |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function checkCryptkey() { |
| global $pemkey; |
| |
| $reg = "|" . SCRIPT . "$|"; |
| $filebase = preg_replace($reg, '', $_SERVER['SCRIPT_FILENAME']); |
| $filebase .= "/.ht-inc/cryptkey"; |
| $idfile = "$filebase/cryptkeyid"; |
| |
| if(is_file($idfile)) { |
| $fh = fopen($idfile, 'r'); |
| $id = fread($fh, 50); |
| fclose($fh); |
| $_id = mysql_real_escape_string($id); |
| |
| $query = "SELECT id " |
| . "FROM cryptkey " |
| . "WHERE id = '$_id'"; |
| $qh = doQuery($query); |
| if($row = mysql_fetch_assoc($qh)) |
| return; |
| } |
| |
| // if no id file and cannot write to cryptkey directory, return |
| if(! is_writable($filebase)) |
| return; |
| |
| # no id file or no matching entry in cryptkey, create new key |
| $keyfile = "$filebase/private.pem"; |
| |
| $_algorithm = constant("OPENSSL_KEYTYPE_" . ASYMALGO); |
| |
| $args = array('private_key_bits' => ASYMLEN, |
| 'private_key_type' => $_algorithm); |
| # open and lock id file before generating key |
| $fh = fopen($idfile, 'w'); |
| if(! flock($fh, LOCK_EX | LOCK_NB)) { |
| # assume collision with another web server generating a key |
| # return because when the key is needed, it should exist from |
| # the other server |
| fclose($fh); |
| return; |
| } |
| # generate key pair |
| $prikeyobj = openssl_pkey_new($args); |
| # create and secure private key file |
| touch($keyfile); |
| chmod($keyfile, 0600); |
| # save private key to file |
| $rc = openssl_pkey_export_to_file($prikeyobj, $keyfile, $pemkey); |
| if(! $rc) { |
| # release lock, close and delete file, return |
| flock($fh, LOCK_UN); |
| fclose($fh); |
| unlink($keyfile); |
| return; |
| } |
| # save public key to database |
| $tmp = openssl_pkey_get_details($prikeyobj); |
| $pubkey = $tmp['key']; |
| $query = "INSERT INTO cryptkey " |
| . "(hostid, " |
| . "hosttype, " |
| . "pubkey, " |
| . "algorithm, " |
| . "algorithmoption, " |
| . "keylength) " |
| . "SELECT COALESCE(MAX(hostid), 0) + 1, " |
| . "'web', " |
| . "'$pubkey', " |
| . "'" . ASYMALGO . "', " |
| . "'" . ASYMOPT . "', " |
| . ASYMLEN . " " |
| . "FROM cryptkey " |
| . "WHERE hosttype = 'web'"; |
| doQuery($query); |
| $cryptkeyid = dbLastInsertID(); |
| # save cryptkey id to file |
| fwrite($fh, $cryptkeyid); |
| # unlock file |
| flock($fh, LOCK_UN); |
| fclose($fh); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn maintenanceCheck() |
| /// |
| /// \brief checks for site being in maintenance; if so, read user message from |
| /// current maintenance file; print site header, maintenance message, and site |
| /// foother; then exit; also removes any old maintenance files |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function maintenanceCheck() { |
| global $authed, $mode, $user; |
| $now = time(); |
| $reg = "|" . SCRIPT . "$|"; |
| $search = preg_replace($reg, '', $_SERVER['SCRIPT_FILENAME']); |
| $search .= "/.ht-inc/maintenance/"; |
| $files = glob("{$search}[0-9]*"); |
| if(! is_array($files)) |
| return; |
| if(empty($files)) { |
| dbConnect(); |
| $query = "SELECT id " |
| . "FROM sitemaintenance " |
| . "WHERE start <= NOW() AND " |
| . "end > NOW()"; |
| $qh = doQuery($query); |
| $ids = array(); |
| while($row = mysql_fetch_assoc($qh)) |
| $ids[] = $row['id']; |
| if(empty($ids)) { |
| dbDisconnect(); |
| return; |
| } |
| $allids = implode(',', $ids); |
| $query = "UPDATE sitemaintenance " |
| . "SET end = NOW() " |
| . "WHERE id IN ($allids)"; |
| doQuery($query, 101, 'vcl', 1); |
| dbDisconnect(); |
| return; |
| } |
| $inmaintenance = 0; |
| $skin = ''; |
| foreach($files as $file) { |
| if(! preg_match("|^$search([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})$|", $file, $matches)) |
| continue; |
| #YYYYMMDDHHMM |
| $tmp = "{$matches[1]}-{$matches[2]}-{$matches[3]} {$matches[4]}:{$matches[5]}:00"; |
| $start = datetimeToUnix($tmp); |
| if($start < $now) { |
| # check to see if end time has been reached |
| $fh = fopen($file, 'r'); |
| $msg = ''; |
| while($line = fgetss($fh)) { |
| if(preg_match("/^END=([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})$/", $line, $matches)) { |
| $tmp = "{$matches[1]}-{$matches[2]}-{$matches[3]} {$matches[4]}:{$matches[5]}:00"; |
| $end = datetimeToUnix($tmp); |
| if($end < $now) { |
| fclose($fh); |
| unlink($file); |
| $_SESSION['usersessiondata'] = array(); |
| return; |
| } |
| else |
| $inmaintenance = 1; |
| } |
| elseif(preg_match("/^THEME=([-A-Za-z0-9@#_:;,\.])+$/", $line, $matches)) { |
| $skin = $matches[1]; |
| } |
| else |
| $msg .= $line; |
| } |
| fclose($fh); |
| if($inmaintenance) |
| break; |
| } |
| } |
| if($inmaintenance) { |
| $authed = 0; |
| $mode = 'inmaintenance'; |
| $user = array(); |
| if(array_key_exists('VCLSKIN', $_COOKIE)) |
| $skin = strtolower($_COOKIE['VCLSKIN']); |
| if($skin != '') { |
| $allskins = array(); |
| foreach(glob('themes/*') as $item) { |
| if(! is_dir($item)) |
| continue; |
| $tmp = explode('/', $item); |
| $item = array_pop($tmp); |
| $allskins[$item] = 1; |
| } |
| if(! array_key_exists($skin, $allskins)) |
| $skin = DEFAULTTHEME; |
| } |
| else |
| $skin = DEFAULTTHEME; |
| setVCLLocale(); |
| require_once("themes/$skin/page.php"); |
| printHTMLHeader(); |
| print "<h2>" . i("Site Currently Under Maintenance") . "</h2>\n"; |
| if(! empty($msg)) { |
| $msg = htmlentities($msg); |
| $msg = preg_replace("/\n/", "<br>\n", $msg); |
| print "$msg<br>\n"; |
| } |
| else |
| print i("This site is currently in maintenance.") . "<br>\n"; |
| $niceend = strftime('%A, %x, %l:%M %P', $end); |
| printf(i("The maintenance is scheduled to end <strong>%s</strong>.") . "<br><br><br>\n", $niceend); |
| printHTMLFooter(); |
| exit; |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn maintenanceNotice() |
| /// |
| /// \brief checks informhoursahead for upcoming maintenance items and prints |
| /// message about upcoming maintenance if currently within warning window |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function maintenanceNotice() { |
| $items = getMaintItems(); |
| foreach($items as $item) { |
| $start = datetimeToUnix($item['start']); |
| $file = date('YmdHi', $start); |
| $secahead = $item['informhoursahead'] * 3600; |
| if($start - $secahead < time()) { |
| $reg = "|" . SCRIPT . "$|"; |
| $search = preg_replace($reg, '', $_SERVER['SCRIPT_FILENAME']); |
| $search .= "/.ht-inc/maintenance/$file"; |
| $files = glob("$search"); |
| if(empty($files)) { |
| $_SESSION['usersessiondata'] = array(); |
| return; |
| } |
| $nicestart = strftime('%A, %x, %l:%M %P', $start); |
| $niceend = strftime('%A, %x, %l:%M %P', datetimeToUnix($item['end'])); |
| print "<div id=\"maintenancenotice\">\n"; |
| print "<strong>" . i("NOTICE:") . "</strong> "; |
| print i("This site will be down for maintenance during the following times:") . "<br><br>\n"; |
| print i("Start:") . " $nicestart<br>\n"; |
| print i("End:") . " $niceend.<br><br>\n"; |
| if($item['allowreservations']) { |
| print i("You will be able to access your reserved machines during this maintenance. However, you will not be able to access information on how to connect to them.") . "<br>\n"; |
| } |
| else { |
| print i("You will not be able to access any of your reservations during this maintenance.") . "<br>\n"; |
| } |
| print "</div>\n"; |
| return; |
| } |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn clearPrivCache() |
| /// |
| /// \brief sets userresources, nodeprivileges, cascadenodeprivileges, and |
| /// userhaspriv keys of $_SESSION array to empty arrays |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function clearPrivCache() { |
| $_SESSION['userresources'] = array(); |
| $_SESSION['nodeprivileges'] = array(); |
| $_SESSION['cascadenodeprivileges'] = array(); |
| $_SESSION['userhaspriv'] = array(); |
| $_SESSION['compstateflow'] = array(); |
| $_SESSION['usersessiondata'] = array(); |
| $_SESSION['variables'] = array(); |
| unset($_SESSION['user']); |
| unset($_SESSION['locales']); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn AJclearPermCache() |
| /// |
| /// \brief ajax wrapper for clearPrivCache |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function AJclearPermCache() { |
| clearPrivCache(); |
| print "alert('Permission cache cleared');"; |
| dbDisconnect(); |
| exit; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn setupSession() |
| /// |
| /// \brief starts php session and initializes useful variables |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function setupSession() { |
| global $mode; |
| if($mode == 'xmlrpccall') |
| $_SESSION = array(); |
| else |
| session_start(); |
| if(! array_key_exists('cachetimestamp', $_SESSION)) |
| $_SESSION['cachetimestamp'] = time(); |
| else { |
| if(($_SESSION['cachetimestamp'] + (PRIV_CACHE_TIMEOUT * 60)) < time()) { |
| clearPrivCache(); |
| $_SESSION['cachetimestamp'] = time(); |
| return; |
| } |
| } |
| if(! array_key_exists('userresources', $_SESSION)) |
| $_SESSION['userresources'] = array(); |
| if(! array_key_exists('nodeprivileges', $_SESSION)) |
| $_SESSION['nodeprivileges'] = array(); |
| if(! array_key_exists('cascadenodeprivileges', $_SESSION)) |
| $_SESSION['cascadenodeprivileges'] = array(); |
| if(! array_key_exists('userhaspriv', $_SESSION)) |
| $_SESSION['userhaspriv'] = array(); |
| if(! array_key_exists('compstateflow', $_SESSION)) |
| $_SESSION['compstateflow'] = array(); |
| if(! array_key_exists('usersessiondata', $_SESSION)) |
| $_SESSION['usersessiondata'] = array(); |
| if(! array_key_exists('variables', $_SESSION)) |
| $_SESSION['variables'] = array(); |
| if(! array_key_exists('persistdata', $_SESSION)) |
| $_SESSION['persistdata'] = array(); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn stopSession() |
| /// |
| /// \brief ends the user's session and prints info to notify the user |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function stopSession() { |
| $_SESSION = array(); |
| if(isset($_COOKIE[session_name()])) |
| setcookie(session_name(), "", time()-42000, '/'); |
| session_destroy(); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn main() |
| /// |
| /// \brief prints a welcome screen |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function main() { |
| global $user, $authed, $mode; |
| print "<H2>" . i("Welcome to the Virtual Computing Lab") . "</H2>\n"; |
| if($authed) { |
| if(! empty($user['lastname']) && ! empty($user['preferredname'])) |
| print i("Hello") . " {$user["preferredname"]} {$user['lastname']}<br><br>\n"; |
| elseif(! empty($user['lastname']) && ! empty($user['firstname'])) |
| print i("Hello") . " {$user["firstname"]} {$user['lastname']}<br><br>\n"; |
| $tmp = array_values($user['groups']); |
| if(count($tmp) == 1 && $tmp[0] == 'nodemo') { |
| print "Your account is a demo account that has expired. "; |
| print "You cannot make any more reservations. Please contact <a href=\""; |
| print "mailto:" . HELPEMAIL . "\">" . HELPEMAIL . "</a> if you need "; |
| print "further access to VCL.<br>\n"; |
| return; |
| } |
| $requests = getUserRequests("all", $user["id"]); |
| if($num = count($requests)) { |
| if($num == 1) |
| print i("You currently have 1 reservation.") . "<br>\n"; |
| else |
| printf(i("You currently have %d reservations.") . "<br>\n", $num); |
| } |
| else { |
| print i("You do not have any current reservations.") . "<br>\n"; |
| } |
| print i("Please make a selection from the menu to continue.") . "<br>\n"; |
| } |
| else { |
| print i("Please log in to start using the VCL system.") . "<br>\n"; |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn abort($errcode, $query) |
| /// |
| /// \param $errcode - error code |
| /// \param $query - a myql query |
| /// |
| /// \brief prints out error message(s), closes db connection, prints footer |
| /// and exits |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function abort($errcode, $query="") { |
| global $mysql_link_vcl, $mysql_link_acct, $ERRORS, $user, $mode; |
| global $ENABLE_ITECSAUTH, $requestInfo, $aborting; |
| if(! isset($aborting)) |
| $aborting = 1; |
| elseif($aborting == 1) |
| return; |
| if($mode == 'xmlrpccall') |
| xmlRPCabort($errcode, $query); |
| if(ONLINEDEBUG && checkUserHasPerm('View Debug Information')) { |
| if($errcode >= 100 && $errcode < 400) { |
| print "<font color=red>" . mysql_error($mysql_link_vcl) . "</font><br>\n"; |
| error_log(mysql_error($mysql_link_vcl)); |
| if($ENABLE_ITECSAUTH) { |
| print "<font color=red>" . mysql_error($mysql_link_acct) . "</font><br>\n"; |
| error_log(mysql_error($mysql_link_acct)); |
| } |
| print "$query<br>\n"; |
| error_log($query); |
| } |
| print "ERROR($errcode): " . $ERRORS["$errcode"] . "<BR>\n"; |
| error_log("==========================================================================="); |
| error_log("ERROR($errcode): " . $ERRORS["$errcode"]); |
| $backtrace = getBacktraceString(FALSE); |
| print "<pre>\n"; |
| print $backtrace; |
| print "</pre>\n"; |
| error_log($backtrace); |
| } |
| else { |
| $message = ""; |
| if($errcode >= 100 && $errcode < 400) { |
| $message .= mysql_error($mysql_link_vcl) . "\n"; |
| if($ENABLE_ITECSAUTH) |
| $message .= mysql_error($mysql_link_acct) . "\n"; |
| $message .= $query . "\n"; |
| } |
| $message .= "ERROR($errcode): " . $ERRORS["$errcode"] . "\n"; |
| if(is_array($user) && array_key_exists('unityid', $user)) |
| $message .= "Logged in user was " . $user["unityid"] . "\n"; |
| $message .= "Mode was $mode\n\n"; |
| if($errcode == 20) { |
| $urlArray = explode('?', $_SERVER["HTTP_REFERER"]); |
| $message .= "HTTP_REFERER URL - " . $urlArray[0] . "\n"; |
| $message .= "correct URL - " . BASEURL . SCRIPT . "\n"; |
| } |
| if($errcode == 40) { |
| $message .= "One of the following computers didn't get a mgmt node:\n"; |
| foreach($requestInfo["images"] as $key => $imageid) { |
| $message .= "imageid: $imageid\n"; |
| $message .= "compid: {$requestInfo['computers'][$key]}\n"; |
| } |
| } |
| $message .= getBacktraceString(FALSE); |
| if($errcode == 8) |
| $message = preg_replace("/Argument#: 3 => .*\n/", "Argument#: 3 => *********\n", $message); |
| $mailParams = "-f" . ENVELOPESENDER; |
| error_log($message); |
| mail(ERROREMAIL, "Error with VCL pages ($errcode)", $message, '', $mailParams); |
| $subj = rawurlencode(i("Problem With VCL")); |
| $href = "<a href=\"mailto:" . HELPEMAIL . "?Subject=$subj\">" . HELPEMAIL . "</a>"; |
| printf(i("An error has occurred. If this problem persists, please email %s for further assistance. Please include the steps you took that led up to this problem in your email message."), $href); |
| } |
| |
| // call clearPrivCache in case that helps clear up what caused the error |
| clearPrivCache(); |
| |
| // release semaphore lock |
| cleanSemaphore(); |
| dbDisconnect(); |
| printHTMLFooter(); |
| exit; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn errorrpt() |
| /// |
| /// \brief takes input from ajax call and emails error to ERROREMAIL |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function errorrpt() { |
| $mailParams = "-f" . ENVELOPESENDER; |
| mail(ERROREMAIL, "Error with VCL pages (ajax sent html wrappers)", $_POST['data'], '', $mailParams); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn validateUserid($loginid) |
| /// |
| /// \param $loginid - a submitted loginid |
| /// |
| /// \return 0 if the loginid is not found in one of the authentications |
| /// systems, 1 if it is |
| /// |
| /// \brief checks to see if $loginid is found in one of the authentication |
| /// systems |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function validateUserid($loginid) { |
| global $affilValFuncArgs, $affilValFunc; |
| if(empty($loginid)) |
| return 0; |
| |
| $rc = getAffilidAndLogin($loginid, $affilid); |
| if($rc == -1) |
| return 0; |
| |
| if(empty($affilid)) |
| return 0; |
| |
| $escloginid = mysql_real_escape_string($loginid); |
| $query = "SELECT id " |
| . "FROM user " |
| . "WHERE unityid = '$escloginid' AND " |
| . "affiliationid = $affilid"; |
| $qh = doQuery($query, 101); |
| if(mysql_num_rows($qh)) |
| return 1; |
| |
| if($rc == 0 && |
| ALLOWADDSHIBUSERS == 1 && |
| strpos($loginid, '@')) { |
| $query = "SELECT shibonly " |
| . "FROM affiliation " |
| . "WHERE id = " . DEFAULT_AFFILID; |
| $qh = doQuery($query); |
| $row = mysql_fetch_assoc($qh); |
| if($row['shibonly'] == 1) |
| return 0; |
| } |
| |
| $valfunc = $affilValFunc[$affilid]; |
| if(array_key_exists($affilid, $affilValFuncArgs)) |
| return $valfunc($affilValFuncArgs[$affilid], $loginid); |
| else |
| return $valfunc($loginid); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn AJvalidateUserid() |
| /// |
| /// \brief checks to see if submitted userid is valid |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function AJvalidateUserid() { |
| $user = processInputVar('user', ARG_STRING); |
| if(validateUserid($user)) |
| sendJSON(array('status' => 'valid')); |
| else |
| sendJSON(array('status' => 'invalid')); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getAffilidAndLogin(&$login, &$affilid) |
| /// |
| /// \param $login - login for user, may include \@affiliation |
| /// \param $affilid - variable in which to stick the affiliation id |
| /// |
| /// \return 1 if $affilid set by a registered function, 0 if set to default, |
| /// -1 if @affiliation was part of $login but did not contain a known |
| /// affiliation |
| /// |
| /// \brief tries registered affiliation lookup functions to determine the |
| /// affiliation id of the user; if it finds it, sticks the affiliationid in |
| /// $affilid and sets $login to not include \@affiliation if it did |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getAffilidAndLogin(&$login, &$affilid) { |
| global $findAffilFuncs; |
| foreach($findAffilFuncs as $func) { |
| $rc = $func($login, $affilid); |
| if($rc) |
| return $rc; |
| } |
| $affilid = DEFAULT_AFFILID; |
| return 0; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn mysql_connect_plus($host, $user, $pwd) |
| /// |
| /// \param $host - mysql host |
| /// \param $user - userid to use for connection |
| /// \param $pwd - password to use for connection |
| /// |
| /// \return mysql resource identifier, 0 if failure to connect |
| /// |
| /// \brief opens a socket connection to $host, if it is not established in 5 |
| /// seconds, returns an error, otherwise, opens a connection to the database |
| /// and returns the identifier |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function mysql_connect_plus($host, $user, $pwd) { |
| $timeout = 5; /* timeout in seconds */ |
| |
| if($fp = @fsockopen($host, 3306, $errno, $errstr, $timeout)) { |
| fclose($fp); |
| return $link = mysql_connect($host, $user, $pwd); |
| } else { |
| #print "ERROR: socket timeout<BR>\n"; |
| return 0; |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn dbConnect() |
| /// |
| /// \brief opens connections to database, the resource identifiers are\n |
| /// \b $mysql_link_vcl - for vcl database\n |
| /// \b $mysql_link_acct - for accounts database\n |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function dbConnect() { |
| global $vclhost, $vcldb, $vclusername, $vclpassword, $mysql_link_vcl; |
| global $accthost, $acctusername, $acctpassword, $mysql_link_acct; |
| global $ENABLE_ITECSAUTH; |
| |
| if($ENABLE_ITECSAUTH) { |
| // open a connection to mysql server for accounts |
| if($mysql_link_acct = mysql_connect_plus($accthost, $acctusername, $acctpassword)) |
| mysql_select_db("accounts", $mysql_link_acct); |
| else |
| $ENABLE_ITECSAUTH = 0; |
| } |
| |
| // open a connection to mysql server for vcl |
| if(! $mysql_link_vcl = mysql_connect_plus($vclhost, $vclusername, $vclpassword)) { |
| die("Error connecting to $vclhost.<br>\n"); |
| } |
| // select the vcl database |
| mysql_select_db($vcldb, $mysql_link_vcl) or abort(104); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn dbDisconnect() |
| /// |
| /// \brief closes connections to the database |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function dbDisconnect() { |
| global $mysql_link_vcl, $mysql_link_acct, $ENABLE_ITECSAUTH; |
| mysql_close($mysql_link_vcl); |
| if($ENABLE_ITECSAUTH) |
| mysql_close($mysql_link_acct); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn doQuery($query, $errcode, $db, $nolog) |
| /// |
| /// \param $query - SQL statement |
| /// \param $errcode - error code |
| /// \param $db - (optional, defaul=vcl), database to query against |
| /// \param $nolog - (optional, defaul=0), don't log to queryLog table |
| /// |
| /// \return $qh - query handle |
| /// |
| /// \brief performs the query and returns $qh or aborts on error |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function doQuery($query, $errcode=101, $db="vcl", $nolog=0) { |
| global $mysql_link_vcl, $mysql_link_acct, $user, $mode, $ENABLE_ITECSAUTH; |
| if($db == "vcl") { |
| if(QUERYLOGGING != 0 && (! $nolog) && |
| preg_match('/^(UPDATE|INSERT|DELETE)/', $query) && |
| strpos($query, 'UPDATE continuations SET expiretime = ') === FALSE) { |
| $logquery = str_replace("'", "\'", $query); |
| $logquery = str_replace('"', '\"', $logquery); |
| if(isset($user['id'])) |
| $id = $user['id']; |
| else |
| $id = 0; |
| $q = "INSERT INTO querylog " |
| . "(userid, " |
| . "timestamp, " |
| . "mode, " |
| . "query) " |
| . "VALUES " |
| . "($id, " |
| . "NOW(), " |
| . "'$mode', " |
| . "'$logquery')"; |
| mysql_query($q, $mysql_link_vcl); |
| } |
| for($i = 0; ! ($qh = mysql_query($query, $mysql_link_vcl)) && $i < 3; $i++) { |
| if(mysql_errno() == '1213') # DEADLOCK, sleep and retry |
| usleep(50); |
| else |
| abort($errcode, $query); |
| } |
| } |
| elseif($db == "accounts") { |
| if($ENABLE_ITECSAUTH) |
| $qh = mysql_query($query, $mysql_link_acct) or abort($errcode, $query); |
| else |
| $qh = NULL; |
| } |
| return $qh; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn dbLastInsertID() |
| /// |
| /// \return last insert id for $mysql_link_vcl |
| /// |
| /// \brief calls mysql_insert_id for $mysql_link_vcl |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function dbLastInsertID() { |
| global $mysql_link_vcl; |
| return mysql_insert_id($mysql_link_vcl); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getOSList() |
| /// |
| /// \return $oslist - array of OSs |
| /// |
| /// \brief builds an array of OSs |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getOSList() { |
| $query = "SELECT id, name, prettyname, type, installtype FROM OS ORDER BY prettyname"; |
| $qh = doQuery($query, "115"); |
| $oslist = array(); |
| while($row = mysql_fetch_assoc($qh)) |
| $oslist[$row['id']] = $row; |
| return $oslist; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getImages($includedeleted=0, $imageid=0) |
| /// |
| /// \param $includedeleted = (optional) 1 to show deleted images, 0 not to |
| /// \param $imageid = (optional) only get data for this image, defaults |
| /// to getting data for all images |
| /// |
| /// \return $imagelist - array of images with the following elements:\n |
| /// \b name - name of image\n |
| /// \b prettyname - pretty name of image\n |
| /// \b ownerid - userid of owner\n |
| /// \b owner - unity id of owner\n |
| /// \b platformid - platformid for the platform the image if for\n |
| /// \b platform - platform the image is for\n |
| /// \b osid - osid for the os on the image\n |
| /// \b os - os the image contains\n |
| /// \b installtype - method used to install image\n |
| /// \b ostypeid - id of the OS type in the image\n |
| /// \b ostype - name of the OS type in the image\n |
| /// \b minram - minimum amount of RAM needed for image\n |
| /// \b minprocnumber - minimum number of processors needed for image\n |
| /// \b minprocspeed - minimum speed of processor(s) needed for image\n |
| /// \b minnetwork - minimum speed of network needed for image\n |
| /// \b maxconcurrent - maximum concurrent usage of this iamge\n |
| /// \b reloadtime - time in minutes for image to be loaded\n |
| /// \b deleted - 'yes' or 'no'; whether or not this image has been deleted\n |
| /// \b test - 0 or 1; whether or not there is a test version of this image\n |
| /// \b resourceid - image's resource id from the resource table\n |
| /// \b lastupdate - datetime image was last updated\n |
| /// \b forcheckout - 0 or 1; whether or not the image is allowed to be directly |
| /// checked out\n |
| /// \b maxinitialtime - maximum time (in minutes) to be shown when requesting |
| /// a reservation that the image can reserved for\n |
| /// \b imagemetaid - NULL or corresponding id from imagemeta table and the |
| /// following additional information:\n |
| /// \b checkuser - whether or not vcld should check for a logged in user\n |
| /// \b sysprep - whether or not to use sysprep on creation of the image\n |
| /// \b connectmethods - array of enabled connect methods\n |
| /// \b subimages - an array of subimages to be loaded along with selected |
| /// image\n |
| /// \b imagerevision - an array of revision info about the image, it has these |
| /// keys: id, revision, userid, user, datecreated, prettydate, production, |
| /// imagename |
| /// |
| /// \brief generates an array of images |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getImages($includedeleted=0, $imageid=0) { |
| # key in $imagelist is for $includedeleted |
| static $imagelist = array(0 => array(), 1 => array()); |
| if(! empty($imagelist[$includedeleted])) { |
| if($imageid == 0) |
| return $imagelist[$includedeleted]; |
| else |
| return array($imageid => $imagelist[$includedeleted][$imageid]); |
| } |
| # get all image meta data |
| $allmetadata = array(); |
| $query = "SELECT checkuser, " |
| . "rootaccess, " |
| . "subimages, " |
| . "sysprep, " |
| . "sethostname, " |
| . "id " |
| . "FROM imagemeta"; |
| $qh = doQuery($query); |
| while($row = mysql_fetch_assoc($qh)) |
| $allmetadata[$row['id']] = $row; |
| |
| # get all image revision data |
| $allrevisiondata = array(); |
| $query = "SELECT i.id, " |
| . "i.imageid, " |
| . "i.revision, " |
| . "i.userid, " |
| . "CONCAT(u.unityid, '@', a.name) AS user, " |
| . "i.datecreated, " |
| . "DATE_FORMAT(i.datecreated, '%c/%d/%y %l:%i %p') AS prettydate, " |
| . "i.deleted, " |
| . "i.datedeleted, " |
| . "i.production, " |
| . "i.imagename " |
| . "FROM imagerevision i, " |
| . "affiliation a, " |
| . "user u " |
| . "WHERE i.userid = u.id AND "; |
| if(! $includedeleted) |
| $query .= "i.deleted = 0 AND "; |
| $query .= "u.affiliationid = a.id"; |
| $qh = doQuery($query, 101); |
| while($row = mysql_fetch_assoc($qh)) { |
| $id = $row['imageid']; |
| unset($row['imageid']); |
| $allrevisiondata[$id][$row['id']] = $row; |
| } |
| $query = "SELECT i.id AS id," |
| . "i.name AS name, " |
| . "i.prettyname AS prettyname, " |
| . "i.ownerid AS ownerid, " |
| . "CONCAT(u.unityid, '@', a.name) AS owner, " |
| . "i.platformid AS platformid, " |
| . "p.name AS platform, " |
| . "i.OSid AS osid, " |
| . "o.name AS os, " |
| . "o.installtype, " |
| . "ot.id AS ostypeid, " |
| . "ot.name AS ostype, " |
| . "i.minram AS minram, " |
| . "i.minprocnumber AS minprocnumber, " |
| . "i.minprocspeed AS minprocspeed, " |
| . "i.minnetwork AS minnetwork, " |
| . "i.maxconcurrent AS maxconcurrent, " |
| . "i.reloadtime AS reloadtime, " |
| . "i.deleted AS deleted, " |
| . "i.test AS test, " |
| . "r.id AS resourceid, " |
| . "i.lastupdate, " |
| . "i.forcheckout, " |
| . "i.maxinitialtime, " |
| . "i.imagemetaid, " |
| . "ad.id AS addomainid, " |
| . "ad.name AS addomain, " |
| . "iadd.baseOU " |
| . "FROM platform p, " |
| . "OS o, " |
| . "OStype ot, " |
| . "resource r, " |
| . "resourcetype t, " |
| . "user u, " |
| . "affiliation a, " |
| . "image i " |
| . "LEFT JOIN imageaddomain iadd ON (i.id = iadd.imageid) " |
| . "LEFT JOIN addomain ad ON (iadd.addomainid = ad.id) " |
| . "WHERE i.platformid = p.id AND " |
| . "r.resourcetypeid = t.id AND " |
| . "t.name = 'image' AND " |
| . "r.subid = i.id AND " |
| . "i.OSid = o.id AND " |
| . "o.type = ot.name AND " |
| . "i.ownerid = u.id AND " |
| . "u.affiliationid = a.id "; |
| if(! $includedeleted) |
| $query .= "AND i.deleted = 0 "; |
| $query .= "ORDER BY i.prettyname"; |
| $qh = doQuery($query, 120); |
| while($row = mysql_fetch_assoc($qh)) { |
| if(is_null($row['maxconcurrent'])) |
| $row['maxconcurrent'] = 0; |
| $imagelist[$includedeleted][$row["id"]] = $row; |
| $imagelist[$includedeleted][$row["id"]]['checkuser'] = 1; |
| $imagelist[$includedeleted][$row["id"]]['rootaccess'] = 1; |
| if($row['ostype'] == 'windows' || $row['ostype'] == 'osx') |
| $imagelist[$includedeleted][$row['id']]['sethostname'] = 0; |
| else |
| $imagelist[$includedeleted][$row['id']]['sethostname'] = 1; |
| $imagelist[$includedeleted][$row['id']]['adauthenabled'] = 0; |
| if($row['addomainid'] != NULL) |
| $imagelist[$includedeleted][$row['id']]['adauthenabled'] = 1; |
| if($row["imagemetaid"] != NULL) { |
| if(isset($allmetadata[$row['imagemetaid']])) { |
| $metaid = $row['imagemetaid']; |
| $imagelist[$includedeleted][$row['id']]['checkuser'] = $allmetadata[$metaid]['checkuser']; |
| $imagelist[$includedeleted][$row['id']]['rootaccess'] = $allmetadata[$metaid]['rootaccess']; |
| $imagelist[$includedeleted][$row['id']]['sysprep'] = $allmetadata[$metaid]['sysprep']; |
| if($allmetadata[$metaid]['sethostname'] != NULL) |
| $imagelist[$includedeleted][$row['id']]['sethostname'] = $allmetadata[$metaid]['sethostname']; |
| $imagelist[$includedeleted][$row["id"]]["subimages"] = array(); |
| if($allmetadata[$metaid]["subimages"]) { |
| $query2 = "SELECT imageid " |
| . "FROM subimages " |
| . "WHERE imagemetaid = $metaid"; |
| $qh2 = doQuery($query2, 101); |
| while($row2 = mysql_fetch_assoc($qh2)) |
| $imagelist[$includedeleted][$row["id"]]["subimages"][] = $row2["imageid"]; |
| } |
| } |
| else |
| $imagelist[$includedeleted][$row["id"]]["imagemetaid"] = NULL; |
| } |
| if(isset($allrevisiondata[$row['id']])) |
| $imagelist[$includedeleted][$row['id']]['imagerevision'] = $allrevisiondata[$row['id']]; |
| $imagelist[$includedeleted][$row['id']]['connectmethods'] = getImageConnectMethods($row['id']); |
| } |
| if($imageid != 0) |
| return array($imageid => $imagelist[$includedeleted][$imageid]); |
| return $imagelist[$includedeleted]; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getServerProfiles($id) |
| /// |
| /// \param $id - (optional) if specified, only return data for specified profile |
| /// |
| /// \return an array where each key is a profile id whose value is an array with |
| /// these values:\n |
| /// \b name - profile name\n |
| /// \b description - profile description\n |
| /// \b imageid - id of image associated with profile\n |
| /// \b image - pretty name of image associated with profile\n |
| /// \b ownerid - user id of owner of profile\n |
| /// \b owner - unityid of owner of profile\n |
| /// \b fixedIP - IP address to be used with deployed profile\n |
| /// \b fixedMAC - MAC address to be used with deployed profile\n |
| /// \b admingroupid - id of admin user group associated with profile\n |
| /// \b admingroup - name of admin user group associated with profile\n |
| /// \b logingroupid - id of login user group associated with profile\n |
| /// \b logingroup - name of login user group associated with profile\n |
| /// \b monitored - whether or not deployed profile should be monitored\n |
| /// \b resourceid - resource id of profile |
| /// |
| /// \brief gets information about server profiles |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| /*function getServerProfiles($id=0) { |
| $key = getKey(array('getServerProfiles', $id)); |
| if(isset($_SESSION['usersessiondata'][$key])) |
| return $_SESSION['usersessiondata'][$key]; |
| |
| $fixeddata = array(); |
| $query = "SELECT name, value FROM variable WHERE name LIKE 'fixedIPsp%'"; |
| $qh = doQuery($query); |
| while($row = mysql_fetch_assoc($qh)) { |
| $spid = str_replace('fixedIPsp', '', $row['name']); |
| $fixeddata[$spid] = Spyc::YAMLLoad($row['value']); |
| } |
| |
| $query = "SELECT s.id, " |
| . "s.name, " |
| . "s.description, " |
| . "s.imageid, " |
| . "i.prettyname AS image, " |
| . "s.ownerid, " |
| . "CONCAT(u.unityid, '@', a.name) AS owner, " |
| . "s.fixedIP, " |
| . "s.fixedMAC, " |
| . "s.admingroupid, " |
| . "CONCAT(ga.name, '@', aa.name) AS admingroup, " |
| . "s.logingroupid, " |
| . "CONCAT(gl.name, '@', al.name) AS logingroup, " |
| . "s.monitored, " |
| . "r.id AS resourceid " |
| . "FROM serverprofile s " |
| . "LEFT JOIN image i ON (i.id = s.imageid) " |
| . "LEFT JOIN user u ON (u.id = s.ownerid) " |
| . "LEFT JOIN affiliation a ON (a.id = u.affiliationid) " |
| . "LEFT JOIN usergroup ga ON (ga.id = s.admingroupid) " |
| . "LEFT JOIN affiliation aa ON (aa.id = ga.affiliationid) " |
| . "LEFT JOIN usergroup gl ON (gl.id = s.logingroupid) " |
| . "LEFT JOIN affiliation al ON (al.id = gl.affiliationid) " |
| . "LEFT JOIN resource r ON (r.subid = s.id) " |
| . "WHERE r.resourcetypeid = 17 "; |
| if($id != 0) |
| $query .= "AND s.id = $id"; |
| else |
| $query .= "ORDER BY name"; |
| $qh = doQuery($query, 101); |
| $profiles = array(); |
| while($row = mysql_fetch_assoc($qh)) { |
| $profiles[$row['id']] = $row; |
| if(isset($fixeddata[$row['id']])) { |
| $profiles[$row['id']]['netmask'] = $fixeddata[$row['id']]['netmask']; |
| $profiles[$row['id']]['router'] = $fixeddata[$row['id']]['router']; |
| $profiles[$row['id']]['dns'] = implode(',', $fixeddata[$row['id']]['dns']); |
| } |
| else { |
| $profiles[$row['id']]['netmask'] = ''; |
| $profiles[$row['id']]['router'] = ''; |
| $profiles[$row['id']]['dns'] = ''; |
| } |
| } |
| $_SESSION['usersessiondata'][$key] = $profiles; |
| return $profiles; |
| }*/ |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getServerProfileImages($userid) |
| /// |
| /// \param $userid - id from user table |
| /// |
| /// \return array where the key is the id of the image and the value is the |
| /// prettyname of the image |
| /// |
| /// \brief builds an array of images that user has access to via server profiles |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| /*function getServerProfileImages($userid) { |
| $key = getKey(array('getServerProfileImages', $userid)); |
| if(isset($_SESSION['usersessiondata'][$key])) |
| return $_SESSION['usersessiondata'][$key]; |
| $resources = getUserResources(array('serverCheckOut', 'serverProfileAdmin'), |
| array('available', 'administer')); |
| $ids = array_keys($resources['serverprofile']); |
| $inids = implode(',', $ids); |
| if(empty($inids)) { |
| $_SESSION['usersessiondata'][$key] = array(); |
| return array(); |
| } |
| $query = "SELECT i.id, " |
| . "i.prettyname AS image " |
| . "FROM serverprofile s, " |
| . "image i " |
| . "WHERE s.imageid = i.id AND " |
| . "s.id IN ($inids)"; |
| $qh = doQuery($query, 101); |
| $profiles = array(); |
| while($row = mysql_fetch_assoc($qh)) |
| $profiles[$row['id']] = $row['image']; |
| $_SESSION['usersessiondata'][$key] = $profiles; |
| return $profiles; |
| }*/ |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getImageRevisions($imageid, $incdeleted) |
| /// |
| /// \param $imageid - id of an image |
| /// \param $incdeleted - (optional, defaults to 0) 1 to include deleted images |
| /// |
| /// \return an array where each key is the id of the image revision and each |
| /// element has these values:\n |
| /// \b id - id of revision\n |
| /// \b revision - revision number\n |
| /// \b creatorid - user id of person that created the revision\n |
| /// \b creator - user@affiliation\n |
| /// \b datecreated - datetime of when revision was created\n |
| /// \b deleted - 1 if deleted, 0 if not\n |
| /// \b production - 1 if production revision, 0 if not\n |
| /// \b comments - comments about the revision\n |
| /// \b imagename - name for files related to revision |
| /// |
| /// \brief gets image revision data related to $imageid |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getImageRevisions($imageid, $incdeleted=0) { |
| $query = "SELECT i.id, " |
| . "i.revision, " |
| . "i.userid AS creatorid, " |
| . "CONCAT(u.unityid, '@', a.name) AS creator, " |
| . "i.datecreated, " |
| . "i.deleted, " |
| . "i.production, " |
| . "i.comments, " |
| . "i.imagename " |
| . "FROM imagerevision i, " |
| . "user u, " |
| . "affiliation a " |
| . "WHERE i.userid = u.id " |
| . "AND u.affiliationid = a.id " |
| . "AND i.imageid = $imageid"; |
| if(! $incdeleted) |
| $query .= " AND i.deleted = 0"; |
| $query .= " ORDER BY revision"; |
| $qh = doQuery($query, 101); |
| $return = array(); |
| while($row = mysql_fetch_assoc($qh)) |
| $return[$row['id']] = $row; |
| return $return; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getImageNotes($imageid) |
| /// |
| /// \param $imageid - id of an image |
| /// \param $revisionid - image revision id |
| /// |
| /// \return an array with these keys:\n |
| /// \b description - description of image\n |
| /// \b usage - notes on using the image |
| /// |
| /// \brief gets data from the imageinfo table for $imageid and $revisionid |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getImageNotes($imageid) { |
| if(empty($imageid)) |
| $imageid = 0; |
| $query = "SELECT description, " |
| . "`usage` " |
| . "FROM image " |
| . "WHERE id = $imageid"; |
| $qh = doQuery($query, 101); |
| if($row = mysql_fetch_assoc($qh)) |
| return $row; |
| else |
| return array('description' => '', 'usage' => ''); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getImageConnectMethods($imageid, $revisionid, $nostatic=0) |
| /// |
| /// \param $imageid - id of an image |
| /// \param $revisionid - (optional, default=0) revision id of image |
| /// \param $nostatic - (optional, default=0) pass 1 to keep from using the |
| /// static variable defined in the function |
| /// |
| /// \return an array of connect methods enabled for specified image where the |
| /// key is the id of the connect method and the value is the description |
| /// |
| /// \brief builds an array of connect methods enabled for the image |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getImageConnectMethods($imageid, $revisionid=0, $nostatic=0) { |
| $key = getKey(array('getImageConnectMethods', (int)$imageid, (int)$revisionid)); |
| if(isset($_SESSION['usersessiondata'][$key])) |
| return $_SESSION['usersessiondata'][$key]; |
| if($revisionid == 0) |
| $revisionid = getProductionRevisionid($imageid, $nostatic); |
| if($revisionid == '') { |
| $_SESSION['usersessiondata'][$key] = array(); |
| return array(); |
| } |
| |
| static $allmethods = array(); |
| if($nostatic) |
| $allmethods = array(); |
| |
| if(empty($allmethods)) { |
| $query = "DROP TEMPORARY TABLE IF EXISTS imageconnectmethods"; |
| doQuery($query); |
| $query = "CREATE TEMPORARY TABLE imageconnectmethods ( " |
| . "imageid smallint(5) unsigned NOT NULL, " |
| . "imagerevisionid mediumint(8) unsigned NOT NULL, " |
| . "connectmethodid tinyint unsigned NOT NULL, " |
| . "description varchar(255) NOT NULL, " |
| . "disabled tinyint(1) unsigned NOT NULL, " |
| . "UNIQUE KEY (imagerevisionid, connectmethodid, disabled) " |
| . ") ENGINE=MEMORY"; |
| doQuery($query, 101); |
| |
| $qbase = "INSERT IGNORE INTO imageconnectmethods " |
| . "SELECT DISTINCT i.id, " |
| . "ir.id, " |
| . "c.id, " |
| . "c.description, " |
| . "cm.disabled " |
| . "FROM image i " |
| . "LEFT JOIN OS o ON (o.id = i.OSid) " |
| . "LEFT JOIN OStype ot ON (ot.name = o.type) " |
| . "LEFT JOIN imagerevision ir ON (ir.imageid = i.id) " |
| . "LEFT JOIN connectmethodmap cm ON (%s) " |
| . "LEFT JOIN connectmethod c ON (cm.connectmethodid = c.id) " |
| . "WHERE cm.autoprovisioned IS NULL " |
| . "HAVING c.id IS NOT NULL " |
| . "ORDER BY i.id, " |
| . "cm.disabled, " |
| . "c.description"; |
| $query = sprintf($qbase, "cm.OStypeid = ot.id"); |
| doQuery($query); |
| $query = sprintf($qbase, "cm.OSid = o.id"); |
| doQuery($query); |
| $query = sprintf($qbase, "cm.imagerevisionid = ir.id"); |
| doQuery($query); |
| |
| $query = "SELECT imageid, " |
| . "imagerevisionid, " |
| . "connectmethodid, " |
| . "description, " |
| . "disabled " |
| . "FROM imageconnectmethods " |
| . "ORDER BY imagerevisionid, " |
| . "connectmethodid, " |
| . "disabled"; |
| |
| $qh = doQuery($query); |
| while($row = mysql_fetch_assoc($qh)) { |
| if($row['disabled'] && |
| isset($allmethods[$row['imageid']][$row['imagerevisionid']][$row['connectmethodid']])) |
| unset($allmethods[$row['imageid']][$row['imagerevisionid']][$row['connectmethodid']]); |
| else |
| $allmethods[$row['imageid']][$row['imagerevisionid']][$row['connectmethodid']] = $row['description']; |
| } |
| } |
| if(! isset($allmethods[$imageid][$revisionid])) { |
| $_SESSION['usersessiondata'][$key] = array(); |
| return array(); |
| } |
| $methods = $allmethods[$imageid][$revisionid]; |
| $_SESSION['usersessiondata'][$key] = $methods; |
| return $methods; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getImageConnectMethodTexts($imageid, $revisionid) |
| /// |
| /// \param $imageid - id of an image |
| /// \param $revisionid - (optional, default=0) revision id of image |
| /// |
| /// \return an array of connect method texts enabled for specified image where |
| /// the key is the id of the connect method and the value is the connecttext |
| /// |
| /// \brief builds an array of connect methods enabled for the image |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getImageConnectMethodTexts($imageid, $revisionid=0) { |
| global $locale; |
| $descfield = 'description'; |
| $textfield = 'connecttext'; |
| if(! preg_match('/^en/', $locale)) { |
| $query = "DESC connectmethod"; |
| $qh = doQuery($query, 101); |
| while($row = mysql_fetch_assoc($qh)) { |
| if($row['Field'] == "description_$locale") |
| $descfield = "description_$locale"; |
| if($row['Field'] == "connecttext_$locale") |
| $textfield = "connecttext_$locale"; |
| } |
| } |
| $cmports = array(); |
| $query = "SELECT id, " |
| . "connectmethodid, " |
| . "port, " |
| . "protocol " |
| . "FROM connectmethodport"; |
| $qh = doQuery($query); |
| while($row = mysql_fetch_assoc($qh)) { |
| $row['key'] = "#Port-{$row['protocol']}-{$row['port']}#"; |
| $cmports[$row['connectmethodid']][] = $row; |
| } |
| if($revisionid == 0) |
| $revisionid = getProductionRevisionid($imageid); |
| $query = "SELECT c.id, " |
| . "c.`$descfield` AS description, " |
| . "c.`$textfield` AS connecttext, " |
| . "cm.disabled " |
| . "FROM connectmethod c, " |
| . "connectmethodmap cm, " |
| . "image i " |
| . "LEFT JOIN OS o ON (o.id = i.OSid) " |
| . "LEFT JOIN OStype ot ON (ot.name = o.type) " |
| . "WHERE i.id = $imageid AND " |
| . "cm.connectmethodid = c.id AND " |
| . "cm.autoprovisioned IS NULL AND " |
| . "(cm.OStypeid = ot.id OR " |
| . "cm.OSid = o.id OR " |
| . "cm.imagerevisionid = $revisionid) " |
| . "ORDER BY cm.disabled, " |
| . "c.`$descfield`"; |
| $methods = array(); |
| $qh = doQuery($query, 101); |
| while($row = mysql_fetch_assoc($qh)) { |
| if($row['disabled']) { |
| if(isset($methods[$row['id']])) |
| unset($methods[$row['id']]); |
| } |
| else |
| $methods[$row['id']] = array('description' => $row['description'], |
| 'connecttext' => $row['connecttext'], |
| 'ports' => $cmports[$row['id']]); |
| } |
| return $methods; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getImageTypes() |
| /// |
| /// \return array of image types where each key is the id and each value is the |
| /// name |
| /// |
| /// \brief builds an array of image types from the imagetype table |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getImageTypes() { |
| $query = "SELECT id, name FROM imagetype ORDER BY name"; |
| $qh = doQuery($query); |
| $data = array(); |
| while($row = mysql_fetch_assoc($qh)) |
| $data[$row['id']] = $row['name']; |
| return $data; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn checkClearImageMeta($imagemetaid, $imageid, $ignorefield) |
| /// |
| /// \param $imagemetaid - id from imagemeta table |
| /// \param $imageid - id from image table |
| /// \param $ignorefield - (optional, default='') field to ignore being different |
| /// from default |
| /// |
| /// \return 0 if imagemeta entry was not deleted, 1 if it was |
| /// |
| /// \brief checks to see if all values of the imagemeta table are defaults, and |
| /// if so, deletes the entry and sets imagemetaid to NULL in image table |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function checkClearImageMeta($imagemetaid, $imageid, $ignorefield='') { |
| # get defaults for imagemeta table |
| $query = "DESC imagemeta"; |
| $qh = doQuery($query, 101); |
| $defaults = array(); |
| while($row = mysql_fetch_assoc($qh)) |
| $defaults[$row['Field']] = $row['Default']; |
| # get imagemeta data |
| $query = "SELECT * FROM imagemeta WHERE id = $imagemetaid"; |
| $qh = doQuery($query, 101); |
| $row = mysql_fetch_assoc($qh); |
| $alldefaults = 1; |
| if(mysql_num_rows($qh) == 0) |
| # it is possible that the imagemeta record could have been deleted before |
| # this was submitted |
| return 1; |
| foreach($row as $field => $val) { |
| if($field == 'id' || $field == $ignorefield) |
| continue; |
| if($defaults[$field] != $val) { |
| $alldefaults = 0; |
| break; |
| } |
| } |
| // if all default values, delete imagemeta entry |
| if($alldefaults) { |
| $query = "DELETE FROM imagemeta WHERE id = $imagemetaid"; |
| doQuery($query, 101); |
| $query = "UPDATE image SET imagemetaid = NULL WHERE id = $imageid"; |
| doQuery($query, 101); |
| return 1; |
| } |
| return 0; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getProductionRevisionid($imageid, $nostatic=0) |
| /// |
| /// \param $imageid |
| /// \param $nostatic - (optional, default=0) pass 1 to keep from using the |
| /// static variable defined in the function |
| /// |
| /// \return the production revision id for $imageid |
| /// |
| /// \brief gets the production revision id for $imageid from the imagerevision |
| /// table |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getProductionRevisionid($imageid, $nostatic=0) { |
| static $alldata = array(); |
| if($nostatic) |
| $alldata = array(); |
| if(! empty($alldata)) |
| if(isset($alldata[$imageid])) |
| return $alldata[$imageid]; |
| else |
| return ''; |
| $query = "SELECT id, " |
| . "imageid " |
| . "FROM imagerevision " |
| . "WHERE production = 1"; |
| $qh = doQuery($query, 101); |
| while($row = mysql_fetch_assoc($qh)) |
| $alldata[$row['imageid']] = $row['id']; |
| return $alldata[$imageid]; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn removeNoCheckout($images) |
| /// |
| /// \param $images - an array of images |
| /// |
| /// \return an array of images with the images that have forcheckout == 0 |
| /// removed |
| /// |
| /// \brief removes any images in $images that have forcheckout == 0 |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function removeNoCheckout($images) { |
| $allimages = getImages(); |
| foreach(array_keys($images) as $id) { |
| if(isset($allimages[$id]) && ! $allimages[$id]["forcheckout"]) |
| unset($images[$id]); |
| } |
| return $images; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getUserResources($userprivs, $resourceprivs, $onlygroups, |
| /// $includedeleted, $userid, $groupid) |
| /// |
| /// \param $userprivs - array of privileges to look for (such as |
| /// imageAdmin, imageCheckOut, etc) - this is an OR list; don't include 'block' |
| /// or 'cascade' |
| /// \param $resourceprivs - array of privileges to look for (such as |
| /// available, administer, manageGroup) - this is an OR list; don't include |
| /// 'block' or 'cascade' |
| /// \param $onlygroups - (optional) if 1, return the resource groups instead |
| /// of the resources |
| /// \param $includedeleted - (optional) included deleted resources if 1, |
| /// don't if 0 |
| /// \param $userid - (optional) id from the user table, if not given, use the |
| /// id of the currently logged in user |
| /// \param $groupid - (optional) id from the usergroup table, if not given, look |
| /// up by $userid; $userid must be 0 to look up by $groupid |
| /// |
| /// \return an array of 2 arrays where the first indexes are resource types |
| /// and each one's arrays are a list of resources available to the user where |
| /// the index of each item is the id and the value is the name of the |
| /// resource\n |
| /// if $onlygroups == 1:\n |
| /// {[computer] => {[groupid] => "groupname",\n |
| /// [groupid] => "groupname"},\n |
| /// [image] => {[groupid] => "groupname",\n |
| /// [groupid] => "groupname"},\n |
| /// ...}\n |
| /// if $onlygroups == 0:\n |
| /// {[computer] => {[compid] => "hostname",\n |
| /// [compid] => "hosename"},\n |
| /// [image] => {[imageid] => "prettyname",\n |
| /// [imageid] => "prettyname"},\n |
| /// ...} |
| /// |
| /// \brief builds a list of resources a user has access to and returns it |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getUserResources($userprivs, $resourceprivs=array("available"), |
| $onlygroups=0, $includedeleted=0, $userid=0, |
| $groupid=0) { |
| global $user; |
| if(isset($userprivs['managementnodeAdmin'])) |
| $userprivs[] = 'mgmtNodeAdmin'; |
| $key = getKey(array($userprivs, $resourceprivs, $onlygroups, $includedeleted, $userid, $groupid)); |
| if(isset($_SESSION['userresources'][$key])) |
| return $_SESSION['userresources'][$key]; |
| #FIXME this whole function could be much more efficient |
| $bygroup = 0; |
| if($userid == 0 && $groupid != 0) |
| $bygroup = 1; |
| if(! $userid) |
| $userid = $user["id"]; |
| $return = array(); |
| |
| $nodeprivs = array(); |
| $startnodes = array(); |
| # build a list of nodes where user is granted $userprivs |
| $inlist = "'" . implode("','", $userprivs) . "'"; |
| $query = "SELECT u.privnodeid " |
| . "FROM userpriv u, " |
| . "userprivtype t " |
| . "WHERE u.userprivtypeid = t.id AND " |
| . "t.name IN ($inlist) AND "; |
| if(! $bygroup) { |
| $query .= "(u.userid = $userid OR " |
| . "u.usergroupid IN (SELECT usergroupid " |
| . "FROM usergroupmembers " |
| . "WHERE userid = $userid))"; |
| } |
| else |
| $query .= "u.usergroupid = $groupid"; |
| $qh = doQuery($query, 101); |
| while($row = mysql_fetch_assoc($qh)) { |
| array_push($startnodes, $row["privnodeid"]); |
| } |
| # build data array from userprivtype and userpriv tables to reduce queries |
| # in addNodeUserResourcePrivs |
| $privdataset = array('user' => array(), 'usergroup' => array()); |
| $query = "SELECT t.name, " |
| . "u.privnodeid " |
| . "FROM userprivtype t, " |
| . "userpriv u " |
| . "WHERE u.userprivtypeid = t.id AND " |
| . "u.userid IS NOT NULL AND " |
| . "u.userid = $userid AND " |
| . "t.name IN ('block','cascade',$inlist)"; |
| $qh = doQuery($query); |
| while($row = mysql_fetch_assoc($qh)) |
| $privdataset['user'][$row['privnodeid']][] = $row['name']; |
| $query = "SELECT t.name, " |
| . "u.usergroupid, " |
| . "u.privnodeid " |
| . "FROM userprivtype t, " |
| . "userpriv u " |
| . "WHERE u.userprivtypeid = t.id AND " |
| . "u.usergroupid IS NOT NULL AND "; |
| if($bygroup) |
| $query .= "u.usergroupid = $groupid AND "; |
| else |
| $query .= "u.usergroupid IN (SELECT usergroupid " |
| . "FROM usergroupmembers " |
| . "WHERE userid = $userid) AND "; |
| $query .= "t.name IN ('block','cascade',$inlist) " |
| . "ORDER BY u.privnodeid, " |
| . "u.usergroupid"; |
| $qh = doQuery($query, 101); |
| while($row = mysql_fetch_assoc($qh)) |
| $privdataset['usergroup'][$row['privnodeid']][] = array('name' => $row['name'], 'groupid' => $row['usergroupid']); |
| |
| # travel up tree looking at privileges granted at parent nodes |
| foreach($startnodes as $nodeid) { |
| getUserResourcesUp($nodeprivs, $nodeid, $userid, $userprivs, $privdataset); |
| } |
| # travel down tree looking at privileges granted at child nodes if cascade privs at this node |
| foreach($startnodes as $nodeid) { |
| getUserResourcesDown($nodeprivs, $nodeid, $userid, $userprivs, $privdataset); |
| } |
| $nodeprivs = simplifyNodePrivs($nodeprivs, $userprivs); // call this before calling addUserResources |
| addUserResources($nodeprivs, $userid); |
| |
| # build a list of resource groups user has access to |
| $resourcegroups = array(); |
| $types = getTypes("resources"); |
| foreach($types["resources"] as $type) { |
| $resourcegroups[$type] = array(); |
| } |
| foreach(array_keys($nodeprivs) as $nodeid) { |
| // if user doesn't have privs at this node, no need to look |
| // at any resource groups here |
| $haspriv = 0; |
| foreach($userprivs as $priv) { |
| if($nodeprivs[$nodeid][$priv]) |
| $haspriv = 1; |
| } |
| if(! $haspriv) |
| continue; |
| # check to see if resource groups has any of $resourceprivs at this node |
| foreach(array_keys($nodeprivs[$nodeid]["resources"]) as $resourceid) { |
| foreach($resourceprivs as $priv) { |
| if(isset($nodeprivs[$nodeid]["resources"][$resourceid][$priv])) { |
| list($type, $name, $id) = explode('/', $resourceid); |
| $resourcegroups[$type][$id] = $name; |
| } |
| } |
| } |
| # check to see if resource groups has any of $resourceprivs cascaded to this node |
| foreach(array_keys($nodeprivs[$nodeid]["cascaderesources"]) as $resourceid) { |
| foreach($resourceprivs as $priv) { |
| if(isset($nodeprivs[$nodeid]["cascaderesources"][$resourceid][$priv]) && |
| ! (isset($nodeprivs[$nodeid]["resources"][$resourceid]["block"]))) { |
| list($type, $name, $id) = explode('/', $resourceid); |
| $resourcegroups[$type][$id] = $name; |
| } |
| } |
| } |
| } |
| |
| if(! $bygroup) |
| addOwnedResourceGroups($resourcegroups, $userid); |
| if($onlygroups) { |
| foreach(array_keys($resourcegroups) as $type) |
| uasort($resourcegroups[$type], "sortKeepIndex"); |
| $_SESSION['userresources'][$key] = $resourcegroups; |
| return $resourcegroups; |
| } |
| |
| $resources = array(); |
| foreach(array_keys($resourcegroups) as $type) { |
| $resources[$type] = |
| getResourcesFromGroups($resourcegroups[$type], $type, $includedeleted); |
| } |
| if(! $bygroup) |
| addOwnedResources($resources, $includedeleted, $userid); |
| $noimageid = getImageId('noimage'); |
| if(isset($resources['image'][$noimageid])) |
| unset($resources['image'][$noimageid]); |
| $_SESSION['userresources'][$key] = $resources; |
| return $resources; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getUserResourcesUp(&$nodeprivs, $nodeid, $userid, |
| /// $resourceprivs, $privdataset) |
| /// |
| /// \param $nodeprivs - node privilege array used in getUserResources |
| /// \param $nodeid - an id from the nodepriv table |
| /// \param $userid - an id from the user table |
| /// \param $resourceprivs - array of privileges to look for (such as |
| /// imageAdmin, imageCheckOut, etc); don't include 'block' or 'cascade' |
| /// \param $privdataset - array of data from userpriv table built in |
| /// getUserResources function |
| /// |
| /// \return modifies $nodeprivs, but doesn't return anything |
| /// |
| /// \brief adds resource privileges to $nodeprivs for the parents of $nodeid |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getUserResourcesUp(&$nodeprivs, $nodeid, $userid, |
| $resourceprivs, $privdataset) { |
| # build list of parent nodes |
| # starting at top, get images available at that node and user privs there and |
| # walk down to $nodeid |
| $nodelist = getParentNodes($nodeid); |
| array_unshift($nodelist, $nodeid); |
| $lastid = 0; |
| while(count($nodelist)) { |
| $id = array_pop($nodelist); |
| if(isset($nodeprivs[$id])) |
| continue; |
| |
| addNodeUserResourcePrivs($nodeprivs, $id, $lastid, $userid, $resourceprivs, $privdataset); |
| $lastid = $id; |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getUserResourcesDown(&$nodeprivs, $nodeid, $userid, |
| /// $resourceprivs, $privdataset) |
| /// |
| /// \param $nodeprivs - node privilege array used in getUserResources |
| /// \param $nodeid - an id from the nodepriv table |
| /// \param $userid - an id from the user table |
| /// \param $resourceprivs - array of privileges to look for (such as |
| /// imageAdmin, imageCheckOut, etc); don't include 'block' or 'cascade' |
| /// \param $privdataset - array of data from userpriv table built in |
| /// getUserResources function |
| /// |
| /// \return modifies $nodeprivs, but doesn't return anything |
| /// |
| /// \brief recursively adds resource privileges to $nodeprivs for any children |
| /// of $nodeid |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getUserResourcesDown(&$nodeprivs, $nodeid, $userid, |
| $resourceprivs, $privdataset) { |
| # FIXME can we check for cascading and if not there, don't descend? |
| $children = getChildNodes($nodeid); |
| foreach($children as $id => $tmp) { |
| addNodeUserResourcePrivs($nodeprivs, $id, $nodeid, $userid, $resourceprivs, $privdataset); |
| getUserResourcesDown($nodeprivs, $id, $userid, $resourceprivs, $privdataset); |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn addNodeUserResourcePrivs(&$nodeprivs, $id, $lastid, $userid, |
| /// $resourceprivs, $privdataset) |
| /// |
| /// \param $nodeprivs - node privilege array used in getUserResources |
| /// \param $id - an id from the nodepriv table |
| /// \param $lastid - $id's parent, 0 if at the root |
| /// \param $userid - an id from the user table |
| /// \param $resourceprivs - array of privileges to look for (such as |
| /// imageAdmin, imageCheckOut, etc); don't include 'block' or 'cascade' |
| /// \param $privdataset - array of data from userpriv table built in |
| /// getUserResources function |
| /// |
| /// \return modifies $nodeprivs, but doesn't return anything |
| /// |
| /// \brief for $id, gets privileges and cascaded privileges the user and any |
| /// groups the user is and adds them to $nodeprivs |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function addNodeUserResourcePrivs(&$nodeprivs, $id, $lastid, $userid, |
| $resourceprivs, $privdataset) { |
| $nodeprivs[$id]["user"] = array("cascade" => 0); |
| foreach($resourceprivs as $priv) { |
| $nodeprivs[$id]["user"][$priv] = 0; |
| } |
| |
| # add permissions for user |
| $block = 0; |
| if(isset($privdataset['user'][$id])) { |
| foreach($privdataset['user'][$id] as $name) { |
| if($name != 'block') |
| $nodeprivs[$id]['user'][$name] = 1; |
| else |
| $block = 1; |
| } |
| } |
| // if don't have anything in $resourceprivs, set cascade = 0 |
| if($nodeprivs[$id]["user"]["cascade"]) { |
| $noprivs = 1; |
| foreach($resourceprivs as $priv) { |
| if($nodeprivs[$id]["user"][$priv]) |
| $noprivs = 0; |
| } |
| if($noprivs) |
| $nodeprivs[$id]["user"]["cascade"] = 0; |
| } |
| // if not blocking at this node, and previous node had cascade |
| if($lastid && ! $block && $nodeprivs[$lastid]["user"]["cascade"]) { |
| # set cascade = 1 |
| $nodeprivs[$id]["user"]["cascade"] = 1; |
| # set each priv in $resourceprivs = 1 |
| foreach($resourceprivs as $priv) { |
| if($nodeprivs[$lastid]["user"][$priv]) |
| $nodeprivs[$id]["user"][$priv] = 1; |
| } |
| } |
| |
| # add permissions for user's groups |
| $basearray = array("cascade" => 0, |
| "block" => 0); |
| foreach($resourceprivs as $priv) |
| $basearray[$priv] = 0; |
| if(isset($privdataset['usergroup'][$id])) { |
| foreach($privdataset['usergroup'][$id] as $data) { |
| if(! isset($nodeprivs[$id][$data["groupid"]])) |
| $nodeprivs[$id][$data["groupid"]] = $basearray; |
| $nodeprivs[$id][$data["groupid"]][$data["name"]] = 1; |
| } |
| } |
| # add groups from $lastid if it is not 0 |
| if($lastid) { |
| foreach($nodeprivs[$lastid] as $groupid => $tmp) { |
| if(isset($nodeprivs[$id][$groupid])) |
| continue; |
| $nodeprivs[$id][$groupid] = $basearray; |
| } |
| } |
| foreach($nodeprivs[$id] as $groupid => $tmp) { |
| if(! is_numeric($groupid)) |
| continue; |
| // if don't have anything in $resourceprivs, set cascade = 0 |
| if($nodeprivs[$id][$groupid]["cascade"]) { |
| $noprivs = 1; |
| foreach($resourceprivs as $priv) { |
| if($nodeprivs[$id][$groupid][$priv]) |
| $noprivs = 0; |
| } |
| if($noprivs) |
| $nodeprivs[$id][$groupid]["cascade"] = 0; |
| } |
| // if group not blocking at this node, and group had cascade at previous |
| # node |
| if($lastid && ! $nodeprivs[$id][$groupid]["block"] && |
| isset($nodeprivs[$lastid][$groupid]) && |
| $nodeprivs[$lastid][$groupid]["cascade"]) { |
| # set cascade = 1 |
| $nodeprivs[$id][$groupid]["cascade"] = 1; |
| # set each priv in $resourceprivs = 1 |
| foreach($resourceprivs as $priv) { |
| if($nodeprivs[$lastid][$groupid][$priv]) |
| $nodeprivs[$id][$groupid][$priv] = 1; |
| } |
| } |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn simplifyNodePrivs($nodeprivs, $resourceprivs) |
| /// |
| /// \param $nodeprivs - node privilege array used in getUserResources |
| /// \param $resourceprivs - array of privileges to look for (such as |
| /// imageAdmin, imageCheckOut, etc); don't include 'block' or 'cascade' |
| /// |
| /// \return a simplified version of $nodeprivs |
| /// |
| /// \brief checks the user and group privileges for each node in $nodeprivs and |
| /// creates a new privilege array that just shows if the user has that |
| /// permission (either directly or from a group) |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function simplifyNodePrivs($nodeprivs, $resourceprivs) { |
| $return = array(); |
| $basearray = array(); |
| foreach($resourceprivs as $priv) { |
| $basearray[$priv] = 0; |
| } |
| foreach(array_keys($nodeprivs) as $nodeid) { |
| $return[$nodeid] = $basearray; |
| foreach(array_keys($nodeprivs[$nodeid]) as $key) { |
| foreach($resourceprivs as $priv) { |
| if($nodeprivs[$nodeid][$key][$priv]) |
| $return[$nodeid][$priv] = 1; |
| } |
| } |
| } |
| return $return; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn addUserResources(&$nodeprivs, $userid) |
| /// |
| /// \param $nodeprivs - node privilege array used in getUserResources |
| /// \param $userid - an id from the user table |
| /// |
| /// \return modifies $nodeprivs, but doesn't return anything |
| /// |
| /// \brief for each node in $nodeprivs, adds any resources that are available |
| /// to $nodeprivs |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function addUserResources(&$nodeprivs, $userid) { |
| require_once(".ht-inc/privileges.php"); |
| foreach(array_keys($nodeprivs) as $nodeid) { |
| $privs = getNodePrivileges($nodeid, "resources"); |
| $nodeprivs[$nodeid]["resources"] = $privs["resources"]; |
| $privs = getNodeCascadePrivileges($nodeid, "resources"); |
| $nodeprivs[$nodeid]["cascaderesources"] = $privs["resources"]; |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn addOwnedResources(&$resources, $includedeleted, $userid) |
| /// |
| /// \param $resources - array of resources from getUserResources |
| /// \param $includedeleted - 1 to include deleted resources, 0 not to |
| /// \param $userid - id from user table |
| /// |
| /// \return modifies $resources, but doesn't return anything |
| /// |
| /// \brief adds resources that the user owns |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function addOwnedResources(&$resources, $includedeleted, $userid) { |
| foreach(array_keys($resources) as $type) { |
| # TODO make this get name field from classes |
| switch($type) { |
| case "image": |
| $field = 'prettyname'; |
| break; |
| case "computer": |
| case "managementnode": |
| $field = 'hostname'; |
| break; |
| default: |
| $field = 'name'; |
| break; |
| } |
| $query = "SELECT id, " |
| . "$field " |
| . "FROM $type " |
| . "WHERE ownerid = $userid"; |
| if(! $includedeleted && |
| ($type == "image" || $type == "computer" || $type == 'config')) |
| $query .= " AND deleted = 0"; |
| if(! $includedeleted && $type == 'managementnode') |
| $query .= " AND stateid != (SELECT id FROM state WHERE name = 'deleted') "; |
| $qh = doQuery($query, 101); |
| while($row = mysql_fetch_assoc($qh)) { |
| if(! isset($resources[$type][$row["id"]])) |
| $resources[$type][$row["id"]] = $row[$field]; |
| } |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn addOwnedResourceGroups(&$resourcegroups, $userid) |
| /// |
| /// \param $resourcegroups - array of resources from getUserResources |
| /// \param $userid - id from user table |
| /// |
| /// \return modifies $resources, but doesn't return anything |
| /// |
| /// \brief adds resources that the user owns |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function addOwnedResourceGroups(&$resourcegroups, $userid) { |
| if(! $user = getUserInfo($userid, 1, 1)) |
| return; |
| $userid = $user["id"]; |
| $groupids = implode(',', array_keys($user["groups"])); |
| if(empty($groupids)) |
| $groupids = "''"; |
| $query = "SELECT g.id AS id, " |
| . "g.name AS name, " |
| . "t.name AS type " |
| . "FROM resourcegroup g, " |
| . "resourcetype t " |
| . "WHERE g.resourcetypeid = t.id AND " |
| . "g.ownerusergroupid IN ($groupids)"; |
| $qh = doQuery($query, 101); |
| while($row = mysql_fetch_assoc($qh)) { |
| if(! isset($resourcegroups[$row["type"]][$row["id"]])) |
| $resourcegroups[$row["type"]][$row["id"]] = $row["name"]; |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getResourcesFromGroups($groups, $type, $includedeleted) |
| /// |
| /// \param $groups - an array of group names |
| /// \param $type - the type of the groups (from resourcetype table) |
| /// \param $includedeleted - 1 to include deleted resources, 0 not to |
| /// |
| /// \return an array of resources where the index is the id of the resource and |
| /// the value is the name of the resource |
| /// |
| /// \brief builds an array of resources from $groups |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getResourcesFromGroups($groups, $type, $includedeleted) { |
| $return = array(); |
| switch($type) { |
| case "image": |
| $field = 'prettyname'; |
| break; |
| case "computer": |
| case "managementnode": |
| $field = 'hostname'; |
| break; |
| default: |
| $field = 'name'; |
| break; |
| } |
| |
| $groups = implode("','", $groups); |
| $inlist = "'$groups'"; |
| |
| $query = "SELECT DISTINCT(r.subid) AS id, " |
| . "t.$field AS name " |
| . "FROM $type t, " |
| . "resource r, " |
| . "resourcegroupmembers m, " |
| . "resourcegroup g, " |
| . "resourcetype rt " |
| . "WHERE r.subid = t.id AND " |
| . "r.id = m.resourceid AND " |
| . "m.resourcegroupid = g.id AND " |
| . "g.name IN ($inlist) AND " |
| . "g.resourcetypeid = rt.id AND " |
| . "rt.name = '$type' "; |
| if(! $includedeleted && |
| ($type == "image" || $type == "computer" || $type == 'config')) { |
| $query .= "AND deleted = 0 "; |
| } |
| if(! $includedeleted && $type == 'managementnode') |
| $query .= "AND t.stateid != (SELECT id FROM state WHERE name = 'deleted') "; |
| /*if($type == "image") |
| $query .= "AND test = 0 ";*/ |
| $query .= "ORDER BY t.$field"; |
| $qh = doQuery($query, 101); |
| while($row = mysql_fetch_assoc($qh)) { |
| $return[$row["id"]] = $row["name"]; |
| } |
| return $return; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn updateUserOrGroupPrivs($name, $node, $adds, $removes, $mode) |
| /// |
| /// \param $name - loginid, user id, or user group id |
| /// \param $node - id of the node |
| /// \param $adds - array of privs (the name, not the id) to add |
| /// \param $removes - array of privs (the name, not the id) to remove |
| /// \param $mode - "user" or "group" |
| /// |
| /// \brief adds/removes $adds/$removes privs for $unityid to/from $node |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function updateUserOrGroupPrivs($name, $node, $adds, $removes, $mode) { |
| if(! (count($adds) || count($removes))) { |
| return; |
| } |
| if($mode == "user") { |
| $field = "userid"; |
| if(is_numeric($name)) |
| $id = $name; |
| else { |
| $id = getUserlistID($name); |
| if(! $id) |
| $id = addUser($name); |
| } |
| } |
| else { |
| $field = "usergroupid"; |
| $id = $name; |
| } |
| foreach($adds as $type) { |
| $typeid = getUserPrivTypeID($type); |
| $query = "INSERT IGNORE INTO userpriv (" |
| . "$field, " |
| . "privnodeid, " |
| . "userprivtypeid) " |
| . "VALUES (" |
| . "$id, " |
| . "$node, " |
| . "$typeid)"; |
| doQuery($query, 375); |
| } |
| foreach($removes as $type) { |
| $typeid = getUserPrivTypeID($type); |
| $query = "DELETE FROM userpriv " |
| . "WHERE $field = $id AND " |
| . "privnodeid = $node AND " |
| . "userprivtypeid = $typeid"; |
| doQuery($query, 376); |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn updateResourcePrivs($group, $node, $adds, $removes) |
| /// |
| /// \param $group - id from resourcegroup table, or group name of the form |
| /// type/name |
| /// \param $node - id of the node |
| /// \param $adds - array of privs (the name, not the id) to add |
| /// \param $removes - array of privs (the name, not the id) to remove |
| /// |
| /// \brief adds/removes $adds/$removes privs for $name to/from $node |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function updateResourcePrivs($group, $node, $adds, $removes) { |
| if(! (count($adds) || count($removes))) { |
| return; |
| } |
| if(is_numeric($group)) |
| $groupid = $group; |
| else |
| $groupid = getResourceGroupID($group); |
| foreach($adds as $type) { |
| $type = mysql_real_escape_string($type); |
| $query = "INSERT IGNORE INTO resourcepriv (" |
| . "resourcegroupid, " |
| . "privnodeid, " |
| . "type) " |
| . "VALUES (" |
| . "$groupid, " |
| . "$node, " |
| . "'$type')"; |
| doQuery($query, 377); |
| } |
| foreach($removes as $type) { |
| $type = mysql_real_escape_string($type); |
| $query = "DELETE FROM resourcepriv " |
| . "WHERE resourcegroupid = $groupid AND " |
| . "privnodeid = $node AND " |
| . "type = '$type'"; |
| doQuery($query, 378); |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getKey($data) |
| /// |
| /// \param $data - an array |
| /// |
| /// \return an md5 string that is unique for $data |
| /// |
| /// \brief generates an md5sum for $data |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getKey($data) { |
| return md5(serialize($data)); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn encryptData($data, $cryptkey, $algo, $option, $keylength) |
| /// |
| /// \param $data - a string |
| /// \param $cryptkey - key for encryption |
| /// \param $algo - algorithm to use for decryption |
| /// \param $option - an algorithm option (such as CBC) |
| /// \param $keylength - length of key being used |
| /// |
| /// \return an encrypted form of $data that has been base64 encoded or NULL if |
| /// encryption failed |
| /// |
| /// \brief encrypts $data with $algo and $option and base64 encodes it; IV is |
| /// generated and prepended to encrypted data before base64 encoding |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function encryptData($data, $cryptkey, $algo, $option, $keylength) { |
| global $ivsize; |
| if(! $data) |
| return false; |
| if(USE_PHPSECLIB) { |
| # only AES is currently supported |
| if($algo == 'AES') { |
| $mode = constant("CRYPT_AES_MODE_$option"); |
| $aes = new Crypt_AES($mode); |
| } |
| else |
| return false; |
| $aes->setKeyLength($keylength); |
| $aes->setKey($cryptkey); |
| $iv = crypt_random_string($ivsize); |
| $aes->setIV($iv); |
| $cryptdata = $aes->encrypt($data); |
| } |
| else { |
| $iv = openssl_random_pseudo_bytes($ivsize); |
| $mode = "{$algo}-{$keylength}-{$option}"; |
| $cryptdata = openssl_encrypt($data, $mode, $cryptkey, 1, $iv); |
| if($cryptdata === FALSE) |
| return NULL; |
| } |
| $cryptdata = $iv . $cryptdata; |
| return trim(base64_encode($cryptdata)); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn decryptData($data, $cryptkey, $algo, $option, $keylength) |
| /// |
| /// \param $data - a string |
| /// \param $cryptkey - key for decryption |
| /// \param $algo - algorithm to use for decryption |
| /// \param $option - an algorithm option (such as CBC) |
| /// \param $keylength - length of key being used |
| /// |
| /// \return decrypted form of $data or false on error |
| /// |
| /// \brief base64 decodes $data and decrypts it; $data is split into IV and |
| /// encrypted data after base64 decoding |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function decryptData($data, $cryptkey, $algo, $option, $keylength) { |
| global $ivsize; |
| if(! $data) |
| return false; |
| $cryptdata = base64_decode($data); |
| $iv = substr($cryptdata, 0, $ivsize); |
| if(strlen($iv) < $ivsize) |
| return false; |
| $cryptdata = substr($cryptdata, $ivsize); |
| if(strlen($cryptdata) == 0) |
| return false; |
| if(USE_PHPSECLIB) { |
| if($algo == 'AES') { |
| $mode = constant("CRYPT_AES_MODE_$option"); |
| $aes = new Crypt_AES($mode); |
| } |
| else |
| return false; |
| $aes->setKeyLength($keylength); |
| $aes->setKey($cryptkey); |
| $aes->setIV($iv); |
| $decryptdata = $aes->decrypt($cryptdata); |
| } |
| else { |
| $mode = "{$algo}-{$keylength}-{$option}"; |
| $decryptdata = openssl_decrypt($cryptdata, $mode, $cryptkey, 1, $iv); |
| if($decryptdata === FALSE) |
| return false; |
| } |
| return trim($decryptdata); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn encryptDBdata($data, $secretid) |
| /// |
| /// \param $data - a string |
| /// \param $secretid - secretid from cryptsecret table |
| /// |
| /// \return base64-encoded, encrypted form of $data or NULL on error |
| /// |
| /// \brief encrypts $data with secret key from cryptsecret table |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function encryptDBdata($data, $secretid) { |
| # fetch cryptsecret from db |
| $cryptkeyid = getCryptKeyID(); |
| if($cryptkeyid == NULL) |
| return NULL; |
| $query = "SELECT cryptsecret, " |
| . "algorithm, " |
| . "algorithmoption, " |
| . "keylength " |
| . "FROM cryptsecret " |
| . "WHERE cryptkeyid = $cryptkeyid AND " |
| . "secretid = $secretid"; |
| $qh = doQuery($query); |
| if(! ($row = mysql_fetch_assoc($qh))) |
| return NULL; |
| $secret = decryptSecretKey($row['cryptsecret']); |
| if($secret === NULL) |
| return NULL; |
| $edata = encryptData($data, $secret, $row['algorithm'], $row['algorithmoption'], $row['keylength']); |
| return $edata; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn encryptSecretKey($secret, $cryptkey) |
| /// |
| /// \param $secret - secret key to encrypt |
| /// \param $cryptkey - id from cryptkey table for public key to use or public |
| /// key itself |
| /// |
| /// \return encrypted data; returns NULL on error |
| /// |
| /// \brief encrypts $secret with key for $cryptkeyid |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function encryptSecretKey($secret, $cryptkey) { |
| if(is_numeric($cryptkey)) { |
| $query = "SELECT pubkey, " |
| . "algorithmoption " |
| . "FROM cryptkey " |
| . "WHERE id = $cryptkey"; |
| $qh = doQuery($query); |
| if(! ($row = mysql_fetch_assoc($qh))) |
| return NULL; |
| $cryptkey = $row['pubkey']; |
| if($row['algorithmoption'] == 'OAEP' || 1) # OAEP only currently supported option |
| $padding = constant('OPENSSL_PKCS1_OAEP_PADDING'); |
| } |
| else |
| $padding = constant('OPENSSL_PKCS1_OAEP_PADDING'); |
| $savehdlr = set_error_handler(create_function('', '')); |
| if(@openssl_public_encrypt($secret, $encdata, $cryptkey, $padding)) { |
| set_error_handler($savehdlr); |
| $b64data = base64_encode($encdata); |
| return $b64data; |
| } |
| set_error_handler($savehdlr); |
| return NULL; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn decryptSecretKey($encsecret) |
| /// |
| /// \param $encsecret - encrypted secret |
| /// |
| /// \return string that is decrypted form of $encsecret or NULL on error |
| /// |
| /// \brief decrypts $encsecret using web server's secret key |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function decryptSecretKey($encsecret) { |
| global $pemkey; |
| $cryptsecret = base64_decode($encsecret); |
| # read private key from file |
| $reg = "|" . SCRIPT . "$|"; |
| $file = preg_replace($reg, '', $_SERVER['SCRIPT_FILENAME']); |
| $file .= "/.ht-inc/cryptkey/private.pem"; |
| $prikey = openssl_pkey_get_private("file://$file", $pemkey); |
| # decrypt secret using private key |
| $savehdlr = set_error_handler(create_function('', '')); |
| if(ASYMOPT == 'OAEP') |
| $padding = constant('OPENSSL_PKCS1_OAEP_PADDING'); |
| # OAEP currently only supported padding option |
| if(! openssl_private_decrypt($cryptsecret, $secret, $prikey, $padding)) { |
| set_error_handler($savehdlr); |
| return NULL; |
| } |
| return $secret; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getSecretKeyID($table, $field, $recordid) |
| /// |
| /// \param $table - name of a database table having a secret |
| /// \param $field - name of field in table referencing secretid |
| /// \param $recordid - id for record in table |
| /// |
| /// \return id corresponding to a cryptsecret.secretid value; if value not found |
| /// and function failed to generate a new secret ID, NULL is returned |
| /// |
| /// \brief gets the id for a cryptsecret.secretid entry from a table containing |
| /// an encrypted value; if no entry is found, a new secret is generated and |
| /// saved in cryptsecret |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getSecretKeyID($table, $field, $recordid) { |
| $query = "SELECT $field FROM $table WHERE id = $recordid"; |
| $qh = doQuery($query); |
| if(($row = mysql_fetch_row($qh)) && $row[0] != 0) |
| return $row[0]; |
| |
| # generate secret key |
| if(USE_PHPSECLIB) |
| $key = crypt_random_string(32); |
| else { |
| $key = openssl_random_pseudo_bytes(32); |
| if($key === FALSE) |
| return NULL; |
| } |
| # encrypt with my public key |
| $cryptkeyid = getCryptKeyID(); |
| if($cryptkeyid === NULL) |
| return NULL; |
| $encdata = encryptSecretKey($key, $cryptkeyid); |
| if($encdata === NULL) |
| return NULL; |
| # write to cryptsecret |
| $query = "INSERT INTO cryptsecret " |
| . "(cryptkeyid, " |
| . "secretid, " |
| . "cryptsecret, " |
| . "algorithm, " |
| . "algorithmoption, " |
| . "keylength) " |
| . "SELECT $cryptkeyid, " |
| . "COALESCE(MAX(secretid), 0) + 1, " |
| . "'$encdata', " |
| . "'" . SYMALGO . "', " |
| . "'" . SYMOPT . "', " |
| . SYMLEN . " " |
| . "FROM cryptsecret"; |
| doQuery($query); |
| $id = dbLastInsertID(); |
| if($id < 1) |
| return NULL; |
| $query = "SELECT secretid FROM cryptsecret WHERE id = $id"; |
| $qh = doQuery($query); |
| if(! ($row = mysql_fetch_assoc($qh))) |
| return NULL; |
| # encrypt with all other public keys and write to cryptsecret |
| encryptWebSecretKeys($key, $row['secretid'], $cryptkeyid); |
| return $row['secretid']; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn deleteSecretKeys($secretid) |
| /// |
| /// \param $secretid - secretid value corresponding to cryptsecret.secretid |
| /// |
| /// \brief deletes all entries in cryptsecret for $secretid |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function deleteSecretKeys($secretid) { |
| $query = "DELETE FROM cryptsecret WHERE secretid = $secretid"; |
| doQuery($query); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getCryptKeyID() |
| /// |
| /// \return id from cryptkey table corresponding to this web server's file |
| /// space; returns NULL on error |
| /// |
| /// \brief reads id from cryptkeyid file in web server's file space; if not |
| /// found, calls checkCryptkey to generate a key and then returns it |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getCryptKeyID() { |
| $reg = "|" . SCRIPT . "$|"; |
| $filebase = preg_replace($reg, '', $_SERVER['SCRIPT_FILENAME']); |
| $filebase .= "/.ht-inc/cryptkey"; |
| $idfile = "$filebase/cryptkeyid"; |
| |
| static $create = 1; # set flag so that recursion only goes one level deep |
| |
| if(! is_file($idfile)) { |
| if($create) { |
| $create = 0; # set to 0, subsequent calls to function should never need to create a key |
| checkCryptkey(); |
| return getCryptKeyID(); |
| } |
| else |
| return NULL; |
| } |
| |
| $fh = fopen($idfile, 'r'); |
| $id = fread($fh, 50); |
| fclose($fh); |
| $_id = mysql_real_escape_string($id); |
| |
| $query = "SELECT id " |
| . "FROM cryptkey " |
| . "WHERE id = '$_id'"; |
| $qh = doQuery($query); |
| if($row = mysql_fetch_assoc($qh)) |
| return $row['id']; |
| |
| if($create) { |
| $create = 0; # set to 0, subsequent calls to function should never need to create a key |
| checkCryptkey(); |
| return getCryptKeyID(); |
| } |
| |
| return NULL; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn encryptWebSecretKeys($secret, $secretid, $skipkeyid=0) |
| /// |
| /// \param $secret - secret key to encrypt |
| /// \param $secretid - id for secret from cryptsecret.secretid |
| /// \param $skipkeyid - (optional, default=0) a cryptkey.id to skip (used if |
| /// calling from a function that just encrypted $secret for a given cryptkey) |
| /// |
| /// \brief encrypts $secret using any existing web server cryptkeys in database |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function encryptWebSecretKeys($secret, $secretid, $skipkeyid=0) { |
| $query = "SELECT id, " |
| . "pubkey " |
| . "FROM cryptkey " |
| . "WHERE id != $skipkeyid AND " |
| . "hosttype = 'web'"; |
| $qh = doQuery($query); |
| $values = array(); |
| while($row = mysql_fetch_assoc($qh)) { |
| $cryptsecret = encryptSecretKey($secret, $row['pubkey']); |
| if($cryptsecret === NULL) |
| continue; |
| $values[] = "({$row['id']}, $secretid, '$cryptsecret', '" |
| . SYMALGO . "', '" . SYMOPT . "', " . SYMLEN . ")"; |
| } |
| if(! empty($values)) { |
| $allvalues = implode(',', $values); |
| $query = "INSERT INTO cryptsecret " |
| . "(cryptkeyid, " |
| . "secretid, " |
| . "cryptsecret, " |
| . "algorithm, " |
| . "algorithmoption, " |
| . "keylength) " |
| . "VALUES $allvalues"; |
| doQuery($query); |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn checkMissingWebSecretKeys() |
| /// |
| /// \brief checks for any web servers missing secret key entries and creates |
| /// them if possible |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function checkMissingWebSecretKeys() { |
| global $mode; |
| $mycryptkeyid = getCryptKeyID(); |
| |
| $values = array(); |
| $query = "SELECT ck.id as cryptkeyid, " |
| . "ck.pubkey as cryptkey, " |
| . "s.id as secretid, " |
| . "s.cryptsecret AS mycryptsecret " |
| . "FROM cryptkey ck " |
| . "JOIN (SELECT secretid as id, cryptsecret " |
| . "FROM cryptsecret " |
| . "WHERE cryptkeyid = $mycryptkeyid) AS s " |
| . "LEFT JOIN cryptsecret cs ON (ck.id = cs.cryptkeyid AND cs.secretid = s.id) " |
| . "WHERE ck.hosttype = 'web' AND " |
| . "cs.secretid IS NULL AND " |
| . "ck.id != $mycryptkeyid"; |
| $qh = doQuery($query); |
| while($row = mysql_fetch_assoc($qh)) { |
| $secret = decryptSecretKey($row['mycryptsecret']); |
| $encsecret = encryptSecretKey($secret, $row['cryptkey']); |
| $values[] = "({$row['cryptkeyid']}, {$row['secretid']}, '$encsecret', '" |
| . SYMALGO . "', '" . SYMOPT . "', " . SYMLEN . ")"; |
| } |
| if(empty($values)) { |
| if($mode == 'checkMissingWebSecretKeys') { |
| print "<h2>Update Missing Web Server Secret Keys</h2>\n"; |
| print "There are no missing secret keys this server has access to."; |
| } |
| return; |
| } |
| |
| addCryptSecretKeyUpdates($values); |
| |
| if($mode == 'checkMissingWebSecretKeys') { |
| print "<h2>Update Missing Web Server Secret Keys</h2>\n"; |
| print "Successfully updated any missing secret keys this server has access to."; |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn checkCryptSecrets($requestid) |
| /// |
| /// \param $requestid - id from request table |
| /// |
| /// \brief ensures cryptsecret contains any needed entries for vcld to process |
| /// $requestid |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function checkCryptSecrets($requestid) { |
| # determine any secretids needed from addomain |
| $secretids = array(); |
| $query = "SELECT ad.secretid, " |
| . "rs.managementnodeid " |
| . "FROM reservation rs " |
| . "LEFT JOIN imageaddomain ia ON (rs.imageid = ia.imageid) " |
| . "LEFT JOIN addomain ad ON (ia.addomainid = ad.id) " |
| . "WHERE rs.requestid = $requestid AND " |
| . "ad.secretid IS NOT NULL"; |
| $qh = doQuery($query); |
| while($row = mysql_fetch_assoc($qh)) |
| $secretids[$row['managementnodeid']][$row['secretid']] = 1; |
| # determine any secretids needed from vmprofile |
| $query = "SELECT vp.secretid, " |
| . "rs.managementnodeid " |
| . "FROM reservation rs " |
| . "JOIN computer c ON (rs.computerid = c.id) " |
| . "LEFT JOIN vmhost vh ON (c.vmhostid = vh.id) " |
| . "LEFT JOIN vmprofile vp ON (vh.vmprofileid = vp.id) " |
| . "WHERE rs.requestid = $requestid AND " |
| . "vp.secretid IS NOT NULL"; |
| $qh = doQuery($query); |
| while($row = mysql_fetch_assoc($qh)) |
| $secretids[$row['managementnodeid']][$row['secretid']] = 1; |
| |
| $mycryptkeyid = getCryptKeyID(); |
| if($mycryptkeyid === NULL && count($secretids)) { |
| # corner case, have no way to decrypt existing secrets, silently fail |
| # mn will call API to attempt to have secrets generated, may have success |
| // if hit another web server or may return error at which point mn |
| # can fail reservation |
| return; |
| } |
| |
| # find any missing secrets for management nodes |
| $values = getMNcryptkeyUpdates($secretids, $mycryptkeyid); |
| # add secrets |
| addCryptSecretKeyUpdates($values); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getMNcryptkeyUpdates($secretidset, $cryptkeyid) |
| /// |
| /// \param $secretidset - array where keys are management node ids and values |
| /// are arrays with keys being secretids to add and values being 1:\n |
| /// array('mnid1' =>\n |
| /// array('secretid1' => 1,\n |
| /// 'secretid1' => 1...\n |
| /// )\n |
| /// ) |
| /// \param $cryptkeyid - id from cryptkey table |
| /// |
| /// \return array of values to be added to the cryptsecret table |
| /// |
| /// \brief determines what secretids are missing from the set passed in, creates |
| /// encrypted values for each passed in management node, and returns a set of |
| /// values that can then be inserted into the cryptsecret table |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getMNcryptkeyUpdates($secretidset, $cryptkeyid) { |
| $values = array(); |
| foreach($secretidset as $mnid => $secretids) { |
| $secretids = array_keys($secretids); |
| $allsecretids = implode(',', $secretids); |
| $query = "SELECT ck.id as cryptkeyid, " |
| . "ck.pubkey as cryptkey, " |
| . "s.id as secretid, " |
| . "mycs.cryptsecret AS mycryptsecret " |
| . "FROM cryptkey ck " |
| . "JOIN (SELECT DISTINCT secretid AS id FROM cryptsecret) AS s " |
| . "JOIN (SELECT cryptsecret, secretid FROM cryptsecret WHERE cryptkeyid = $cryptkeyid) AS mycs " |
| . "LEFT JOIN cryptsecret cs ON (s.id = cs.secretid AND ck.id = cs.cryptkeyid) " |
| . "WHERE mycs.secretid = s.id AND " |
| . "ck.hostid = $mnid AND " |
| . "ck.hosttype = 'managementnode' AND " |
| . "s.id in ($allsecretids) AND " |
| . "cs.secretid IS NULL"; |
| $qh = doQuery($query); |
| while($row = mysql_fetch_assoc($qh)) { |
| $secret = decryptSecretKey($row['mycryptsecret']); |
| $encsecret = encryptSecretKey($secret, $row['cryptkey']); |
| $values[] = "({$row['cryptkeyid']}, {$row['secretid']}, '$encsecret', '" |
| . SYMALGO . "', '" . SYMOPT . "', " . SYMLEN . ")"; |
| } |
| } |
| return $values; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn addCryptSecretKeyUpdates($values) |
| /// |
| /// \param $values - array of cryptsecret values that can be joined by commas |
| /// and used as the VALUES portion of an INSERT statement |
| /// |
| /// \brief inserts values into cryptsecret table |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function addCryptSecretKeyUpdates($values) { |
| if(empty($values)) |
| return; |
| $allvalues = implode(',', $values); |
| $query = "INSERT INTO cryptsecret " |
| . "(cryptkeyid, " |
| . "secretid, " |
| . "cryptsecret, " |
| . "algorithm, " |
| . "algorithmoption, " |
| . "keylength) " |
| . "VALUES $allvalues"; |
| doQuery($query); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getParentNodes($node) |
| /// |
| /// \param $node - a privnode id |
| /// |
| /// \return an array of parents of $node |
| /// |
| /// \brief build array of node's parents with 0th index being immediate parent |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getParentNodes($node) { |
| global $nodeparents; |
| if(isset($nodeparents[$node])) |
| return $nodeparents[$node]; |
| |
| $nodelist = array(); |
| while($node != 1) { |
| $nodeinfo = getNodeInfo($node); |
| $node = $nodeinfo["parent"]; |
| if($node == NULL) |
| break; |
| $nodelist[] = $node; |
| } |
| $nodeparents[$node] = $nodelist; |
| return $nodelist; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getChildNodes($parent) |
| /// |
| /// \param parent - (optional) the parent of all the children; defaults to 2 |
| /// (the root node) |
| /// |
| /// \return an array of nodes |
| /// |
| /// \brief gets all children for $parent |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getChildNodes($parent=DEFAULT_PRIVNODE) { |
| global $cache; |
| if(! isset($cache['nodes'])) |
| # call getNodeInfo to populate $cache['nodes'] |
| getNodeInfo($parent); |
| |
| static $allnodes = array(); |
| if(empty($allnodes)) { |
| foreach($cache['nodes'] as $id => $node) { |
| unset($node['id']); |
| $allnodes[$node['parent']][$id] = $node; |
| } |
| } |
| if(isset($allnodes[$parent])) |
| return $allnodes[$parent]; |
| else |
| return array(); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getUserGroups($groupType, $affiliationid) |
| /// |
| /// \param $groupType - (optional, default = 0) 0 for all groups, 1 for custom |
| /// groups, 2 for courseroll groups |
| /// \param $affiliationid - (optional, default = 0) 0 for groups of any |
| /// affiliation, or the id of an affiliation for only groups with that |
| /// affiliation |
| /// |
| /// \return an array where each index is an id from usergroup and the values |
| /// are arrays with the indexes:\n |
| /// name\n |
| /// groupaffiliation\n |
| /// groupaffiliationid\n |
| /// ownerid\n |
| /// owner\n |
| /// affiliation\n |
| /// editgroupid\n |
| /// editgroup\n |
| /// editgroupaffiliationid\n |
| /// editgroupaffiliation\n |
| /// custom\n |
| /// courseroll\n |
| /// initialmaxtime\n |
| /// totalmaxtime\n |
| /// maxextendtime\n |
| /// overlapResCount |
| /// |
| /// \brief builds list of user groups\n |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getUserGroups($groupType=0, $affiliationid=0) { |
| global $user; |
| $key = getKey(array($groupType, $affiliationid, $user['showallgroups'])); |
| if(isset($_SESSION['usersessiondata'][$key])) |
| return $_SESSION['usersessiondata'][$key]; |
| $return = array(); |
| $query = "SELECT ug.id, " |
| . "ug.name, " |
| . "ga.name AS groupaffiliation, " |
| . "ug.affiliationid AS groupaffiliationid, " |
| . "ug.ownerid, " |
| . "u.unityid AS owner, " |
| . "a.name AS affiliation, " |
| . "ug.editusergroupid AS editgroupid, " |
| . "eug.name AS editgroup, " |
| . "eug.affiliationid AS editgroupaffiliationid, " |
| . "euga.name AS editgroupaffiliation, " |
| . "ug.custom, " |
| . "ug.courseroll, " |
| . "ug.initialmaxtime, " |
| . "ug.totalmaxtime, " |
| . "ug.maxextendtime, " |
| . "ug.overlapResCount " |
| . "FROM usergroup ug " |
| . "LEFT JOIN user u ON (ug.ownerid = u.id) " |
| . "LEFT JOIN usergroup eug ON (ug.editusergroupid = eug.id) " |
| . "LEFT JOIN affiliation a ON (u.affiliationid = a.id) " |
| . "LEFT JOIN affiliation ga ON (ug.affiliationid = ga.id) " |
| . "LEFT JOIN affiliation euga ON (eug.affiliationid = euga.id) " |
| . "WHERE 1 "; |
| if($groupType == 1) |
| $query .= "AND ug.custom = 1 "; |
| elseif($groupType == 2) |
| $query .= "AND ug.courseroll = 1 "; |
| if(! $user['showallgroups'] && $affiliationid) |
| $query .= "AND ug.affiliationid = $affiliationid "; |
| $query .= "ORDER BY name"; |
| $qh = doQuery($query, 280); |
| while($row = mysql_fetch_assoc($qh)) { |
| if(! empty($row["owner"]) && ! empty($row['affiliation'])) |
| $row['owner'] = "{$row['owner']}@{$row['affiliation']}"; |
| if($user['showallgroups'] || $affiliationid == 0) |
| $row['name'] = "{$row['name']}@{$row['groupaffiliation']}"; |
| $return[$row["id"]] = $row; |
| } |
| $_SESSION['usersessiondata'][$key] = $return; |
| return $return; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getUserEditGroups($id) |
| /// |
| /// \param $id - user id (string or numeric) |
| /// |
| /// \return an array of groups where each key is the group id |
| /// |
| /// \brief builds an array of groups for which $id can edit the membership |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getUserEditGroups($id) { |
| global $user; |
| if(! is_numeric($id)) |
| $id = getUserlistID($id); |
| if($user['showallgroups']) { |
| $query = "SELECT DISTINCT(u.id), " |
| . "CONCAT(u.name, '@', a.name) AS name " |
| . "FROM `usergroup` u, " |
| . "`usergroupmembers` m, " |
| . "affiliation a " |
| . "WHERE u.editusergroupid = m.usergroupid AND " |
| . "u.affiliationid = a.id AND " |
| . "(u.ownerid = $id OR m.userid = $id) " |
| . "ORDER BY name"; |
| } |
| else { |
| $query = "SELECT DISTINCT(u.id), " |
| . "u.name " |
| . "FROM `usergroup` u, " |
| . "`usergroupmembers` m " |
| . "WHERE u.editusergroupid = m.usergroupid AND " |
| . "(u.ownerid = $id OR m.userid = $id) AND " |
| . "u.affiliationid = {$user['affiliationid']} " |
| . "ORDER BY name"; |
| } |
| $qh = doQuery($query, 101); |
| $groups = array(); |
| while($row = mysql_fetch_assoc($qh)) { |
| $groups[$row['id']] = $row['name']; |
| } |
| return $groups; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getUserGroupPrivs($groupid='') |
| /// |
| /// \param $groupid (optional, default='') - if specified, only get permissions |
| /// granted to this user group; if not specified, get information about |
| /// all groups |
| /// |
| /// \return array of data about user group permissions where each element is an |
| /// array with these keys:\n |
| /// \b usergroup - name of user group\n |
| /// \b usergroupid - id of user group\n |
| /// \b permission - permission granted to user group\n |
| /// \b permid - id of permission granted to user group |
| /// |
| /// \brief builds an array of data about permissions granted to user groups |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getUserGroupPrivs($groupid='') { |
| $data = array(); |
| $query = "SELECT ug.name AS usergroup, " |
| . "ugp.usergroupid, " |
| . "ugpt.name AS permission, " |
| . "ugp.userprivtypeid AS permid " |
| . "FROM usergroup ug, " |
| . "usergrouppriv ugp, " |
| . "usergroupprivtype ugpt " |
| . "WHERE ugp.usergroupid = ug.id AND " |
| . "ugp.userprivtypeid = ugpt.id "; |
| if(! empty($groupid)) |
| $query .= "AND ugp.usergroupid = $groupid "; |
| $query .= "ORDER BY ug.name, " |
| . "ugpt.name"; |
| $qh = doQuery($query, 101); |
| while($row = mysql_fetch_assoc($qh)) |
| $data[] = $row; |
| return $data; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getUserGroupPrivTypes() |
| /// |
| /// \return array of information about user group permissions where each index |
| /// is the id of the permission and each element has these keys:\n |
| /// \b id - id of permission\n |
| /// \b name - name of permission\n |
| /// \b help - additional information about permission |
| /// |
| /// \brief builds an array of information about the user group permissions |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getUserGroupPrivTypes() { |
| $data = array(); |
| $query = "SELECT id, name, help FROM usergroupprivtype ORDER BY name"; |
| $qh = doQuery($query, 101); |
| while($row = mysql_fetch_assoc($qh)) |
| $data[$row['id']] = $row; |
| return $data; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getResourceGroups($type, $id) |
| /// |
| /// \param $type - (optional) a name from the resourcetype table, defaults to |
| /// be empty |
| /// \param $id - (optional) id of a resource group |
| /// |
| /// \return an array of resource groups where each key is a group id and each |
| /// value is an array with these elements:\n |
| /// \b name - type and name of group combined as type/name\n |
| /// \b ownerid - id of owning user group\n |
| /// \b owner - name of owning user group |
| /// |
| /// \brief builds list of resource groups |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getResourceGroups($type='', $id='') { |
| $return = array(); |
| $query = "SELECT g.id AS id, " |
| . "g.name AS name, " |
| . "t.name AS type, " |
| . "g.ownerusergroupid AS ownerid, " |
| . "CONCAT(u.name, '@', a.name) AS owner " |
| . "FROM resourcegroup g, " |
| . "resourcetype t, " |
| . "usergroup u, " |
| . "affiliation a " |
| . "WHERE g.resourcetypeid = t.id AND " |
| . "g.ownerusergroupid = u.id AND " |
| . "u.affiliationid = a.id "; |
| |
| if(! empty($type)) |
| $query .= "AND t.name = '$type' "; |
| |
| if(! empty($id)) |
| $query .= "AND g.id = $id "; |
| |
| $query .= "ORDER BY t.name, g.name"; |
| $qh = doQuery($query, 281); |
| while($row = mysql_fetch_assoc($qh)) { |
| if(empty($type)) |
| $return[$row["id"]]["name"] = $row["type"] . "/" . $row["name"]; |
| else |
| $return[$row["id"]]["name"] = $row["name"]; |
| $return[$row["id"]]["ownerid"] = $row["ownerid"]; |
| $return[$row["id"]]["owner"] = $row["owner"]; |
| } |
| return $return; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getResourceGroupMemberships($type) |
| /// |
| /// \param $type - (optional) a name from the resourcetype table, defaults to |
| /// "all" |
| /// |
| /// \return an array where each index is a resource type and the values are |
| /// arrays where each index is a resource id and its values are an array of |
| /// resource group ids that it is a member of |
| /// |
| /// \brief builds an array of group memberships for resources |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getResourceGroupMemberships($type="all") { |
| $return = array(); |
| |
| if($type == "all") |
| $types = getTypes("resources"); |
| else |
| $types = array("resources" => array($type)); |
| |
| foreach($types["resources"] as $type) { |
| $return[$type] = array(); |
| $query = "SELECT r.subid AS id, " |
| . "gm.resourcegroupid AS groupid " |
| . "FROM resource r, " |
| . "resourcegroupmembers gm, " |
| . "resourcetype t " |
| . "where t.name = '$type' AND " |
| . "gm.resourceid = r.id AND " |
| . "r.resourcetypeid = t.id"; |
| $qh = doQuery($query, 282); |
| while($row = mysql_fetch_assoc($qh)) |
| $return[$type][$row["id"]][] = $row["groupid"]; |
| } |
| return $return; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getResourceGroupMembers($type) |
| /// |
| /// \param $type - (optional) a name from the resourcetype table, defaults to |
| /// "all" |
| /// |
| /// \return an array where each index is a resource type and the values are |
| /// arrays where each index is a resourcegroup id and its values are an array of |
| /// resource ids that are each an array, resulting in this:\n |
| /// Array {\n |
| /// [resourcetype] => Array {\n |
| /// [resourcegroupid] => Array {\n |
| /// [resourceid] => Array {\n |
| /// [subid] => resource sub id\n |
| /// [name] => name of resource\n |
| /// }\n |
| /// }\n |
| /// }\n |
| /// } |
| /// |
| /// \brief builds an array of resource group members that don't have the deleted |
| /// flag set |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getResourceGroupMembers($type="all") { |
| $key = getKey(array('getResourceGroupMembers', $type)); |
| if(isset($_SESSION['userresources'][$key])) |
| return $_SESSION['userresources'][$key]; |
| $return = array(); |
| |
| if($type == "computer") { |
| $names = "c.hostname AS computer, c.deleted "; |
| $joins = "LEFT JOIN computer c ON (r.subid = c.id AND r.resourcetypeid = (SELECT id FROM resourcetype WHERE name = 'computer')) "; |
| $orders = "c.hostname"; |
| $types = "'computer'"; |
| } |
| elseif($type == "image") { |
| $names = "i.prettyname AS image, i.deleted "; |
| $joins = "LEFT JOIN image i ON (r.subid = i.id AND r.resourcetypeid = (SELECT id FROM resourcetype WHERE name = 'image')) "; |
| $orders = "i.prettyname"; |
| $types = "'image'"; |
| } |
| elseif($type == "schedule") { |
| $names = "s.name AS schedule "; |
| $joins = "LEFT JOIN schedule s ON (r.subid = s.id AND r.resourcetypeid = (SELECT id FROM resourcetype WHERE name = 'schedule')) "; |
| $orders = "s.name"; |
| $types = "'schedule'"; |
| } |
| elseif($type == "managementnode") { |
| $names = "m.hostname AS managementnode "; |
| $joins = "LEFT JOIN managementnode m ON (r.subid = m.id AND r.resourcetypeid = (SELECT id FROM resourcetype WHERE name = 'managementnode')) "; |
| $orders = "m.hostname"; |
| $types = "'managementnode'"; |
| } |
| elseif($type == "addomain") { |
| $names = "ad.name AS addomain "; |
| $joins = "LEFT JOIN addomain ad ON (r.subid = ad.id AND r.resourcetypeid = (SELECT id FROM resourcetype WHERE name = 'addomain')) "; |
| $orders = "ad.name"; |
| $types = "'addomain'"; |
| } |
| else { |
| $names = "c.hostname AS computer, " |
| . "c.deleted, " |
| . "i.prettyname AS image, " |
| . "i.deleted AS deleted2, " |
| . "s.name AS schedule, " |
| . "m.hostname AS managementnode, " |
| . "ad.name AS addomain "; |
| $joins = "LEFT JOIN computer c ON (r.subid = c.id AND r.resourcetypeid = (SELECT id FROM resourcetype WHERE name = 'computer')) " |
| . "LEFT JOIN image i ON (r.subid = i.id AND r.resourcetypeid = (SELECT id FROM resourcetype WHERE name = 'image')) " |
| . "LEFT JOIN schedule s ON (r.subid = s.id AND r.resourcetypeid = (SELECT id FROM resourcetype WHERE name = 'schedule')) " |
| . "LEFT JOIN managementnode m ON (r.subid = m.id AND r.resourcetypeid = (SELECT id FROM resourcetype WHERE name = 'managementnode')) " |
| . "LEFT JOIN addomain ad ON (r.subid = ad.id AND r.resourcetypeid = (SELECT id FROM resourcetype WHERE name = 'addomain')) "; |
| $orders = "c.hostname, " |
| . "i.prettyname, " |
| . "s.name, " |
| . "m.hostname, " |
| . "ad.name"; |
| $types = "'computer','image','schedule','managementnode','addomain'"; |
| } |
| |
| $query = "SELECT rgm.resourcegroupid, " |
| . "rgm.resourceid, " |
| . "rt.name AS resourcetype, " |
| . "r.subid, " |
| . $names |
| . "FROM resourcegroupmembers rgm, " |
| . "resourcetype rt, " |
| . "resource r " |
| . $joins |
| . "WHERE rgm.resourceid = r.id AND " |
| . "r.resourcetypeid = rt.id AND " |
| . "rt.name in ($types) " |
| . "ORDER BY rt.name, " |
| . "rgm.resourcegroupid, " |
| . $orders; |
| $qh = doQuery($query, 282); |
| while($row = mysql_fetch_assoc($qh)) { |
| if(isset($row['deleted']) && $row['deleted'] == 1) |
| continue; |
| if(isset($row['deleted2']) && $row['deleted2'] == 1) |
| continue; |
| $return[$row['resourcetype']][$row['resourcegroupid']][$row['resourceid']] = |
| array('subid' => $row['subid'], |
| 'name' => $row[$row['resourcetype']]); |
| } |
| $_SESSION['userresources'][$key] = $return; |
| return $return; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getUserGroupMembers($groupid) |
| /// |
| /// \param $groupid - a usergroup id |
| /// |
| /// \return an array of unityids where the index is the userid |
| /// |
| /// \brief builds an array of user group memberships |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getUserGroupMembers($groupid) { |
| $return = array(); |
| |
| $query = "SELECT m.userid AS id, " |
| . "CONCAT(u.unityid, '@', a.name) AS user " |
| . "FROM usergroupmembers m, " |
| . "affiliation a, " |
| . "user u " |
| . "WHERE m.usergroupid = $groupid AND " |
| . "m.userid = u.id AND " |
| . "u.affiliationid = a.id " |
| . "ORDER BY u.unityid"; |
| $qh = doQuery($query, 101); |
| while($row = mysql_fetch_assoc($qh)) { |
| $return[$row["id"]] = $row['user']; |
| } |
| return $return; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn addUserGroupMember($loginid, $groupid) |
| /// |
| /// \param $loginid - a user's loginid |
| /// \param $groupid - a usergroup id |
| /// |
| /// \brief adds an entry to usergroupmembers for $unityid and $groupid |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function addUserGroupMember($loginid, $groupid) { |
| $userid = getUserlistID($loginid); |
| $groups = getUsersGroups($userid); |
| |
| if(in_array($groupid, array_keys($groups))) |
| return; |
| |
| $query = "INSERT INTO usergroupmembers " |
| . "(userid, " |
| . "usergroupid) " |
| . "VALUES " |
| . "($userid, " |
| . "$groupid)"; |
| doQuery($query, 101); |
| checkUpdateServerRequestGroups($groupid); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn deleteUserGroupMember($userid, $groupid) |
| /// |
| /// \param $userid - a userid |
| /// \param $groupid - a usergroup id |
| /// |
| /// \brief deletes an entry from usergroupmembers for $userid and $groupid |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function deleteUserGroupMember($userid, $groupid) { |
| $query = "DELETE FROM usergroupmembers " |
| . "WHERE userid = $userid AND " |
| . "usergroupid = $groupid"; |
| doQuery($query, 101); |
| checkUpdateServerRequestGroups($groupid); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getUserlistID($loginid, $noadd) |
| /// |
| /// \param $loginid - login ID |
| /// \param $noadd - (optional, default=0) 0 to try to add user to database if |
| /// not there, 1 to only return the id if it already exists in the database |
| /// |
| /// \return id from userlist table for the user |
| /// |
| /// \brief gets id field from userlist table for $loginid; if it does not exist, |
| /// calls addUser to add it to the table |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getUserlistID($loginid, $noadd=0) { |
| $_loginid = $loginid; |
| getAffilidAndLogin($loginid, $affilid); |
| |
| if(empty($affilid)) |
| abort(12); |
| |
| $query = "SELECT id " |
| . "FROM user " |
| . "WHERE unityid = '$loginid' AND " |
| . "affiliationid = $affilid"; |
| $qh = doQuery($query, 140); |
| if(mysql_num_rows($qh)) { |
| $row = mysql_fetch_row($qh); |
| return $row[0]; |
| } |
| if($noadd) |
| return NULL; |
| return addUser($_loginid); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getUsersLastImage($userid) |
| /// |
| /// \param $userid - a numeric user id |
| /// |
| /// \return id of user's last used image or NULL if user has no entries in the |
| /// log table |
| /// |
| /// \brief gets the user's last used image from the log table |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getUsersLastImage($userid) { |
| $query = "SELECT imageid " |
| . "FROM log " |
| . "WHERE userid = $userid " |
| . "ORDER BY id DESC " |
| . "LIMIT 1"; |
| $qh = doQuery($query, 101); |
| if($row = mysql_fetch_assoc($qh)) |
| return $row['imageid']; |
| return NULL; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getAffiliations() |
| /// |
| /// \return an array of affiliations where each index is the id of the |
| /// affiliation |
| /// |
| /// \brief gets a list of all affiliations |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getAffiliations() { |
| $query = "SELECT id, name FROM affiliation ORDER BY name"; |
| $qh = doQuery($query, 101); |
| $return = array(); |
| while($row = mysql_fetch_assoc($qh)) |
| $return[$row['id']] = $row['name']; |
| return $return; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getUserUnityID($userid) |
| /// |
| /// \param $userid - an id from the user table |
| /// |
| /// \return unityid for $userid or NULL if $userid not found |
| /// |
| /// \brief gets the unityid for $userid |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getUserUnityID($userid) { |
| global $cache; |
| if(! isset($cache['unityids'])) |
| $cache['unityids'] = array(); |
| if(isset($cache['unityids'][$userid])) |
| return $cache['unityids'][$userid]; |
| $query = "SELECT unityid FROM user WHERE id = $userid"; |
| $qh = doQuery($query, 101); |
| if(mysql_num_rows($qh)) { |
| $row = mysql_fetch_row($qh); |
| $cache['unityids'][$userid] = $row[0]; |
| return $row[0]; |
| } |
| return NULL; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getAffiliationID($affil) |
| /// |
| /// \param $affil - name of an affiliation |
| /// |
| /// \return id from affiliation table |
| /// |
| /// \brief gets id field from affiliation table for $affil |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getAffiliationID($affil) { |
| $affil = mysql_real_escape_string($affil); |
| $query = "SELECT id FROM affiliation WHERE name = '$affil'"; |
| $qh = doQuery($query, 101); |
| if(mysql_num_rows($qh)) { |
| $row = mysql_fetch_row($qh); |
| return $row[0]; |
| } |
| return NULL; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getAffiliationName($affilid) |
| /// |
| /// \param $affilid - id of an affiliation |
| /// |
| /// \return name from affiliation table |
| /// |
| /// \brief gets name field from affiliation table for $affilid |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getAffiliationName($affilid) { |
| $query = "SELECT name FROM affiliation WHERE id = $affilid"; |
| $qh = doQuery($query, 101); |
| if(mysql_num_rows($qh)) { |
| $row = mysql_fetch_row($qh); |
| return $row[0]; |
| } |
| return NULL; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getAffiliationDataUpdateText($affilid) |
| /// |
| /// \param $affilid - (optional) specify an affiliation id to get only the text |
| /// for that id |
| /// |
| /// \return an array of the html text to display for updating user information |
| /// that is displayed on the User Preferences page |
| /// |
| /// \brief gets dataUpdateText from affiliation table |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getAffiliationDataUpdateText($affilid=0) { |
| $query = "SELECT id, dataUpdateText FROM affiliation"; |
| if($affilid) |
| $query .= " WHERE id = $affilid"; |
| $qh = doQuery($query, 101); |
| while($row = mysql_fetch_assoc($qh)) |
| $return[$row['id']] = $row['dataUpdateText']; |
| return $return; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getAffiliationTheme($affilid) |
| /// |
| /// \param $affilid - id of an affiliation, or 0 to get theme for Global |
| /// |
| /// \return name of the affiliations's theme |
| /// |
| /// \brief gets affiliation.theme for the specified affiliation |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getAffiliationTheme($affilid) { |
| if($affilid == 0) { |
| $query = "SELECT theme FROM affiliation WHERE name = 'Global'"; |
| } |
| else { |
| $query = "SELECT COALESCE(a1.theme, a2.theme) AS theme " |
| . "FROM affiliation a1, " |
| . "affiliation a2 " |
| . "WHERE a1.id = $affilid AND " |
| . "a2.name = 'Global'"; |
| } |
| $qh = doQuery($query); |
| if(($row = mysql_fetch_assoc($qh)) && ! empty($row['theme'])) |
| return $row['theme']; |
| else |
| return DEFAULTTHEME; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn processInputVar($vartag, $type, $defaultvalue, $stripwhitespace) |
| /// |
| /// \param $vartag - name of GET or POST variable |
| /// \param $type - tag type:\n |
| /// \b ARG_NUMERIC - numeric\n |
| /// \b ARG_STRING - string\n |
| /// \b ARG_MULTINUMERIC - an array of numbers |
| /// \param $defaultvalue - default value for the variable (NULL if not passed in) |
| /// \param $stripwhitespace - (optional, default=0) - set to 1 to strip |
| /// whitespace from the beginning and end of the value |
| /// |
| /// \return safe value for the GET or POST variable |
| /// |
| /// \brief checks for $vartag in the $_POST array, then the $_GET array; then |
| /// sanitizes the variable to make sure it doesn't contain anything malicious |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function processInputVar($vartag, $type, $defaultvalue=NULL, $stripwhitespace=0) { |
| if((array_key_exists($vartag, $_POST) && |
| ! is_array($_POST[$vartag]) && |
| strncmp("{$_POST[$vartag]}", "0", 1) == 0 && |
| $type == ARG_NUMERIC && |
| strncmp("{$_POST[$vartag]}", "0x0", 3) != 0) || |
| (array_key_exists($vartag, $_GET) && |
| ! is_array($_GET[$vartag]) && |
| strncmp("{$_GET[$vartag]}", "0", 1) == 0 && |
| $type == ARG_NUMERIC && |
| strncmp("{$_GET[$vartag]}", "0x0", 3) != 0)) { |
| $_POST[$vartag] = "zero"; |
| } |
| if(!empty($_POST[$vartag])) { |
| $return = $_POST[$vartag]; |
| } |
| elseif(!empty($_GET[$vartag])) { |
| $return = $_GET[$vartag]; |
| } |
| else { |
| if($type == ARG_MULTINUMERIC || $type == ARG_MULTISTRING) { |
| $return = array(); |
| } |
| else { |
| $return = $defaultvalue; |
| } |
| } |
| if($return == "zero") { |
| $return = "0"; |
| } |
| |
| if($type == ARG_MULTINUMERIC) { |
| foreach($return as $index => $value) { |
| $return[$index] = strip_tags($value); |
| if($stripwhitespace) |
| $return[$index] = trim($return[$index]); |
| if($return[$index] == 'zero') |
| $return[$index] = '0'; |
| } |
| } |
| elseif($type == ARG_MULTISTRING) { |
| foreach($return as $index => $value) { |
| $return[$index] = strip_tags($value); |
| if($stripwhitespace) |
| $return[$index] = trim($return[$index]); |
| } |
| } |
| else { |
| $return = strip_tags($return); |
| if($stripwhitespace) |
| $return = trim($return); |
| } |
| |
| if(! empty($return) && $type == ARG_NUMERIC) { |
| if(! is_numeric($return)) { |
| return preg_replace('([^\d])', '', $return); |
| } |
| } |
| elseif(! empty($return) && $type == ARG_STRING) { |
| if(! is_string($return)) { |
| print "ERROR (code:3)<br>\n"; |
| printHTMLFooter(); |
| cleanSemaphore(); |
| exit(); |
| } |
| #print "before - $return<br>\n"; |
| #$return = addslashes($return); |
| #$return = str_replace("\'", "", $return); |
| #$return = str_replace("\"", "", $return); |
| #print "after - $return<br>\n"; |
| } |
| elseif(! empty($return) && $type == ARG_MULTINUMERIC) { |
| foreach($return as $index => $value) { |
| if(! is_numeric($value)) { |
| $return[$index] = preg_replace('([^\d])', '', $value); |
| } |
| } |
| return $return; |
| } |
| elseif(! empty($return) && $type == ARG_MULTISTRING) { |
| foreach($return as $index => $value) { |
| if(! is_string($value)) { |
| print "ERROR (code:3)<br>\n"; |
| printHTMLFooter(); |
| cleanSemaphore(); |
| exit(); |
| } |
| } |
| return $return; |
| } |
| |
| if(is_string($return)) { |
| if(strlen($return) == 0) { |
| $return = $defaultvalue; |
| } |
| } |
| |
| return $return; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getContinuationVar($name, $defaultval) |
| /// |
| /// \param $name (optional, default=NULL)- key of value to return from |
| /// $contdata or omit to get all of $contdata |
| /// \param $defaultval (optional, default=NULL) - default value in case $name |
| /// does not exist in $contdata |
| /// |
| /// \return if $name is passed, $contdata[$name] or $defaultval; if $name is |
| /// omitted, $contdata |
| /// |
| /// \brief returns the requested value from $contdata or a default value if |
| /// $name does not exist in $contdata; if both args are omitted, just return all |
| /// of $contdata |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getContinuationVar($name=NULL, $defaultval=NULL) { |
| global $contdata, $inContinuation; |
| if($name === NULL) { |
| return $contdata; |
| } |
| if(! $inContinuation) |
| return $defaultval; |
| if(array_key_exists($name, $contdata)) { |
| if(! is_object($contdata[$name]) && $contdata[$name] == 'zero') |
| return 0; |
| return $contdata[$name]; |
| } |
| return $defaultval; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn processInputData($data, $type, $addslashes, $defaultvalue) |
| /// |
| /// \param $data - data to sanitize |
| /// \param $type - tag type:\n |
| /// \b ARG_NUMERIC - numeric\n |
| /// \b ARG_STRING - string\n |
| /// \b ARG_MULTINUMERIC - an array of numbers |
| /// \param $addslashes - (optional, defaults to 0) set to 1 if values should |
| /// have addslashes called to escape things |
| /// \param $defaultvalue - (optional, defaults to NULL) default value for the |
| /// variable |
| /// |
| /// \return a sanitized version of $data |
| /// |
| /// \brief sanitizes $data to keep bad stuff from being passed in |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function processInputData($data, $type, $addslashes=0, $defaultvalue=NULL) { |
| if(strncmp("$data", "0", 1) == 0 && |
| $type == ARG_NUMERIC && |
| strncmp("$data", "0x0", 3) != 0) { |
| $data = "zero"; |
| } |
| if(!empty($data)) |
| $return = $data; |
| else { |
| if($type == ARG_MULTINUMERIC || $type == ARG_MULTISTRING) |
| $return = array(); |
| else |
| $return = $defaultvalue; |
| } |
| if($return == "zero") |
| $return = "0"; |
| |
| if($type == ARG_MULTINUMERIC) { |
| foreach($return as $index => $value) { |
| $return[$index] = strip_tags($value); |
| if($return[$index] == 'zero') |
| $return[$index] = '0'; |
| } |
| } |
| elseif($type == ARG_MULTISTRING) { |
| foreach($return as $index => $value) { |
| $return[$index] = strip_tags($value); |
| } |
| } |
| else |
| $return = strip_tags($return); |
| |
| if(! empty($return) && $type == ARG_NUMERIC) { |
| if(! is_numeric($return)) { |
| return preg_replace('([^\d])', '', $return); |
| } |
| } |
| elseif(! empty($return) && $type == ARG_STRING) { |
| if(! is_string($return)) |
| $return = $defaultvalue; |
| } |
| elseif(! empty($return) && $type == ARG_MULTINUMERIC) { |
| foreach($return as $index => $value) { |
| if(! is_numeric($value)) { |
| $return[$index] = preg_replace('([^\d])', '', $value); |
| } |
| } |
| return $return; |
| } |
| elseif(! empty($return) && $type == ARG_MULTISTRING) { |
| foreach($return as $index => $value) { |
| if(! is_string($value)) |
| $return[$index] = $defaultvalue; |
| elseif($addslashes) |
| $return[$index] = mysql_real_escape_string($value); |
| } |
| return $return; |
| } |
| |
| if(is_string($return)) { |
| if(strlen($return) == 0) |
| $return = $defaultvalue; |
| elseif($addslashes) |
| $return = mysql_real_escape_string($return); |
| } |
| |
| return $return; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getUserInfo($id, $noupdate, $numeric) |
| /// |
| /// \param $id - unity ID for the user or user's id from database |
| /// \param $noupdate - (optional, default=0) specify 1 to skip updating user's |
| /// data if lastupdated timestamp is expired |
| /// \param $numeric - (optional, default=0) 1 specifies $id corresponds to the |
| /// id field from the user table; 0 otherwise |
| /// |
| /// \return 0 if fail to fetch data or $user - an array with these elements:\n |
| /// \b unityid - unity ID for the user\n |
| /// \b affiliationid - affiliation id of user\n |
| /// \b affiliation - affiliation of user\n |
| /// \b login - login ID for the user (unity ID or part before \@sign)\n |
| /// \b firstname - user's first name\n |
| /// \b lastname - user's last name\n |
| /// \b preferredname - user's preferred name\n |
| /// \b email - user's preferred email address\n |
| /// \b emailnotices - bool for sending email notices to user\n |
| /// \b IMtype - user's preferred IM protocol\n |
| /// \b IMid - user's IM id\n |
| /// \b id - user's id from database\n |
| /// \b width - pixel width for rdp files\n |
| /// \b height - pixel height for rdp files\n |
| /// \b bpp - color depth for rdp files\n |
| /// \b audiomode - 'none' or 'local' - audio mode for rdp files\n |
| /// \b mapdrives - 0 or 1 - map drives for rdp files; 1 means to map\n |
| /// \b mapprinters - 0 or 1 - map printers for rdp files; 1 means to map\n |
| /// \b mapserial - 0 or 1 - map serial ports for rdp files; 1 means to map\n |
| /// \b rdpport - preferred port for RDP\n |
| /// \b showallgroups - 0 or 1 - show only user groups matching user's |
| /// affiliation or show all user groups\n |
| /// \b lastupdated - datetime the information was last updated\n |
| /// \b groups - array of groups user is a member of where the index is the id |
| /// of the group and the value is the name of the group\n |
| /// \b privileges - array of privileges that the user has |
| /// |
| /// \brief gets the user's information from the db and puts it into an array; |
| /// if the user is not in the db, query ldap and add them; if the user changed |
| /// their name and unity id; fix information in db based on numeric unity id; |
| /// returns NULL if could not get information about the user |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getUserInfo($id, $noupdate=0, $numeric=0) { |
| $affilid = DEFAULT_AFFILID; |
| if(! $numeric) { |
| $rc = getAffilidAndLogin($id, $affilid); |
| if($rc == -1) |
| return NULL; |
| } |
| |
| $user = array(); |
| $query = "SELECT u.unityid AS unityid, " |
| . "u.affiliationid, " |
| . "af.name AS affiliation, " |
| . "u.firstname AS firstname, " |
| . "u.lastname AS lastname, " |
| . "u.preferredname AS preferredname, " |
| . "u.email AS email, " |
| . "u.emailnotices, " |
| . "i.name AS IMtype, " |
| . "u.IMid AS IMid, " |
| . "u.id AS id, " |
| . "u.width AS width, " |
| . "u.height AS height, " |
| . "u.bpp AS bpp, " |
| . "u.audiomode AS audiomode, " |
| . "u.mapdrives AS mapdrives, " |
| . "u.mapprinters AS mapprinters, " |
| . "u.mapserial AS mapserial, " |
| . "COALESCE(u.rdpport, 3389) AS rdpport, " |
| . "u.showallgroups, " |
| . "u.lastupdated AS lastupdated, " |
| . "u.usepublickeys, " |
| . "u.sshpublickeys, " |
| . "af.shibonly " |
| . "FROM affiliation af, " |
| . "user u " |
| . "LEFT JOIN IMtype i ON (u.IMtypeid = i.id) " |
| . "WHERE u.affiliationid = af.id AND "; |
| if($numeric) |
| $query .= "u.id = $id"; |
| else |
| $query .= "u.unityid = '$id' AND af.id = $affilid"; |
| |
| $qh = doQuery($query, "105"); |
| if($user = mysql_fetch_assoc($qh)) { |
| $user['sshpublickeys'] = htmlspecialchars($user['sshpublickeys']); |
| if((datetimeToUnix($user["lastupdated"]) > time() - SECINDAY) || |
| $user['unityid'] == 'vclreload' || |
| $user['affiliation'] == 'Local' || |
| $user['shibonly'] || |
| $noupdate) { |
| # get user's groups |
| $user["groups"] = getUsersGroups($user["id"], 1); |
| $user["groupperms"] = getUsersGroupPerms(array_keys($user['groups'])); |
| |
| checkExpiredDemoUser($user['id'], $user['groups']); |
| |
| # get user's privileges |
| $user["privileges"] = getOverallUserPrivs($user["id"]); |
| |
| if(preg_match('/@/', $user['unityid'])) { |
| $tmparr = explode('@', $user['unityid']); |
| $user['login'] = $tmparr[0]; |
| } |
| else |
| $user['login'] = $user['unityid']; |
| |
| $blockids = getBlockAllocationIDs($user); |
| $user['memberCurrentBlock'] = count($blockids); |
| return $user; |
| } |
| } |
| if($numeric) |
| $user = updateUserData($id, "numeric"); |
| else |
| $user = updateUserData($id, "loginid", $affilid); |
| if(! is_null($user)) { |
| $blockids = getBlockAllocationIDs($user); |
| $user['memberCurrentBlock'] = count($blockids); |
| } |
| return $user; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getUsersGroups($userid, $includeowned, $includeaffil) |
| /// |
| /// \param $userid - an id from the user table |
| /// \param $includeowned - (optional, default=0) include groups the user owns |
| /// but is not in |
| /// \param $includeaffil - (optional, default=0) include @affiliation in name |
| /// of group |
| /// |
| /// \return an array of the user's groups where the index is the id of the |
| /// group |
| /// |
| /// \brief builds a array of the groups the user is member of |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getUsersGroups($userid, $includeowned=0, $includeaffil=0) { |
| if($includeaffil) { |
| $query = "SELECT m.usergroupid, " |
| . "CONCAT(g.name, '@', a.name) AS name " |
| . "FROM usergroupmembers m, " |
| . "usergroup g, " |
| . "affiliation a " |
| . "WHERE m.userid = $userid AND " |
| . "m.usergroupid = g.id AND " |
| . "g.affiliationid = a.id"; |
| } |
| else { |
| $query = "SELECT m.usergroupid, " |
| . "g.name " |
| . "FROM usergroupmembers m, " |
| . "usergroup g " |
| . "WHERE m.userid = $userid AND " |
| . "m.usergroupid = g.id"; |
| } |
| $qh = doQuery($query, "101"); |
| $groups = array(); |
| while($row = mysql_fetch_assoc($qh)) { |
| $groups[$row["usergroupid"]] = $row["name"]; |
| } |
| if($includeowned) { |
| if($includeaffil) { |
| $query = "SELECT g.id AS usergroupid, " |
| . "CONCAT(g.name, '@', a.name) AS name " |
| . "FROM usergroup g, " |
| . "affiliation a " |
| . "WHERE g.ownerid = $userid AND " |
| . "g.affiliationid = a.id"; |
| } |
| else { |
| $query = "SELECT id AS usergroupid, " |
| . "name " |
| . "FROM usergroup " |
| . "WHERE ownerid = $userid"; |
| } |
| $qh = doQuery($query, "101"); |
| while($row = mysql_fetch_assoc($qh)) { |
| $groups[$row["usergroupid"]] = $row["name"]; |
| } |
| } |
| uasort($groups, "sortKeepIndex"); |
| return $groups; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getUsersGroupPerms($usergroupids) |
| /// |
| /// \param $usergroupids - array of user group ids |
| /// |
| /// \return array of permissions where each index is the permission id and each |
| /// element is the name of the permission |
| /// |
| /// \brief builds an array of all permissions granted to a user via that user's |
| /// user groups |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getUsersGroupPerms($usergroupids) { |
| if(empty($usergroupids)) |
| return array(); |
| $inlist = implode(',', $usergroupids); |
| if($inlist == '') |
| return array(); |
| $query = "SELECT DISTINCT t.id, " |
| . "t.name " |
| . "FROM usergroupprivtype t, " |
| . "usergrouppriv u " |
| . "WHERE u.usergroupid IN ($inlist) AND " |
| . "u.userprivtypeid = t.id " |
| . "ORDER BY t.name"; |
| $perms = array(); |
| $qh = doQuery($query, 101); |
| while($row = mysql_fetch_assoc($qh)) |
| $perms[$row['id']] = $row['name']; |
| return $perms; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn checkUserHasPerm($perm, $userid=0) |
| /// |
| /// \param $perm - name of a user group permission |
| /// \param $userid (optional, default=0) - if specified, check for $userid |
| /// having $perm; otherwise, check logged in user |
| /// |
| /// \return 1 if user has $perm, 0 otherwise |
| /// |
| /// \brief checks to see if a user has been granted a permission through that |
| /// user's group memberships |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function checkUserHasPerm($perm, $userid=0) { |
| global $user; |
| if($userid == 0) { |
| if(isset($user['groupperms'])) |
| $perms = $user['groupperms']; |
| else |
| return 0; |
| } |
| else { |
| $usersgroups = getUsersGroups($userid, 1); |
| $perms = getUsersGroupPerms(array_keys($usersgroups)); |
| } |
| if(is_array($perms) && in_array($perm, $perms)) |
| return 1; |
| return 0; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn updateUserData($id, $type, $affilid) |
| /// |
| /// \param $id - user's unity id or id from user table |
| /// \param $type - (optional, default=loginid) - numericid or loginid |
| /// numericid is the user's numeric id; loginid is the other form (ie a unity |
| /// id) |
| /// \param $affilid - (optional, default=DEFAULT_AFFILID) - affiliation id |
| /// |
| /// \return 0 if fail to update data or an array with these elements:\n |
| /// \b id - user's numeric unity id\n |
| /// \b unityid - unity ID for the user\n |
| /// \b affiliation - user's affiliation\n |
| /// \b affiliationid - user's affiliation id\n |
| /// \b firstname - user's first name\n |
| /// \b lastname - user's last name\n |
| /// \b email - user's preferred email address\n |
| /// \b IMtype - user's preferred IM protocol\n |
| /// \b IMid - user's IM id\n |
| /// \b lastupdated - datetime the information was last updated |
| /// |
| /// \brief looks up the logged in user's info in ldap and updates it in the db |
| /// or adds it to the db |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function updateUserData($id, $type="loginid", $affilid=DEFAULT_AFFILID) { |
| global $updateUserFunc, $updateUserFuncArgs; |
| if($type == 'numeric') { |
| $query = "SELECT unityid, " |
| . "affiliationid " |
| . "FROM user " |
| . "WHERE id = $id"; |
| $qh = doQuery($query, 101); |
| if($row = mysql_fetch_assoc($qh)) { |
| $id = $row['unityid']; |
| $type = 'loginid'; |
| $affilid = $row['affiliationid']; |
| } |
| else |
| abort(1); |
| } |
| $updateFunc = $updateUserFunc[$affilid]; |
| if(array_key_exists($affilid, $updateUserFuncArgs)) |
| return $updateFunc($updateUserFuncArgs[$affilid], $id); |
| else |
| return $updateFunc($id); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn addUser($loginid) |
| /// |
| /// \param $loginid - a login id |
| /// |
| /// \return id from user table for the user, NULL if userid not in table |
| /// |
| /// \brief looks up the user via LDAP and adds to DB |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function addUser($loginid) { |
| global $addUserFuncArgs, $addUserFunc; |
| getAffilidAndLogin($loginid, $affilid); |
| if(empty($affilid)) |
| abort(11); |
| $addfunc = $addUserFunc[$affilid]; |
| if(array_key_exists($affilid, $addUserFuncArgs)) |
| return $addfunc($addUserFuncArgs[$affilid], $loginid); |
| else |
| return $addfunc($loginid); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn updateUserPrefs($userid, $preferredname, $width, $height, $bpp, $audio, |
| /// $mapdrives, $mapprinters, $mapserial, $rdpport) |
| /// |
| /// \param $userid - id from user table |
| /// \param $preferredname - user's preferred name |
| /// \param $width - pixel width for rdp files |
| /// \param $height - pixel height for rdp files |
| /// \param $bpp - color depth for rdp files |
| /// \param $audio - 'none' or 'local' - audio preference for rdp files |
| /// \param $mapdrives - 0 or 1 - 1 to map local drives in rdp files |
| /// \param $mapprinters - 0 or 1 - 1 to map printers in rdp files |
| /// \param $mapserial - 0 or 1 - 1 to map serial ports in rdp files |
| /// \param $rdpport - port for RDP to listen on |
| /// |
| /// \return number of rows affected by update (\b NOTE: this may be 0 if none |
| /// of the values were actually changes |
| /// |
| /// \brief updates the preferences for the user |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function updateUserPrefs($userid, $preferredname, $width, $height, $bpp, $audio, |
| $mapdrives, $mapprinters, $mapserial, $rdpport) { |
| global $mysql_link_vcl; |
| $preferredname = mysql_real_escape_string($preferredname); |
| $audio = mysql_real_escape_string($audio); |
| if($rdpport == 3389) |
| $rdpport = 'NULL'; |
| $query = "UPDATE user SET " |
| . "preferredname = '$preferredname', " |
| . "width = '$width', " |
| . "height = '$height', " |
| . "bpp = $bpp, " |
| . "audiomode = '$audio', " |
| . "mapdrives = $mapdrives, " |
| . "mapprinters = $mapprinters, " |
| . "mapserial = $mapserial, " |
| . "rdpport = $rdpport " |
| . "WHERE id = $userid"; |
| doQuery($query, 270); |
| return mysql_affected_rows($mysql_link_vcl); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getOverallUserPrivs($userid) |
| /// |
| /// \param $userid - an id from the user table |
| /// |
| /// \return an array of privileges types that the user has somewhere in the |
| /// privilege tree |
| /// |
| /// \brief get the privilege types that the user has somewhere in the |
| /// privilege tree |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getOverallUserPrivs($userid) { |
| $query = "SELECT DISTINCT t.name " |
| . "FROM userprivtype t, " |
| . "userpriv u " |
| . "WHERE u.userprivtypeid = t.id AND " |
| . "t.name NOT IN ('configAdmin', 'serverProfileAdmin') AND " |
| . "(u.userid = $userid OR " |
| . "u.usergroupid IN (SELECT usergroupid " |
| . "FROM usergroupmembers " |
| . "WHERE userid = $userid) OR " |
| . "u.usergroupid IN (SELECT id " |
| . "FROM usergroup " |
| . "WHERE ownerid = $userid))"; |
| $qh = doQuery($query, 107); |
| $privileges = array(); |
| while($row = mysql_fetch_row($qh)) |
| $privileges[] = $row[0]; |
| if(in_array("mgmtNodeAdmin", $privileges)) |
| $privileges[] = 'managementnodeAdmin'; |
| return $privileges; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getBlockAllocationIDs($user) |
| /// |
| /// \param $user - array of user data |
| /// |
| /// \return array of block allocation ids that are currently active for $user |
| /// |
| /// \brief checks to see if $user is a member of an active block allocation |
| /// (active also includes allocations starting within 15 minutes) |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getBlockAllocationIDs($user) { |
| $groupids = array_keys($user['groups']); |
| if(empty($groupids)) |
| return array(); |
| $inids = implode(',', $groupids); |
| $query = "SELECT r.id " |
| . "FROM blockRequest r, " |
| . "blockTimes t " |
| . "WHERE t.blockRequestid = r.id AND " |
| . "r.status = 'accepted' AND " |
| . "t.start <= DATE_ADD(NOW(), INTERVAL 15 MINUTE) AND " |
| . "t.end > NOW() AND " |
| . "t.skip = 0 AND " |
| . "r.groupid IN ($inids)"; |
| $ids = array(); |
| $qh = doQuery($query, 101); |
| while($row = mysql_fetch_assoc($qh)) |
| $ids[] = $row['id']; |
| return $ids; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn isAvailable($images, $imageid, $imagerevisionid, $start, $end, |
| /// $holdcomps, $requestid, $userid, $ignoreprivileges, |
| /// $forimaging, $ip, $mac, $skipconcurrentcheck) |
| /// |
| /// \param $images - array as returned from getImages |
| /// \param $imageid - imageid from the image table |
| /// \param $imagerevisionid - id of revision of image from imagerevision table |
| /// \param $start - unix timestamp for start of reservation |
| /// \param $end - unix timestamp for end of reservation |
| /// \param $holdcomps - bool - 1 to lock computers for later adding to |
| /// reservation, 0 not to; use 0 when just checking for estimated availability, |
| /// use 1 when finding computers to actually reserve |
| /// \param $requestid - (optional) a requestid; if checking for an available |
| /// timeslot to update a request, pass the request id that will be updated; |
| /// otherwise, don't pass this argument |
| /// \param $userid - (optional) id from user table |
| /// \param $ignoreprivileges (optional, default=0) - 0 (false) or 1 (true) - set |
| /// to 1 to look for computers from any that are mapped to be able to run the |
| /// image; set to 0 to only look for computers from ones that are both mapped |
| /// and that $userid has been granted access to through the privilege tree |
| /// \param $forimaging - (optional, default=0) - 0 if normal reservation, 1 if |
| /// an imaging reservation |
| /// \param $ip - (optional, default='') ip address to be assigned; assumed to |
| /// be a server profile reservation if defined |
| /// \param $mac - (optional, default='') mac address to be assigned; assumed to |
| /// be a server profile reservation if defined |
| /// \param $skipconcurrentcheck (optional, default=0) - set to 1 to skip check |
| /// for concurrent use of image; useful for setting up reload reservations |
| /// |
| /// \return -4 if unavailable due to an ip/mac conflict with another machine |
| /// -3 if unavailable due to an ip/mac conflict with another reservation |
| /// -2 if specified time period is during a maintenance window |
| /// -1 if $imageid is limited in the number of concurrent reservations |
| /// available, and the limit has been reached |
| /// 0 if combination is not available\n |
| /// an integer >0 if it is available |
| /// |
| /// \brief checks that the passed in arguments constitute an available request |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function isAvailable($images, $imageid, $imagerevisionid, $start, $end, |
| $holdcomps, $requestid=0, $userid=0, $ignoreprivileges=0, |
| $forimaging=0, $ip='', $mac='', $skipconcurrentcheck=0) { |
| global $requestInfo, $user; |
| $requestInfo["start"] = $start; |
| $requestInfo["end"] = $end; |
| $requestInfo["imageid"] = $imageid; |
| $requestInfo["ipwarning"] = 0; |
| $allocatedcompids = array(0); |
| $debug = getContinuationVar('debug', 0); |
| |
| if(! is_array($imagerevisionid)) |
| $imagerevisionid = array($imageid => array($imagerevisionid)); |
| elseif(empty($imagerevisionid)) |
| $imagerevisionid = array($imageid => array(getProductionRevisionid($imageid))); |
| |
| if(schCheckMaintenance($start, $end)) |
| return debugIsAvailable(-2, 1, $start, $end, $imagerevisionid); |
| |
| if(! array_key_exists($imageid, $images)) |
| return debugIsAvailable(0, 20, $start, $end, $imagerevisionid); |
| |
| if($requestInfo["start"] <= time()) { |
| $now = 1; |
| $nowfuture = 'now'; |
| } |
| else { |
| $now = 0; |
| $nowfuture = 'future'; |
| } |
| |
| $scheduleids = getAvailableSchedules($start, $end); |
| |
| $requestInfo["computers"] = array(); |
| $requestInfo["computers"][0] = 0; |
| $requestInfo["images"][0] = $imageid; |
| $requestInfo["imagerevisions"][0] = $imagerevisionid[$imageid][0]; |
| |
| # build array of subimages |
| # TODO handle mininstance |
| if(! $forimaging && $images[$imageid]["imagemetaid"] != NULL) { |
| $count = 1; |
| foreach($images[$imageid]["subimages"] as $imgid) { |
| $requestInfo['computers'][$count] = 0; |
| $requestInfo['images'][$count] = $imgid; |
| if(array_key_exists($imgid, $imagerevisionid) && |
| array_key_exists($count, $imagerevisionid[$imgid])) |
| $requestInfo['imagerevisions'][$count] = $imagerevisionid[$imgid][$count]; |
| else |
| $requestInfo['imagerevisions'][$count] = getProductionRevisionid($imgid); |
| $count++; |
| } |
| } |
| |
| $startstamp = unixToDatetime($start); |
| $endstamp = unixToDatetime($end + 900); |
| |
| if(! empty($mac) || ! empty($ip)) { |
| # check for overlapping use of mac or ip |
| $query = "SELECT rq.id " |
| . "FROM reservation rs, " |
| . "request rq, " |
| . "serverrequest sr " |
| . "WHERE '$startstamp' < (rq.end + INTERVAL 900 SECOND) AND " |
| . "'$endstamp' > rq.start AND " |
| . "sr.requestid = rq.id AND " |
| . "rs.requestid = rq.id AND " |
| . "(sr.fixedIP = '$ip' OR " |
| . "sr.fixedMAC = '$mac') AND " |
| . "rq.stateid NOT IN (1,5,11,12) "; |
| if($requestid) |
| $query .= "AND rq.id != $requestid "; |
| $query .= "LIMIT 1"; |
| $qh = doQuery($query, 101); |
| if(mysql_num_rows($qh)) { |
| return debugIsAvailable(-3, 2, $start, $end, $imagerevisionid); |
| } |
| |
| # check for IP being used by a management node |
| $query = "SELECT id " |
| . "FROM managementnode " |
| . "WHERE IPaddress = '$ip' AND " |
| . "stateid != 1"; |
| $qh = doQuery($query, 101); |
| if(mysql_num_rows($qh)) { |
| return debugIsAvailable(-4, 16, $start, $end, $imagerevisionid); |
| } |
| } |
| |
| if($requestid) |
| $requestData = getRequestInfo($requestid); |
| |
| $vmhostcheckdone = 0; |
| $ignorestates = "'maintenance','vmhostinuse','hpc','failed'"; |
| if($now) |
| # computers from reservations with a user directed reinstall will be in |
| # the reloading state, but they will be removed from the list later on |
| $ignorestates .= ",'timeout','inuse'"; |
| |
| foreach($requestInfo["images"] as $key => $imageid) { |
| # check for max concurrent usage of image |
| if(! $skipconcurrentcheck && |
| $images[$imageid]['maxconcurrent'] != NULL) { |
| if($userid == 0) |
| $usersgroups = $user['groups']; |
| else { |
| $testuser = getUserInfo($userid, 0, 1); |
| if(is_null($testuser)) |
| return debugIsAvailable(0, 17, $start, $end, $imagerevisionid); |
| $usersgroups = $testuser['groups']; |
| } |
| $decforedit = 0; |
| $compids = array(); |
| $reloadid = getUserlistID('vclreload@Local'); |
| $query = "SELECT rs.computerid, " |
| . "rq.id AS reqid " |
| . "FROM reservation rs, " |
| . "request rq " |
| . "WHERE '$startstamp' < (rq.end + INTERVAL 900 SECOND) AND " |
| . "'$endstamp' > rq.start AND " |
| . "rs.requestid = rq.id AND " |
| . "rs.imageid = $imageid AND " |
| . "rq.stateid NOT IN (1,5,11,12,16,17) AND " |
| . "rq.userid != $reloadid"; |
| $qh = doQuery($query, 101); |
| while($row = mysql_fetch_assoc($qh)) { |
| $compids[] = $row['computerid']; |
| if($row['reqid'] == $requestid) |
| $decforedit = 1; |
| } |
| $usagecnt = count($compids); |
| $allids = implode("','", $compids); |
| $ignoregroups = implode("','", array_keys($usersgroups)); |
| $query = "SELECT COUNT(bc.imageid) AS currentusage " |
| . "FROM blockComputers bc, " |
| . "blockRequest br, " |
| . "blockTimes bt " |
| . "WHERE bc.blockTimeid = bt.id AND " |
| . "bt.blockRequestid = br.id AND " |
| . "bc.imageid = $imageid AND " |
| . "bc.computerid NOT IN ('$allids') AND " |
| . "br.groupid NOT IN ('$ignoregroups') AND " |
| . "'$startstamp' < (bt.end + INTERVAL 900 SECOND) AND " |
| . "'$endstamp' > bt.start AND " |
| . "bt.skip != 1 AND " |
| . "br.status != 'deleted'"; |
| $qh = doQuery($query); |
| if(! $row = mysql_fetch_assoc($qh)) { |
| cleanSemaphore(); |
| return debugIsAvailable(0, 3, $start, $end, $imagerevisionid); |
| } |
| if(($usagecnt + $row['currentusage'] - $decforedit) >= $images[$imageid]['maxconcurrent']) { |
| cleanSemaphore(); |
| return debugIsAvailable(-1, 4, $start, $end, $imagerevisionid); |
| } |
| } |
| |
| $platformid = getImagePlatform($imageid); |
| if(is_null($platformid)) { |
| cleanSemaphore(); |
| return debugIsAvailable(0, 5, $start, $end, $imagerevisionid); |
| } |
| |
| # get computers $imageid maps to |
| $compids = getMappedResources($imageid, "image", "computer"); |
| if(! count($compids)) { |
| cleanSemaphore(); |
| return debugIsAvailable(0, 6, $start, $end, $imagerevisionid); |
| } |
| $mappedcomputers = implode(',', $compids); |
| if($debug) { |
| $cnt = count($compids); |
| print "console.log('mapped computers: $cnt');"; |
| } |
| |
| // if $ip specified, only look at computers under management nodes that can |
| # handle that network |
| if($ip != '') { |
| $mappedmns = getMnsFromImage($imageid); |
| $mnnets = checkAvailableNetworks($ip); |
| $intersect = array_intersect($mappedmns, $mnnets); |
| $tmpcompids = array(); |
| foreach($intersect as $mnid) { |
| $tmp2 = getMappedResources($mnid, 'managementnode', 'computer'); |
| $tmpcompids = array_merge($tmpcompids, $tmp2); |
| } |
| $tmpcompids = array_unique($tmpcompids); |
| $newcompids = array_intersect($compids, $tmpcompids); |
| if(! count($newcompids)) { |
| cleanSemaphore(); |
| return debugIsAvailable(0, 18, $start, $end, $imagerevisionid); |
| } |
| $mappedcomputers = implode(',', $newcompids); |
| } |
| |
| #get computers for available schedules and platforms |
| $computerids = array(); |
| $currentids = array(); |
| $blockids = array(); |
| $altRemoveBlockCheck = 0; |
| // if we are modifying a request and it is after the start time, only allow |
| // the scheduled computer(s) to be modified |
| if($requestid && datetimeToUnix($requestData["start"]) <= time()) { |
| $altRemoveBlockCheck = 1; |
| foreach($requestData["reservations"] as $key2 => $res) { |
| if($res["imageid"] == $imageid) { |
| $compid = $res["computerid"]; |
| unset($requestData['reservations'][$key2]); |
| break; |
| } |
| } |
| array_push($computerids, $compid); |
| array_push($currentids, $compid); |
| $query = "SELECT scheduleid " |
| . "FROM computer " |
| . "WHERE id = $compid"; |
| $qh = doQuery($query, 128); |
| $row = mysql_fetch_row($qh); |
| if(! in_array($row[0], $scheduleids)) { |
| cleanSemaphore(); |
| return debugIsAvailable(0, 7, $start, $end, $imagerevisionid, $computerids, $currentids, $blockids); |
| } |
| // set $virtual to 0 so that it is defined later but skips the additional code |
| $virtual = 0; |
| } |
| // otherwise, build a list of computers |
| else { |
| # determine if image is bare metal or virtual |
| $query = "SELECT OS.installtype " |
| . "FROM image i " |
| . "LEFT JOIN OS ON (i.OSid = OS.id) " |
| . "WHERE i.id = $imageid"; |
| $qh = doQuery($query, 101); |
| if(! ($row = mysql_fetch_assoc($qh))) { |
| cleanSemaphore(); |
| return debugIsAvailable(0, 8, $start, $end, $imagerevisionid, $computerids, $currentids, $blockids); |
| } |
| # TODO might need to check for other strings for KVM, OpenStack, etc |
| if(preg_match('/(vmware)/', $row['installtype'])) |
| $virtual = 1; |
| else |
| $virtual = 0; |
| |
| # get list of available computers |
| if(! $ignoreprivileges) { |
| $resources = getUserResources(array("imageAdmin", "imageCheckOut"), |
| array("available"), 0, 0, $userid); |
| $usercomputers = implode("','", array_keys($resources["computer"])); |
| $usercomputers = "'$usercomputers'"; |
| if($debug) { |
| $cnt = count($resources['computer']); |
| print "console.log('computers available to user: $cnt');"; |
| } |
| } |
| $alloccompids = implode(",", $allocatedcompids); |
| |
| # get list of computers we can provision image to |
| |
| $schedules = implode(',', $scheduleids); |
| |
| #image.OSid->OS.installtype->OSinstalltype.id->provisioningOSinstalltype.provisioningid->computer.provisioningid |
| $query = "SELECT DISTINCT c.id, " |
| . "c.currentimageid, " |
| . "c.imagerevisionid " |
| . "FROM state s, " |
| . "image i " |
| . "LEFT JOIN OS o ON (o.id = i.OSid) " |
| . "LEFT JOIN OSinstalltype oi ON (oi.name = o.installtype) " |
| . "LEFT JOIN provisioningOSinstalltype poi ON (poi.OSinstalltypeid = oi.id) " |
| . "LEFT JOIN computer c ON (poi.provisioningid = c.provisioningid) " |
| . "LEFT JOIN semaphore se ON (c.id = se.computerid) " |
| . "WHERE i.id = $imageid AND " |
| . "c.scheduleid IN ($schedules) AND " |
| . "c.platformid = $platformid AND " |
| . "c.stateid = s.id AND " |
| . "s.name NOT IN ($ignorestates) AND " |
| . "c.RAM >= i.minram AND " |
| . "c.procnumber >= i.minprocnumber AND " |
| . "c.procspeed >= i.minprocspeed AND " |
| . "c.network >= i.minnetwork AND " |
| . "c.deleted = 0 AND " |
| . "(c.type != 'virtualmachine' OR c.vmhostid IS NOT NULL) AND "; |
| if(! $ignoreprivileges) |
| $query .= "c.id IN ($usercomputers) AND "; |
| $query .= "c.id IN ($mappedcomputers) AND " |
| . "c.id NOT IN ($alloccompids) AND " |
| . "(se.expires IS NULL OR se.expires < NOW()) " |
| . "ORDER BY RAM, " |
| . "(c.procspeed * c.procnumber), " |
| . "network"; |
| |
| $qh = doQuery($query, 129); |
| while($row = mysql_fetch_assoc($qh)) { |
| array_push($computerids, $row['id']); |
| if($row['currentimageid'] == $imageid && |
| $row['imagerevisionid'] == $requestInfo['imagerevisions'][$key]) { |
| array_push($currentids, $row['id']); |
| } |
| } |
| # get computer ids available from block allocations |
| $blockdata = getAvailableBlockComputerids($imageid, $start, $end, |
| $allocatedcompids); |
| $blockids = $blockdata['compids']; |
| } |
| |
| # return 0 if no computers available |
| if(empty($computerids) && empty($blockids)) |
| return debugIsAvailable(0, 21, $start, $end, $imagerevisionid, $computerids, $currentids, $blockids, array(), $virtual); |
| |
| #remove computers from list that are already scheduled |
| $usedComputerids = array(); |
| $query = "SELECT DISTINCT rs.computerid " |
| . "FROM reservation rs, " |
| . "request rq " |
| . "WHERE '$startstamp' < (rq.end + INTERVAL 900 SECOND) AND " |
| . "'$endstamp' > rq.start AND " |
| . "rq.id != $requestid AND " |
| . "rs.requestid = rq.id AND " |
| . "rq.stateid NOT IN (5, 12, 19) AND " # failed, complete, reload |
| . "(rq.stateid != 14 OR rq.laststateid != 19)"; # pending/reload |
| $qh = doQuery($query, 130); |
| while($row = mysql_fetch_row($qh)) { |
| array_push($usedComputerids, $row[0]); |
| } |
| |
| $computerids = array_diff($computerids, $usedComputerids); |
| $currentids = array_diff($currentids, $usedComputerids); |
| $blockids = array_diff($blockids, $usedComputerids); |
| |
| // if modifying a reservation and $computerids is now empty, return 0 |
| if($requestid && empty($computerids)) { |
| cleanSemaphore(); |
| return debugIsAvailable(0, 9, $start, $end, $imagerevisionid, $computerids, $currentids, $blockids, array(), $virtual); |
| } |
| |
| # return 0 if no computers available |
| if(empty($computerids) && empty($currentids) && empty($blockids)) |
| return debugIsAvailable(0, 19, $start, $end, $imagerevisionid, $computerids, $currentids, $blockids, array(), $virtual); |
| |
| # remove computers from list that are allocated to block allocations |
| if($altRemoveBlockCheck) { |
| if(editRequestBlockCheck($computerids[0], $imageid, $start, $end)) { |
| cleanSemaphore(); |
| return debugIsAvailable(0, 10, $start, $end, $imagerevisionid, $computerids, $currentids, $blockids, array(), $virtual); |
| } |
| } |
| elseif(! count($blockids)) { # && ! $altRemoveBlockCheck |
| $usedBlockCompids = getUsedBlockComputerids($start, $end); |
| $computerids = array_diff($computerids, $usedBlockCompids); |
| $currentids = array_diff($currentids, $usedBlockCompids); |
| } |
| |
| if($virtual && empty($currentids) && ! empty($computerids)) { |
| # find computers whose hosts can handle the required RAM - we don't |
| # need to do this if there are VMs with the requested image already |
| # available because they would already fit within the host's available |
| # RAM |
| |
| if(! $vmhostcheckdone) { |
| $vmhostcheckdone = 1; |
| $query = "DROP TEMPORARY TABLE IF EXISTS VMhostCheck"; |
| doQuery($query, 101); |
| |
| $query = "CREATE TEMPORARY TABLE VMhostCheck ( " |
| . "RAM mediumint unsigned NOT NULL, " |
| . "allocRAM int NOT NULL, " |
| . "vmhostid smallint unsigned NOT NULL " |
| . ") ENGINE=MEMORY"; |
| doQuery($query, 101); |
| |
| $query = "INSERT INTO VMhostCheck " |
| . "SELECT c.RAM, " |
| . "SUM(i.minram), " |
| . "v.id " |
| . "FROM vmhost v " |
| . "LEFT JOIN computer c ON (v.computerid = c.id) " |
| . "LEFT JOIN computer c2 ON (v.id = c2.vmhostid) " |
| . "LEFT JOIN image i ON (c2.currentimageid = i.id) " |
| . "WHERE c.stateid = 20 " |
| . "GROUP BY v.id"; |
| doQuery($query, 101); |
| } |
| |
| $inids = implode(',', $computerids); |
| // if want overbooking, modify the last part of the WHERE clause |
| $query = "SELECT c.id " |
| . "FROM VMhostCheck v " |
| . "LEFT JOIN computer c ON (v.vmhostid = c.vmhostid) " |
| . "LEFT JOIN image i ON (c.currentimageid = i.id) " |
| . "WHERE c.id IN ($inids) AND " |
| . "(v.allocRAM - CAST(i.minram AS SIGNED) + {$images[$imageid]['minram']}) < v.RAM " |
| . "ORDER BY c.RAM, " |
| . "(c.procspeed * c.procnumber), " |
| . "c.network"; |
| $qh = doQuery($query, 101); |
| $newcompids = array(); |
| while($row = mysql_fetch_assoc($qh)) |
| $newcompids[] = $row['id']; |
| $computerids = $newcompids; |
| } |
| |
| # check for use of specified IP address, have to wait until here |
| # because there may be a computer already assigned the IP that |
| # can be used for this reservation |
| if(! empty($ip) && $now) { |
| $allcompids = array_merge($computerids, $blockids); |
| if(empty($allcompids)) |
| return debugIsAvailable(0, 13, $start, $end, $imagerevisionid, $computerids, $currentids, $blockids, array(), $virtual); |
| $inids = implode(',', $allcompids); |
| $query = "SELECT id " |
| . "FROM computer " |
| . "WHERE id NOT IN ($inids) AND " |
| . "deleted = 0 AND " |
| . "stateid != 1 AND " |
| . "IPaddress = '$ip' AND " |
| . "(type != 'virtualmachine' OR " |
| . "vmhostid IS NOT NULL)"; |
| $qh = doQuery($query); |
| if(mysql_num_rows($qh)) { |
| if($now) |
| return debugIsAvailable(-4, 18, $start, $end, $imagerevisionid, $computerids, $currentids, $blockids, array(), $virtual); |
| $requestInfo['ipwarning'] = 1; |
| } |
| $query = "SELECT id " |
| . "FROM computer " |
| . "WHERE id in ($inids) AND " |
| . "IPaddress = '$ip'"; |
| if($requestid) |
| $query .= " AND id != $compid"; # TODO test this |
| $qh = doQuery($query); |
| $cnt = mysql_num_rows($qh); |
| if($cnt > 1) { |
| if($now) |
| return debugIsAvailable(-4, 22, $start, $end, $imagerevisionid, $computerids, $currentids, $blockids, array(), $virtual); |
| $requestInfo['ipwarning'] = 1; |
| } |
| elseif($cnt == 1) { |
| $row = mysql_fetch_assoc($qh); |
| $computerids = array($row['id']); |
| $blockids = array(); |
| } |
| } |
| |
| # remove any recently reserved computers that could have been an |
| # undetected failure |
| $failedids = getPossibleRecentFailures($userid, $imageid); |
| $shortened = 0; |
| if(! empty($failedids)) { |
| $origcomputerids = $computerids; |
| $origcurrentids = $currentids; |
| $origblockids = $blockids; |
| if(! empty($computerids)) { |
| $testids = array_diff($computerids, $failedids); |
| if(! empty($testids)) { |
| $shortened = 1; |
| $computerids = $testids; |
| $currentids = array_diff($currentids, $failedids); |
| } |
| } |
| if(! empty($blockids)) { |
| $testids = array_diff($blockids, $failedids); |
| if(! empty($testids)) { |
| $shortened = 1; |
| $blockids = $testids; |
| } |
| } |
| } |
| |
| # allocate a computer |
| $_imgrevid = $requestInfo['imagerevisions'][$key]; |
| $comparr = allocComputer($blockids, $currentids, $computerids, |
| $startstamp, $endstamp, $nowfuture, $imageid, $_imgrevid, |
| $holdcomps, $requestid); |
| if(empty($comparr) && $shortened) |
| $comparr = allocComputer($origblockids, $origcurrentids, |
| $origcomputerids, $startstamp, $endstamp, $nowfuture, |
| $imageid, $_imgrevid, $holdcomps, $requestid); |
| if(empty($comparr)) { |
| cleanSemaphore(); |
| return debugIsAvailable(0, 11, $start, $end, $imagerevisionid, $computerids, $currentids, $blockids, $failedids, $virtual); |
| } |
| |
| $requestInfo["computers"][$key] = $comparr['compid']; |
| $requestInfo["mgmtnodes"][$key] = $comparr['mgmtid']; |
| $requestInfo["loaded"][$key] = $comparr['loaded']; |
| $requestInfo['fromblock'][$key] = $comparr['fromblock']; |
| if($comparr['fromblock']) |
| $requestInfo['blockdata'][$key] = $blockdata[$comparr['compid']]; |
| array_push($allocatedcompids, $comparr['compid']); |
| } |
| |
| return debugIsAvailable(1, 12, $start, $end, $imagerevisionid, $computerids, $currentids, $blockids, array(), $virtual); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn debugIsAvailable($rc, $loc, $start, $end, $imagerevisionid, |
| /// $compids=array(), $currentids=array(), |
| /// $blockids=array(), $failedids=array(), $virtual='') |
| /// |
| /// \param $rc - return code |
| /// \param $loc - location from isAvailable function |
| /// \param $start - as passed to isAvailable function |
| /// \param $end - as passed to isAvailable function |
| /// \param $imagerevisionid - as passed to isAvailable function |
| /// \param $compids - $computerids from isAvailable |
| /// \param $currentids - $currentids from isAvailable |
| /// \param $blockids - $blockids from isAvailable |
| /// \param $failedids - $failedids from isAvailable |
| /// \param $virtual - $virtual from isAvailable |
| /// |
| /// \return $rc as passed in |
| /// |
| /// \brief prints debug line about why isAvailable returned specified return |
| /// code in javascript console if user has 'View Debug Information' user group |
| /// permission and has set the debug flag; most data passed in is currently |
| /// unused, but allows for a single place to add code for debugging |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function debugIsAvailable($rc, $loc, $start, $end, $imagerevisionid, |
| $compids=array(), $currentids=array(), |
| $blockids=array(), $failedids=array(), $virtual='') { |
| global $user, $mode, $requestInfo; |
| $debug = getContinuationVar('debug', 0); |
| if(! $debug || |
| $mode != 'AJupdateWaitTime' || |
| ! checkUserHasPerm('View Debug Information')) |
| return $rc; |
| switch($loc) { |
| case "1": |
| $msg = "site maintenance is scheduled for the requested time"; |
| break; |
| case "20": |
| $msg = "invalid image id submitted - not found in images available to the user"; |
| break; |
| case "2": |
| $msg = "an overlapping server reservation has the same fixed IP or MAC address"; |
| break; |
| case "16": |
| $msg = "the requested fixed IP address is currently in use by a management node"; |
| break; |
| case "17": |
| $msg = "failed to look up information about the specified user"; |
| break; |
| case "3": |
| $msg = "failed to get image usage count for block allocations"; |
| break; |
| case "4": |
| $msg = "max concurrent usage of image exceeded (includes those set aside for block allocations)"; |
| break; |
| case "5": |
| $msg = "failed to get platform of image"; |
| break; |
| case "6": |
| $msg = "image is not mapped to any computers"; |
| break; |
| case "18": |
| $msg = "no available computers under a management node that can handle the specified IP address"; |
| break; |
| case "7": |
| $msg = "the schedule of the currently reserved computer does not allow for the requested time"; |
| break; |
| case "8": |
| $msg = "failed to get OSinstalltype for image"; |
| break; |
| case "21": |
| $msg = "no computers with a matching schedule and platform, and in an available state, and available to the user, and mapped to the image, and matching image resource requirements"; |
| break; |
| case "9": |
| $msg = "not able to change existing reservation time for currently reserved computer"; |
| break; |
| case "19": |
| $msg = "no computers available (after removing scheduled computers/before performing virtual host resource checks)"; |
| break; |
| case "10": |
| $msg = "modification time overlaps with time computer is set aside for block allocation"; |
| break; |
| case "13": |
| $msg = "no computers available (after virtual host resource checks/before performing overlapping IP address check)"; |
| break; |
| case "18": |
| $msg = "requested IP address in use by another computer"; |
| break; |
| case "22": |
| $msg = "at least 2 computers have the requested IP address assigned to them"; |
| break; |
| case "11": |
| $msg = "unable to get either a management node or semaphore for available computer"; |
| break; |
| case "12": |
| $msg = "successfully found a computer (id: {$requestInfo['computers'][0]})"; |
| break; |
| } |
| print "console.log('$msg');"; |
| return $rc; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getAvailableSchedules($start, $end) |
| /// |
| /// \param $start - start time in unix timestamp form |
| /// \param $end - end time in unix timestamp form |
| /// |
| /// \return array of schedule ids |
| /// |
| /// \brief gets schedules available for given start and end time |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getAvailableSchedules($start, $end) { |
| # get list of schedules |
| $starttime = minuteOfWeek($start); |
| $endtime = minuteOfWeek($end); |
| |
| # request is within a single week |
| if(weekOfYear($start) == weekOfYear($end)) { |
| $query = "SELECT scheduleid " |
| . "FROM scheduletimes " |
| . "WHERE start <= $starttime AND " |
| . "end >= $endtime"; |
| } |
| # request covers at least a week's worth of time |
| elseif($end - $start >= SECINDAY * 7) { |
| $query = "SELECT scheduleid " |
| . "FROM scheduletimes " |
| . "WHERE start = 0 AND " |
| . "end = 10080"; |
| } |
| # request starts in one week and ends in the following week |
| else { |
| $query = "SELECT s1.scheduleid " |
| . "FROM scheduletimes s1, " |
| . "scheduletimes s2 " |
| . "WHERE s1.scheduleid = s2.scheduleid AND " |
| . "s1.start <= $starttime AND " |
| . "s1.end = 10080 AND " |
| . "s2.start = 0 AND " |
| . "s2.end >= $endtime"; |
| } |
| |
| $scheduleids = array(); |
| $qh = doQuery($query, 127); |
| while($row = mysql_fetch_row($qh)) { |
| array_push($scheduleids, $row[0]); |
| } |
| return $scheduleids; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getImagePlatform($imageid) |
| /// |
| /// \param $imageid - id of an image |
| /// |
| /// \return id of image's platform |
| /// |
| /// \brief gets the platformid for $imageid |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getImagePlatform($imageid) { |
| $query = "SELECT platformid FROM image WHERE id = $imageid"; |
| $qh = doQuery($query, 125); |
| if(! $row = mysql_fetch_assoc($qh)) |
| return NULL; |
| return $row['platformid']; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn schCheckMaintenance($start, $end) |
| /// |
| /// \param $start - unix timestamp for start of reservation |
| /// \param $end - unix timestamp for end of reservation |
| /// |
| /// \return true if time window conflicts with maintenance window; false if not |
| /// |
| /// \brief checks to see if the specified window conflicts with a maintenance |
| /// window |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function schCheckMaintenance($start, $end) { |
| $startdt = unixToDatetime($start); |
| $enddt = unixToDatetime($end); |
| $query = "SELECT id " |
| . "FROM sitemaintenance " |
| . "WHERE ((allowreservations = 0 AND " |
| . "(('$enddt' > start) AND ('$startdt' < end))) OR " |
| . "(('$startdt' > (start - INTERVAL 30 MINUTE)) AND ('$startdt' < end))) AND " |
| . "end > NOW()"; |
| $qh = doQuery($query, 101); |
| if($row = mysql_fetch_row($qh)) |
| return true; |
| return false; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn allocComputer($blockids, $currentids, $computerids, $start, $end, |
| /// $nowfuture, $imageid, $imagerevisionid, $holdcomps, |
| /// $requestid) |
| /// |
| /// \param $blockids - array of computer ids |
| /// \param $currentids - array of computer ids |
| /// \param $computerids - array of computer ids |
| /// \param $start - start time in datetime format |
| /// \param $start - end time in datetime format |
| /// \param $nowfuture - "now" or "future" |
| /// \param $holdcomps - bool - 1 to lock computers for later adding to |
| /// reservation, 0 not to; use 0 when just checking for estimated availability, |
| /// use 1 when finding computers to actually reserve |
| /// \param $requestid - id of request if called for editing an existing one |
| /// |
| /// \return empty array if failed to allocate a computer; array with these keys |
| /// on success:\n |
| /// \b compid - id of computer\n |
| /// \b mgmtid - id of management node for computer\n |
| /// \b loaded - 0 or 1 - whether or not computer is loaded with desired image |
| /// |
| /// \brief determines a computer to use from $blockids, $currentids, |
| /// and $computerids, looking at the arrays in that order and |
| /// tries to allocate a management node for it |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function allocComputer($blockids, $currentids, $computerids, $start, $end, |
| $nowfuture, $imageid, $imagerevisionid, $holdcomps, |
| $requestid) { |
| global $requestInfo; |
| $ret = array(); |
| if(SCHEDULER_ALLOCATE_RANDOM_COMPUTER) { |
| shuffle($blockids); |
| shuffle($currentids); |
| shuffle($computerids); |
| } |
| foreach($blockids as $compid) { |
| $mgmtnodeid = findManagementNode($compid, $start, $nowfuture); |
| if($mgmtnodeid == 0) |
| continue; |
| if($holdcomps && ! getSemaphore($imageid, $imagerevisionid, $mgmtnodeid, $compid, $start, $end, $requestid)) |
| continue; |
| $ret['compid'] = $compid; |
| $ret['mgmtid'] = $mgmtnodeid; |
| $ret['loaded'] = 1; |
| $ret['fromblock'] = 1; |
| return $ret; |
| } |
| foreach($currentids as $compid) { |
| $mgmtnodeid = findManagementNode($compid, $start, $nowfuture); |
| if($mgmtnodeid == 0) |
| continue; |
| if($holdcomps && ! getSemaphore($imageid, $imagerevisionid, $mgmtnodeid, $compid, $start, $end, $requestid)) |
| continue; |
| $ret['compid'] = $compid; |
| $ret['mgmtid'] = $mgmtnodeid; |
| $ret['loaded'] = 1; |
| $ret['fromblock'] = 0; |
| return $ret; |
| } |
| foreach($computerids as $compid) { |
| $mgmtnodeid = findManagementNode($compid, $start, $nowfuture); |
| if($mgmtnodeid == 0) |
| continue; |
| if($holdcomps && ! getSemaphore($imageid, $imagerevisionid, $mgmtnodeid, $compid, $start, $end, $requestid)) |
| continue; |
| $ret['compid'] = $compid; |
| $ret['mgmtid'] = $mgmtnodeid; |
| $ret['loaded'] = 0; |
| $ret['fromblock'] = 0; |
| return $ret; |
| } |
| return $ret; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getSemaphore($imageid, $imagerevisionid, $mgmtnodeid, $compid, $start, |
| /// $end, $requestid=0) |
| /// |
| /// \param $imageid - id of image |
| /// \param $imagerevisionid - id of image revision |
| /// \param $mgmtnodeid - id of management node |
| /// \param $compid - id of computer |
| /// \param $start - start of reservation in datetime format |
| /// \param $end - end of reservation in datetime format |
| /// \param $requestid - (optional) if passed, ignores checking for conflict |
| /// in request table for matching id |
| /// |
| /// \return 0 on failure, 1 on success |
| /// |
| /// \brief tries to get a semaphore for the requested computer |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getSemaphore($imageid, $imagerevisionid, $mgmtnodeid, $compid, $start, |
| $end, $requestid=0) { |
| global $mysql_link_vcl, $uniqid; |
| $query = "INSERT INTO semaphore " |
| . "SELECT c.id, " |
| . "$imageid, " |
| . "$imagerevisionid, " |
| . "$mgmtnodeid, " |
| . "NOW() + INTERVAL " . SEMTIMEOUT . " SECOND, " |
| . "'$uniqid' " |
| . "FROM computer c " |
| . "LEFT JOIN semaphore s ON (c.id = s.computerid) " |
| . "WHERE c.id = $compid AND " |
| . "(s.expires IS NULL OR s.expires < NOW()) " |
| . "LIMIT 1"; |
| doQuery($query); |
| $rc = mysql_affected_rows($mysql_link_vcl); |
| |
| # check to see if another process allocated this one |
| if($rc) { |
| $query = "SELECT rq.id " |
| . "FROM request rq, " |
| . "reservation rs " |
| . "WHERE rs.requestid = rq.id AND " |
| . "rs.computerid = $compid AND " |
| . "rq.start < '$end' AND " |
| . "rq.end > '$start' AND " |
| . "rq.stateid NOT IN (5, 12, 19) AND " # failed, complete, reload |
| . "(rq.stateid != 14 OR rq.laststateid != 19)"; # pending/reload |
| if($requestid) |
| $query .= " AND rq.id != $requestid"; |
| $qh = doQuery($query); |
| $rc2 = mysql_num_rows($qh); |
| if($rc2) { |
| $query = "DELETE FROM semaphore " |
| . "WHERE computerid = $compid AND " |
| . "procid = '$uniqid'"; |
| doQuery($query); |
| return 0; |
| } |
| } |
| return $rc; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn retryGetSemaphore($imageid, $imagerevisionid, $mgmtnodeid, $compid, |
| /// $start, $end, $requestid=0, $tries=5, $delay=200000) |
| /// |
| /// \param $imageid - id of image |
| /// \param $imagerevisionid - id of image revision |
| /// \param $mgmtnodeid - id of management node |
| /// \param $compid - id of computer |
| /// \param $start - start of reservation in datetime format |
| /// \param $end - end of reservation in datetime format |
| /// \param $requestid - (optional) if passed, ignores checking for conflict |
| /// \param $tries - (optional, default=5) number of attempts to make for getting |
| /// a semaphore |
| /// \param $delay - (optional, default=200000) microseconds to wait between |
| /// tries |
| /// |
| /// \return 0 on failure, 1 on success |
| /// |
| /// \brief makes multiple attempts to get a semaphore for a computer; useful |
| /// when needing to do an operation on a specific computer |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function retryGetSemaphore($imageid, $imagerevisionid, $mgmtnodeid, $compid, |
| $start, $end, $requestid=0, $tries=5, $delay=200000) { |
| for($i = 0; $i < $tries; $i++) { |
| if(getSemaphore($imageid, $imagerevisionid, $mgmtnodeid, $compid, $start, $end, $requestid)) { |
| return 1; |
| } |
| else |
| usleep($delay); |
| } |
| return 0; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getPossibleRecentFailures($userid, $imageid) |
| /// |
| /// \param $userid - check log data for this user; if $userid = 0, check for |
| /// currently logged in user |
| /// \param $imageid - check log data for this image |
| /// |
| /// \return array of computerids that may have recently given the user a problem |
| /// |
| /// \brief checks for recent reservations by the user that were very short and |
| /// within a recent time frame in case there was a computer that gave a problem |
| /// that the backend did not pick up |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getPossibleRecentFailures($userid, $imageid) { |
| if($userid == 0) { |
| global $user; |
| $userid = $user['id']; |
| } |
| $comps = array(); |
| $query = "SELECT s.computerid " |
| . "FROM log l " |
| . "LEFT JOIN sublog s ON (s.logid = l.id) " |
| . "WHERE l.start > (NOW() - INTERVAL 90 MINUTE) AND " |
| . "l.finalend < NOW() AND " |
| . "l.userid = $userid AND " |
| . "l.imageid = $imageid AND " |
| . "l.wasavailable = 1 AND " |
| . "l.ending != 'failed'"; |
| $qh = doQuery($query, 101); |
| while($row = mysql_fetch_assoc($qh)) |
| $comps[] = $row['computerid']; |
| return $comps; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getMappedResources($resourcesubid, $resourcetype1, $resourcetype2) |
| /// |
| /// \param $resourcesubid - id of a resource from its table (ie an imageid) |
| /// \param $resourcetype1 - type of $resourcesubid (name or id) |
| /// \param $resourcetype2 - type of resource $resourcesubid maps to |
| /// |
| /// \return an array of resource ids of type $resourcetype2 |
| /// |
| /// \brief gets a list of resources of type $resourcetype2 that $resourcesubid |
| /// of type $resourcetype1 maps to based on the resourcemap table |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getMappedResources($resourcesubid, $resourcetype1, $resourcetype2) { |
| if(! is_numeric($resourcetype1)) |
| $resourcetype1 = getResourceTypeID($resourcetype1); |
| if(! is_numeric($resourcetype2)) |
| $resourcetype2 = getResourceTypeID($resourcetype2); |
| |
| # get $resourcesubid's resource id |
| $query = "SELECT id " |
| . "FROM resource " |
| . "WHERE subid = $resourcesubid AND " |
| . "resourcetypeid = $resourcetype1"; |
| $qh = doQuery($query, 101); |
| $row = mysql_fetch_row($qh); |
| $resourceid = $row[0]; |
| |
| # get groups $resourceid is in |
| $resourcegroupids = array(); |
| $query = "SELECT resourcegroupid " |
| . "FROM resourcegroupmembers " |
| . "WHERE resourceid = $resourceid"; |
| $qh = doQuery($query, 101); |
| while($row = mysql_fetch_row($qh)) { |
| array_push($resourcegroupids, $row[0]); |
| } |
| |
| # get $resourcetype2 groups that $resourcegroupids map to |
| if(! count($resourcegroupids)) |
| return array(); |
| $inlist = implode(',', $resourcegroupids); |
| $type2groupids = array(); |
| |
| # get all mappings from resourcemap table where $resourcetype1 == |
| # resourcemap.resourcetypeid1 |
| $query = "SELECT resourcegroupid2 " |
| . "FROM resourcemap " |
| . "WHERE resourcegroupid1 IN ($inlist) AND " |
| . "resourcetypeid1 = $resourcetype1 AND " |
| . "resourcetypeid2 = $resourcetype2"; |
| $qh = doQuery($query, 101); |
| while($row = mysql_fetch_row($qh)) { |
| array_push($type2groupids, $row[0]); |
| } |
| |
| # get all mappings from resourcemap table where $resourcetype1 == |
| # resourcemap.resourcetypeid2 |
| $query = "SELECT resourcegroupid1 " |
| . "FROM resourcemap " |
| . "WHERE resourcegroupid2 IN ($inlist) AND " |
| . "resourcetypeid2 = $resourcetype1 AND " |
| . "resourcetypeid1 = $resourcetype2"; |
| $qh = doQuery($query, 101); |
| while($row = mysql_fetch_row($qh)) { |
| array_push($type2groupids, $row[0]); |
| } |
| |
| # get $resourcetype2 items in $type2groupids groups |
| if(! count($type2groupids)) |
| return array(); |
| $inlist = implode(',', $type2groupids); |
| $mappedresources = array(); |
| $query = "SELECT r.subid " |
| . "FROM resource r, " |
| . "resourcegroupmembers m " |
| . "WHERE m.resourcegroupid IN ($inlist) AND " |
| . "m.resourceid = r.id"; |
| $qh = doQuery($query, 101); |
| while($row = mysql_fetch_row($qh)) { |
| array_push($mappedresources, $row[0]); |
| } |
| return $mappedresources; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn checkOverlap($start, $end, $max, $requestid) |
| /// |
| /// \param $start - unix timestamp for start of reservation |
| /// \param $end - unix timestamp for end of reservation |
| /// \param $max - max allowed overlapping reservations |
| /// \param $requestid - (optional) a requestid to ignore when checking for an |
| /// overlap; use this when changing an existing request |
| /// |
| /// \return 0 if user doesn't have a reservation overlapping the time period |
| /// between $start and $end; 1 if the user does |
| /// |
| /// \brief checks for a user having an overlapping reservation with the |
| /// specified time period |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function checkOverlap($start, $end, $max, $requestid=0) { |
| global $user; |
| $requests = getUserRequests("all"); |
| $count = 0; |
| if($max > 0) |
| $max--; |
| foreach(array_keys($requests) as $id) { |
| if(! (($requests[$id]["currstateid"] == 12 || |
| $requests[$id]["currstateid"] == 14) && |
| $requests[$id]["laststateid"] == 11) && |
| $requests[$id]["currstateid"] != 5 && |
| $requests[$id]["currstateid"] != 10 && |
| $requests[$id]["currstateid"] != 16 && |
| ! ($requests[$id]["currstateid"] == 14 && |
| $requests[$id]["laststateid"] == 16) && |
| $requests[$id]["id"] != $requestid && |
| ($start < datetimeToUnix($requests[$id]["end"]) && |
| $end > datetimeToUnix($requests[$id]["start"])) && |
| $requests[$id]['serverowner'] == 1) { |
| $count++; |
| if($count > $max) |
| return 1; |
| } |
| } |
| return 0; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn editRequestBlockCheck($compid, $imageid, $start, $end) |
| /// |
| /// \param $compid - id of computer to check |
| /// \param $imageid - id of image being checked |
| /// \param $start - start of time period in unix timestamp format |
| /// \param $end - end of time period in unix timestamp format |
| /// |
| /// \return 1 if time period overlaps with a block allocation unavailable to the |
| /// logged in user; 0 if not |
| /// |
| /// \brief checks to see if $compid is part of a block allocation that the |
| /// current user is not part of or is set for a different image than what the |
| /// user is currently using on the computer |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function editRequestBlockCheck($compid, $imageid, $start, $end) { |
| global $user; |
| $groupids = implode(',', array_keys($user['groups'])); |
| if(! count($user['groups'])) |
| $groupids = "''"; |
| $startdt = unixToDatetime($start); |
| $enddt = unixToDatetime($end); |
| $query = "SELECT bc.computerid " |
| . "FROM blockComputers bc, " |
| . "blockTimes bt, " |
| . "blockRequest r " |
| . "WHERE bc.blockTimeid = bt.id AND " |
| . "bt.blockRequestid = r.id AND " |
| . "bc.computerid = $compid AND " |
| . "(bt.start - INTERVAL 15 MINUTE) < '$enddt' AND " |
| . "bt.end > '$startdt' AND " |
| . "(r.groupid NOT IN ($groupids) OR " |
| . "r.imageid != $imageid) AND " |
| . "r.status = 'accepted'"; |
| $qh = doQuery($query, 101); |
| return(mysql_num_rows($qh)); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getReloadStartTime() |
| /// |
| /// \return unix timestamp |
| /// |
| /// \brief determines the nearest 15 minute increment of an hour that is less |
| /// than the current time |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getReloadStartTime() { |
| $nowArr = getdate(); |
| if($nowArr["minutes"] == 0) |
| $subtract = 0; |
| elseif($nowArr["minutes"] < 15) |
| $subtract = $nowArr["minutes"] * 60; |
| elseif($nowArr["minutes"] < 30) |
| $subtract = ($nowArr["minutes"] - 15) * 60; |
| elseif($nowArr["minutes"] < 45) |
| $subtract = ($nowArr["minutes"] - 30) * 60; |
| elseif($nowArr["minutes"] < 60) |
| $subtract = ($nowArr["minutes"] - 45) * 60; |
| $start = time() - $subtract; |
| $start -= $start % 60; |
| return $start; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getMaxOverlap($userid) |
| /// |
| /// \param $userid - id from user table |
| /// |
| /// \return max number of allowed overlapping reservations for user |
| /// |
| /// \brief determines how many overlapping reservations $user can have based on |
| /// the groups $user is a member of |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getMaxOverlap($userid) { |
| $query = "SELECT u.overlapResCount " |
| . "FROM usergroup u, " |
| . "usergroupmembers m " |
| . "WHERE m.usergroupid = u.id AND " |
| . "m.userid = $userid " |
| . "ORDER BY u.overlapResCount DESC " |
| . "LIMIT 1"; |
| $qh = doQuery($query, 101); |
| if($row = mysql_fetch_assoc($qh)) |
| return $row['overlapResCount']; |
| else |
| return 1; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn addRequest($forimaging, $revisionid, $nousercheck) |
| /// |
| /// \param $forimaging - (optional) 0 if a normal request, 1 if a request for |
| /// creating a new image |
| /// \param $revisionid - (optional) desired revision id of the image |
| /// \param $checkuser - (optional, default=1) 0 or 1 - value to set for |
| /// request.checkuser |
| /// |
| /// \return id from request table that corresponds to the added entry |
| /// |
| /// \brief adds an entry to the request and reservation tables |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function addRequest($forimaging=0, $revisionid=array(), $checkuser=1) { |
| global $requestInfo, $user, $uniqid, $mysql_link_vcl; |
| $startstamp = unixToDatetime($requestInfo["start"]); |
| $endstamp = unixToDatetime($requestInfo["end"]); |
| $now = time(); |
| |
| if($requestInfo["start"] <= $now) { |
| $start = unixToDatetime($now); |
| $nowfuture = "now"; |
| } |
| else { |
| $start = $startstamp; |
| $nowfuture = "future"; |
| } |
| |
| addLogEntry($nowfuture, $start, $endstamp, 1, $requestInfo["imageid"]); |
| |
| $qh = doQuery("SELECT LAST_INSERT_ID() FROM log", 131); |
| if(! $row = mysql_fetch_row($qh)) { |
| abort(132); |
| } |
| $logid = $row[0]; |
| |
| # add single entry to request table |
| $query = "INSERT INTO request " |
| . "(stateid, " |
| . "userid, " |
| . "laststateid, " |
| . "logid, " |
| . "forimaging, " |
| . "start, " |
| . "end, " |
| . "daterequested, " |
| . "checkuser) " |
| . "VALUES " |
| . "(13, " |
| . "{$user['id']}, " |
| . "13, " |
| . "$logid, " |
| . "$forimaging, " |
| . "'$startstamp', " |
| . "'$endstamp', " |
| . "NOW(), " |
| . "$checkuser)"; |
| $qh = doQuery($query, 136); |
| |
| $qh = doQuery("SELECT LAST_INSERT_ID() FROM request", 134); |
| if(! $row = mysql_fetch_row($qh)) { |
| abort(135); |
| } |
| $requestid = $row[0]; |
| |
| # add requestid to log entry |
| $query = "UPDATE log " |
| . "SET requestid = $requestid " |
| . "WHERE id = $logid"; |
| doQuery($query, 101); |
| |
| # add an entry to the reservation table for each image |
| # NOTE: make sure parent image is the first entry we add |
| # so that it has the lowest reservationid |
| foreach($requestInfo["images"] as $key => $imageid) { |
| if(array_key_exists($imageid, $revisionid) && |
| ! empty($revisionid[$imageid])) |
| $imagerevisionid = array_shift($revisionid[$imageid]); |
| else |
| $imagerevisionid = getProductionRevisionid($imageid); |
| $computerid = $requestInfo["computers"][$key]; |
| $mgmtnodeid = $requestInfo['mgmtnodes'][$key]; |
| $fromblock = $requestInfo['fromblock'][$key]; |
| if($fromblock) |
| $blockdata = $requestInfo['blockdata'][$key]; |
| else |
| $blockdata = array(); |
| |
| addSublogEntry($logid, $imageid, $imagerevisionid, $computerid, |
| $mgmtnodeid, $fromblock, $blockdata); |
| } |
| |
| $query = "INSERT INTO reservation " |
| . "(requestid, " |
| . "computerid, " |
| . "imageid, " |
| . "imagerevisionid, " |
| . "managementnodeid) " |
| . "SELECT $requestid, " |
| . "computerid, " |
| . "imageid, " |
| . "imagerevisionid, " |
| . "managementnodeid " |
| . "FROM semaphore " |
| . "WHERE expires > NOW() AND " |
| . "procid = '$uniqid'"; |
| doQuery($query); |
| $cnt = mysql_affected_rows($mysql_link_vcl); |
| if($cnt == 0) { |
| # reached this point SEMTIMEOUT seconds after getting semaphore, clean up and abort |
| $query = "DELETE FROM request WHERE id = $requestid"; |
| doQuery($query); |
| $query = "UPDATE log SET wasavailable = 0 WHERE id = $logid"; |
| doQuery($query); |
| $query = "DELETE FROM sublog WHERE logid = $logid"; |
| doQuery($query); |
| abort(400); |
| } |
| else { |
| $query = "INSERT INTO changelog " |
| . "(logid, " |
| . "start, " |
| . "end, " |
| . "timestamp) " |
| . "VALUES " |
| . "($logid, " |
| . "'$start', " |
| . "'$endstamp', " |
| . "NOW())"; |
| doQuery($query, 136); |
| } |
| // release semaphore lock |
| cleanSemaphore(); |
| |
| checkCryptSecrets($requestid); |
| |
| return $requestid; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn simpleAddRequest($compid, $imageid, $revisionid, $start, $end, |
| /// $stateid, $userid) { |
| /// |
| /// \param $compid - a computer id |
| /// \param $imageid - an iamge id |
| /// \param $revisionid - revisionid for $imageid |
| /// \param $start - starting time in datetime format |
| /// \param $end - ending time in datetime format |
| /// \param $stateid - state for request |
| /// \param $userid - userid for request |
| /// |
| /// \return id for the request or 0 on failure |
| /// |
| /// \brief adds an entry to the request and reservation tables |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function simpleAddRequest($compid, $imageid, $revisionid, $start, $end, |
| $stateid, $userid) { |
| $mgmtnodeid = findManagementNode($compid, $start, 'now'); |
| if($mgmtnodeid == 0) |
| return 0; |
| |
| $query = "INSERT INTO request " |
| . "(stateid, " |
| . "userid, " |
| . "laststateid, " |
| . "start, " |
| . "end, " |
| . "daterequested) " |
| . "VALUES " |
| . "($stateid, " |
| . "$userid, " |
| . "$stateid, " |
| . "'$start', " |
| . "'$end', " |
| . "NOW())"; |
| doQuery($query, 101); |
| |
| $requestid = dbLastInsertID(); |
| if($requestid == 0) |
| abort(135); |
| |
| # add an entry to the reservation table for each image |
| $query = "INSERT INTO reservation " |
| . "(requestid, " |
| . "computerid, " |
| . "imageid, " |
| . "imagerevisionid, " |
| . "managementnodeid) " |
| . "VALUES " |
| . "($requestid, " |
| . "$compid, " |
| . "$imageid, " |
| . "$revisionid, " |
| . "$mgmtnodeid)"; |
| doQuery($query, 101); |
| $testid = dbLastInsertID(); |
| if($testid == 0) |
| abort(135); |
| |
| return $requestid; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn findManagementNode($compid, $start, $nowfuture) |
| /// |
| /// \param $compid - a computer id |
| /// \param $start - start time for the reservation (datetime format) |
| /// \param $nowfuture - type of reservation - "now" or "future" |
| /// |
| /// \return a management node id |
| /// |
| /// \brief finds a management node that can handle $compid, if none found, |
| /// returns 0 |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function findManagementNode($compid, $start, $nowfuture) { |
| global $HTMLheader; |
| $allmgmtnodes = array_keys(getManagementNodes($nowfuture)); |
| $mapped = getMappedResources($compid, "computer", "managementnode"); |
| $usablemgmtnodes = array_intersect($allmgmtnodes, $mapped); |
| $mgmtnodecnt = array(); |
| foreach($usablemgmtnodes as $id) { |
| $mgmtnodecnt[$id] = 0; |
| } |
| if(! count($usablemgmtnodes)) |
| return 0; |
| $inlist = implode(',', $usablemgmtnodes); |
| $mystart = datetimeToUnix($start); |
| $start = unixToDatetime($mystart - 1800); |
| $end = unixToDatetime($mystart + 1800); |
| $query = "SELECT DISTINCT COUNT(rs.managementnodeid) AS count, " |
| . "rs.managementnodeid AS mnid " |
| . "FROM reservation rs, " |
| . "request rq " |
| . "WHERE rs.managementnodeid IN ($inlist) AND " |
| . "rs.requestid = rq.id AND " |
| . "rq.start > '$start' AND " |
| . "rq.start < '$end' " |
| . "GROUP BY rs.managementnodeid " |
| . "ORDER BY count"; |
| $qh = doQuery($query, 101); |
| while($row = mysql_fetch_assoc($qh)) { |
| $mgmtnodecnt[$row["mnid"]] = $row["count"]; |
| } |
| uasort($mgmtnodecnt, "sortKeepIndex"); |
| $keys = array_keys($mgmtnodecnt); |
| return array_shift($keys); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getRequestInfo($id, $returnNULL) |
| /// |
| /// \param $id - id of request |
| /// \param $returnNULL - (optional, default=0) return NULL if reservation no |
| /// longer exists |
| /// |
| /// \return an array containing the following elements:\n |
| /// \b stateid - stateid of the request\n |
| /// \b laststateid - laststateid of the request\n |
| /// \b userid - id from the db of the user\n |
| /// \b start - start of request\n |
| /// \b end - end of request\n |
| /// \b daterequested - date request was made\n |
| /// \b datemodified - date request was last modified\n |
| /// \b id - id of this request\n |
| /// \b logid - id from log table\n |
| /// \b test - test flag\n |
| /// \b forimaging - 0 if request is normal, 1 if it is for imaging\n |
| /// \b checkuser - 1 if connected user timeout checks are enabled, 0 if not\n |
| /// \b serverrequest - 0 if request is normal, 1 if it is a server request\n |
| /// \b servername - name of server if server request\n |
| /// \b admingroupid - id of admin user group if server request\n |
| /// \b logingroupid - id of login user group if server request\n |
| /// \b fixedIP - possible fixed IP address if server request\n |
| /// \b fixedMAC - possible fixed MAC address if server request\n\n |
| /// an array of reservations associated with the request whose key is |
| /// 'reservations', each with the following items:\n |
| /// \b imageid - id of the image\n |
| /// \b imagerevisionid - id of the image revision\n |
| /// \b production - image revision production flag (0 or 1)\n |
| /// \b image - name of the image\n |
| /// \b prettyimage - pretty name of the image\n |
| /// \b OS - name of the os\n |
| /// \b OStype - type of the os\n |
| /// \b computerid - id of the computer\n |
| /// \b reservationid - id of the corresponding reservation\n |
| /// \b reservedIP - ip address of reserved computer\n |
| /// \b hostname - hostname of reserved computer\n |
| /// \b forcheckout - whether or not the image is intended for checkout\n |
| /// \b password - password for this computer\n |
| /// \b connectIP - IP to which user will connect\n |
| /// \b remoteIP - IP of remote user\n\n |
| /// an array of arrays of passwords whose key is 'passwds', with the next key |
| /// being the reservationid and the elements being the userid as a key and that |
| /// user's password as the value |
| /// |
| /// \brief creates an array with info about request $id |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getRequestInfo($id, $returnNULL=0) { |
| global $printedHTMLheader, $HTMLheader; |
| if(empty($id)) |
| abort(9); |
| $query = "SELECT stateid, " |
| . "laststateid, " |
| . "userid, " |
| . "start, " |
| . "end, " |
| . "daterequested, " |
| . "datemodified, " |
| . "logid, " |
| . "test, " |
| . "forimaging, " |
| . "checkuser " |
| . "FROM request " |
| . "WHERE id = $id"; |
| $qh = doQuery($query, 165); |
| if(! ($data = mysql_fetch_assoc($qh))) { |
| if($returnNULL) |
| return NULL; |
| # FIXME handle XMLRPC cases |
| if(! $printedHTMLheader) |
| print $HTMLheader; |
| print "<h1>" . i("OOPS! - Reservation Has Expired") . "</h1>\n"; |
| $h = i("The selected reservation is no longer available. Go to <a>Reservations</a> to request a new reservation or select another one that is available."); |
| print preg_replace('|<a>(.+)</a>|', '<a href="' . BASEURL . SCRIPT . '?mode=viewRequests">\1</a>', $h); |
| printHTMLFooter(); |
| dbDisconnect(); |
| exit; |
| } |
| $data["id"] = $id; |
| $query = "SELECT rs.imageid, " |
| . "rs.imagerevisionid, " |
| . "rs.managementnodeid, " |
| . "ir.production, " |
| . "i.name AS image, " |
| . "i.prettyname AS prettyimage, " |
| . "o.prettyname AS OS, " |
| . "o.type AS OStype, " |
| . "rs.computerid, " |
| . "rs.id AS reservationid, " |
| . "c.IPaddress AS reservedIP, " |
| . "c.hostname, " |
| . "i.forcheckout, " |
| . "rs.pw AS password, " |
| . "COALESCE(nh.publicIPaddress, c.IPaddress) AS connectIP, " |
| . "rs.remoteIP, " |
| . "ad.domainDNSName " |
| . "FROM reservation rs, " |
| . "image i " |
| . "LEFT JOIN imageaddomain iadd ON (i.id = iadd.imageid) " |
| . "LEFT JOIN addomain ad ON (iadd.addomainid = ad.id), " |
| . "imagerevision ir, " |
| . "OS o, " |
| . "computer c " |
| . "LEFT JOIN nathostcomputermap n ON (c.id = n.computerid) " |
| . "LEFT JOIN nathost nh ON (n.nathostid = nh.id) " |
| . "WHERE rs.requestid = $id AND " |
| . "rs.imageid = i.id AND " |
| . "rs.imagerevisionid = ir.id AND " |
| . "i.OSid = o.id AND " |
| . "rs.computerid = c.id " |
| . "ORDER BY rs.id"; |
| $qh = doQuery($query, 101); |
| $data["reservations"] = array(); |
| $data['passwds'] = array(); |
| $resids = array(); |
| while($row = mysql_fetch_assoc($qh)) { |
| array_push($data["reservations"], $row); |
| $resids[] = $row['reservationid']; |
| $data['passwds'][$row['reservationid']][$data['userid']] = $row['password']; |
| } |
| $query = "SELECT id, " |
| . "name, " |
| . "admingroupid, " |
| . "logingroupid, " |
| . "fixedIP, " |
| . "fixedMAC " |
| . "FROM serverrequest " |
| . "WHERE requestid = $id"; |
| $qh = doQuery($query, 101); |
| if($row = mysql_fetch_assoc($qh)) { |
| $data['serverrequest'] = 1; |
| $data['servername'] = $row['name']; |
| $data['admingroupid'] = $row['admingroupid']; |
| $data['logingroupid'] = $row['logingroupid']; |
| $data['fixedIP'] = $row['fixedIP']; |
| $data['fixedMAC'] = $row['fixedMAC']; |
| $inids = implode(',', $resids); |
| $query = "SELECT reservationid, " |
| . "userid, " |
| . "password " |
| . "FROM reservationaccounts " |
| . "WHERE reservationid IN ($inids)"; |
| $qh = doQuery($query); |
| while($row = mysql_fetch_assoc($qh)) |
| $data['passwds'][$row['reservationid']][$row['userid']] = $row['password']; |
| } |
| else |
| $data['serverrequest'] = 0; |
| return $data; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn updateRequest($requestid, $nowfuture) |
| /// |
| /// \param $requestid - the id of the request to be updated |
| /// \param $nowfuture (optional) - "now" or "future"; whether the |
| /// |
| /// \brief updates an entry to the request and reservation tables |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function updateRequest($requestid, $nowfuture="now") { |
| global $requestInfo; |
| $startstamp = unixToDatetime($requestInfo["start"]); |
| $endstamp = unixToDatetime($requestInfo["end"]); |
| |
| $query = "SELECT logid FROM request WHERE id = $requestid"; |
| $qh = doQuery($query, 146); |
| if(! $row = mysql_fetch_row($qh)) { |
| abort(148); |
| } |
| $logid = $row[0]; |
| |
| $query = "UPDATE request " |
| . "SET start = '$startstamp', " |
| . "end = '$endstamp', " |
| . "datemodified = NOW() " |
| . "WHERE id = $requestid"; |
| doQuery($query, 101); |
| |
| if($nowfuture == 'now') { |
| addChangeLogEntry($logid, NULL, $endstamp, $startstamp, NULL, NULL, 1); |
| return; |
| } |
| |
| $requestData = getRequestInfo($requestid); |
| foreach($requestInfo["images"] as $key => $imgid) { |
| foreach($requestData["reservations"] as $key2 => $res) { |
| if($res["imageid"] == $imgid) { |
| $oldCompid = $res["computerid"]; |
| unset($requestData['reservations'][$key2]); |
| break; |
| } |
| } |
| $computerid = $requestInfo["computers"][$key]; |
| $mgmtnodeid = $requestInfo['mgmtnodes'][$key]; |
| |
| $query = "UPDATE reservation " |
| . "SET computerid = $computerid, " |
| . "managementnodeid = $mgmtnodeid " |
| . "WHERE requestid = $requestid AND " |
| . "imageid = $imgid AND " |
| . "computerid = $oldCompid " |
| . "LIMIT 1"; # without this, it can update one row to have the |
| # same computer as another row; then, the later row |
| # could be updated, which would end up setting both |
| # rows to the same computer |
| doQuery($query, 147); |
| addChangeLogEntry($logid, NULL, $endstamp, $startstamp, $computerid, NULL, |
| 1); |
| $query = "UPDATE sublog " |
| . "SET computerid = $computerid " |
| . "WHERE logid = $logid AND " |
| . "imageid = $imgid AND " |
| . "computerid = $oldCompid"; |
| doQuery($query, 101); |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn deleteRequest($request) |
| /// |
| /// \param $request - an array from getRequestInfo |
| /// |
| /// \brief removes a request from the request and reservation tables |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function deleteRequest($request) { |
| # new - 13 |
| # deleted - 1 |
| # complete - 12 |
| # reserved - 3 |
| # inuse - 8 |
| # pending - 14 |
| # timeout - 11 |
| $now = time(); |
| if(datetimeToUnix($request["start"]) < $now) { |
| # current: new, last: none OR |
| # current: pending, last: new |
| if($request["stateid"] == 13 || |
| ($request["stateid"] == 14 && $request["laststateid"] == 13)) { |
| $query = "UPDATE request " |
| . "SET stateid = 1, " |
| . "laststateid = 3 " |
| . "WHERE id = {$request['id']}"; |
| } |
| # current: reserved, last: new OR |
| # current: pending, last: reserved |
| elseif(($request["stateid"] == 3 && $request["laststateid"] == 13) || |
| ($request["stateid"] == 14 && $request["laststateid"] == 3)) { |
| $query = "UPDATE request " |
| . "SET stateid = 1, " |
| . "laststateid = 3 " |
| . "WHERE id = {$request['id']}"; |
| } |
| # current: inuse, last: reserved OR |
| # current: pending, last: inuse |
| elseif(($request["stateid"] == 8 && $request["laststateid"] == 3) || |
| ($request["stateid"] == 14 && $request["laststateid"] == 8)) { |
| $query = "UPDATE request " |
| . "SET stateid = 1, " |
| . "laststateid = 8 " |
| . "WHERE id = {$request['id']}"; |
| } |
| # shouldn't happen, but if current: pending, set to deleted or |
| // if not current: pending, set laststate to current state and |
| # current state to deleted |
| else { |
| if($request["stateid"] == 14) { |
| $query = "UPDATE request " |
| . "SET stateid = 1 " |
| . "WHERE id = {$request['id']}"; |
| } |
| else { |
| # somehow a user submitted a deleteRequest where the current |
| # stateid was empty |
| if(! is_numeric($request["stateid"]) || $request["stateid"] < 0) |
| $request["stateid"] = 1; |
| $query = "UPDATE request " |
| . "SET stateid = 1, " |
| . "laststateid = {$request['stateid']} " |
| . "WHERE id = {$request['id']}"; |
| } |
| } |
| $qh = doQuery($query, 150); |
| |
| addChangeLogEntry($request["logid"], NULL, unixToDatetime($now), NULL, |
| NULL, "released"); |
| return; |
| } |
| |
| if($request['serverrequest']) { |
| $query = "SELECT id FROM serverrequest WHERE requestid = {$request['id']}"; |
| $qh = doQuery($query); |
| if($row = mysql_fetch_assoc($qh)) { |
| $query = "DELETE FROM serverrequest WHERE requestid = {$request['id']}"; |
| doQuery($query, 152); |
| deleteVariable("fixedIPsr{$row['id']}"); |
| } |
| } |
| |
| $query = "DELETE FROM request WHERE id = {$request['id']}"; |
| doQuery($query, 153); |
| |
| $query = "DELETE FROM reservation WHERE requestid = {$request['id']}"; |
| doQuery($query, 154); |
| |
| addChangeLogEntry($request["logid"], NULL, NULL, NULL, NULL, "deleted"); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn moveReservationsOffComputer($compid, $count) |
| /// |
| /// \param $compid - (optional) id of computer from which to move reservations |
| /// \param $count - (optional) number of reservations to move, defaults to |
| /// all of them |
| /// |
| /// \return 0 if failed to move reservations, 1 if succeeded, -1 if no |
| /// reservations were found on $compid |
| /// |
| /// \brief attempts to move reservations off of a $compid - if $compid is not |
| /// given, removes all reservations from the computer with the least number; |
| /// NOTE - cleanSemaphore should be called after this by the calling function |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function moveReservationsOffComputer($compid=0, $count=0) { |
| global $requestInfo, $user; |
| $resInfo = array(); |
| $checkstart = unixToDatetime(time() + 180); |
| if($compid == 0) { |
| $resources = getUserResources(array("imageAdmin", "imageCheckOut"), |
| array("available"), 0, 0); |
| $computers = implode("','", array_keys($resources["computer"])); |
| $computers = "'$computers'"; |
| $query = "SELECT DISTINCT COUNT(rs.id) AS reservations, " |
| . "rs.computerid " |
| . "FROM reservation rs, " |
| . "request rq " |
| . "WHERE rq.start > '$checkstart' AND " |
| . "rs.computerid IN ($computers) " |
| . "GROUP BY computerid " |
| . "ORDER BY reservations " |
| . "LIMIT 1"; |
| $qh = doQuery($query, 101); |
| if($row = mysql_fetch_assoc($qh)) |
| $compid = $row["computerid"]; |
| else |
| return -1; |
| } |
| # get all reservation info for $compid |
| $query = "SELECT rs.id, " |
| . "rs.requestid, " |
| . "rs.imageid, " |
| . "rs.imagerevisionid, " |
| . "rq.logid, " |
| . "rq.userid, " |
| . "rq.start, " |
| . "rq.end " |
| . "FROM reservation rs, " |
| . "request rq " |
| . "WHERE rs.computerid = $compid AND " |
| . "rs.requestid = rq.id AND " |
| . "rq.start > '$checkstart' AND " |
| . "rq.stateid NOT IN (1, 5, 11, 12) " |
| . "ORDER BY rq.start"; |
| if($count) |
| $query .= " LIMIT $count"; |
| $qh = doQuery($query, 101); |
| while($row = mysql_fetch_assoc($qh)) { |
| $resInfo[$row["id"]] = $row; |
| } |
| if(! count($resInfo)) |
| return -1; |
| $images = getImages(); |
| $allmovable = 1; |
| # TODO eventually, for clusters, there will probably be restrictions on how the computers |
| # relate to each other; at that point, this will need to be updated to make sure the computer |
| # a reservation is reassigned to meets the same restrictions |
| foreach($resInfo as $res) { |
| // pass forimaging = 1 so that isAvailable only looks at one computer |
| $rc = isAvailable($images, $res["imageid"], $res['imagerevisionid'], |
| datetimeToUnix($res["start"]), datetimeToUnix($res["end"]), 0, |
| 0, $res["userid"], 0, 1); |
| if($rc < 1) { |
| $allmovable = 0; |
| break; |
| } |
| } |
| if(! $allmovable) |
| return 0; |
| foreach($resInfo as $res) { |
| $rc = isAvailable($images, $res["imageid"], $res['imagerevisionid'], |
| datetimeToUnix($res["start"]), datetimeToUnix($res["end"]), 1, |
| 0, $res["userid"], 0, 1); |
| if($rc > 0) { |
| $newcompid = array_shift($requestInfo["computers"]); |
| # get mgmt node for computer |
| $mgmtnodeid = findManagementNode($newcompid, $res['start'], 'future'); |
| # update mgmt node and computer in reservation table |
| $query = "UPDATE reservation " |
| . "SET computerid = $newcompid, " |
| . "managementnodeid = $mgmtnodeid " |
| . "WHERE id = {$res['id']}"; |
| doQuery($query, 101); |
| # add changelog entry |
| addChangeLogEntry($res['logid'], NULL, NULL, NULL, $newcompid); |
| # update sublog entry |
| $query = "UPDATE sublog " |
| . "SET computerid = $newcompid, " |
| . "managementnodeid = $mgmtnodeid " |
| . "WHERE logid = {$res['logid']} AND " |
| . "computerid = $compid"; |
| doQuery($query, 101); |
| } |
| else |
| return 0; |
| } |
| return 1; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn moveReservationsOffVMs($compid, $sem) |
| /// |
| /// \param $compid - id of host computer from which to move |
| /// reservations |
| /// \param $sem - (optional) array of data to be used when getting a semaphore |
| /// for a VM after reservations have been moved off of it; must include these |
| /// keys: imageid, revid, mnid, start (datetime), end (datetime) |
| /// |
| /// \brief attempts to move reservations off of any VMs assigned to a $compid |
| /// NOTE - cleanSemaphore should be called after this by the calling function |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function moveReservationsOffVMs($compid, $sem=0) { |
| if(! is_array($sem)) { |
| $sem = array(); |
| $sem['imageid'] = getImageId('noimage'); |
| $sem['revid'] = getProductionRevisionid($sem['imageid']); |
| if(! ($sem['mnid'] = getAnyManagementNodeID())) |
| return; |
| $sem['start'] = unixToDatetime(time()); |
| $sem['end'] = '2038-01-01 00:00:00'; |
| } |
| $query = "SELECT vm.id " |
| . "FROM computer vm, " |
| . "vmhost v " |
| . "WHERE v.computerid = $compid AND " |
| . "vm.vmhostid = v.id"; |
| $qh = doQuery($query); |
| while($row = mysql_fetch_assoc($qh)) { |
| $rc = moveReservationsOffComputer($row['id']); |
| if($rc != 0) |
| # lock computer so that reservations on other VMs on this host do not get moved to it |
| getSemaphore($sem['imageid'], $sem['revid'], $sem['mnid'], $row['id'], $sem['start'], $sem['end']); |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getCompFinalReservationTime($compid, $extraskipstate=0) |
| /// |
| /// \param $compid - a computer id |
| /// \param $extraskipstate - (default=0) id of an additional request state to |
| /// ignore; if 0 passed, no additional states are ignored |
| /// |
| /// \return unix timestamp of last end time of any reservations for $compid |
| /// |
| /// \brief determines the final end time of all reservations on a computer |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getCompFinalReservationTime($compid, $extraskipstate=0) { |
| $end = 0; |
| $skipstates = "1,5,12"; |
| if($extraskipstate) |
| $skipstates .= ",$extraskipstate"; |
| $query = "SELECT UNIX_TIMESTAMP(rq.end) as end " |
| . "FROM request rq, " |
| . "reservation rs " |
| . "WHERE rs.requestid = rq.id AND " |
| . "rs.computerid = $compid AND " |
| . "rq.stateid NOT IN ($skipstates) " |
| . "ORDER BY rq.end DESC " |
| . "LIMIT 1"; |
| $qh = doQuery($query, 101); |
| if($row = mysql_fetch_assoc($qh)) |
| $end = $row['end']; |
| $query = "SELECT UNIX_TIMESTAMP(t.end) as end " |
| . "FROM blockComputers c, " |
| . "blockTimes t " |
| . "WHERE c.computerid = $compid AND " |
| . "c.blockTimeid = t.id AND " |
| . "t.end > NOW() " |
| . "ORDER BY t.end DESC " |
| . "LIMIT 1"; |
| $qh = doQuery($query, 101); |
| if($row = mysql_fetch_assoc($qh)) |
| if($row['end'] > $end) |
| $end = $row['end']; |
| return $end; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getCompFinalVMReservationTime($hostid, $addsemaphores, $notomaintenance) |
| /// |
| /// \param $hostid - computer id of a vm host |
| /// \param $addsemaphores - (optional, default = 0) 1 to add semaphores for each |
| /// of the VMs |
| /// \param $notomaintenance - (optional, default = 0) 1 to ignore any |
| /// tomaintenance reservations |
| /// |
| /// \return unix timestamp of last end time of any reservations for VMs on |
| /// $hostid; 0 if no reservations; -1 if $addsemaphores = 1 and failed to get |
| /// semaphores |
| /// |
| /// \brief determines the final end time of all reservations of all VMs on a |
| /// VM host computer |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getCompFinalVMReservationTime($hostid, $addsemaphores=0, |
| $notomaintenance=0) { |
| global $uniqid, $mysql_link_vcl; |
| if($addsemaphores) { |
| $query = "SELECT vm.id " |
| . "FROM computer vm, " |
| . "vmhost v " |
| . "WHERE v.computerid = $hostid AND " |
| . "vm.vmhostid = v.id"; |
| $qh = doQuery($query); |
| $compids = array(); |
| while($row = mysql_fetch_assoc($qh)) |
| $compids[] = $row['id']; |
| if(empty($compids)) |
| return 0; |
| $allcompids = implode(',', $compids); |
| $imageid = getImageId('noimage'); |
| $revid = getProductionRevisionid($imageid); |
| $tmp = getManagementNodes(); |
| $tmp = array_keys($tmp); |
| $mnid = $tmp[0]; |
| $query = "INSERT INTO semaphore " |
| . "SELECT c.id, " |
| . "$imageid, " |
| . "$revid, " |
| . "$mnid, " |
| . "NOW() + INTERVAL " . SEMTIMEOUT . " SECOND, " |
| . "'$uniqid' " |
| . "FROM computer c " |
| . "LEFT JOIN semaphore s ON (c.id = s.computerid) " |
| . "WHERE c.id IN ($allcompids) AND " |
| . "(s.expires IS NULL OR s.expires < NOW()) " |
| . "GROUP BY c.id"; |
| doQuery($query); |
| $cnt = mysql_affected_rows($mysql_link_vcl); |
| if($cnt != count($compids)) |
| return -1; |
| } |
| |
| $end = 0; |
| $skipstates = '1,5,12'; |
| if($notomaintenance) |
| $skipstates .= ',18'; |
| $query = "SELECT UNIX_TIMESTAMP(rq.end) as end " |
| . "FROM request rq, " |
| . "reservation rs " |
| . "WHERE rs.requestid = rq.id AND " |
| . "rq.stateid NOT IN ($skipstates) AND " |
| . "rs.computerid IN (SELECT vm.id " |
| . "FROM computer vm, " |
| . "vmhost v " |
| . "WHERE v.computerid = $hostid AND " |
| . "vm.vmhostid = v.id) " |
| . "ORDER BY rq.end DESC " |
| . "LIMIT 1"; |
| $qh = doQuery($query, 101); |
| if($row = mysql_fetch_assoc($qh)) |
| $end = $row['end']; |
| $query = "SELECT UNIX_TIMESTAMP(t.end) as end " |
| . "FROM blockComputers c, " |
| . "blockTimes t " |
| . "WHERE c.blockTimeid = t.id AND " |
| . "t.end > NOW() AND " |
| . "c.computerid IN (SELECT vm.id " |
| . "FROM computer vm, " |
| . "vmhost v " |
| . "WHERE v.computerid = $hostid AND " |
| . "vm.vmhostid = v.id) " |
| . "ORDER BY t.end DESC " |
| . "LIMIT 1"; |
| $qh = doQuery($query, 101); |
| if($row = mysql_fetch_assoc($qh)) |
| if($row['end'] > $end) |
| $end = $row['end']; |
| return $end; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getExistingChangeStateStartTime($compid, $stateid) |
| /// |
| /// \param $compid - computer id |
| /// \param $stateid - id of state of reservation |
| /// |
| /// \return unix timestamp |
| /// |
| /// \brief gets the start time for the earliest existing reservation for $compid |
| /// that has a state of $stateid |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getExistingChangeStateStartTime($compid, $stateid) { |
| $query = "SELECT rq.start " |
| . "FROM request rq, " |
| . "reservation rs " |
| . "WHERE rs.requestid = rq.id AND " |
| . "rs.computerid = $compid AND " |
| . "rq.stateid = $stateid AND " |
| . "rq.start > NOW() " |
| . "ORDER BY rq.start " |
| . "LIMIT 1"; |
| $qh = doQuery($query); |
| if($row = mysql_fetch_assoc($qh)) |
| return datetimeToUnix($row['start']); |
| return 0; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn updateExistingToState($compid, $start, $stateid) |
| /// |
| /// \param $compid - computer id |
| /// \param $start - new start time in datetime format |
| /// \param $stateid - id of state for existing reservation |
| /// |
| /// \brief updates the start time of an existing reservation for $compid with a |
| /// state of $stateid |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function updateExistingToState($compid, $start, $stateid) { |
| $query = "UPDATE request rq, " |
| . "reservation rs " |
| . "SET rq.start = '$start' " |
| . "WHERE rs.requestid = rq.id AND " |
| . "rq.stateid = $stateid AND " |
| . "rq.start > '$start' AND " |
| . "rs.computerid = $compid"; |
| doQuery($query); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getUserRequests($type, $id) |
| /// |
| /// \param $type - "normal", "forimaging", or "all" |
| /// \param $id - (optional) user's id from userlist table |
| /// |
| /// \return an array of user's requests; the array has the following elements |
| /// for each entry where forcheckout == 1 for the image:\n |
| /// \b id - id of the request\n |
| /// \b userid - id of user owning request\n |
| /// \b imageid - id of requested image\n |
| /// \b imagerevisionid - revision id of requested image\n |
| /// \b image - name of requested image\n |
| /// \b prettyimage - pretty name of requested image\n |
| /// \b OS - name of the requested os\n |
| /// \b OSinstalltype - installtype for OS\n |
| /// \b start - start time of request\n |
| /// \b end - end time of request\n |
| /// \b daterequested - date request was made\n |
| /// \b currstateid - current stateid of request\n |
| /// \b currstate - current state of request\n |
| /// \b laststateid - last stateid of request\n |
| /// \b laststate - last state of request\n |
| /// \b forimaging - 0 if an normal request, 1 if imaging request\n |
| /// \b forcheckout - 1 if image is available for reservations, 0 if not\n |
| /// \b test - test flag - 0 or 1\n |
| /// \b longterm - 1 if request length is > 24 hours\n |
| /// \b server - 1 if corresponding entry in serverprofiles\n |
| /// \b serverowner - 1 user owns the reservation, 0 if not\n |
| /// \b resid - id of primary reservation\n |
| /// \b compimageid - currentimageid for primary computer\n |
| /// \b computerstateid - current stateid of primary computer\n |
| /// \b computerid - id of primary computer\n |
| /// \b IPaddress - IP address of primary computer\n |
| /// \b comptype - type of primary computer\n |
| /// \b vmhostid - if VM, id of host's entry in vmhost table, NULL otherwise\n |
| /// the following additional items if a server request (values will be NULL |
| /// if not a server request), some values can be NULL:\n |
| /// \b servername - name of server request\n |
| /// \b serverrequestid - from server request table\n |
| /// \b fixedIP - if specified for request\n |
| /// \b fixedMAC - if specified for request\n |
| /// \b serveradmingroupid - id of admin user group\n |
| /// \b serveradmingroup - name of admin user group\n |
| /// \b serverlogingroupid - id of login user group\n |
| /// \b serverlogingroup - name of login user group\n |
| /// \b monitored - whether or not request is to be monitored (0 or 1)\n |
| /// \b useraccountready - whether or not all accounts for this user have been |
| /// created on the reserved machine(s)\n |
| /// and an array of subimages named reservations with the following elements |
| /// for each subimage:\n |
| /// \b resid - id of reservation\n |
| /// \b imageid - id of requested image\n |
| /// \b imagerevisionid - revision id of requested image\n |
| /// \b image - name of requested image\n |
| /// \b prettyname - pretty name of requested image\n |
| /// \b OS - name of the requested os\n |
| /// \b compimageid - currentimageid for computer\n |
| /// \b computerstateid - current stateid of computer\n |
| /// \b computerid - id of reserved computer\n |
| /// \b IPaddress - IP address of reserved computer\n |
| /// \b type - type of computer\n |
| /// \b resacctuserid - empty if user account has not been created on this machine |
| /// yet, the user's numeric id if it has\n |
| /// \b password - password for this user on the machine; if it is empty but |
| /// resacctuserid is not empty, the user should use a federated password |
| /// |
| /// \brief builds an array of current requests made by the user |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getUserRequests($type, $id=0) { |
| global $user; |
| if($id == 0) |
| $id = $user["id"]; |
| $includegroups = getUsersGroups($user["id"]); |
| if(empty($includegroups)) |
| $ingroupids = "''"; |
| else |
| $ingroupids = implode(',', array_keys($includegroups)); |
| $query = "SELECT i.name AS image, " |
| . "i.prettyname AS prettyimage, " |
| . "i.id AS imageid, " |
| . "rq.userid, " |
| . "rq.start, " |
| . "rq.end, " |
| . "rq.daterequested, " |
| . "rq.id, " |
| . "o.prettyname AS OS, " |
| . "o.type AS ostype, " |
| . "o.installtype AS OSinstalltype, " |
| . "rq.stateid AS currstateid, " |
| . "s.name AS currstate, " |
| . "rq.laststateid, " |
| . "ls.name AS laststate, " |
| . "rs.computerid, " |
| . "rs.id AS resid, " |
| . "c.currentimageid AS compimageid, " |
| . "c.stateid AS computerstateid, " |
| . "c.IPaddress, " |
| . "c.type AS comptype, " |
| . "c.vmhostid, " |
| . "rq.forimaging, " |
| . "i.forcheckout, " |
| . "rs.managementnodeid, " |
| . "rs.imagerevisionid, " |
| . "rq.test," |
| . "sp.name AS servername, " |
| . "sp.requestid AS serverrequestid, " |
| . "sp.fixedIP, " |
| . "sp.fixedMAC, " |
| . "sp.admingroupid AS serveradmingroupid, " |
| . "uga.name AS serveradmingroup, " |
| . "sp.logingroupid AS serverlogingroupid, " |
| . "ugl.name AS serverlogingroup, " |
| . "sp.monitored, " |
| . "ra.password, " |
| . "ra.userid AS resacctuserid, " |
| . "rs.pw " |
| . "FROM image i, " |
| . "OS o, " |
| . "computer c, " |
| . "state s, " |
| . "state ls, " |
| . "request rq " |
| . "LEFT JOIN serverrequest sp ON (sp.requestid = rq.id) " |
| . "LEFT JOIN usergroup uga ON (uga.id = sp.admingroupid) " |
| . "LEFT JOIN usergroup ugl ON (ugl.id = sp.logingroupid) " |
| . "LEFT JOIN reservation rs ON (rs.requestid = rq.id) " |
| . "LEFT JOIN reservationaccounts ra ON (ra.reservationid = rs.id AND ra.userid = $id) " |
| . "WHERE (rq.userid = $id OR " |
| . "sp.admingroupid IN ($ingroupids) OR " |
| . "sp.logingroupid IN ($ingroupids)) AND " |
| . "rs.imageid = i.id AND " |
| . "rq.end > NOW() AND " |
| . "i.OSid = o.id AND " |
| . "c.id = rs.computerid AND " |
| . "rq.stateid = s.id AND " |
| . "s.name NOT IN ('deleted', 'makeproduction') AND " |
| . "rq.laststateid = ls.id AND " |
| . "ls.name NOT IN ('deleted', 'makeproduction') "; |
| if($type == "normal") |
| $query .= "AND rq.forimaging = 0 " |
| . "AND i.forcheckout = 1 " |
| . "AND sp.requestid IS NULL "; |
| if($type == "forimaging") |
| $query .= "AND rq.forimaging = 1 " |
| . "AND sp.requestid IS NULL "; |
| if($type == "server") |
| $query .= "AND sp.requestid IS NOT NULL "; |
| $query .= "ORDER BY rq.start, " |
| . "rs.id"; |
| $qh = doQuery($query, 160); |
| $count = -1; |
| $data = array(); |
| $foundids = array(); |
| $lastreqid = 0; |
| while($row = mysql_fetch_assoc($qh)) { |
| if($row['id'] != $lastreqid) { |
| $lastreqid = $row['id']; |
| $count++; |
| $data[$count] = $row; |
| $data[$count]['useraccountready'] = 1; |
| $data[$count]['reservations'] = array(); |
| } |
| if(array_key_exists($row['id'], $foundids)) { |
| $data[$count]['reservations'][] = array( |
| 'resid' => $row['resid'], |
| 'image' => $row['image'], |
| 'prettyname' => $row['prettyimage'], |
| 'imageid' => $row['imageid'], |
| 'imagerevisionid' => $row['imagerevisionid'], |
| 'OS' => $row['OS'], |
| 'computerid' => $row['computerid'], |
| 'compimageid' => $row['compimageid'], |
| 'computerstateid' => $row['computerstateid'], |
| 'IPaddress' => $row['IPaddress'], |
| 'comptype' => $row['comptype'], |
| 'password' => $row['password'], |
| 'resacctuserid' => $row['resacctuserid'] |
| ); |
| if($row['userid'] != $id && empty($row['resacctuserid'])) |
| $data[$count]['useraccountready'] = 0; |
| continue; |
| } |
| $foundids[$row['id']] = 1; |
| if(! is_null($row['serverrequestid'])) { |
| $data[$count]['server'] = 1; |
| $data[$count]['longterm'] = 0; |
| if($row['userid'] == $user['id']) { |
| $data[$count]['serverowner'] = 1; |
| $data[$count]['serveradmin'] = 1; |
| } |
| else { |
| $data[$count]['serverowner'] = 0; |
| if(! empty($row['serveradmingroupid']) && |
| array_key_exists($row['serveradmingroupid'], $user['groups'])) |
| $data[$count]['serveradmin'] = 1; |
| else |
| $data[$count]['serveradmin'] = 0; |
| } |
| } |
| elseif((datetimeToUnix($row['end']) - datetimeToUnix($row['start'])) > SECINDAY) { |
| $data[$count]['server'] = 0; |
| $data[$count]['longterm'] = 1; |
| $data[$count]['serverowner'] = 1; |
| $data[$count]['serveradmin'] = 1; |
| } |
| else { |
| $data[$count]['server'] = 0; |
| $data[$count]['longterm'] = 0; |
| $data[$count]['serverowner'] = 1; |
| $data[$count]['serveradmin'] = 1; |
| } |
| if($row['userid'] != $id && empty($row['resacctuserid'])) |
| $data[$count]['useraccountready'] = 0; |
| } |
| return $data; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn isComputerLoading($request, $computers) |
| /// |
| /// \param $request - an element from the array returned from getUserRequests |
| /// \param $computers - array from getComputers |
| /// |
| /// \return 1 if a computer is loading, 0 if not |
| /// |
| /// \brief checks all computers associated with the request to see if they |
| /// are loading |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function isComputerLoading($request, $computers) { |
| if($computers[$request["computerid"]]["stateid"] == 6 || |
| ($computers[$request["computerid"]]["stateid"] == 2 && |
| $computers[$request["computerid"]]["imagerevisionid"] != $request["imagerevisionid"])) |
| return 1; |
| foreach($request["reservations"] as $res) { |
| if($computers[$res["computerid"]]["stateid"] == 6 || |
| ($computers[$res["computerid"]]["stateid"] == 2 && |
| $computers[$res["computerid"]]["imagerevisionid"] != $res["imagerevisionid"])) |
| return 1; |
| } |
| return 0; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getMaxReloadTime($request, $images) |
| /// |
| /// \param $request - an element from the array returned from getUserRequests |
| /// \param $images - array returned from getImages |
| /// |
| /// \return the max reload time for all images associated with $request |
| /// |
| /// \brief looks at all the reload times for images associated with $request |
| /// and returns the longest one |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getMaxReloadTime($request, $images) { |
| $reloadtime = $images[$request["imageid"]]["reloadtime"]; |
| foreach($request["reservations"] as $res) { |
| if($images[$res["imageid"]]["reloadtime"] > $reloadtime) |
| $reloadtime = $images[$res["imageid"]]["reloadtime"]; |
| } |
| return $reloadtime; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn datetimeToUnix($datetime) |
| /// |
| /// \param $datetime - a mysql datetime |
| /// |
| /// \return timestamp - a unix timestamp |
| /// |
| /// \brief converts a mysql datetime to a unix timestamp |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function datetimeToUnix($datetime) { |
| $tmp = explode(' ', $datetime); |
| list($year, $month, $day) = explode('-', $tmp[0]); |
| list($hour, $min, $sec) = explode(':', $tmp[1]); |
| return mktime($hour, $min, $sec, $month, $day, $year, -1); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn unixToDatetime($timestamp) |
| /// |
| /// \param $timestamp - a unix timestamp |
| /// |
| /// \return datetime - a mysql datetime |
| /// |
| /// \brief converts a unix timestamp to a mysql datetime |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function unixToDatetime($timestamp) { |
| return date("Y-m-d H:i:s", $timestamp); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn numdatetimeToDatetime($numtime) |
| /// |
| /// \param $numtime - date and time in YYYYMMDDHHMMSS format |
| /// |
| /// \return a mysql datetime formatted string (YYYY-MM-DD HH:MM:SS) |
| /// |
| /// \brief converts numeric date and time into datetime format |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function numdatetimeToDatetime($numtime) { |
| $year = substr($numtime, 0, 4); |
| $month = substr($numtime, 4, 2); |
| $day = substr($numtime, 6, 2); |
| $hour = substr($numtime, 8, 2); |
| $min = substr($numtime, 10, 2); |
| $sec = substr($numtime, 12, 2); |
| return "$year-$month-$day $hour:$min:$sec"; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn minuteOfDay($hour, $min) |
| /// |
| /// \param $hour - hour of the day (0 - 23) |
| /// \param $min - minute into the hour (0 - 59) |
| /// |
| /// \return minutes into the day (0 - 1439) |
| /// |
| /// \brief converts hour:min to minutes since midnight |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function minuteOfDay($hour, $min) { |
| return ($hour * 60) + $min; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn minuteOfDay2($time) |
| /// |
| /// \param $time - in format 'HH:MM (am|pm)' |
| /// |
| /// \return minutes into the day (0 - 1439) |
| /// |
| /// \brief converts 'HH:MM (am|pm)' to minutes since midnight |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function minuteOfDay2($time) { |
| $timeArr = explode(':', $time); |
| $hour = $timeArr[0]; |
| $timeArr = explode(' ', $timeArr[1]); |
| $min = $timeArr[0]; |
| $meridian = $timeArr[1]; |
| if($meridian == "am" && $hour == 12) { |
| return $min; |
| } |
| elseif($meridian == "pm" && $hour < 12) { |
| $hour += 12; |
| } |
| return ($hour * 60) + $min; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn minuteOfWeek($ts) |
| /// |
| /// \param $ts - a unix timestamp |
| /// |
| /// \return minute of the week |
| /// |
| /// \brief takes a unix timestamp and returns how many minutes into the week it |
| /// is with the week starting on Sunday at midnight |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function minuteOfWeek($ts) { |
| # ((day of week (0-6)) * 1440) + ((hour in day) * 60) + (min in hour) |
| return (date('w', $ts) * 1440) + (date('G', $ts) * 60) + date('i', $ts); |
| } |
| |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn minuteToTime($minutes) |
| /// |
| /// \param $minutes - minutes since midnight |
| /// |
| /// \return time string in the form (H)H:MM (am/pm) |
| /// |
| /// \brief converts "minutes since midnight" to time of day |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function minuteToTime($minutes) { |
| $hour = sprintf("%d", $minutes / 60); |
| $min = sprintf("%02d", $minutes % 60); |
| $meridian = "am"; |
| if($hour == 0) { |
| $hour = 12; |
| } |
| elseif($hour == 12) { |
| $meridian = "pm"; |
| } |
| elseif($hour > 12) { |
| $hour -= 12; |
| $meridian = "pm"; |
| } |
| return "$hour:$min $meridian"; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn hour12to24($hour, $meridian) |
| /// |
| /// \param $hour - 1 to 12 |
| /// \param $meridian - am or pm |
| /// |
| /// \return 24 hour equivilent of $hour $meridian |
| /// |
| /// \brief converts 12 hour format to 24 hour format |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function hour12to24($hour, $meridian) { |
| if($meridian == 'pm' && $hour < 12) |
| return $hour + 12; |
| elseif($meridian == 'am' && $hour == 12) |
| return 0; |
| return $hour; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn hour24to12($hour) { |
| /// |
| /// \param $hour - hour of day in 24 hour format |
| /// |
| /// \return array with two elements where the first item is the hour and the |
| // second item is either 'am' or 'pm' |
| /// |
| /// \brief converts 24 hour to 12 hour + am/pm |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function hour24to12($hour) { |
| $m = 'am'; |
| if($hour == 0) |
| $hour = 12; |
| elseif($hour == 12) |
| $m = 'pm'; |
| elseif($hour > 12) { |
| $m = 'pm'; |
| $hour -= 12; |
| } |
| return array($hour, $m); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getDepartmentName($id) |
| /// |
| /// \param $id - id for a department in the department table |
| /// |
| /// \return if found, department name; if not, 0 |
| /// |
| /// \brief looks up the name field corresponding to $id in the department table |
| /// and returns it |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getDepartmentName($id) { |
| $query = "SELECT name FROM department WHERE id = '$id'"; |
| $qh = doQuery($query, 101); |
| if($row = mysql_fetch_row($qh)) { |
| return $row[0]; |
| } |
| else { |
| return 0; |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getImageId($image) |
| /// |
| /// \param $image - name of an image (must match name (not prettyname) in the |
| /// image table) |
| /// |
| /// \return the id of matching $image in the image table or 0 if lookup fails |
| /// |
| /// \brief looks up the id for $image and returns it |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getImageId($image) { |
| $qh = doQuery("SELECT id FROM image WHERE name = '$image'", 170); |
| if($row = mysql_fetch_row($qh)) { |
| return $row[0]; |
| } |
| return 0; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getOSId($os) |
| /// |
| /// \param $os - name of an os (must match name in the os table |
| /// |
| /// \return the id of matching $os in the os table or 0 if lookup fails |
| /// |
| /// \brief looks up the id for $os and returns it |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getOSId($os) { |
| $qh = doQuery("SELECT id FROM OS WHERE name = '$os'", 175); |
| if($row = mysql_fetch_row($qh)) { |
| return $row[0]; |
| } |
| return 0; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getStates() |
| /// |
| /// \return array of states where the index are the id from the state table |
| /// |
| /// \brief gets names for states in state table |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getStates() { |
| $qh = doQuery("SELECT id, name FROM state", 176); |
| $states = array(); |
| while($row = mysql_fetch_row($qh)) { |
| $states[$row[0]] = $row[1]; |
| } |
| return $states; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getPlatforms() |
| /// |
| /// \return array of platforms where the index are the id from the platform table |
| /// |
| /// \brief gets names for platforms in platform table |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getPlatforms() { |
| $qh = doQuery("SELECT id, name FROM platform", 178); |
| $platforms = array(); |
| while($row = mysql_fetch_row($qh)) { |
| $platforms[$row[0]] = $row[1]; |
| } |
| return $platforms; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getProvisioning() |
| /// |
| /// \return array of provisioning engines where each index is the id and the |
| /// value is an array with these keys: name, prettyname, moduleid, modulename |
| /// |
| /// \brief gets data from provisioning table |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getProvisioning() { |
| $query = "SELECT p.id, " |
| . "p.name, " |
| . "p.prettyname, " |
| . "p.moduleid, " |
| . "m.prettyname AS modulename " |
| . "FROM provisioning p, " |
| . "module m " |
| . "WHERE p.moduleid = m.id " |
| . "ORDER BY p.prettyname"; |
| $qh = doQuery($query, 101); |
| $provisioning = array(); |
| while($row = mysql_fetch_assoc($qh)) |
| $provisioning[$row['id']] = $row; |
| return $provisioning; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getProvisioningTypes() |
| /// |
| /// \return array of provisioning types allowed for each computer type of this |
| /// form:\n |
| /// {[blade] => {[id] => type,\n |
| /// [id] => type},\n |
| /// [lab] => {[id] => type}\n |
| /// [virtualmachine] => {[id] => type,\n |
| /// [id] => type}\n |
| /// |
| /// \brief generates an array of provisioning types allowed for each computer |
| /// type |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getProvisioningTypes() { |
| $query = "SELECT id, prettyname FROM provisioning WHERE name = 'none'"; |
| $qh = doQuery($query); |
| $none = mysql_fetch_assoc($qh); |
| $query = "SELECT p.id, " |
| . "p.prettyname, " |
| . "o.name AS `type` " |
| . "FROM provisioning p, " |
| . "OSinstalltype o, " |
| . "provisioningOSinstalltype po " |
| . "WHERE po.provisioningid = p.id AND " |
| . "po.OSinstalltypeid = o.id " |
| . "ORDER BY o.name"; |
| $qh = doQuery($query); |
| $types = array('blade' => array($none['id'] => $none['prettyname']), |
| 'lab' => array(), |
| 'virtualmachine' => array()); |
| while($row = mysql_fetch_assoc($qh)) { |
| if($row['type'] == 'kickstart' || $row['type'] == 'partimage') |
| $types['blade'][$row['id']] = $row['prettyname']; |
| elseif($row['type'] == 'none') |
| $types['lab'][$row['id']] = $row['prettyname']; |
| else |
| $types['virtualmachine'][$row['id']] = $row['prettyname']; |
| } |
| return $types; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getSchedules() |
| /// |
| /// \return array of schedules where the index are the id from the schedule table, |
| /// each index has the following elements:\n |
| /// \b name - name of schedule\n |
| /// \b ownerid - user id of owner\n |
| /// \b owner - unity id of owner\n |
| /// \b resourceid - id from resource table\n |
| /// \b times - array of start and end times for the schedule |
| /// |
| /// \brief gets information for schedules in schedule table |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getSchedules() { |
| $query = "SELECT s.id, " |
| . "s.name, " |
| . "s.ownerid, " |
| . "CONCAT(u.unityid, '@', a.name) AS owner, " |
| . "r.id AS resourceid " |
| . "FROM schedule s, " |
| . "resource r, " |
| . "resourcetype t, " |
| . "user u, " |
| . "affiliation a " |
| . "WHERE r.subid = s.id AND " |
| . "r.resourcetypeid = t.id AND " |
| . "t.name = 'schedule' AND " |
| . "s.ownerid = u.id AND " |
| . "u.affiliationid = a.id " |
| . "ORDER BY s.name"; |
| $qh = doQuery($query, 179); |
| $schedules = array(); |
| while($row = mysql_fetch_assoc($qh)) { |
| $schedules[$row["id"]] = $row; |
| $schedules[$row["id"]]["times"] = array(); |
| } |
| $query = "SELECT scheduleid, " |
| . "start, " |
| . "end " |
| . "FROM scheduletimes " |
| . "ORDER BY scheduleid, " |
| . "start"; |
| $qh = doQuery($query, 101); |
| while($row = mysql_fetch_assoc($qh)) { |
| array_push($schedules[$row["scheduleid"]]["times"], |
| array("start" => $row["start"], "end" => $row["end"])); |
| } |
| return $schedules; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn formatMinOfWeek($min) |
| /// |
| /// \param $min - minute of the week |
| /// |
| /// \return a string with the day of week and time |
| /// |
| /// \brief formats $min into something useful for printing |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function formatMinOfWeek($min) { |
| $time = minuteToTime($min % 1440); |
| if($min / 1440 == 0) { |
| return "Sunday, $time"; |
| } |
| elseif((int)($min / 1440) == 1) { |
| return "Monday, $time"; |
| } |
| elseif((int)($min / 1440) == 2) { |
| return "Tuesday, $time"; |
| } |
| elseif((int)($min / 1440) == 3) { |
| return "Wednesday, $time"; |
| } |
| elseif((int)($min / 1440) == 4) { |
| return "Thursday, $time"; |
| } |
| elseif((int)($min / 1440) == 5) { |
| return "Friday, $time"; |
| } |
| elseif((int)($min / 1440) == 6) { |
| return "Saturday, $time"; |
| } |
| elseif((int)($min / 1440) > 6) { |
| return "Sunday, $time"; |
| } |
| else { |
| return "$time"; |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getManagementNodes($alive, $includedeleted, $id) |
| /// |
| /// \param $alive - (optional) if given, only return "alive" nodes, can be |
| /// either "now" or "future" so we know how recently it must |
| /// have checked in |
| /// \param $includedeleted - (optional, default=0) 1 to include management |
| /// nodes with a state of deleted, 0 to leave them out |
| /// \param $id - (optional, default is all nodes) specify an id of a management |
| /// node to only have data for that node returned |
| /// |
| /// \return an array of management nodes where eash index is the id from the |
| /// managementnode table and each element is an array of data about the node |
| /// |
| /// \brief builds an array of data about the management nodes\n |
| /// if $alive = now, must have checked in within 5 minutes\n |
| /// if $alive = future, must have checked in within 1 hour |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getManagementNodes($alive="neither", $includedeleted=0, $id=0) { |
| if($alive == "now") |
| $lastcheckin = unixToDatetime(time() - 300); |
| elseif($alive == "future") |
| $lastcheckin = unixToDatetime(time() - 3600); |
| |
| $query = "SELECT m.id, " |
| . "m.IPaddress, " |
| . "m.hostname, " |
| . "m.ownerid, " |
| . "CONCAT(u.unityid, '@', a.name) as owner, " |
| . "m.stateid, " |
| . "s.name as state, " |
| . "m.lastcheckin, " |
| . "m.checkininterval, " |
| . "m.installpath, " |
| . "m.imagelibenable, " |
| . "m.imagelibgroupid, " |
| . "rg.name AS imagelibgroup, " |
| . "m.imagelibuser, " |
| . "m.imagelibkey, " |
| . "m.keys, " |
| . "m.sshport, " |
| . "m.publicIPconfiguration AS publicIPconfig, " |
| . "m.publicSubnetMask AS publicnetmask, " |
| . "m.publicDefaultGateway AS publicgateway, " |
| . "m.publicDNSserver AS publicdnsserver, " |
| . "m.sysadminEmailAddress AS sysadminemail, " |
| . "m.sharedMailBox AS sharedmailbox, " |
| . "r.id as resourceid, " |
| . "m.availablenetworks, " |
| . "m.NOT_STANDALONE AS federatedauth, " |
| . "nh.publicIPaddress AS natpublicIPaddress, " |
| . "COALESCE(nh.internalIPaddress, '') AS natinternalIPaddress " |
| . "FROM user u, " |
| . "state s, " |
| . "affiliation a, " |
| . "managementnode m " |
| . "LEFT JOIN resourcegroup rg ON (m.imagelibgroupid = rg.id) " |
| . "LEFT JOIN resourcetype rt ON (rt.name = 'managementnode') " |
| . "LEFT JOIN resource r ON (r.resourcetypeid = rt.id AND r.subid = m.id) " |
| . "LEFT JOIN nathost nh ON (r.id = nh.resourceid) " |
| . "WHERE m.ownerid = u.id AND " |
| . "m.stateid = s.id AND " |
| . "u.affiliationid = a.id"; |
| if($id != 0) |
| $query .= " AND m.id = $id"; |
| if($includedeleted == 0) |
| $query .= " AND s.name != 'deleted'"; |
| if($alive == "now" || $alive == "future") { |
| $query .= " AND m.lastcheckin > '$lastcheckin'" |
| . " AND s.name != 'maintenance'"; |
| } |
| $qh = doQuery($query, 101); |
| $return = array(); |
| while($row = mysql_fetch_assoc($qh)) { |
| if(is_null($row['natpublicIPaddress'])) { |
| $row['nathostenabled'] = 0; |
| $row['natpublicIPaddress'] = ''; |
| } |
| else |
| $row['nathostenabled'] = 1; |
| $return[$row["id"]] = $row; |
| $return[$row['id']]['availablenetworks'] = explode(',', $row['availablenetworks']); |
| if($row['state'] == 'deleted') |
| $return[$row['id']]['deleted'] = 1; |
| else |
| $return[$row['id']]['deleted'] = 0; |
| } |
| |
| # Get items from variable table for specific management node id |
| foreach ($return as $mn_id => $value ) { |
| if(array_key_exists("hostname", $value)) { |
| $mn_hostname = $value['hostname']; |
| $timeservers = getVariable('timesource|'.$mn_hostname); |
| if($timeservers == NULL) { |
| $timeservers = getVariable('timesource|global'); |
| } |
| $return[$mn_id]['timeservers'] = $timeservers; |
| } |
| } |
| |
| return $return; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getMnsFromImage($imageid) |
| /// |
| /// \param $imageid - id of an image |
| /// |
| /// \return array of management node ids |
| /// |
| /// \brief determines which management nodes can handle an image based on |
| /// image group to computer group, then computer group to management node group |
| /// mapping |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getMnsFromImage($imageid) { |
| $comps = getMappedResources($imageid, 'image', 'computer'); |
| if(empty($comps)) |
| return array(); |
| $inlist = implode(',', $comps); |
| $query = "SELECT DISTINCT rgm.resourcegroupid " |
| . "FROM resourcegroupmembers rgm, " |
| . "resource r, " |
| . "computer c " |
| . "WHERE c.id = r.subid AND " |
| . "r.resourcetypeid = 12 AND " |
| . "r.id = rgm.resourceid AND " |
| . "c.id in ($inlist)"; |
| $qh = doQuery($query); |
| $compgroups = array(); |
| while($row = mysql_fetch_assoc($qh)) |
| $compgroups[] = $row['resourcegroupid']; |
| $mngrps = array(); |
| foreach($compgroups as $grpid) { |
| $mngrpset = getResourceMapping('managementnode', 'computer', '', implode(',', $compgroups)); |
| foreach($mngrpset as $mngrpid => $compgrpset) |
| $mngrps[$mngrpid] = 1; |
| } |
| $mngrpnames = array(); |
| foreach(array_keys($mngrps) as $mnid) { |
| $mngrpnames[] = getResourceGroupName($mnid); |
| } |
| $mns = getResourcesFromGroups($mngrpnames, 'managementnode', 0); |
| $mnids = array(); |
| foreach($mns as $mnid => $name) |
| $mnids[$mnid] = 1; |
| return array_keys($mnids); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getAnyManagementNodeID() |
| /// |
| /// \return id of any management node available to user; 0 if none available |
| /// |
| /// \brief finds a management node available to the user; primarily useful for |
| /// getting an id to be used when getting a semaphore lock on a computer when |
| /// the computer isn't actually going to be loaded as a result of the lock |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getAnyManagementNodeID() { |
| # try getting id from getUserResources because that data should already be in cache |
| $resources = getUserResources(array("imageCheckOut", "mgmtNodeAdmin")); |
| if(! empty($resources['managementnode'])) { |
| $tmp = array_keys($resources['managementnode']); |
| return $tmp[0]; |
| } |
| $allmns = array_keys(getManagementNodes('future')); |
| if(empty($allmns)) |
| return 0; |
| return $allmns[0]; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn checkAvailableNetworks($ip) |
| /// |
| /// \param $ip - public ip address for a reservation |
| /// |
| /// \return array of management node ids that can handle $ip |
| /// |
| /// \brief finds any management nodes that can manage networks containing $ip |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function checkAvailableNetworks($ip) { |
| $ip = ip2long($ip); |
| $mnids = array(); |
| $mns = getManagementNodes(); |
| foreach($mns as $mn) { |
| foreach($mn['availablenetworks'] as $net) { |
| if($net == '') |
| continue; |
| list($net, $netmask) = explode('/', $net); |
| $net = ip2long($net); |
| $mask = pow(2, (32 - $netmask)) - 1; |
| $mask = ~ $mask; |
| if(($ip & $mask) == ($net & $mask)) |
| $mnids[$mn['id']] = 1; |
| } |
| } |
| return array_keys($mnids); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getPredictiveModules() |
| /// |
| /// \return an array of predictive loading modules where the index is the module |
| /// id and the value is a row of data from the module table |
| /// |
| /// \brief gets all the predictive loading modules from the module table |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getPredictiveModules() { |
| $query = "SELECT id, " |
| . "name, " |
| . "prettyname, " |
| . "description, " |
| . "perlpackage " |
| . "FROM module " |
| . "WHERE perlpackage LIKE 'VCL::Module::Predictive::%'"; |
| $qh = doQuery($query, 101); |
| $modules = array(); |
| while($row = mysql_fetch_assoc($qh)) |
| $modules[$row['id']] = $row; |
| return $modules; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getTimeSlots($compids, $end, $start) |
| /// |
| /// \param $compids - array of computer ids |
| /// \param $end - (optional) end time as unix timestamp |
| /// \param $start - (optional) start time as unix timestamp |
| /// |
| /// \return array of free/used timeslotes |
| /// |
| /// \brief generates an array of availability for computers where index is a |
| /// computerid with a value that is an array whose indexes are unix timestamps |
| /// that increment by 15 minutes with a value that is an array with 2 indexes: |
| /// 'scheduleclosed' and 'available' that tell if the computer's schedule is |
| /// closed at that moment and if the computer is available at that moment\n |
| /// Array {\n |
| /// [computerid0] => Array {\n |
| /// [timeslot0] => Array {\n |
| /// [scheduleclosed] => (0/1)\n |
| /// [available] => (0/1)\n |
| /// }\n |
| /// ...\n |
| /// [timeslotN] => Array {...}\n |
| /// }\n |
| /// ...\n |
| /// [computeridN] => Array {...}\n |
| /// } |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getTimeSlots($compids, $end=0, $start=0) { |
| if(empty($compids)) |
| return array(); |
| $requestid = processInputVar("requestid", ARG_NUMERIC, 0); |
| |
| $platsel = getContinuationVar("platforms"); |
| if(empty($platsel)) |
| $platsel = processInputVar("platforms", ARG_MULTINUMERIC); |
| $schsel = getContinuationVar("schedules"); |
| if(empty($schsel)) |
| $schsel = processInputVar("schedules", ARG_MULTINUMERIC); |
| |
| # all computations done with unix timestamps |
| if($end != 0) { |
| $enddate = unixToDatetime($end); |
| } |
| if($start != 0) { |
| $startdate = unixToDatetime($start); |
| } |
| |
| $computerids = array(); |
| $reservedComputerids = array(); |
| $schedules = getSchedules(); |
| $times = array(); |
| $scheduleids = array(); |
| $compinlist = implode(",", $compids); |
| $query = "SELECT id, scheduleid " |
| . "FROM computer " |
| . "WHERE scheduleid IS NOT NULL AND " |
| . "scheduleid != 0 AND " |
| . "id IN ($compinlist) "; |
| if(! empty($schsel) && ! empty($platsel)) { |
| $schinlist = implode(',', $schsel); |
| $platinlist = implode(',', $platsel); |
| $query .= "AND scheduleid IN ($schinlist) " |
| . "AND platformid IN ($platinlist)"; |
| } |
| $qh = doQuery($query, 155); |
| while($row = mysql_fetch_row($qh)) { |
| array_push($computerids, $row[0]); |
| $times[$row[0]] = array(); |
| $scheduleids[$row[0]] = $row[1]; |
| } |
| |
| if($start != 0 && $end != 0) { |
| $query = "SELECT rs.computerid, " |
| . "rq.start, " |
| . "rq.end + INTERVAL 900 SECOND AS end, " |
| . "rq.id, " |
| . "u.unityid, " |
| . "i.prettyname " |
| . "FROM reservation rs, " |
| . "request rq, " |
| . "user u, " |
| . "image i " |
| . "WHERE (rq.start < '$enddate' AND " |
| . "rq.end > '$startdate') AND " |
| . "rq.id = rs.requestid AND " |
| . "u.id = rq.userid AND " |
| . "i.id = rs.imageid AND " |
| . "rq.stateid NOT IN (1,5,12) " |
| . "ORDER BY rs.computerid, " |
| . "rq.start"; |
| } |
| else { |
| $query = "SELECT rs.computerid, " |
| . "rq.start, " |
| . "rq.end + INTERVAL 900 SECOND AS end, " |
| . "rq.id, " |
| . "u.unityid, " |
| . "i.prettyname " |
| . "FROM reservation rs, " |
| . "request rq, " |
| . "user u, " |
| . "image i " |
| . "WHERE rq.end > NOW() AND " |
| . "rq.id = rs.requestid AND " |
| . "u.id = rq.userid AND " |
| . "i.id = rs.imageid AND " |
| . "rq.stateid NOT IN (1,5,12) " |
| . "ORDER BY rs.computerid, " |
| . "rq.start"; |
| } |
| $qh = doQuery($query, 156); |
| |
| $id = ""; |
| while($row = mysql_fetch_row($qh)) { |
| if($row[3] == $requestid) { |
| continue; |
| } |
| if($id != $row[0]) { |
| $count = 0; |
| $id = $row[0]; |
| array_push($reservedComputerids, $id); |
| } |
| $times[$id][$count] = array(); |
| $times[$id][$count]["start"] = datetimeToUnix($row[1]); |
| $times[$id][$count]["end"] = datetimeToUnix($row[2]); |
| $times[$id][$count]["requestid"] = $row[3]; |
| $times[$id][$count]["unityid"] = $row[4]; |
| $times[$id][$count++]["prettyimage"] = $row[5]; |
| } |
| |
| # use floor function to get to a 15 min increment for start |
| if($start != 0) { |
| $start = unixFloor15($start); |
| } |
| else { |
| $start = unixFloor15() + 900; |
| } |
| |
| # last time to look at |
| if($end != 0) { |
| $endtime = $end; |
| } |
| else { |
| $endtime = $start + (DAYSAHEAD * SECINDAY); |
| } |
| |
| $blockData = getBlockTimeData($start, $endtime); |
| $maintItems = getMaintItemsForTimeTable($start, $endtime); |
| $reserveInfo = array(); // 0 = reserved, 1 = available |
| foreach($computerids as $id) { |
| $reserveInfo[$id] = array(); |
| $first = 1; |
| # loop from $start to $endtime by 15 minute increments |
| for($current = $start, $count = 0, $max = count($times[$id]); |
| $current < $endtime; |
| $current += 900) { |
| /*print "compid - $id<br>\n"; |
| print "count - $count<br>\n"; |
| print "current - " . unixToDatetime($current) . "<br>\n"; |
| if(array_key_exists($count, $times[$id])) { |
| print "start - " . unixToDatetime($times[$id][$count]["start"]) . "<br>\n"; |
| print "end - " . unixToDatetime($times[$id][$count]["end"]) . "<br>\n"; |
| } |
| print "-----------------------------------------------------<br>\n";*/ |
| $reserveInfo[$id][$current]['blockAllocation'] = 0; |
| $reserveInfo[$id][$current]["inmaintenance"] = 0; |
| if(scheduleClosed($id, $current, $schedules[$scheduleids[$id]])) { |
| $reserveInfo[$id][$current]["available"] = 0; |
| $reserveInfo[$id][$current]["scheduleclosed"] = 1; |
| continue; |
| } |
| if(checkInMaintenanceForTimeTable($current, $current + 900, $maintItems)) { |
| $reserveInfo[$id][$current]["available"] = 0; |
| $reserveInfo[$id][$current]["inmaintenance"] = 1; |
| continue; |
| } |
| if($blockid = isBlockAllocationTime($id, $current, $blockData)) { |
| $reserveInfo[$id][$current]['blockAllocation'] = 1; |
| $reserveInfo[$id][$current]['blockInfo']['groupid'] = $blockData[$blockid]['groupid']; |
| $reserveInfo[$id][$current]['blockInfo']['imageid'] = $blockData[$blockid]['imageid']; |
| $reserveInfo[$id][$current]['blockInfo']['name'] = $blockData[$blockid]['name']; |
| $reserveInfo[$id][$current]['blockInfo']['image'] = $blockData[$blockid]['image']; |
| } |
| $reserveInfo[$id][$current]["scheduleclosed"] = 0; |
| //if computer not in $reservedComputerids, it is free |
| if(! in_array($id, $reservedComputerids)) { |
| $reserveInfo[$id][$current]["available"] = 1; |
| continue; |
| } |
| //if past an end |
| if($count != $max && $current >= $times[$id][$count]["end"]) { |
| $count++; |
| } |
| # past the end of all reservations |
| if($count == $max) { |
| $reserveInfo[$id][$current]["available"] = 1; |
| continue; |
| } |
| //if before any start times |
| if($count == 0 && $current < $times[$id][0]["start"]) { |
| $reserveInfo[$id][$current]["available"] = 1; |
| continue; |
| } |
| //if between a start and end time |
| if($current >= $times[$id][$count]["start"] && |
| $current < $times[$id][$count]["end"]) { |
| if($first) { |
| # set the previous 15 minute block to show as busy to allow for load time |
| $first = 0; |
| $reserveInfo[$id][$current - 900]['blockAllocation'] = 0; |
| $reserveInfo[$id][$current - 900]["scheduleclosed"] = 0; |
| $reserveInfo[$id][$current - 900]["available"] = 0; |
| $reserveInfo[$id][$current - 900]["requestid"] = $times[$id][$count]["requestid"]; |
| $reserveInfo[$id][$current - 900]["unityid"] = $times[$id][$count]["unityid"]; |
| $reserveInfo[$id][$current - 900]["prettyimage"] = $times[$id][$count]["prettyimage"]; |
| } |
| $reserveInfo[$id][$current]["available"] = 0; |
| $reserveInfo[$id][$current]["requestid"] = $times[$id][$count]["requestid"]; |
| $reserveInfo[$id][$current]["unityid"] = $times[$id][$count]["unityid"]; |
| $reserveInfo[$id][$current]["prettyimage"] = $times[$id][$count]["prettyimage"]; |
| continue; |
| } |
| //if after previous end but before this start |
| if($current >= $times[$id][$count - 1]["end"] && |
| $current < $times[$id][$count]["start"]) { |
| $reserveInfo[$id][$current]["available"] = 1; |
| continue; |
| } |
| # shouldn't get here; print debug info if we do |
| if(checkUserHasPerm('View Debug Information')) { |
| print "******************************************************<br>\n"; |
| print "current - " . unixToDatetime($current) . "<br>\n"; |
| print "endtime - " . unixToDatetime($endtime) . "<br>\n"; |
| print "count - $count<br>\n"; |
| print "max - $max<br>\n"; |
| print "start - " . unixToDatetime($times[$id][$count]["start"]) . "<br>\n"; |
| print "end - " . unixToDatetime($times[$id][$count]["end"]) . "<br>\n"; |
| print "------------------------------------------------------<br>\n"; |
| } |
| } |
| } |
| return $reserveInfo; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn unixFloor15($timestamp) |
| /// |
| /// \param $timestamp - (optional) unix timestamp, defaults to now |
| /// |
| /// \return floored timestamp |
| /// |
| /// \brief takes $timestamp and floors it to a 15 minute increment with 0 seconds |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function unixFloor15($timestamp=0) { |
| if($timestamp == 0) { |
| $timestamp = time(); |
| } |
| $timeval = getdate($timestamp); |
| if($timeval["minutes"] < 15) { |
| $timeval["minutes"] = 0; |
| } |
| elseif($timeval["minutes"] < 30) { |
| $timeval["minutes"] = 15; |
| } |
| elseif($timeval["minutes"] < 45) { |
| $timeval["minutes"] = 30; |
| } |
| elseif($timeval["minutes"] < 60) { |
| $timeval["minutes"] = 45; |
| } |
| return mktime($timeval["hours"], |
| $timeval["minutes"], |
| 0, |
| $timeval["mon"], |
| $timeval["mday"], |
| $timeval["year"], |
| -1); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn pickTimeTable() |
| /// |
| /// \brief prints a form for selecting what elements to show in the timetable |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function pickTimeTable() { |
| $data = getUserComputerMetaData(); |
| print "<H2 align=center>Time Table</H2>\n"; |
| print "Select the criteria for the computers you want to have in the timetable:\n"; |
| print "<FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n"; |
| print "<table summary=\"\">\n"; |
| print " <TR>\n"; |
| print " <TH>Platforms:</TH>\n"; |
| print " <TH>Schedules:</TH>\n"; |
| print " </TR>\n"; |
| print " <TR valign=top>\n"; |
| print " <TD>\n"; |
| printSelectInput("platforms[]", $data["platforms"], -1, 0, 1); |
| print " </TD>\n"; |
| print " <TD>\n"; |
| printSelectInput("schedules[]", $data["schedules"], -1, 0, 1); |
| print " </TD>\n"; |
| print " </TR>\n"; |
| print "</table>\n"; |
| $cont = addContinuationsEntry('showTimeTable'); |
| print "<INPUT type=hidden name=continuation value=\"$cont\">\n"; |
| print "<INPUT type=submit value=Submit>\n"; |
| print "</FORM>\n"; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn showTimeTable($links) |
| /// |
| /// \param $links - 1 to make free times links; 0 for no links |
| /// |
| /// \brief prints out a timetable of free/used timeslots |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function showTimeTable($links) { |
| global $mode, $user; |
| $imaging = getContinuationVar('imaging', 0); |
| if($links == 1) { |
| $imageid = getContinuationVar('imageid'); |
| $length = getContinuationVar('length'); |
| $requestid = getContinuationVar('requestid', 0); |
| $showmessage = getContinuationVar('showmessage', 0); |
| $platforms = array(); |
| $schedules = array(); |
| } |
| else { |
| $imageid = 0; |
| $length = 0; |
| $requestid = 0; |
| $showmessage = 0; |
| $platforms = getContinuationVar("platforms"); |
| if(empty($platforms)) |
| $platforms = processInputVar("platforms", ARG_MULTINUMERIC); |
| $schedules = getContinuationVar("schedules"); |
| if(empty($schedules)) |
| $schedules = processInputVar("schedules", ARG_MULTINUMERIC); |
| } |
| $argstart = getContinuationVar("start"); |
| $argend = getContinuationVar("end"); |
| |
| $resources = getUserResources(array("computerAdmin")); |
| $userCompIDs = array_keys($resources["computer"]); |
| |
| $computerData = getComputers(); |
| $imageData = getImages(); |
| $now = time(); |
| if($links) { |
| $resources = getUserResources(array("imageAdmin", "imageCheckOut")); |
| $usercomputerids = array_keys($resources["computer"]); |
| # get list of computers' platformids |
| $qh = doQuery("SELECT platformid FROM image WHERE id = $imageid", 110); |
| $row = mysql_fetch_row($qh); |
| $platformid = $row[0]; |
| $computer_platformids = array(); |
| $qh = doQuery("SELECT id, platformid FROM computer", 111); |
| while($row = mysql_fetch_row($qh)) { |
| $computer_platformids[$row[0]] = $row[1]; |
| } |
| $mappedcomputers = getMappedResources($imageid, "image", "computer"); |
| $compidlist = array_intersect($mappedcomputers, $usercomputerids); |
| } |
| else |
| $compidlist = $userCompIDs; |
| if(! empty($argstart) && ! empty($argend)) { |
| $timeslots = getTimeSlots($compidlist, $argend, $argstart); |
| $start = $argstart; |
| $end = $argend; |
| } |
| else { |
| $start = $now; |
| $end = $start + (SECINDAY / 2); |
| $timeslots = getTimeSlots($compidlist, $end); |
| } |
| |
| print "<DIV align=center>\n"; |
| print "<H2>" . i("Time Table") . "</H2>\n"; |
| print "</DIV>\n"; |
| $computeridrow = ""; |
| $displayedids = array(); |
| $computers = array_keys($timeslots); |
| if($links) { |
| $computers = array_intersect($computers, $usercomputerids); |
| } |
| foreach($computers as $id) { |
| if($links) { |
| # don't show computers that don't meet hardware criteria, are not |
| # in the available state, are the wrong platform, or wrong group, |
| # or aren't mapped in resourcemap |
| if($computer_platformids[$id] != $platformid || |
| ($computerData[$id]["stateid"] != 2 && |
| $computerData[$id]["stateid"] != 3 && |
| $computerData[$id]["stateid"] != 6 && |
| $computerData[$id]["stateid"] != 8) || |
| $computerData[$id]["ram"] < $imageData[$imageid]["minram"] || |
| $computerData[$id]["procnumber"] < $imageData[$imageid]["minprocnumber"] || |
| $computerData[$id]["procspeed"] < $imageData[$imageid]["minprocspeed"] || |
| $computerData[$id]["network"] < $imageData[$imageid]["minnetwork"] || |
| ! in_array($id, $mappedcomputers)) { |
| continue; |
| } |
| } |
| elseif(! array_key_exists($id, $computerData) || |
| ! in_array($computerData[$id]["platformid"], $platforms) || |
| ! in_array($computerData[$id]["scheduleid"], $schedules) || |
| ! in_array($id, $userCompIDs)) { |
| continue; |
| } |
| $computeridrow .= " <TH>$id</TH>\n"; |
| array_push($displayedids, $id); |
| } |
| if(empty($displayedids)) { |
| if($links) { |
| print i("There are currently no computers available that can run the application you selected.") . "\n"; |
| } |
| else { |
| print i("There are no computers that meet the specified criteria") . "\n"; |
| } |
| return; |
| } |
| if($showmessage) { |
| print i("The time you have requested to use the environment is not available. You may select from the green blocks of time to select an available time slot to make a reservation.") . "<br>\n"; |
| } |
| print "<table summary=\"\">\n"; |
| print " <TR>\n"; |
| print " <TD>"; |
| # print Previous/Next links |
| if(! empty($argstart) && ($argstart - (SECINDAY / 2) > $now - 600)) { |
| $prevstart = $start - (SECINDAY / 2); |
| $prevend = $end - (SECINDAY / 2); |
| print "<FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n"; |
| $cdata = array('start' => $prevstart, |
| 'end' => $prevend, |
| 'imageid' => $imageid, |
| 'requestid' => $requestid, |
| 'length' => $length, |
| 'platforms' => $platforms, |
| 'schedules' => $schedules, |
| 'imaging' => $imaging); |
| $cont = addContinuationsEntry($mode, $cdata, SECINDAY); |
| print "<INPUT type=hidden name=continuation value=\"$cont\">\n"; |
| print "<INPUT type=submit value=" . i("Previous") . ">\n"; |
| print "</FORM>\n"; |
| } |
| print "</TD>\n"; |
| print " <TD>"; |
| if($end + (SECINDAY / 2) < $now + DAYSAHEAD * SECINDAY) { |
| $nextstart = $start + (SECINDAY / 2); |
| $nextend = $end + (SECINDAY / 2); |
| print "<FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n"; |
| $cdata = array('start' => $nextstart, |
| 'end' => $nextend, |
| 'imageid' => $imageid, |
| 'requestid' => $requestid, |
| 'length' => $length, |
| 'platforms' => $platforms, |
| 'schedules' => $schedules, |
| 'imaging' => $imaging); |
| $cont = addContinuationsEntry($mode, $cdata, SECINDAY); |
| print "<INPUT type=hidden name=continuation value=\"$cont\">\n"; |
| print "<INPUT type=submit value=" . i("Next") . ">\n"; |
| print "</FORM>\n"; |
| } |
| print "</TD>\n"; |
| print " </TR>\n"; |
| print " <TR>\n"; |
| print " <TD>\n"; |
| |
| $tmpArr = array_keys($computers); |
| $first = $computers[$tmpArr[0]]; |
| print " <table id=ttlayout summary=\"\">\n"; |
| if(! $links || checkUserHasPerm('View Debug Information')) { |
| print " <TR>\n"; |
| print " <TH align=right>Computer ID:</TH>\n"; |
| print $computeridrow; |
| print " </TR>\n"; |
| } |
| $yesterday = ""; |
| foreach(array_keys($timeslots[$first]) as $stamp) { |
| if($stamp < $now) |
| continue; |
| print " <TR>\n"; |
| $stampArr = getdate($stamp); |
| $label = ""; |
| if($stampArr["mday"] != $yesterday) { |
| if(array_key_exists('tzoffset', $_SESSION['persistdata'])) |
| $label = date('n/d/Y+g:i+a', $stamp + $_SESSION['persistdata']['tzoffset'] * 60); |
| else |
| $label = date('n/d/Y+g:i+a', $stamp); |
| $label = str_replace('+', ' ', $label); |
| $yesterday = $stampArr["mday"]; |
| } |
| elseif($stampArr["minutes"] == 0) { |
| if(array_key_exists('tzoffset', $_SESSION['persistdata'])) |
| $label = date('g:i a', $stamp + $_SESSION['persistdata']['tzoffset'] * 60); |
| else |
| $label = date('g:i a', $stamp); |
| } |
| print " <TH align=right>$label</TH>\n"; |
| $free = 0; |
| # print the cells |
| foreach($computers as $id) { |
| if(! in_array($id, $displayedids)) { |
| continue; |
| } |
| if($links && ($computer_platformids[$id] != $platformid || |
| $computerData[$id]["stateid"] == 10 || |
| $computerData[$id]["stateid"] == 5)) { |
| continue; |
| } |
| # maintenance window |
| if($timeslots[$id][$stamp]["inmaintenance"] == 1) { |
| print " <TD bgcolor=\"#a0a0a0\"><img src=images/gray.jpg "; |
| print "alt=sitemaintenance border=0></TD>\n"; |
| } |
| # computer's schedule is currently closed |
| elseif($timeslots[$id][$stamp]["scheduleclosed"] == 1) { |
| print " <TD bgcolor=\"#a0a0a0\"><img src=images/gray.jpg "; |
| print "alt=scheduleclosed border=0></TD>\n"; |
| } |
| # computer is in maintenance state |
| elseif($computerData[$id]["stateid"] == 10) { |
| print " <TD bgcolor=\"#a0a0a0\"><img src=images/gray.jpg "; |
| print "alt=maintenance border=0></TD>\n"; |
| } |
| # computer is reserved for a block allocation that doesn't match this |
| elseif($timeslots[$id][$stamp]['blockAllocation'] && |
| ($timeslots[$id][$stamp]['blockInfo']['imageid'] != $imageid || # this line threw an error at one point, but we couldn't recreate it later |
| (! in_array($timeslots[$id][$stamp]['blockInfo']['groupid'], array_keys($user['groups'])))) && |
| $timeslots[$id][$stamp]['available']) { |
| if($links) { |
| print " <TD bgcolor=\"#ff0000\"><img src=images/red.jpg "; |
| print "alt=blockallocation border=0></TD>\n"; |
| } |
| else { |
| print " <TD bgcolor=\"#e58304\"><img src=images/orange.jpg "; |
| $title = "Block Allocation: {$timeslots[$id][$stamp]['blockInfo']['name']}\n" |
| . "Image: {$timeslots[$id][$stamp]['blockInfo']['image']}"; |
| print "alt=blockallocation border=0 title=\"$title\"></TD>\n"; |
| } |
| } |
| # computer is free |
| elseif($timeslots[$id][$stamp]["available"]) { |
| if($links) { |
| print " <TD bgcolor=\"#00ff00\"><a href=\"" . BASEURL . SCRIPT; |
| print "?mode=viewRequests&stamp=$stamp&imageid=$imageid&length=$length&imaging=$imaging\"><img "; |
| print "src=images/green.jpg alt=free border=0></a></TD>\n"; |
| } |
| else { |
| print " <TD bgcolor=\"#00ff00\"><img src=images/green.jpg alt=free border=0></TD>\n"; |
| } |
| } |
| # computer is used |
| else { |
| if($links) { |
| print " <TD bgcolor=\"#ff0000\"><font color=\"#ff0000\">used</font></TD>\n"; |
| } |
| else { |
| $title = i("User:") . " " . $timeslots[$id][$stamp]["unityid"] |
| . " " . i("Image:") . " " . $timeslots[$id][$stamp]["prettyimage"]; |
| $ttdata = array('start' => $argstart, |
| 'end' => $argend, |
| 'imageid' => $imageid, |
| 'requestid' => $timeslots[$id][$stamp]["requestid"], |
| 'length' => $length, |
| 'platforms' => $platforms, |
| 'schedules' => $schedules, |
| 'imaging' => $imaging); |
| $cdata = array('requestid' => $timeslots[$id][$stamp]["requestid"], |
| 'ttdata' => $ttdata); |
| $cont = addContinuationsEntry('viewRequestInfo', $cdata); |
| print " <TD bgcolor=\"#ff0000\"><a href=\"" . BASEURL; |
| print SCRIPT . "?continuation=$cont\"><img src=images/red.jpg "; |
| print "alt=used border=0 title=\"$title\"></a></TD>\n"; |
| } |
| } |
| } |
| print " </TR>\n"; |
| } |
| print " </table>\n"; |
| print " </TD>\n"; |
| print " </TR>\n"; |
| print " <TR>\n"; |
| print " <TD>"; |
| # print Previous/Next links |
| if(! empty($argstart) && ($argstart - (SECINDAY / 2) > $now - 600)) { |
| $prevstart = $start - (SECINDAY / 2); |
| $prevend = $end - (SECINDAY / 2); |
| print "<FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n"; |
| $cdata = array('start' => $prevstart, |
| 'end' => $prevend, |
| 'imageid' => $imageid, |
| 'requestid' => $requestid, |
| 'length' => $length, |
| 'platforms' => $platforms, |
| 'schedules' => $schedules, |
| 'imaging' => $imaging); |
| $cont = addContinuationsEntry($mode, $cdata, SECINDAY); |
| print "<INPUT type=hidden name=continuation value=\"$cont\">\n"; |
| print "<INPUT type=submit value=" . i("Previous") . ">\n"; |
| print "</FORM>\n"; |
| } |
| print "</TD>\n"; |
| print " <TD>"; |
| if($end + (SECINDAY / 2) < $now + DAYSAHEAD * SECINDAY) { |
| $nextstart = $start + (SECINDAY / 2); |
| $nextend = $end + (SECINDAY / 2); |
| print "<FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n"; |
| $cdata = array('start' => $nextstart, |
| 'end' => $nextend, |
| 'imageid' => $imageid, |
| 'requestid' => $requestid, |
| 'length' => $length, |
| 'platforms' => $platforms, |
| 'schedules' => $schedules, |
| 'imaging' => $imaging); |
| $cont = addContinuationsEntry($mode, $cdata, SECINDAY); |
| print "<INPUT type=hidden name=continuation value=\"$cont\">\n"; |
| print "<INPUT type=submit value=" . i("Next") . ">\n"; |
| print "</FORM>\n"; |
| } |
| print "</TD>\n"; |
| print " </TR>\n"; |
| print "</table>\n"; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn findAvailableTimes($start, $end, $imageid, $userid, $usedaysahead, |
| // $reqid='', $extendonly=0, $ip='', $mac='') |
| /// |
| /// \param $start - desired start time (epoch time) |
| /// \param $end - desired end time (epoch time) |
| /// \param $imageid - desired image |
| /// \param $userid - id of user to check for |
| /// \param $usedaysahead - 1 to limit suggested start time based on DAYSAHEAD, |
| /// 0 not to |
| /// \param $reqid - (optional, default='') id of a request to ignore - use this |
| /// when editing an existing reservation |
| /// \param $extendonly - (optional, default=0) if set to 1, only check for how |
| /// long this reservation can be extended; $reqid also be given a value and |
| /// function will only search for extensions to existing reservation on same |
| /// computer |
| /// \param $ip - (optional, default='') desired IP address |
| /// \param $mac - (optional, default='') desired MAC address |
| /// |
| /// \return an array where each key is a unix timestamp for the start time of |
| /// the available slot and each element is an array with these items:\n |
| /// \b start - start of slot in datetime format\n |
| /// \b startts - start of slot in unix timestamp format\n |
| /// \b duration - length of slot in minutes\n |
| /// \b compid - id of computer for slot |
| /// |
| /// \brief builds an array of available time slots close to the submitted |
| /// parameters |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function findAvailableTimes($start, $end, $imageid, $userid, $usedaysahead, |
| $reqid='', $extendonly=0, $ip='', $mac='') { |
| global $user; |
| if($userid == $user['id']) |
| $ingroups = implode(',', array_keys($user['groups'])); |
| else { |
| $userdata = getUserInfo($userid, 0, 1); |
| $ingroups = implode(',', array_keys($userdata['groups'])); |
| } |
| # TODO make this work for cluster images |
| if(! $extendonly) { |
| $mappedcomputers = getMappedResources($imageid, 'image', 'computer'); |
| $resources = getUserResources(array('imageAdmin', 'imageCheckOut'), |
| array('available'), 0, 0, $userid); |
| $compids = array_intersect($mappedcomputers, array_keys($resources['computer'])); |
| if(! count($compids)) { |
| return array(); |
| } |
| $incompids = implode(',', $compids); |
| } |
| else { |
| $request = getRequestInfo($reqid); |
| $incompids = $request['reservations'][0]['computerid']; |
| } |
| $scheduleids = getAvailableSchedules($start, $end); |
| if(empty($scheduleids)) |
| return array(); |
| $schedules = implode(',', $scheduleids); |
| $platformid = getImagePlatform($imageid); |
| if(is_null($platformid)) |
| return array(); |
| $reqduration = $end - $start; |
| $startdt = unixToDatetime($start); |
| $end += 900; |
| $enddt = unixToDatetime($end); |
| $ignorestates = "'maintenance','vmhostinuse','hpc','failed'"; |
| $nowignorestates = "$ignorestates,'timeout'"; |
| if(! $extendonly) |
| $nowignorestates .= ",'reloading','reload','inuse'"; |
| $slots = array(); |
| $removes = array(); |
| $minstart = $start; |
| $maxend = $start; |
| $newcompids = array(); |
| $daysahead = time() + (DAYSAHEAD * SECINDAY); |
| |
| # add computers that are available now with no future reservations |
| # restricting duration; we do this so that they'll be in our arrays to check |
| # for concurrent image use, block allocations, ip/mac overlap, and |
| # maintenance window overlap |
| $query = "SELECT c.id AS compid " |
| . "FROM computer c, " |
| . "image i, " |
| . "state s, " |
| . "provisioningOSinstalltype poi, " |
| . "OSinstalltype oi, " |
| . "OS o " |
| . "WHERE c.stateid = s.id AND " |
| . "i.id = $imageid AND " |
| . "s.name NOT IN ($nowignorestates) AND " |
| . "c.platformid = $platformid AND " |
| . "c.scheduleid IN ($schedules) AND " |
| . "i.OSid = o.id AND " |
| . "o.installtype = oi.name AND " |
| . "oi.id = poi.OSinstalltypeid AND " |
| . "poi.provisioningid = c.provisioningid AND " |
| . "(c.type != 'virtualmachine' OR c.vmhostid IS NOT NULL) AND " |
| . "c.RAM >= i.minram AND " |
| . "c.procnumber >= i.minprocnumber AND " |
| . "c.procspeed >= i.minprocspeed AND " |
| . "c.network >= i.minnetwork AND " |
| . "c.id NOT IN (SELECT rs.computerid " |
| . "FROM reservation rs, " |
| . "request rq " |
| . "WHERE rs.requestid = rq.id AND "; |
| if($reqid != '') |
| $query .= "rq.id != $reqid AND "; |
| $query .= "DATE_ADD(rq.end, INTERVAL 15 MINUTE) >= '$startdt' AND " |
| . "rs.computerid IN ($incompids)) AND " |
| . "c.id IN ($incompids) " |
| . "ORDER BY RAM, " |
| . "(c.procspeed * c.procnumber), " |
| . "network"; |
| $qh = doQuery($query, 101); |
| while($row = mysql_fetch_assoc($qh)) { |
| $row['duration'] = $reqduration; |
| $row['startts'] = $start; |
| $row['start'] = $startdt; |
| $row['endts'] = $start + $reqduration; |
| $slots[$row['compid']] = array(); |
| $slots[$row['compid']][] = $row; |
| $newcompids[] = $row['compid']; |
| } |
| |
| if(! $extendonly) { |
| # find available timeslots based on spacing between existing reservations |
| $query = "SELECT rs1.computerid AS compid, " |
| . "DATE_ADD(rq1.end, INTERVAL 15 MINUTE) AS start, " |
| . "MIN(UNIX_TIMESTAMP(rq2.start) - UNIX_TIMESTAMP(rq1.end) - 1800) AS duration " # 1800 is adding 15 min to end of rq1.end and end of requested reservation |
| . "FROM request rq1, " |
| . "request rq2, " |
| . "reservation rs1, " |
| . "reservation rs2, " |
| . "image i, " |
| . "state s, " |
| . "computer c, " |
| . "provisioningOSinstalltype poi, " |
| . "OSinstalltype oi, " |
| . "OS o " |
| . "WHERE rq1.id = rs1.requestid AND " |
| . "rs2.requestid = rq2.id AND " |
| . "rq1.id != rq2.id AND " |
| . "rq1.start < rq2.start AND " |
| . "DATE_ADD(rq1.end, INTERVAL 15 MINUTE) >= '$startdt' AND " |
| . "rs1.computerid = rs2.computerid AND " |
| . "rs1.computerid IN ($incompids) AND " |
| . "i.id = $imageid AND " |
| . "c.id = rs1.computerid AND " |
| . "c.platformid = $platformid AND " |
| . "c.scheduleid IN ($schedules) AND " |
| . "i.OSid = o.id AND " |
| . "o.installtype = oi.name AND " |
| . "oi.id = poi.OSinstalltypeid AND " |
| . "poi.provisioningid = c.provisioningid AND " |
| . "(c.type != 'virtualmachine' OR c.vmhostid IS NOT NULL) AND " |
| . "c.RAM >= i.minram AND " |
| . "c.procnumber >= i.minprocnumber AND " |
| . "c.procspeed >= i.minprocspeed AND " |
| . "c.network >= i.minnetwork AND " |
| . "c.stateid = s.id AND " |
| . "s.name NOT IN ($ignorestates) AND "; |
| if($reqid != '') |
| $query .= "rq1.id != $reqid AND " |
| . "rq2.id != $reqid AND "; |
| $query .= "(c.type != 'virtualmachine' OR c.vmhostid IS NOT NULL) " |
| . "GROUP BY rq1.id "; |
| $query .= "ORDER BY rs1.computerid, rq1.start, rq1.end"; |
| $qh = doQuery($query, 101); |
| while($row = mysql_fetch_assoc($qh)) { |
| $row['startts'] = datetimeToUnix($row['start']); |
| if($row['startts'] % 900) { |
| $row['startts'] = $row['startts'] - ($row['startts'] % 900) + 900; |
| $row['start'] = unixToDatetime($row['startts']); |
| $row['duration'] -= 900; |
| } |
| if($row['duration'] >= 1800) { |
| if($usedaysahead && $row['startts'] > $daysahead) |
| continue; |
| if($row['duration'] > $reqduration) |
| $row['duration'] = $reqduration; |
| $row['endts'] = $row['startts'] + $row['duration']; |
| $slots[$row['compid']][] = $row; |
| if($row['startts'] < $minstart) |
| $minstart = $row['startts']; |
| if($row['endts'] > $maxend) |
| $maxend = $row['endts']; |
| $newcompids[] = $row['compid']; |
| } |
| } |
| } |
| |
| # find slots that are available now |
| $query = "SELECT UNIX_TIMESTAMP(MIN(rq.start)) - UNIX_TIMESTAMP('$startdt') - 900 AS duration, " |
| . "UNIX_TIMESTAMP(MIN(rq.start)) AS endts, " |
| . "rs.computerid AS compid " |
| . "FROM request rq, " |
| . "reservation rs, " |
| . "image i, " |
| . "state s, " |
| . "computer c, " |
| . "provisioningOSinstalltype poi, " |
| . "OSinstalltype oi, " |
| . "OS o " |
| . "WHERE rs.requestid = rq.id AND " |
| . "(rq.start > '$startdt' OR " |
| . "(DATE_ADD(rq.end, INTERVAL 15 MINUTE) > '$startdt' AND rq.start <= '$startdt')) AND " |
| . "rs.computerid IN ($incompids) AND " |
| . "i.id = $imageid AND " |
| . "c.id = rs.computerid AND " |
| . "c.platformid = $platformid AND " |
| . "c.scheduleid IN ($schedules) AND " |
| . "i.OSid = o.id AND " |
| . "o.installtype = oi.name AND " |
| . "oi.id = poi.OSinstalltypeid AND " |
| . "poi.provisioningid = c.provisioningid AND " |
| . "(c.type != 'virtualmachine' OR c.vmhostid IS NOT NULL) AND " |
| . "c.RAM >= i.minram AND " |
| . "c.procnumber >= i.minprocnumber AND " |
| . "c.procspeed >= i.minprocspeed AND " |
| . "c.network >= i.minnetwork AND " |
| . "c.stateid = s.id AND " |
| . "s.name NOT IN ($nowignorestates) AND "; |
| if($reqid != '') |
| $query .= "rq.id != $reqid AND "; |
| $query .= "(c.type != 'virtualmachine' OR c.vmhostid IS NOT NULL) " |
| . "GROUP BY rs.computerid"; |
| $qh = doQuery($query, 101); |
| while($row = mysql_fetch_assoc($qh)) { |
| if($row['endts'] % 900) { |
| $row['endts'] = $row['endts'] - ($row['endts'] % 900); |
| $row['duration'] -= 900; |
| } |
| if($row['duration'] >= 1800) { |
| if($row['duration'] > $reqduration) |
| $row['duration'] = $reqduration; |
| $row['start'] = $startdt; |
| $row['startts'] = $start; |
| $slots[$row['compid']][] = $row; |
| if($row['endts'] > $maxend) |
| $maxend = $row['endts']; |
| $newcompids[] = $row['compid']; |
| } |
| } |
| |
| # find slots that are available after all reservations are over |
| $query = "SELECT UNIX_TIMESTAMP(MAX(rq.end)) + 900 AS startts, " |
| . "DATE_ADD(MAX(rq.end), INTERVAL 15 MINUTE) AS start, " |
| . "rs.computerid AS compid " |
| . "FROM request rq, " |
| . "reservation rs, " |
| . "image i, " |
| . "state s, " |
| . "computer c, " |
| . "provisioningOSinstalltype poi, " |
| . "OSinstalltype oi, " |
| . "OS o " |
| . "WHERE rs.requestid = rq.id AND " |
| . "(rq.start > '$startdt' OR " |
| . "(DATE_ADD(rq.end, INTERVAL 15 MINUTE) > '$startdt' AND rq.start <= '$startdt')) AND " |
| . "rs.computerid IN ($incompids) AND " |
| . "i.id = $imageid AND " |
| . "c.id = rs.computerid AND " |
| . "c.platformid = $platformid AND " |
| . "c.scheduleid IN ($schedules) AND " |
| . "i.OSid = o.id AND " |
| . "o.installtype = oi.name AND " |
| . "oi.id = poi.OSinstalltypeid AND " |
| . "poi.provisioningid = c.provisioningid AND " |
| . "(c.type != 'virtualmachine' OR c.vmhostid IS NOT NULL) AND " |
| . "c.RAM >= i.minram AND " |
| . "c.procnumber >= i.minprocnumber AND " |
| . "c.procspeed >= i.minprocspeed AND " |
| . "c.network >= i.minnetwork AND " |
| . "c.deleted = 0 AND " |
| . "c.stateid = s.id AND " |
| . "s.name NOT IN ($ignorestates) AND "; |
| if($reqid != '') |
| $query .= "rq.id != $reqid AND "; |
| $query .= "(c.type != 'virtualmachine' OR c.vmhostid IS NOT NULL) " |
| . "GROUP BY rs.computerid"; |
| if($extendonly) |
| $query .= " HAVING start = '$startdt'"; |
| $qh = doQuery($query, 101); |
| while($row = mysql_fetch_assoc($qh)) { |
| if($usedaysahead && $row['startts'] > $daysahead) |
| continue; |
| if($row['startts'] % 900) { |
| $row['startts'] = $row['startts'] - ($row['startts'] % 900) + 900; |
| $row['start'] = unixToDatetime($row['startts']); |
| } |
| $row['endts'] = $row['startts'] + $reqduration; |
| $row['duration'] = $reqduration; |
| $slots[$row['compid']][] = $row; |
| if($row['endts'] > $maxend) |
| $maxend = $row['endts']; |
| $newcompids[] = $row['compid']; |
| } |
| if(empty($newcompids)) |
| return array(); |
| |
| # remove block computers |
| $minstartdt = unixToDatetime($minstart); |
| $maxenddt = unixToDatetime($maxend); |
| $newincompids = implode(',', $newcompids); |
| $query = "SELECT bc.computerid AS compid, " |
| . "UNIX_TIMESTAMP(bt.start) AS start, " |
| . "UNIX_TIMESTAMP(bt.end) AS end " |
| . "FROM blockComputers bc, " |
| . "blockTimes bt, " |
| . "blockRequest br " |
| . "WHERE bt.id = bc.blockTimeid AND " |
| . "br.id = bt.blockRequestid AND " |
| . "bt.skip = 0 AND " |
| . "bt.start < '$maxenddt' AND " |
| . "bt.end > '$minstartdt' AND "; |
| if($ingroups != '') |
| $query .= "(br.groupid NOT IN ($ingroups) OR " |
| . "br.imageid != $imageid) AND "; |
| $query .= "bc.computerid IN ($newincompids)"; |
| $qh = doQuery($query); |
| while($row = mysql_fetch_assoc($qh)) { |
| if(isset($slots[$row['compid']])) |
| fATremoveOverlaps($slots, $row['compid'], $row['start'], $row['end'], 0); |
| } |
| |
| # remove mac/ip overlaps |
| $newcompids = array_keys($slots); |
| $newincompids = implode(',', $newcompids); |
| if(! empty($ip) || ! empty($mac)) { |
| $query = "SELECT rs.computerid AS compid, " |
| . "UNIX_TIMESTAMP(rq.start) AS start, " |
| . "UNIX_TIMESTAMP(rq.end) AS end " |
| . "FROM serverrequest s, " |
| . "request rq, " |
| . "reservation rs " |
| . "WHERE s.requestid = rq.id AND " |
| . "rs.requestid = rq.id AND " |
| . "rq.start < '$maxenddt' AND " |
| . "rq.end > '$minstartdt' AND " |
| . "rs.computerid IN ($newincompids) AND "; |
| if($reqid != '') |
| $query .= "rq.id != $reqid AND "; |
| if(! empty($ip) && ! empty($mac)) |
| $query .= "(s.fixedIP = '$ip' OR s.fixedMAC = '$mac')"; |
| elseif(! empty($ip)) |
| $query .= "s.fixedIP = '$ip'"; |
| elseif(! empty($mac)) |
| $query .= "s.fixedIP = '$mac'"; |
| $qh = doQuery($query); |
| while($row = mysql_fetch_assoc($qh)) { |
| if(isset($slots[$row['compid']])) |
| fATremoveOverlaps($slots, $row['compid'], $row['start'], $row['end'], 0); |
| } |
| } |
| |
| # remove slots overlapping with scheduled maintenance |
| $query = "SELECT UNIX_TIMESTAMP(start) AS start, " |
| . "UNIX_TIMESTAMP(end) AS end, " |
| . "allowreservations " |
| . "FROM sitemaintenance " |
| . "WHERE start < '$maxenddt' AND " |
| . "end > '$minstartdt'"; |
| $qh = doQuery($query); |
| while($row = mysql_fetch_assoc($qh)) { |
| foreach(array_keys($slots) AS $compid) |
| fATremoveOverlaps($slots, $compid, $row['start'], $row['end'], |
| $row['allowreservations']); |
| } |
| |
| $imgdata = getImages(0, $imageid); |
| $options = array(); |
| foreach($slots AS $comp) { |
| foreach($comp AS $data) { |
| $data['duration'] = $data['duration'] - ($data['duration'] % 900); |
| if(! $extendonly) { |
| if($data['duration'] > 3600 && $data['duration'] < 7200) |
| $data['duration'] = 3600; |
| elseif($data['duration'] > 7200 && $data['duration'] < (SECINDAY * 2)) |
| $data['duration'] = $data['duration'] - ($data['duration'] % 7200); |
| elseif($data['duration'] > (SECINDAY * 2)) |
| $data['duration'] = $data['duration'] - ($data['duration'] % SECINDAY); |
| } |
| # skip computers that have no controlling management node |
| if(! findManagementNode($data['compid'], $data['start'], 'future')) |
| continue; |
| # skip slots that would cause a concurrent use violation |
| if($imgdata[$imageid]['maxconcurrent'] != NULL && |
| fATconcurrentOverlap($data['startts'], $data['duration'], $imageid, |
| $imgdata[$imageid]['maxconcurrent'], $ignorestates, |
| $extendonly, $reqid)) |
| continue; |
| if(isset($options[$data['startts']])) { |
| if($data['duration'] > $options[$data['startts']]['duration']) { |
| $options[$data['startts']]['duration'] = $data['duration']; |
| if(checkUserHasPerm('View Debug Information')) |
| $options[$data['startts']]['compid'] = $data['compid']; |
| } |
| } |
| else { |
| $options[$data['startts']] = array('start' => $data['start'], |
| 'startts' => $data['startts'], |
| 'duration' => $data['duration']); |
| if(checkUserHasPerm('View Debug Information')) |
| $options[$data['startts']]['compid'] = $data['compid']; |
| } |
| } |
| } |
| uasort($options, "sortAvailableTimesByStart"); |
| return $options; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn fATremoveOverlaps($array, $compid, $start, $end, $allowstart) |
| /// |
| /// \param $array - array of time slots - pass by reference |
| /// \param $compid - id of computer to check |
| /// \param $start - start of time period |
| /// \param $end - end of time period |
| /// \param $allowstart - whether or not $start can be within $array time slot |
| /// |
| /// \brief removes timeslots from $array that overlap with $start and $end |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function fATremoveOverlaps(&$array, $compid, $start, $end, $allowstart) { |
| foreach($array[$compid] AS $key => $data) { |
| if($data['startts'] < $end && $data['endts'] > $start) { |
| # reservation within slot |
| if($data['startts'] <= $start && $data['endts'] >= $end) { |
| if($allowstart) |
| continue; |
| $test1 = $data['duration'] - ($data['endts'] - $start) - 900; |
| $test2 = $data['duration'] - ($end - $data['startts']) - 900; |
| if($test1 < 1800 && $test2 < 1800) |
| unset($array[$compid][$key]); |
| elseif($test1 >= 1800 && $test2 < 1800) |
| $array[$compid][$key]['duration'] = $test1; |
| elseif($test1 < 1800 && $test2 >= 1800) { |
| $array[$compid][$key]['duration'] = $test2; |
| $array[$compid][$key]['startts'] = $end + 900; |
| $array[$compid][$key]['start'] = unixToDatetime($end + 900); |
| } |
| else { |
| $array[$compid][$key]['duration'] = $test1; |
| $new = array('duration' => $test2, |
| 'endts' => $end + 900 + $test2, |
| 'compid' => $compid, |
| 'start' => unixToDatetime($end + 900), |
| 'startts' => $end + 900); |
| $array[$compid][] = $new; |
| } |
| } |
| # start of reservation overlaps slot |
| elseif($data['startts'] < $start && $data['endts'] > $start) { |
| if($allowstart) |
| continue; |
| $test = $data['duration'] - ($data['endts'] - $start) - 900; |
| if($test >= 1800) |
| $array[$compid][$key]['duration'] = $test; |
| else |
| unset($array[$compid][$key]); |
| } |
| # end of reservation overlaps slot |
| elseif($data['startts'] < $end && $data['endts'] > $end) { |
| $test = $data['duration'] - ($end - $data['startts']) - 900; |
| if($test >= 1800) { |
| $array[$compid][$key]['duration'] = $test; |
| $array[$compid][$key]['startts'] = $end + 900; |
| $array[$compid][$key]['start'] = unixToDatetime($end + 900); |
| } |
| else |
| unset($array[$compid][$key]); |
| } |
| # slot within reservation |
| #if($data['startts'] >= $start && $data['endts'] <= $end) |
| else |
| unset($array[$compid][$key]); |
| } |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn fATconcurrentOverlap($start, $length, $imageid, $maxoverlap, |
| // $ignorestates, $extendonly, $reqid) |
| /// |
| /// \param $start - start time (epoch time) |
| /// \param $length - desired duration in seconds |
| /// \param $imageid - id of image |
| /// \param $maxoverlap - max allowed overlapping reservations for image |
| /// \param $ignorestates - computers with these states should be ignored |
| /// \param $extendonly - 1 if this is an extension, 0 otherwise |
| /// \param $reqid - id of request if $extendonly is 1 |
| /// |
| /// \return 1 if this would violate max concurrent use of the image, 0 if not |
| /// |
| /// \brief determines if a reservation during the specified time slot would |
| /// violate the max concurrent reservations for $imageid |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function fATconcurrentOverlap($start, $length, $imageid, $maxoverlap, |
| $ignorestates, $extendonly, $reqid) { |
| $end = $start + $length; |
| $query = "SELECT rq.start, " |
| . "rq.end " |
| . "FROM request rq, " |
| . "reservation rs, " |
| . "state s, " |
| . "computer c " |
| . "WHERE rs.requestid = rq.id AND " |
| . "rs.computerid = c.id AND " |
| . "rs.imageid = $imageid AND " |
| . "UNIX_TIMESTAMP(rq.start) < $end AND " |
| . "UNIX_TIMESTAMP(rq.end) > $start AND " |
| . "c.stateid = s.id AND " |
| . "s.name NOT IN ($ignorestates)"; |
| if($extendonly) |
| $query .= " AND rq.id != $reqid"; |
| $qh = doQuery($query); |
| if(mysql_num_rows($qh) >= $maxoverlap) |
| return 1; |
| return 0; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn sortAvailableTimesByStart($a, $b) |
| /// |
| /// \param $a - first item |
| /// \param $b - second item |
| /// |
| /// \return -1 if $a < $b, 0 if $a == $b, 1 if $a > $b |
| /// |
| /// \brief used to sort suggested times in findAvailableTimes |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function sortAvailableTimesByStart($a, $b) { |
| $ats = datetimeToUnix($a['start']); |
| $bts = datetimeToUnix($b['start']); |
| if($ats < $bts) |
| return -1; |
| if($ats > $bts) |
| return 1; |
| return 0; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getComputers($sort, $includedeleted, $compid) |
| /// |
| /// \param $sort - (optional) 1 to sort; 0 not to |
| /// \param $includedeleted = (optional) 1 to show deleted images, 0 not to |
| /// \param $compid - (optional) only get info for this computer id |
| /// |
| /// \return an array with info about the computers in the comptuer table; each |
| /// element's index is the id from the table; each element has the following |
| /// items\n |
| /// \b state - current state of the computer\n |
| /// \b stateid - id of current state\n |
| /// \b owner - unity id of owner\n |
| /// \b ownerid - user id of owner\n |
| /// \b platform - computer's platform\n |
| /// \b platformid - id of computer's platform\n |
| /// \b schedule - computer's schedule\n |
| /// \b scheduleid - id of computer's schedule\n |
| /// \b currentimg - computer's current image\n |
| /// \b currentimgid - id of computer's current image\n |
| /// \b imagerevisionid - revision id of computer's current image\n |
| /// \b nextimg - computer's next image\n |
| /// \b nextimgid - id of computer's next image\n |
| /// \b nextimg - computer's next image\n |
| /// \b nextimgid - id of computer's next image\n |
| /// \b ram - amount of RAM in computer in MB\n |
| /// \b procnumber - number of processors in computer\n |
| /// \b procspeed - speed of processor(s) in MHz\n |
| /// \b network - speed of computer's NIC\n |
| /// \b hostname - computer's hostname\n |
| /// \b IPaddress - computer's IP address\n |
| /// \b privateIPaddress - computer's private IP address\n |
| /// \b eth0macaddress - computer's eth0 mac address\n |
| /// \b eth1macaddress - computer's eth1 mac address\n |
| /// \b type - either 'blade' or 'lab' - used to determine what backend utilities\n |
| /// \b deleted - 0 or 1; whether or not this computer has been deleted\n |
| /// \b resourceid - computer's resource id from the resource table\n |
| /// \b location - computer's location\n |
| /// \b provisioningid - id of provisioning engine\n |
| /// \b provisioning - pretty name of provisioning engine\n |
| /// \b vmprofileid - if vmhost, id of vmprofile |
| /// need to be used to manage computer\n |
| /// \b natenabled - 0 or 1; if NAT is enabled for this computer\n |
| /// \b nathostid - id from nathost table if NAT is enabled or empty string if |
| /// not |
| /// |
| /// \brief builds an array of computers |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getComputers($sort=0, $includedeleted=0, $compid="") { |
| $nathosts = getNAThosts(); |
| $return = array(); |
| $query = "SELECT c.id AS id, " |
| . "st.name AS state, " |
| . "c.stateid AS stateid, " |
| . "CONCAT(u.unityid, '@', a.name) AS owner, " |
| . "u.id AS ownerid, " |
| . "p.name AS platform, " |
| . "c.platformid AS platformid, " |
| . "sc.name AS schedule, " |
| . "c.scheduleid AS scheduleid, " |
| . "cur.prettyname AS currentimg, " |
| . "c.currentimageid AS currentimgid, " |
| . "c.imagerevisionid, " |
| . "ir.revision AS imagerevision, " |
| . "next.prettyname AS nextimg, " |
| . "c.nextimageid AS nextimgid, " |
| . "c.RAM AS ram, " |
| . "c.procnumber AS procnumber, " |
| . "c.procspeed AS procspeed, " |
| . "c.network AS network, " |
| . "c.hostname AS hostname, " |
| . "c.IPaddress AS IPaddress, " |
| . "c.privateIPaddress, " |
| . "c.eth0macaddress, " |
| . "c.eth1macaddress, " |
| . "c.type AS type, " |
| . "c.deleted AS deleted, " |
| . "r.id AS resourceid, " |
| . "c.notes, " |
| . "c.vmhostid, " |
| . "c2.hostname AS vmhost, " |
| . "c2.id AS vmhostcomputerid, " |
| . "c.location, " |
| . "c.provisioningid, " |
| . "pr.prettyname AS provisioning, " |
| . "vh2.vmprofileid, " |
| . "c.predictivemoduleid, " |
| . "m.prettyname AS predictivemodule, " |
| . "nh.id AS nathostid, " |
| . "nh2.id AS nathostenabledid, " |
| . "COALESCE(nh2.publicIPaddress, '') AS natpublicIPaddress, " |
| . "COALESCE(nh2.internalIPaddress, '') AS natinternalIPaddress " |
| . "FROM state st, " |
| . "platform p, " |
| . "schedule sc, " |
| . "image cur, " |
| . "user u, " |
| . "affiliation a, " |
| . "module m, " |
| . "computer c " |
| . "LEFT JOIN resourcetype t ON (t.name = 'computer') " |
| . "LEFT JOIN resource r ON (r.resourcetypeid = t.id AND r.subid = c.id) " |
| . "LEFT JOIN vmhost vh ON (c.vmhostid = vh.id) " |
| . "LEFT JOIN vmhost vh2 ON (c.id = vh2.computerid) " |
| . "LEFT JOIN computer c2 ON (c2.id = vh.computerid) " |
| . "LEFT JOIN image next ON (c.nextimageid = next.id) " |
| . "LEFT JOIN provisioning pr ON (c.provisioningid = pr.id) " |
| . "LEFT JOIN nathostcomputermap nm ON (nm.computerid = c.id) " |
| . "LEFT JOIN nathost nh ON (nm.nathostid = nh.id) " |
| . "LEFT JOIN nathost nh2 ON (r.id = nh2.resourceid) " |
| . "LEFT JOIN imagerevision ir ON (c.imagerevisionid = ir.id) " |
| . "WHERE c.stateid = st.id AND " |
| . "c.platformid = p.id AND " |
| . "c.scheduleid = sc.id AND " |
| . "c.currentimageid = cur.id AND " |
| . "c.ownerid = u.id AND " |
| . "u.affiliationid = a.id AND " |
| . "c.predictivemoduleid = m.id "; |
| if(! $includedeleted) |
| $query .= "AND c.deleted = 0 "; |
| if(! empty($compid)) |
| $query .= "AND c.id = $compid "; |
| $query .= "ORDER BY c.hostname"; |
| $qh = doQuery($query, 180); |
| while($row = mysql_fetch_assoc($qh)) { |
| if(is_null($row['nathostid'])) { |
| $row['natenabled'] = 0; |
| $row['nathost'] = ''; |
| } |
| else { |
| $row['natenabled'] = 1; |
| $row['nathost'] = $nathosts[$row['nathostid']]['hostname']; |
| } |
| if(is_null($row['nathostenabledid'])) |
| $row['nathostenabled'] = 0; |
| else |
| $row['nathostenabled'] = 1; |
| $return[$row['id']] = $row; |
| } |
| if($sort) { |
| uasort($return, "sortComputers"); |
| } |
| return $return; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getUserComputerMetaData() |
| /// |
| /// \return an array of 2 indices - platforms, schedules - where each |
| /// index's value is an array of user's computer's data |
| /// |
| /// \brief builds an array of platforms and schedules for user's computers |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getUserComputerMetaData() { |
| $key = getKey(array('getUserComputerMetaData')); |
| if(isset($_SESSION['usersessiondata'][$key])) |
| return $_SESSION['usersessiondata'][$key]; |
| $computers = getComputers(); |
| $resources = getUserResources(array("computerAdmin"), |
| array("administer", "manageGroup"), 0, 1); |
| $return = array("platforms" => array(), |
| "schedules" => array()); |
| foreach(array_keys($resources["computer"]) as $compid) { |
| if(! array_key_exists($compid, $computers)) |
| continue; |
| if(! in_array($computers[$compid]["platform"], $return["platforms"])) |
| $return["platforms"][$computers[$compid]["platformid"]] = |
| $computers[$compid]["platform"]; |
| if(! in_array($computers[$compid]["schedule"], $return["schedules"])) |
| $return["schedules"][$computers[$compid]["scheduleid"]] = |
| $computers[$compid]["schedule"]; |
| } |
| uasort($return["platforms"], "sortKeepIndex"); |
| uasort($return["schedules"], "sortKeepIndex"); |
| $_SESSION['usersessiondata'][$key] = $return; |
| return $return; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getCompStateFlow($compid) |
| /// |
| /// \param $compid - a computer id |
| /// |
| /// \return an array of data about the flow of states for $compid; the following |
| /// keys and elements are returned:\n |
| /// \b repeatid - id from computerloadstate for the repeat state\n |
| /// \b stateids - array of computerloadstate ids for this flow in the order |
| /// they occur\n |
| /// \b nextstates - array where each key is a computerloadstate id and its value |
| /// is that state's following state; the last state has a NULL value\n |
| /// \b totaltime - estimated time (in seconds) it takes for all states to |
| /// complete\n |
| /// \b data - array where each key is is a computerloadstate id and each value |
| /// is an array with these elements:\n |
| /// \b stateid - same as key\n |
| /// \b state - name of this state\n |
| /// \b nextstateid - id of next state\n |
| /// \b nextstate - name of next state\n |
| /// \b statetime - estimated time it takes for this state to complete |
| /// |
| /// \brief gathers information about the flow of states for $compid |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getCompStateFlow($compid) { |
| $key = getKey(array($compid)); |
| if(array_key_exists($key, $_SESSION['compstateflow'])) |
| return $_SESSION['compstateflow'][$key]; |
| |
| # get id for repeat state, useful because several of the calling functions |
| # need this information |
| $query = "SELECT id FROM computerloadstate WHERE loadstatename = 'repeat'"; |
| $qh = doQuery($query, 101); |
| if(! $row = mysql_fetch_assoc($qh)) |
| return array(); |
| $loadstates['repeatid'] = $row['id']; |
| |
| $query = "SELECT `type` FROM computer WHERE id = $compid"; |
| $qh = doQuery($query, 101); |
| if(! $row = mysql_fetch_assoc($qh)) |
| return array(); |
| |
| $type = $row['type']; |
| $query = "SELECT cf.computerloadstateid AS stateid, " |
| . "cs1.prettyname AS state, " |
| . "cs1.loadstatename AS statename, " |
| . "cf.nextstateid, " |
| . "cs2.prettyname AS nextstate, " |
| . "cs1.est AS statetime " |
| . "FROM computerloadstate cs1, " |
| . "computerloadflow cf " |
| . "LEFT JOIN computerloadstate cs2 ON (cf.nextstateid = cs2.id) " |
| . "WHERE cf.computerloadstateid = cs1.id AND " |
| . "cf.type = '$type' "; |
| $query2 = $query . "AND cf.computerloadstateid NOT IN " |
| . "(SELECT nextstateid FROM computerloadflow WHERE `type` = '$type' " |
| . "AND nextstateid IS NOT NULL)"; |
| $qh = doQuery($query2, 101); |
| if(! $row = mysql_fetch_assoc($qh)) |
| return array(); |
| $loadstates['data'][$row['stateid']] = $row; |
| $loadstates['stateids'] = array($row['stateid']); |
| $loadstates['nextstates'] = array($row['stateid'] => $row['nextstateid']); |
| $loadstates['totaltime'] = 0; |
| for($i = 0; $i < 100; $i++) { # don't want an endless loop |
| $query2 = $query . "AND cf.computerloadstateid = {$row['nextstateid']} " |
| . "AND `type` = '$type'"; |
| $qh = doQuery($query2, 101); |
| if(! $row = mysql_fetch_assoc($qh)) { |
| $_SESSION['compstateflow'][$key] = $loadstates; |
| return $loadstates; |
| } |
| else { |
| array_push($loadstates['stateids'], $row['stateid']); |
| $loadstates['nextstates'][$row['stateid']] = $row['nextstateid']; |
| $loadstates['totaltime'] += $row['statetime']; |
| $loadstates['data'][$row['stateid']] = $row; |
| } |
| if(empty($row['nextstateid'])) { |
| $_SESSION['compstateflow'][$key] = $loadstates; |
| return $loadstates; |
| } |
| } |
| $_SESSION['compstateflow'][$key] = $loadstates; |
| return $loadstates; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getCompLoadLog($resid) |
| /// |
| /// \param $resid - reservation id |
| /// |
| /// \return an array where each key is an id from the computerloadlog table and |
| /// each element is an array with these items:\n |
| /// \b computerid - id of computer\n |
| /// \b loadstateid - load id of this state\n |
| /// \b ts - unix timestamp when item entered in log\n |
| /// \b time - actual time (in seconds) this state took |
| /// |
| /// \brief gets information from the computerloadlog table for $resid |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getCompLoadLog($resid) { |
| $query = "SELECT UNIX_TIMESTAMP(rq.start) AS start, " |
| . "UNIX_TIMESTAMP(rq.daterequested) AS reqtime, " |
| . "rs.computerid " |
| . "FROM request rq, " |
| . "reservation rs " |
| . "WHERE rs.id = $resid AND " |
| . "rs.requestid = rq.id " |
| . "LIMIT 1"; |
| $qh = doQuery($query, 101); |
| if(! $row = mysql_fetch_assoc($qh)) |
| abort(113); |
| if($row['start'] < $row['reqtime']) { |
| # now |
| $reqtime = $row['reqtime']; |
| $future = 0; |
| } |
| else |
| $future = 1; |
| $flow = getCompStateFlow($row['computerid']); |
| $instates = implode(',', $flow['stateids']); |
| $query = "SELECT id, " |
| . "computerid, " |
| . "loadstateid, " |
| . "UNIX_TIMESTAMP(timestamp) AS ts " |
| . "FROM computerloadlog " |
| . "WHERE reservationid = $resid AND " |
| . "(loadstateid IN ($instates) OR " |
| . "loadstateid = {$flow['repeatid']}) " |
| . "ORDER BY id"; |
| $qh = doQuery($query, 101); |
| $last = array(); |
| $data = array(); |
| while($row = mysql_fetch_assoc($qh)) { |
| $data[$row['id']] = $row; |
| if(empty($last)) { |
| if($future) |
| # just set to 10 sec for first state since we don't know when a preload started |
| $data[$row['id']]['time'] = 10; |
| else |
| $data[$row['id']]['time'] = $row['ts'] - $reqtime; |
| } |
| else |
| $data[$row['id']]['time'] = $row['ts'] - $last['ts']; |
| $last = $row; |
| } |
| return $data; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getImageLoadEstimate($imageid) |
| /// |
| /// \param $imageid - id of an image |
| /// |
| /// \return estimated time in seconds that it takes to load $imageid |
| /// |
| /// \brief determines an estimated load time (in seconds) that it takes $imageid |
| /// to load based on the last 12 months of log data |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getImageLoadEstimate($imageid) { |
| $query = "SELECT AVG(UNIX_TIMESTAMP(loaded) - UNIX_TIMESTAMP(start)) AS avgloadtime " |
| . "FROM log " |
| . "WHERE imageid = $imageid AND " |
| . "wasavailable = 1 AND " |
| . "UNIX_TIMESTAMP(loaded) - UNIX_TIMESTAMP(start) > 120 AND " |
| . "loaded > start AND " |
| . "ending != 'failed' AND " |
| . "nowfuture = 'now' AND " |
| . "start > (NOW() - INTERVAL 12 MONTH) AND " |
| . "UNIX_TIMESTAMP(loaded) - UNIX_TIMESTAMP(start) < 1800"; |
| $qh = doQuery($query, 101); |
| if($row = mysql_fetch_assoc($qh)) { |
| if(! empty($row['avgloadtime'])) |
| return (int)$row['avgloadtime']; |
| else |
| return 0; |
| } |
| else |
| return 0; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getComputerCounts(&$computers) |
| /// |
| /// \param $computers - array returned from getComputers |
| /// |
| /// \brief adds a "counts" field for each computer in $computers that is the |
| /// total number of reservations that computer has had |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getComputerCounts(&$computers) { |
| foreach(array_keys($computers) as $compid) { |
| $query = "SELECT COUNT(logid) " |
| . "FROM sublog " |
| . "WHERE computerid = $compid"; |
| $qh = doQuery($query, 101); |
| if($row = mysql_fetch_row($qh)) |
| $computers[$compid]["counts"] = $row[0]; |
| else |
| $computers[$compid]["counts"] = 0; |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn sortComputers($a, $b) |
| /// |
| /// \param $a - first input passed in by uasort |
| /// \param $b - second input passed in by uasort |
| /// |
| /// \return -1, 0, or 1 if $a < $b, $a == $b, $a > $b, respectively |
| /// |
| /// \brief determines if $a should go before or after $b |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function sortComputers($a, $b) { |
| //if somehow there are empty strings passed in, push them to the end |
| if(empty($a)) { |
| return 1; |
| } |
| if(empty($b)) { |
| return -1; |
| } |
| |
| $a['hostname'] = preg_replace('/-UNDELETED-[0-9]+$/', '', $a['hostname']); |
| $b['hostname'] = preg_replace('/-UNDELETED-[0-9]+$/', '', $b['hostname']); |
| |
| # get hostname and first part of domain name |
| $tmp = explode('.', $a["hostname"]); |
| $h1 = array_shift($tmp); |
| $domain1 = array_shift($tmp); |
| $letters1 = preg_replace('([^a-zA-Z])', '', $h1); |
| |
| $tmp = explode('.', $b["hostname"]); |
| $h2 = array_shift($tmp); |
| $domain2 = array_shift($tmp); |
| $letters2 = preg_replace('([^a-zA-Z])', '', $h2); |
| |
| // if different domain names, return based on that |
| $cmp = strcasecmp($domain1, $domain2); |
| if($cmp) { |
| return $cmp; |
| } |
| |
| // if non-numeric part is different, return based on that |
| $cmp = strcasecmp($letters1, $letters2); |
| if($cmp) { |
| return $cmp; |
| } |
| |
| // at this point, the only difference is in the numbers |
| $digits1 = preg_replace('([^\d-])', '', $h1); |
| $digits1Arr = explode('-', $digits1); |
| $digits2 = preg_replace('([^\d-])', '', $h2); |
| $digits2Arr = explode('-', $digits2); |
| |
| $len1 = count($digits1Arr); |
| $len2 = count($digits2Arr); |
| for($i = 0; $i < $len1 && $i < $len2; $i++) { |
| if($digits1Arr[$i] < $digits2Arr[$i]) { |
| return -1; |
| } |
| elseif($digits1Arr[$i] > $digits2Arr[$i]) { |
| return 1; |
| } |
| } |
| |
| return 0; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getAvailableBlockComputerids($imageid, $start, $end, $allocatedcompids) |
| /// |
| /// \param $imageid - id of an image |
| /// \param $start - starting time in unix timestamp form |
| /// \param $end - ending time in unix timestamp form |
| /// \param $allocatedcompids - array of computer ids that have already been |
| /// allocated while processing this reservation |
| /// |
| /// \return an array with the key 'compids' that is an array of available |
| /// computerids; additional keys exist for each computerid that are arrays |
| /// of block data for that computer with these keys:\n |
| /// \b start - start of block time\n |
| /// \b end - end of block time\n |
| /// \b blockid - id of block request |
| /// |
| /// \brief gets all computer ids that are part of a block allocation the logged |
| /// in user is a part of that are available between $start and $end |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getAvailableBlockComputerids($imageid, $start, $end, $allocatedcompids) { |
| global $user; |
| $data = array('compids' => array()); |
| $groupids = implode(',', array_keys($user['groups'])); |
| if(! count($user['groups'])) |
| $groupids = "''"; |
| $startdt = unixToDatetime($start); |
| $enddt = unixToDatetime($end); |
| $alloccompids = implode(",", $allocatedcompids); |
| $query = "SELECT c.computerid, " |
| . "t.start, " |
| . "t.end, " |
| . "r.id AS blockid " |
| . "FROM blockComputers c, " |
| . "blockRequest r, " |
| . "blockTimes t, " |
| . "state s, " |
| . "computer c2 " |
| . "WHERE r.groupid IN ($groupids) AND " |
| . "r.status = 'accepted' AND " |
| . "c.computerid = c2.id AND " |
| . "c2.currentimageid = $imageid AND " |
| . "r.expireTime > NOW() AND " |
| . "t.blockRequestid = r.id AND " |
| . "c.blockTimeid = t.id AND " |
| . "t.start < '$enddt' AND " |
| . "t.end > '$startdt' AND " |
| . "c2.stateid = s.id AND " |
| . "s.name != 'failed' AND " |
| . "c2.id NOT IN ($alloccompids) " |
| . "ORDER BY s.name"; |
| $qh = doQuery($query, 101); |
| while($row = mysql_fetch_assoc($qh)) { |
| $data['compids'][] = $row['computerid']; |
| $data[$row['computerid']] = $row; |
| } |
| return $data; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getUsedBlockComputerids($start, $end) |
| /// |
| /// \param $start - starting time in unix timestamp form |
| /// \param $end - ending time in unix timestamp form |
| /// |
| /// \return array of computer ids |
| /// |
| /// \brief gets a list of all computerids that are allocated to block |
| /// allocations during the given times |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getUsedBlockComputerids($start, $end) { |
| $compids = array(); |
| $startdt = unixToDatetime($start); |
| $enddt = unixToDatetime($end); |
| $query = "SELECT c.computerid " |
| . "FROM blockComputers c, " |
| . "blockTimes t " |
| . "WHERE t.end > '$startdt' AND " |
| . "t.start < '$enddt' AND " |
| . "c.blockTimeid = t.id"; |
| $qh = doQuery($query, 101); |
| while($row = mysql_fetch_assoc($qh)) { |
| array_push($compids, $row['computerid']); |
| } |
| return $compids; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getNAThosts($id=0, $sort=0) |
| /// |
| /// \param $id - (optional) only get info for this NAT host |
| /// \param $sort - (optional) 1 to sort; 0 not to |
| /// |
| /// \return an array with info about the NAT hosts; each element's index is the |
| /// id from the table; each element has the following items\n |
| /// \b hostname\n |
| /// \b publicIPaddress - IP to which users will connect |
| /// |
| /// \brief builds an array of NAT hosts |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getNAThosts($id=0, $sort=0) { |
| $nathosts = array(); |
| $query = "SELECT n.id, " |
| . "n.publicIPaddress, " |
| . "COALESCE(c.hostname, m.hostname) AS hostname " |
| . "FROM nathost n " |
| . "LEFT JOIN resource r ON (n.resourceid = r.id) " |
| . "LEFT JOIN resourcetype rt ON (r.resourcetypeid = rt.id) " |
| . "LEFT JOIN computer c ON (c.id = r.subid AND rt.name = 'computer') " |
| . "LEFT JOIN managementnode m ON (m.id = r.subid AND rt.name = 'managementnode') " |
| . "WHERE (c.deleted IS NULL OR c.deleted = 0) AND " |
| . "(m.stateid IS NULL OR m.stateid != (SELECT id FROM state WHERE name = 'deleted'))"; |
| if($id) |
| $query .= " WHERE n.id = $id"; |
| $qh = doQuery($query); |
| while($row = mysql_fetch_assoc($qh)) |
| $nathosts[$row['id']] = $row; |
| if($sort) |
| uasort($nathosts, "sortKeepIndex"); |
| return $nathosts; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getReservationNATports($resid) |
| /// |
| /// \param $resid - id of a reservation |
| /// |
| /// \return an array of arrays of NAT ports for $resid; the first level index |
| /// is the connectmethod id; the second level index is the key used for |
| /// substituting the port in the connectmethod text; each second level element |
| /// has the following items\n |
| /// \b publicport\n |
| /// \b connectmethodportid\n |
| /// \b privateport\n |
| /// \b protocol\n |
| /// \b connectmethodid |
| /// |
| /// \brief builds an array of NAT port connection method data for a reservation |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getNATports($resid) { |
| $ports = array(); |
| $query = "SELECT n.publicport, " |
| . "n.connectmethodportid, " |
| . "c.port AS privateport, " |
| . "c.protocol, " |
| . "c.connectmethodid " |
| . "FROM natport n, " |
| . "connectmethodport c " |
| . "WHERE n.connectmethodportid = c.id AND " |
| . "n.reservationid = $resid"; |
| $qh = doQuery($query); |
| while($row = mysql_fetch_assoc($qh)) |
| $ports[$row['connectmethodid']]["#Port-{$row['protocol']}-{$row['privateport']}#"] = $row; |
| return $ports; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getADdomains($addomainid=0) |
| /// |
| /// \param $addomainid - (optional) id of an AD domain |
| /// |
| /// \return array of available AD domains with the following keys:\n |
| /// \b id\n |
| /// \b resourceid\n |
| /// \b name\n |
| /// \b ownerid\n |
| /// \b owner\n |
| /// \b domaindnsname\n |
| /// \b username\n |
| /// \b dnsservers\n |
| /// \b secretid |
| /// |
| /// \brief builds an array of AD domains |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getADdomains($addomainid=0) { |
| $query = "SELECT ad.id, " |
| . "r.id AS resourceid, " |
| . "ad.name, " |
| . "ad.ownerid, " |
| . "CONCAT(u.unityid, '@', a.name) AS owner, " |
| . "ad.domainDNSName AS domaindnsname, " |
| . "ad.username, " |
| . "ad.dnsServers AS dnsservers, " |
| . "ad.secretid " |
| . "FROM addomain ad, " |
| . "affiliation a, " |
| . "user u, " |
| . "resource r, " |
| . "resourcetype rt " |
| . "WHERE ad.ownerid = u.id AND " |
| . "u.affiliationid = a.id AND " |
| . "r.subid = ad.id AND " |
| . "r.resourcetypeid = rt.id AND " |
| . "rt.name = 'addomain'"; |
| if($addomainid) |
| $query .= " AND ad.id = $addomainid"; |
| |
| $qh = doQuery($query); |
| $addomainlist = array(); |
| while($row = mysql_fetch_assoc($qh)) |
| $addomainlist[$row['id']] = $row; |
| return $addomainlist; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getBlockTimeData($start, $end) |
| /// |
| /// \param $start - (optional) start time of blockTimes to get in unix timestamp |
| /// form |
| /// \param $end - (optional) end time of blockTimes to get in unix timestamp |
| /// form |
| /// |
| /// \return an array of block allocation data where each index in a blockTime id |
| /// and the value is an array with these elements:\n |
| /// \b blockid - id of block allocation\n |
| /// \b name - name of block allocation\n |
| /// \b imageid - id of selected image\n |
| /// \b image - name of selected image\n |
| /// \b numMachines - number of machines allocated\n |
| /// \b groupid - user group associated with allocation\n |
| /// \b repeating - weekly, monthly, or list\n |
| /// \b ownerid - id from user table of the owner\n |
| /// \b managementnodeid - id of management node handling allocation\n |
| /// \b expireTime - time at which the allocation will be completely finished\n |
| /// \b timeid - id of blockTimes entry\n |
| /// \b start - dattime for starting time of block time\n |
| /// \b end - dattime for ending time of block time\n |
| /// \b unixstart - unix timestamp for starting time of block time\n |
| /// \b unixend - unix timestamp for ending time of block time\n |
| /// \b computerids - array of computer ids allocated for the block time |
| /// |
| /// \brief builds an array of block allocation data |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getBlockTimeData($start="", $end="") { |
| $return = array(); |
| $query = "SELECT r.id AS blockid, " |
| . "r.name, " |
| . "r.imageid, " |
| . "i.prettyname AS image, " |
| . "r.numMachines, " |
| . "r.groupid, " |
| . "r.repeating, " |
| . "r.ownerid, " |
| . "r.managementnodeid, " |
| . "r.expireTime, " |
| . "t.id AS timeid, " |
| . "t.start, " |
| . "t.end " |
| . "FROM blockRequest r, " |
| . "blockTimes t, " |
| . "image i " |
| . "WHERE r.id = t.blockRequestid AND " |
| . "r.status = 'accepted' AND " |
| . "r.imageid = i.id"; |
| if(! empty($start)) |
| $query .= " AND t.start < '" . unixToDatetime($end) . "'"; |
| if(! empty($end)) |
| $query .= " AND t.end > '" . unixToDatetime($start) . "'"; |
| $query .= " ORDER BY t.start, t.end"; |
| $qh = doQuery($query, 101); |
| while($row = mysql_fetch_assoc($qh)) { |
| $return[$row['timeid']] = $row; |
| $return[$row['timeid']]['unixstart'] = datetimeToUnix($row['start']); |
| $return[$row['timeid']]['unixend'] = datetimeToUnix($row['end']); |
| $return[$row['timeid']]['computerids'] = array(); |
| $query2 = "SELECT computerid " |
| . "FROM blockComputers " |
| . "WHERE blockTimeid = {$row['timeid']}"; |
| $qh2 = doQuery($query2, 101); |
| while($row2 = mysql_fetch_assoc($qh2)) |
| array_push($return[$row['timeid']]['computerids'], $row2['computerid']); |
| } |
| return $return; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn isBlockAllocationTime($compid, $ts, $blockData) |
| /// |
| /// \param $compid - a computer id |
| /// \param $ts - a timestamp |
| /// \param $blockData - an array as returned from getBlockTimeData |
| /// |
| /// \return the blockTimeid $ts falls in to if it does; 0 if it doesn't fall |
| /// into any block times |
| /// |
| /// \brief determines if $ts falls into a block time $compid is part of |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function isBlockAllocationTime($compid, $ts, $blockData) { |
| foreach(array_keys($blockData) as $timeid) { |
| if(in_array($compid, $blockData[$timeid]['computerids']) && |
| $ts >= $blockData[$timeid]['unixstart'] && |
| $ts < $blockData[$timeid]['unixend']) |
| return $timeid; |
| } |
| return 0; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn isImageBlockTimeActive($imageid) |
| /// |
| /// \param $imageid - id of an image |
| /// |
| /// \return 1 if a block time for a block allocation for $imageid has had the |
| /// processed flag set and the end time has not been reached; 0 otherwise |
| /// |
| /// \brief checks to see if a block time for $imageid has been processed but not |
| /// yet ended |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function isImageBlockTimeActive($imageid) { |
| $now = time(); |
| $nowdt = unixToDatetime($now); |
| $query = "SELECT bt.id " |
| . "FROM blockTimes bt, " |
| . "blockRequest br " |
| . "WHERE bt.blockRequestid = br.id AND " |
| . "bt.processed = 1 AND " |
| . "bt.end > '$nowdt' AND " |
| . "br.imageid = $imageid"; |
| $qh = doQuery($query, 101); |
| if($row = mysql_fetch_assoc($qh)) |
| return 1; |
| return 0; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn printSelectInput($name, $dataArr, $selectedid, $skip, $multiple, $domid, |
| /// $extra) |
| /// |
| /// \param $name - name of input element |
| /// \param $dataArr - array containing options |
| /// \param $selectedid - (optional) index of $dataArr to be initially selected; |
| /// use -1 for nothing to be selected |
| /// \param $skip - (optional) this is used if the array from getImages is passed |
| /// as $dataArr so we know to skip the 'No Image" element |
| /// \param $multiple - (optional) use this to print select input with the |
| /// multiple tag set |
| /// \param $domid - (optional) use this to pass in the javascript id to be used |
| /// for the select object |
| /// \param $extra - (optional) any extra attributes that need to be set |
| /// |
| /// \brief prints out a select input part of a form\n |
| /// it is assumed that if $selectedid is left off, we assume $dataArr has no |
| /// index '-1'\n |
| /// each OPTION's value is the index of that element of the array |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function printSelectInput($name, $dataArr, $selectedid=-1, $skip=0, $multiple=0, |
| $domid="", $extra="") { |
| print selectInputHTML($name, $dataArr, $domid, $extra, $selectedid, $skip, |
| $multiple); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn selectInputAutoDijitHTML($name, $dataArr, $domid='', $extra='', |
| /// $selectedid=-1) { |
| /// |
| /// \param $name - name of input element |
| /// \param $dataArr - array containing options |
| /// \param $domid - (optional) use this to pass in the javascript id to be used |
| /// for the select object |
| /// \param $extra - (optional) any extra attributes that need to be set |
| /// \param $selectedid - (optional) index of $dataArr to be initially selected; |
| /// use -1 for nothing to be selected |
| /// |
| /// \return html |
| /// |
| /// \brief wrapper for calling selectInputHTML with the resulting element |
| /// being a dijit.form.Select if number of items is <= 10 and being a |
| /// dijit.form.FilteringSelect if number of items is > 10 |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function selectInputAutoDijitHTML($name, $dataArr, $domid='', $extra='', |
| $selectedid=-1) { |
| if(count($dataArr) > 10 && |
| USEFILTERINGSELECT && count($dataArr) < FILTERINGSELECTTHRESHOLD) |
| $type = 'dojoType="dijit.form.FilteringSelect" queryExpr="*${0}*"'; |
| else |
| $type = 'dojoType="dijit.form.Select" maxHeight="250"'; |
| return selectInputHTML($name, $dataArr, $domid, "$type $extra", $selectedid); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn selectInputHTML($name, $dataArr, $domid, $extra, $selectedid, $skip, |
| /// $multiple) |
| /// |
| /// \param $name - name of input element |
| /// \param $dataArr - array containing options |
| /// \param $domid - (optional) use this to pass in the javascript id to be used |
| /// for the select object |
| /// \param $extra - (optional) any extra attributes that need to be set |
| /// \param $selectedid - (optional) index of $dataArr to be initially selected; |
| /// use -1 for nothing to be selected |
| /// \param $skip - (optional) this is used if the array from getImages is passed |
| /// as $dataArr so we know to skip the 'No Image" element |
| /// \param $multiple - (optional) use this to print select input with the |
| /// multiple tag set |
| /// |
| /// \brief generates HTML for select input |
| /// it is assumed that if $selectedid is left off, we assume $dataArr has no |
| /// index '-1'\n |
| /// each OPTION's value is the index of that element of the array |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function selectInputHTML($name, $dataArr, $domid="", $extra="", $selectedid=-1, |
| $skip=0, $multiple=0) { |
| $h = ''; |
| if(! empty($domid)) |
| $domid = "id=\"$domid\""; |
| if($multiple) |
| $multiple = "multiple"; |
| else |
| $multiple = ""; |
| if($name != '') |
| $h .= " <select name=$name $multiple $domid $extra>\n"; |
| else |
| $h .= " <select $multiple $domid $extra>\n"; |
| foreach(array_keys($dataArr) as $id) { |
| if(($dataArr[$id] != 0 && empty($dataArr[$id]))) |
| continue; |
| if($id == $selectedid) |
| $h .= " <option value=\"$id\" selected=\"selected\">"; |
| else |
| $h .= " <option value=\"$id\">"; |
| if(is_array($dataArr[$id])) { |
| if(array_key_exists('prettyname', $dataArr[$id])) |
| $h .= $dataArr[$id]['prettyname'] . "</option>\n"; |
| elseif(array_key_exists('name', $dataArr[$id])) |
| $h .= $dataArr[$id]['name'] . "</option>\n"; |
| elseif(array_key_exists('hostname', $dataArr[$id])) |
| $h .= $dataArr[$id]['hostname'] . "</option>\n"; |
| } |
| else |
| $h .= $dataArr[$id] . "</option>\n"; |
| } |
| $h .= " </select>\n"; |
| return $h; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn labeledFormItem($id, $label, $type, $constraints='', $required=1, |
| /// $value='', $errmsg='', $validator='', $extra=array(), |
| /// $width='', $help='', $addbr=1) { |
| /// |
| /// \param $id - dom id of form element |
| /// \param $label - text for label of element |
| /// \param $type - type of element; one of: text, textarea, spinner, select, |
| /// selectonly, check (selectonly forces dijit.form.Select rather than |
| /// possibily being dijit.form.FilteringSelect based on number of elements) |
| /// \param $constraints - (optional, default='') constraints for element; if |
| /// a select element, the array of options |
| /// \param $required - (optional, default=1) whether or not the form element is |
| /// required |
| /// \param $value - (optional, default='') initial value of form element |
| /// \param $errmsg - (optional, default='') error message; only used for text |
| /// elements |
| /// \param $validator - (optional, default='') validation function; only used |
| /// for text elements |
| /// \param $extra - (optional, default=array()) array of additional attributes |
| /// to set for the element |
| /// \param $width - (optional, default varies per element) width of element; |
| /// must include units |
| /// \param $help - (optional, default='') text to display after the form |
| /// element |
| /// \param $addbr - (optional, default=1) add an html break tag after the |
| /// element |
| /// |
| /// \return html |
| /// |
| /// \brief generates HTML form element with a preceding label tag |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function labeledFormItem($id, $label, $type, $constraints='', $required=1, |
| $value='', $errmsg='', $validator='', $extra=array(), |
| $width='', $help='', $addbr=1) { |
| if($extra == '') |
| $extra = array(); |
| $h = ''; |
| if($required) |
| $required = 'true'; |
| else |
| $required = 'false'; |
| switch($type) { |
| case 'text': |
| case 'password': |
| if($width == '') |
| $width = '300px'; |
| $h .= "<label for=\"$id\">$label:</label>\n"; |
| $h .= "<span class=\"labeledform\">\n"; |
| $h .= "<input type=\"$type\" "; |
| $h .= "dojoType=\"dijit.form.ValidationTextBox\" "; |
| $h .= "required=\"$required\" "; |
| if($constraints != '') |
| $h .= "regExp=\"$constraints\" "; |
| if($errmsg != '') |
| $h .= "invalidMessage=\"$errmsg\" "; |
| $h .= "style=\"width: $width\" "; |
| if($validator != '') |
| $h .= "validator=\"$validator\" "; |
| if($value != '') |
| $h .= "value=\"$value\" "; |
| foreach($extra as $key => $val) |
| $h .= "$key=\"$val\" "; |
| $h .= "id=\"$id\">"; |
| if($help != '') |
| $h .= $help; |
| $h .= "</span>"; |
| if($addbr) |
| $h .= "<br>"; |
| $h .= "\n"; |
| break; |
| case 'textarea': |
| if($width == '') |
| $width = '300px'; |
| $h .= "<label style=\"vertical-align: top;\" for=\"$id\">$label:</label>\n"; |
| $h .= "<span class=\"labeledform\">\n"; |
| $h .= "<textarea "; |
| $h .= "dojoType=\"dijit.form.Textarea\" "; |
| $h .= "style=\"width: $width; text-align: left;\" "; |
| foreach($extra as $key => $val) |
| $h .= "$key=\"$val\" "; |
| $h .= "id=\"$id\">"; |
| $h .= $value; |
| $h .= "</textarea>\n"; |
| if($help != '') |
| $h .= $help; |
| $h .= "</span>"; |
| if($addbr) |
| $h .= "<br>"; |
| $h .= "\n"; |
| break; |
| case 'spinner': |
| if($width == '') |
| $width = '70px'; |
| $h .= "<label for=\"$id\">$label:</label>\n"; |
| $h .= "<span class=\"labeledform\">\n"; |
| $h .= "<input dojoType=\"dijit.form.NumberSpinner\" "; |
| $h .= "required=\"$required\" "; |
| $h .= "style=\"width: $width\" "; |
| if($value !== '') |
| $h .= "value=\"$value\" "; |
| if($constraints != '') |
| $h .= "constraints=\"$constraints\" "; |
| foreach($extra as $key => $val) |
| $h .= "$key=\"$val\" "; |
| $h .= "id=\"$id\">"; |
| if($help != '') |
| $h .= $help; |
| $h .= "</span>"; |
| if($addbr) |
| $h .= "<br>"; |
| $h .= "\n"; |
| break; |
| case 'select': |
| case 'selectonly': |
| if($value == '') |
| $value = -1; |
| $h .= "<label for=\"$id\">$label:</label>\n"; |
| $h .= "<span class=\"labeledform\">\n"; |
| $flat = ''; |
| foreach($extra as $key => $val) |
| $flat .= "$key=\"$val\" "; |
| if($width != '') |
| $flat .= "style=\"width: $width;\" "; |
| if($type == 'selectonly') |
| $h .= selectInputHTML('', $constraints, $id, "dojoType=\"dijit.form.Select\" maxHeight=\"250\" $flat", $value); |
| else |
| $h .= selectInputAutoDijitHTML('', $constraints, $id, $flat, $value); |
| if($help != '') |
| $h .= $help; |
| $h .= "</span>"; |
| if($addbr) |
| $h .= "<br>"; |
| $h .= "\n"; |
| break; |
| case 'check': |
| $h .= "<label for=\"$id\">$label:</label>\n"; |
| $h .= "<span class=\"labeledform\">\n"; |
| $h .= "<input dojoType=\"dijit.form.CheckBox\" "; |
| if($value !== '') |
| $h .= "value=\"$value\" "; |
| foreach($extra as $key => $val) |
| $h .= "$key=\"$val\" "; |
| $h .= "id=\"$id\">"; |
| if($help != '') |
| $h .= $help; |
| $h .= "</span>"; |
| if($addbr) |
| $h .= "<br>"; |
| $h .= "\n"; |
| break; |
| } |
| return $h; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn dijitButton($id, $label, $onclick='', $wraprightdiv=0) |
| /// |
| /// \param $id - dom id of button |
| /// \param $label - label for button |
| /// \param $onclick - javascript function to call when clicked including |
| /// parenthesis, arguments, and semicolon |
| /// \param $wraprightdiv - (optional, default=0) set to 1 to wrap button in |
| /// a div element set to right align text |
| /// |
| /// \return html |
| /// |
| /// \brief generates HTML for a dijit button |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function dijitButton($id, $label, $onclick='', $wraprightdiv=0) { |
| $h = ''; |
| if($wraprightdiv) |
| $h .= "<div style=\"text-align: right;\">\n"; |
| $h .= "<button dojoType=\"dijit.form.Button\" id=\"$id\">\n"; |
| $h .= " $label\n"; |
| if($onclick != '') { |
| $h .= " <script type=\"dojo/method\" event=\"onClick\">\n"; |
| $h .= " $onclick\n"; |
| $h .= " </script>\n"; |
| } |
| $h .= "</button>\n"; |
| if($wraprightdiv) |
| $h .= "</div>\n"; |
| return $h; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn requestIsReady($request) |
| /// |
| /// \param $request - a request element from the array returned by |
| /// getUserRequests |
| /// |
| /// \return 1 if request is ready for a user to connect, 0 if not |
| /// |
| /// \brief checks to see if a request is |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function requestIsReady($request) { |
| foreach($request["reservations"] as $res) { |
| if($res["computerstateid"] != 3 && $res["computerstateid"] != 8) |
| return 0; |
| } |
| if(($request["currstateid"] == 14 && // request current state pending |
| $request["laststateid"] == 3 && // and last state reserved and |
| $request["computerstateid"] == 3) || // computer reserved |
| ($request["currstateid"] == 8 && // request current state inuse |
| $request["computerstateid"] == 8) || // and computer state inuse |
| ($request["currstateid"] == 29 && // request current state servermodified |
| $request["computerstateid"] == 8) || // and computer state inuse |
| ($request["currstateid"] == 29 && // request current state servermodified |
| $request["computerstateid"] == 3) || // and computer state reserved |
| ($request["currstateid"] == 14 && // request current state pending |
| $request["laststateid"] == 8 && // and last state inuse and |
| $request["computerstateid"] == 8) || // computer inuse |
| ($request["currstateid"] == 14 && // request current state pending |
| $request["laststateid"] == 8 && // and last state inuse |
| $request["computerstateid"] == 3)) { // and computer reserved |
| return 1; |
| } |
| return 0; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn printSubmitErr($errno, $index, $errorDiv) |
| /// |
| /// \param $errno - an error value, should correspond to an defined constant |
| /// \param $index - (optional) if $submitErrMsg will be an array, the index |
| /// of the element to print |
| /// \param $errorDiv - (optional, default=0), set to 1 to wrap the error in a |
| /// div with class of errormsg |
| /// |
| /// \brief if the error is set, prints the corresponding error message |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function printSubmitErr($errno, $index=0, $errorDiv=0) { |
| global $submitErr, $submitErrMsg; |
| if($submitErr & $errno) { |
| if($errorDiv) |
| print "<p class=errormsg>"; |
| if(is_array($submitErrMsg[$errno])) |
| print "<font color=red><em>{$submitErrMsg[$errno][$index]}</em></font>"; |
| else |
| print "<font color=red><em>{$submitErrMsg[$errno]}</em></font>"; |
| if($errorDiv) |
| print "</p>"; |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn printArray($array) |
| /// |
| /// \param $array - an array to print |
| /// |
| /// \brief prints out an array in HTML friendly format |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function printArray($array) { |
| print "<pre>\n"; |
| print_r($array); |
| print "</pre>\n"; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn prettyDatetime($stamp, $showyear=0, $notzoffset=0) |
| /// |
| /// \param $stamp - a timestamp in unix or mysql datetime format |
| /// \param $showyear (optional, default=0) - set to 1 to include year |
| /// \param $notzoffset (optional, default=0) - set to 1 to prevent timezone |
| /// conversion |
| /// |
| /// \return date/time in html format of [Day of week], [month] [day of month], |
| /// [HH:MM] [am/pm] |
| /// |
| /// \brief reformats the datetime to look better |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function prettyDatetime($stamp, $showyear=0, $notzoffset=0) { |
| global $locale; |
| if(! preg_match('/^[\d]+$/', $stamp)) |
| $stamp = datetimeToUnix($stamp); |
| if(! $notzoffset && isset($_SESSION['persistdata']['tzoffset'])) |
| $stamp += $_SESSION['persistdata']['tzoffset'] * 60; |
| if($showyear) |
| $return = strftime('%A, %b %-d, %Y, %l:%M %P', $stamp); |
| else |
| $return = strftime('%A, %b %-d, %l:%M %P', $stamp); |
| return $return; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn minToHourMin($min) |
| /// |
| /// \param $min - minutes |
| /// |
| /// \return a string value |
| /// |
| /// \brief um, I don't know how to describe this, just look at the code |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function minToHourMin($min) { |
| if($min < 60) |
| return $min . " " . i("minutes"); |
| elseif($min == 60) |
| return i("1 hour"); |
| elseif($min % 60 == 0) |
| return sprintf("%d " . i("hours"), $min / 60); |
| elseif($min % 30 == 0) |
| return sprintf("%.1f " . i("hours"), $min / 60); |
| else |
| return sprintf("%.2f " . i("hours"), $min / 60); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn secToMinSec($sec) |
| /// |
| /// \param $sec - seconds |
| /// |
| /// \return a string value |
| /// |
| /// \brief takes seconds and converts to min:sec |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function secToMinSec($sec) { |
| if($sec < 60) |
| return sprintf("0:%02d", $sec); |
| elseif($sec == 60) |
| return "1:00"; |
| elseif($sec % 60 == 0) |
| return sprintf("%d:00", $sec / 60); |
| else |
| return sprintf("%d:%02d", $sec / 60, $sec % 60); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn prettyLength($minutes) |
| /// |
| /// \param $minutes - a value in minutes |
| /// |
| /// \return a string in the form of [length] [units] |
| /// |
| /// \brief converts from $minutes to either "[minutes] minutes" or |
| /// "[hours] hour(s) |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function prettyLength($minutes) { |
| if($minutes < 60) |
| return (int)$minutes . " " . i("minutes"); |
| elseif($minutes == 60) |
| return i("1 hour"); |
| elseif($minutes % 60 == 0) |
| return (int)($minutes / 60) . " " . i("hours"); |
| else { |
| $hours = (int)($minutes / 60); |
| $min = (int)($minutes % 60); |
| if($hours == 1) |
| return "$hours " . i("hour") . ", $min " . i("minutes"); |
| else |
| return "$hours " . i("hours") . ", $min " . i("minutes"); |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn AJsetTZoffset() |
| /// |
| /// \brief sets tzoffset in persistdata array in session |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function AJsetTZoffset() { |
| $remtzoffset = processInputVar('offset', ARG_NUMERIC, 0) * -1; |
| if($remtzoffset > 1560 || $remtzoffset < -1560) |
| $remtzoffset = 0; |
| $defaulttz = date_default_timezone_get(); |
| $tzobj = timezone_open($defaulttz); |
| $now = date_create('now', timezone_open('UTC')); |
| $mytzoffset = timezone_offset_get($tzobj, $now) / 60; # offset in minutes |
| $diff = $remtzoffset - $mytzoffset; |
| $_SESSION['persistdata']['tzoffset'] = $remtzoffset - $mytzoffset; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn addLoadTime($imageid, $start, $loadtime) |
| /// |
| /// \param $imageid - id of loaded image |
| /// \param $start - start time in unix timestamp format |
| /// \param $loadtime - time it took to load image in seconds |
| /// |
| /// \brief adds an entry to the imageloadtimes table |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function addLoadTime($imageid, $start, $loadtime) { |
| $query = "INSERT INTO imageloadtimes " |
| . "(imageid, " |
| . "starttime, " |
| . "loadtimeseconds) " |
| . "VALUES " |
| . "($imageid, " |
| . "$start, " |
| . "$loadtime)"; |
| doQuery($query, 245); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn scheduleClosed($computerid, $timestamp, $schedule) |
| /// |
| /// \param $computerid - id of a computer |
| /// \param $timestamp - time to check |
| /// \param $schedule - an element from the array returned from getSchedules |
| /// |
| /// \return 1 if schedule is closed at $timestamp, 0 if it is open |
| /// |
| /// \brief checks to see if the computer's schedule is open or closed at |
| /// $timestamp |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function scheduleClosed($computerid, $timestamp, $schedule) { |
| $time = minuteOfWeek($timestamp); |
| foreach($schedule["times"] as $schtime) { |
| if($schtime["start"] <= $time && $time < $schtime["end"]) |
| return 0; |
| } |
| return 1; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn checkInMaintenanceForTimeTable($start, $end, $items) |
| /// |
| /// \param $start - start time in unix timestamp format |
| /// \param $end - end time in unix timestamp format |
| /// \param $items - list of maintenance items as returned by |
| /// getMaintItemsForTimeTable |
| /// |
| /// \return 1 if specified time period falls in an maintenance window, 0 if not |
| /// |
| /// \brief checks if the specified time period overlaps with a scheduled |
| /// maintenance window |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function checkInMaintenanceForTimeTable($start, $end, $items) { |
| foreach($items as $item) { |
| if($item['start'] < $end && $item['end'] > $start) |
| return 1; |
| } |
| return 0; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn updateGroups($newusergroups, $userid) |
| /// |
| /// \param $newusergroups - array of $userid's current set of user groups |
| /// \param $userid - id of user from user table |
| /// |
| /// \brief updates user's groups and adds any new ones to the group |
| /// table |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function updateGroups($newusergroups, $userid) { |
| $query = "SELECT m.usergroupid " |
| . "FROM usergroupmembers m, " |
| . "usergroup u " |
| . "WHERE m.userid = $userid AND " |
| . "m.usergroupid = u.id AND " |
| . "u.custom = 0 AND " |
| . "u.courseroll = 0"; |
| $qh = doQuery($query, 305); |
| $oldusergroups = array(); |
| while($row = mysql_fetch_row($qh)) { |
| array_push($oldusergroups, $row[0]); |
| } |
| if(count(array_diff($oldusergroups, $newusergroups)) || |
| count(array_diff($newusergroups, $oldusergroups))) { |
| $query = "DELETE m " |
| . "FROM usergroupmembers m, " |
| . "usergroup u " |
| . "WHERE m.userid = $userid AND " |
| . "m.usergroupid = u.id AND " |
| . "u.custom = 0 AND " |
| . "u.courseroll = 0"; |
| doQuery($query, 306); |
| foreach($newusergroups as $id) { |
| $query = "INSERT INTO usergroupmembers " |
| . "(userid, usergroupid) " |
| . "VALUES ($userid, $id) " |
| . "ON DUPLICATE KEY UPDATE " |
| . "userid = $userid, usergroupid = $id"; |
| doQuery($query, 307); |
| checkUpdateServerRequestGroups($id); |
| } |
| } |
| return $newusergroups; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getUserGroupID($name, $affilid, $noadd) |
| /// |
| /// \param $name - a group name |
| /// \param $affilid - (optional, defaults to DEFAULT_AFFILID) affiliation id |
| /// for $name |
| /// \param $noadd - (optional, defaults to 0) set to 1 to return NULL if group |
| /// does not exist instead of adding it to table |
| /// |
| /// \return id for $name from group table |
| /// |
| /// \brief looks up the id for $name in the group table; if the name is |
| /// not currently in the table, adds it and returns the new id |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getUserGroupID($name, $affilid=DEFAULT_AFFILID, $noadd=0) { |
| $query = "SELECT id " |
| . "FROM usergroup " |
| . "WHERE name = '$name' AND " |
| . "affiliationid = $affilid"; |
| $qh = doQuery($query, 300); |
| if($row = mysql_fetch_row($qh)) |
| return $row[0]; |
| elseif($noadd) |
| return NULL; |
| $query = "INSERT INTO usergroup " |
| . "(name, " |
| . "affiliationid, " |
| . "custom, " |
| . "courseroll) " |
| . "VALUES " |
| . "('$name', " |
| . "$affilid, " |
| . "0, " |
| . "0)"; |
| doQuery($query, 301); |
| $qh = doQuery("SELECT LAST_INSERT_ID() FROM usergroup", 302); |
| if(! $row = mysql_fetch_row($qh)) { |
| abort(303); |
| } |
| return $row[0]; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getUserGroupName($id, $incAffil) |
| /// |
| /// \param $id - id of a user group |
| /// \param $incAffil - 0 or 1 (optional, defaults to 0); include @ and |
| /// affiliation at the end |
| /// |
| /// \return name for $id from usergroup table or 0 if name not found |
| /// |
| /// \brief looks up the name for $id in the group table |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getUserGroupName($id, $incAffil=0) { |
| if($incAffil) { |
| $query = "SELECT CONCAT(u.name, '@', a.name) as name " |
| . "FROM usergroup u, " |
| . "affiliation a " |
| . "WHERE u.id = $id AND " |
| . "u.affiliationid = a.id"; |
| } |
| else { |
| $query = "SELECT name " |
| . "FROM usergroup " |
| . "WHERE id = $id"; |
| } |
| $qh = doQuery($query, 101); |
| if($row = mysql_fetch_row($qh)) |
| return $row[0]; |
| return 0; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn checkUpdateServerRequestGroups($groupid) |
| /// |
| /// \param $groupid = id of a user group |
| /// |
| /// \brief checks for any server requests with an admin or login group of |
| /// $groupid; if any exist, set request stateid to servermodified |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function checkUpdateServerRequestGroups($groupid) { |
| $query = "UPDATE request " |
| . "SET stateid = 29 " |
| . "WHERE stateid IN (3, 7, 8, 14, 16, 24, 25, 26, 27, 28) AND " |
| . "id IN " |
| . "(SELECT requestid " |
| . "FROM serverrequest " |
| . "WHERE admingroupid = $groupid OR " |
| . "logingroupid = $groupid)"; |
| doQuery($query, 101); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getMaintItems($id) |
| /// |
| /// \param $id (optional) - if specified, id of maintenance item to get info |
| /// about |
| /// |
| /// \return array of maintenance items where each id is a maintenance id and |
| /// each element is an array with these keys:\n |
| /// \b id - id of maintenance item\n |
| /// \b start - start of maintenance item (datetime)\n |
| /// \b end - end of maintenance item (datetime)\n |
| /// \b ownerid - id from user table of owner of this maintenance item\n |
| /// \b owner - unityid@affiliation of owner\n |
| /// \b created - date/time entry was created (or last modified)\n |
| /// \b reason - reason viewable by sysadmins for maintenance item\n |
| /// \b usermessage - message viewable by all users for maintenance item\n |
| /// \b informhoursahead - number of hours before start that a message will be |
| /// displayed to all site users about the upcoming maintenance\n |
| /// \b allowreservations - whether or not reservations can extend into this |
| /// maintenance window (0 or 1) |
| /// |
| /// \brief builds a list of current maintenance items and returns them |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getMaintItems($id=0) { |
| $key = getKey(array('getMaintItems', $id)); |
| if(isset($_SESSION['usersessiondata'][$key])) |
| return $_SESSION['usersessiondata'][$key]; |
| $query = "SELECT m.id, " |
| . "m.start, " |
| . "m.end, " |
| . "m.ownerid, " |
| . "CONCAT(u.unityid, '@', a.name) AS owner, " |
| . "m.created, " |
| . "m.reason, " |
| . "m.usermessage, " |
| . "m.informhoursahead, " |
| . "m.allowreservations " |
| . "FROM sitemaintenance m, " |
| . "user u, " |
| . "affiliation a " |
| . "WHERE m.ownerid = u.id AND " |
| . "u.affiliationid = a.id AND " |
| . "m.end > NOW() "; |
| if($id) |
| $query .= "AND m.id = $id "; |
| $query .= "ORDER BY m.start"; |
| $qh = doQuery($query, 101); |
| $data = array(); |
| while($row = mysql_fetch_assoc($qh)) |
| $data[$row['id']] = $row; |
| $_SESSION['usersessiondata'][$key] = $data; |
| return $data; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getMaintItemsForTimeTable($start, $end) |
| /// |
| /// \param $start - start time in unix timestamp format |
| /// \param $end - end time in unix timestamp format |
| /// |
| /// \return array of maintenance items that overlap with $start and $end where |
| /// each item has 2 keys:\n |
| /// \b start - start time in unix timestamp format\n |
| /// \b end - end time in unix timestamp format |
| /// |
| /// \brief builds a simple list of maintenance items and returns them |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getMaintItemsForTimeTable($start, $end) { |
| $key = getKey(array('getMaintItemsForTimeTable', $start, $end)); |
| if(isset($_SESSION['usersessiondata'][$key])) |
| return $_SESSION['usersessiondata'][$key]; |
| $startdt = unixToDatetime($start); |
| $enddt = unixToDatetime($end); |
| $query = "SELECT UNIX_TIMESTAMP(start - INTERVAL 30 MINUTE) AS start, " |
| . "UNIX_TIMESTAMP(end) AS end " |
| . "FROM sitemaintenance " |
| . "WHERE end > '$startdt' AND " |
| . "start < '$enddt' " |
| . "ORDER BY start"; |
| $qh = doQuery($query, 101); |
| $data = array(); |
| while($row = mysql_fetch_assoc($qh)) |
| $data[] = $row; |
| $_SESSION['usersessiondata'][$key] = $data; |
| return $data; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn unset_by_val($needle, &$haystack) |
| /// |
| /// \param $needle - value to remove from array |
| /// \param $haystack - array |
| /// |
| /// \brief removes all entries from an array having $needle as their value |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function unset_by_val($needle, &$haystack) { |
| while(($gotcha = array_search($needle,$haystack)) > -1) { |
| unset($haystack[$gotcha]); |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn sendRDPfile() |
| /// |
| /// \brief generates and uploads a rdp file to the user |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function sendRDPfile() { |
| global $user; |
| # for more info on this file, see |
| # http://dev.remotenetworktechnology.com/ts/rdpfile.htm |
| $requestid = getContinuationVar("requestid"); |
| $resid = getContinuationVar("resid"); |
| |
| $cmid = getContinuationVar('cmid'); |
| |
| $request = getRequestInfo("$requestid"); |
| if($request['stateid'] == 11 || $request['stateid'] == 12 || |
| ($request['stateid'] == 14 && |
| ($request['laststateid'] == 11 || $request['laststateid'] == 12))) { |
| $cont = addContinuationsEntry('viewRequests'); |
| header("Location: " . BASEURL . SCRIPT . "?continuation=$cont"); |
| return; |
| } |
| foreach($request["reservations"] as $res) { |
| if($res['reservationid'] == $resid) { |
| $ipaddress = $res["connectIP"]; |
| break; |
| } |
| } |
| if(empty($ipaddress)) |
| return; |
| $passwd = $request['passwds'][$resid][$user['id']]; |
| |
| $connectData = getImageConnectMethodTexts($res['imageid'], |
| $res['imagerevisionid']); |
| $natports = getNATports($resid); |
| $port = ''; |
| |
| $method = $connectData[$cmid]; |
| if(preg_match('/remote desktop/i', $method['description']) || |
| preg_match('/RDP/i', $method['description'])) { |
| # assume index 0 of ports for nat |
| if(! empty($natports) && array_key_exists($method['ports'][0]['key'], $natports[$cmid])) |
| $port = ':' . $natports[$cmid][$method['ports'][0]['key']]['publicport']; |
| else { |
| if($method['ports'][0]['key'] == '#Port-TCP-3389#' && |
| $user['rdpport'] != 3389) |
| $port = ':' . $user['rdpport']; |
| else |
| $port = ':' . $method['ports'][0]['port']; |
| } |
| } |
| |
| $width = $user["width"]; |
| $height = $user["height"]; |
| if($width == 0) { |
| $screenmode = 2; |
| $width = 1024; |
| $height = 768; |
| } |
| else |
| $screenmode = 1; |
| $bpp = $user["bpp"]; |
| if($user["audiomode"] == "none") |
| $audiomode = 2; |
| else |
| $audiomode = 0; |
| $redirectdrives = $user["mapdrives"]; |
| $redirectprinters = $user["mapprinters"]; |
| $redirectcomports = $user["mapserial"]; |
| |
| header("Content-type: application/rdp"); |
| if($request['serverrequest']) { |
| if(count($request['reservations']) == 1) |
| header("Content-Disposition: inline; filename=\"{$request['servername']}.rdp\""); |
| else |
| header("Content-Disposition: inline; filename=\"{$request['servername']}-{$res['prettyimage']}.rdp\""); |
| } |
| else |
| header("Content-Disposition: inline; filename=\"{$res['prettyimage']}.rdp\""); |
| print "screen mode id:i:$screenmode\r\n"; |
| print "desktopwidth:i:$width\r\n"; |
| print "desktopheight:i:$height\r\n"; |
| print "session bpp:i:$bpp\r\n"; |
| |
| print "winposstr:s:0,1,0,0,5000,4000\r\n"; |
| # 0: |
| # 1: use coordinates for the window position, as opposed to 3 - maximized |
| # 0: left position in client coordinates |
| # 0: top position in client coordinates |
| # 5000: width in pixels - set large to avoid scrollbars |
| # 4000: height in pixels - set large to avoid scrollbars |
| |
| print "full address:s:$ipaddress$port\r\n"; |
| print "compression:i:1\r\n"; |
| print "keyboardhook:i:2\r\n"; |
| print "audiomode:i:$audiomode\r\n"; |
| print "redirectdrives:i:$redirectdrives\r\n"; |
| print "redirectprinters:i:$redirectprinters\r\n"; |
| print "redirectcomports:i:$redirectcomports\r\n"; |
| print "redirectsmartcards:i:1\r\n"; |
| print "displayconnectionbar:i:1\r\n"; |
| print "autoreconnection enabled:i:1\r\n"; |
| if(preg_match('/(.*)@(.*)/', $user['unityid'], $matches)) |
| $userid = $matches[1]; |
| else |
| $userid = $user["unityid"]; |
| if($request['reservations'][0]['domainDNSName'] != '' && ! strlen($passwd)) |
| $userid .= "@" . $request['reservations'][0]['domainDNSName']; |
| elseif($request['reservations'][0]['OStype'] == 'windows') |
| $userid = ".\\$userid"; |
| print "username:s:$userid\r\n"; |
| print "clear password:s:$passwd\r\n"; |
| print "domain:s:\r\n"; |
| print "alternate shell:s:\r\n"; |
| print "shell working directory:s:\r\n"; |
| print "disable wallpaper:i:1\r\n"; |
| print "disable full window drag:i:1\r\n"; |
| print "disable menu anims:i:1\r\n"; |
| print "disable themes:i:0\r\n"; |
| print "disable cursor setting:i:0\r\n"; |
| print "bitmapcachepersistenable:i:1\r\n"; |
| //print "connect to console:i:1\r\n"; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn addLogEntry($nowfuture, $start, $end, $wasavailable, $imageid) |
| /// |
| /// \param $nowfuture - 'now' or 'future' |
| /// \param $start - mysql datetime for starting time |
| /// \param $end - mysql datetime for initialend and finalend |
| /// \param $wasavailable - 0 or 1, whether or not the request was available |
| /// when requested |
| /// \param $imageid - id of requested image |
| /// |
| /// \brief adds an entry to the log table |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function addLogEntry($nowfuture, $start, $end, $wasavailable, $imageid) { |
| global $user; |
| $query = "INSERT INTO log " |
| . "(userid, " |
| . "nowfuture, " |
| . "start, " |
| . "initialend, " |
| . "finalend, " |
| . "wasavailable, " |
| . "ending, " |
| . "imageid) " |
| . "VALUES " |
| . "({$user['id']}, " |
| . "'$nowfuture', " |
| . "'$start', " |
| . "'$end', " |
| . "'$end', " |
| . "$wasavailable, " |
| . "'none', " |
| . "$imageid)"; |
| $qh = doQuery($query, 260); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn addChangeLogEntry($logid, $remoteIP, $end, $start, $computerid, |
| /// $ending, $wasavailable) |
| /// |
| /// \param $logid - id matching entry in log table |
| /// \param $remoteIP - ip of remote computer (pass NULL if this isn't being |
| /// updated) |
| /// \param $end - (optional) ending time of request (mysql datetime) |
| /// \param $start - (optional) starting time of request (mysql datetime) |
| /// \param $computerid - (optional) id from computer table |
| /// \param $ending - (optional) 'deleted' or 'released' - how reservation ended |
| /// \param $wasavailable - (optional) 0 or 1 - if a newly requested time was |
| /// available; \b NOTE: pass -1 instead of NULL if you don't want this field |
| /// to be updated |
| /// |
| /// \brief adds an entry to the changelog table and updates information in |
| /// the log table |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function addChangeLogEntry($logid, $remoteIP, $end=NULL, $start=NULL, |
| $computerid=NULL, $ending=NULL, $wasavailable=-1) { |
| if($logid == 0) { |
| return; |
| } |
| $query = "SELECT computerid, " |
| . "start, " |
| . "initialend, " |
| . "remoteIP, " |
| . "wasavailable, " |
| . "ending " |
| . "FROM log " |
| . "WHERE id = $logid"; |
| $qh = doQuery($query, 265); |
| if(! $log = mysql_fetch_assoc($qh)) { |
| abort(30); |
| } |
| $log["computerid"] = array(); |
| $query = "SELECT computerid FROM sublog WHERE logid = $logid"; |
| $qh = doQuery($query, 101); |
| while($row = mysql_fetch_assoc($qh)) { |
| array_push($log["computerid"], $row["computerid"]); |
| } |
| $changed = 0; |
| |
| $query1 = "INSERT INTO changelog " |
| . "(logid, " |
| . "start, " |
| . "end, " |
| . "computerid, " |
| . "remoteIP, " |
| . "wasavailable, " |
| . "timestamp) " |
| . "VALUES " |
| . "($logid, "; |
| |
| $query2Arr = array(); |
| |
| # start |
| if($start != NULL && $start != $log["start"]) { |
| $query1 .= "'$start', "; |
| # only update start time in log table if it is in the future |
| if($wasavailable != 0 && datetimeToUnix($log['start']) > time()) |
| array_push($query2Arr, "start = '$start'"); |
| $changed = 1; |
| } |
| else { |
| $query1 .= "NULL, "; |
| } |
| |
| # end |
| if($end != NULL && $end != $log["initialend"]) { |
| $query1 .= "'$end', "; |
| if($wasavailable != 0) { |
| if(datetimeToUnix($log["start"]) > time()) |
| array_push($query2Arr, "initialend = '$end'"); |
| array_push($query2Arr, "finalend = '$end'"); |
| } |
| $changed = 1; |
| } |
| else { |
| $query1 .= "NULL, "; |
| } |
| |
| # computerid |
| if($computerid != NULL && |
| ! in_array($computerid, $log["computerid"])) { |
| $query1 .= "$computerid, "; |
| $changed = 1; |
| } |
| else { |
| $query1 .= "NULL, "; |
| } |
| |
| # remoteIP |
| if($remoteIP != NULL && $remoteIP != $log["remoteIP"]) { |
| $query1 .= "'$remoteIP', "; |
| array_push($query2Arr, "remoteIP = '$remoteIP'"); |
| $changed = 1; |
| } |
| else { |
| $query1 .= "NULL, "; |
| } |
| |
| # wasavailable |
| if($wasavailable != -1 && $wasavailable != $log["wasavailable"]) { |
| $query1 .= "$wasavailable, "; |
| array_push($query2Arr, "wasavailable = $wasavailable"); |
| $changed = 1; |
| } |
| else { |
| $query1 .= "NULL, "; |
| } |
| |
| # ending |
| if($ending != NULL && $ending != $log["ending"]) { |
| array_push($query2Arr, "ending = '$ending'"); |
| $changed = 1; |
| } |
| $query1 .= "NOW())"; |
| |
| if($changed) { |
| doQuery($query1, 266); |
| if(! empty($query2Arr)) { |
| $query2 = "UPDATE log SET " . implode(', ', $query2Arr) |
| . " WHERE id = $logid"; |
| doQuery($query2, 267); |
| } |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn addChangeLogEntryOther($logid, $data) |
| /// |
| /// \param $logid - id matching entry in log table |
| /// \param $data - data to be inserted in the other field |
| /// |
| /// \brief adds an entry to the other field in the changelog table |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function addChangeLogEntryOther($logid, $data) { |
| $data = mysql_real_escape_string($data); |
| $query = "INSERT INTO changelog " |
| . "(logid, " |
| . "timestamp, " |
| . "other) " |
| . "VALUES " |
| . "($logid, " |
| . "NOW(), " |
| . "'$data')"; |
| doQuery($query); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn addSublogEntry($logid, $imageid, $imagerevisionid, $computerid, |
| /// $mgmtnodeid, $fromblock, $blockdata) |
| /// |
| /// \param $logid - id of parent log entry |
| /// \param $imageid - id of requested image |
| /// \param $imagerevisionid - revision id of requested image |
| /// \param $computerid - assigned computer id |
| /// \param $mgmtnodeid - id of management node handling this reservation |
| /// \param $fromblock - boolean telling if this computer is from a block |
| /// allocation |
| /// \param $blockdata - if $fromblock is 1, this contains data about the block |
| /// allocation |
| /// |
| /// \brief adds an entry to the log table |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function addSublogEntry($logid, $imageid, $imagerevisionid, $computerid, |
| $mgmtnodeid, $fromblock, $blockdata) { |
| $query = "SELECT predictivemoduleid " |
| . "FROM computer " |
| . "WHERE id = $computerid"; |
| $qh = doQuery($query, 101); |
| $row = mysql_fetch_assoc($qh); |
| $predictiveid = $row['predictivemoduleid']; |
| $query = "SELECT c.type, " |
| . "v.computerid AS hostid " |
| . "FROM computer c " |
| . "LEFT JOIN vmhost v ON (c.vmhostid = v.id) " |
| . "WHERE c.id = $computerid"; |
| $qh = doQuery($query, 101); |
| $row = mysql_fetch_assoc($qh); |
| if($row['type'] == 'virtualmachine') |
| $hostcomputerid = $row['hostid']; |
| else |
| $hostcomputerid = 'NULL'; |
| $query = "INSERT INTO sublog " |
| . "(logid, " |
| . "imageid, " |
| . "imagerevisionid, " |
| . "computerid, " |
| . "managementnodeid, " |
| . "predictivemoduleid, "; |
| if($fromblock) { |
| $query .= "blockRequestid, " |
| . "blockStart, " |
| . "blockEnd, "; |
| } |
| $query .= "hostcomputerid) " |
| . "VALUES " |
| . "($logid, " |
| . "$imageid, " |
| . "$imagerevisionid, " |
| . "$computerid, " |
| . "$mgmtnodeid, " |
| . "$predictiveid, "; |
| if($fromblock) { |
| $query .= "{$blockdata['blockid']}, " |
| . "'{$blockdata['start']}', " |
| . "'{$blockdata['end']}', "; |
| } |
| $query .= "$hostcomputerid)"; |
| doQuery($query, 101); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getTypes($subtype) |
| /// |
| /// \param $subtype - (optional) "users", "resources", or "both" |
| /// |
| /// \return an array with 2 indexes: users and resources, each of which is an |
| /// array of those types |
| /// |
| /// \brief returns an array of arrays of types |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getTypes($subtype="both") { |
| $types = array("users" => array(), |
| "resources" => array()); |
| if($subtype == "users" || $subtype == "both") { |
| $query = "SELECT id, name FROM userprivtype WHERE name NOT IN ('configAdmin', 'serverProfileAdmin')"; |
| $qh = doQuery($query, 365); |
| while($row = mysql_fetch_assoc($qh)) { |
| if($row["name"] == "block" || $row["name"] == "cascade") |
| continue; |
| $types["users"][$row["id"]] = $row["name"]; |
| } |
| } |
| if($subtype == "resources" || $subtype == "both") { |
| $query = "SELECT id, name FROM resourcetype"; |
| $qh = doQuery($query, 366); |
| while($row = mysql_fetch_assoc($qh)) |
| $types["resources"][$row["id"]] = $row["name"]; |
| } |
| return $types; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getUserPrivTypeID($type) |
| /// |
| /// \param $type - type name |
| /// |
| /// \return id of $type |
| /// |
| /// \brief looks up the id for $type in the userprivtype table |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getUserPrivTypeID($type) { |
| $query = "SELECT id FROM userprivtype WHERE name = '$type'"; |
| $qh = doQuery($query, 370); |
| if($row = mysql_fetch_row($qh)) |
| return $row[0]; |
| else |
| return NULL; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getUserMaxTimes($uid) |
| /// |
| /// \param $uid - (optional) user's unityid or user table id |
| /// |
| /// \return max time in minutes that the user can checkout a reservation |
| /// |
| /// \brief looks through all of the user's groups to find the max checkout time |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getUserMaxTimes($uid=0) { |
| global $user; |
| $return = array("initial" => 0, |
| "total" => 0, |
| "extend" => 0); |
| if($uid == 0) |
| $groupids = array_keys($user["groups"]); |
| else { |
| $groupids = array_keys(getUsersGroups($uid, 1)); |
| } |
| if(! count($groupids)) |
| array_push($groupids, getUserGroupID(DEFAULTGROUP)); |
| |
| |
| $allgroups = getUserGroups(); |
| foreach($groupids as $id) { |
| if($return["initial"] < $allgroups[$id]["initialmaxtime"]) |
| $return["initial"] = $allgroups[$id]["initialmaxtime"]; |
| if($return["total"] < $allgroups[$id]["totalmaxtime"]) |
| $return["total"] = $allgroups[$id]["totalmaxtime"]; |
| if($return["extend"] < $allgroups[$id]["maxextendtime"]) |
| $return["extend"] = $allgroups[$id]["maxextendtime"]; |
| } |
| return $return; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getReservationLengths($max) |
| /// |
| /// \param $max - max allowed length in minutes |
| /// |
| /// \return array of lengths up to $max starting with 30 minutes, 1 hour, |
| /// 2 hours, then increasing by 2 hours up to 47 hours, then 2 days, then |
| /// increasing by 1 day; indexes are the duration in minutes |
| /// |
| /// \brief generates an array of reservation lengths |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getReservationLengths($max) { |
| $lengths = array(); |
| if($max >= 30) |
| $lengths["30"] = "30 " . i("minutes"); |
| if($max >= 45) |
| $lengths["45"] = "45 " . i("minutes"); |
| if($max >= 60) |
| $lengths["60"] = i("1 hour"); |
| for($i = 120; $i <= $max && $i < 2880; $i += 120) |
| $lengths[$i] = $i / 60 . " " . i("hours"); |
| for($i = 2880; $i <= $max && $i <= 64800; $i += 1440) |
| $lengths[$i] = $i / 1440 . " " . i("days"); |
| for($i = 70560; $i <= $max; $i += 10080) |
| $lengths[$i] = $i / 10080 . " " . i("weeks"); |
| return $lengths; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getReservationLength($length) |
| /// |
| /// \param $length - reservation length to convert (in minutes) |
| /// |
| /// \return human readable reservation length |
| /// |
| /// \brief converts minutes to "## minutes", "## hours", or "## days" |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getReservationLength($length) { |
| if($length < 60) |
| return ($length % 60) - ($length % 60 % 15) . " " . i("minutes"); |
| if($length < 120) |
| return i("1 hour"); |
| if($length < 2880) |
| return intval($length / 60) . " " . i("hours"); |
| if($length < 64800) |
| return intval($length / 1440) . " " . i("days"); |
| return intval($length / 10080) . " " . i("weeks"); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getReservationExtenstion($length) |
| /// |
| /// \param $length - reservation extension length to convert (in minutes) |
| /// |
| /// \return human readable reservation extension length |
| /// |
| /// \brief converts minutes to "## minutes", "## hours", or "## days" |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getReservationExtenstion($length) { |
| if($length < 60) |
| return ($length % 60) - ($length % 60 % 15) . " " . i("minutes"); |
| if($length < 75) |
| return i("1 hour"); |
| if($length < 120) { |
| $min = ($length % 60) - ($length % 60 % 15); |
| return sprintf('%d:%02d ' . i('hours'), intval($length / 60), $min); |
| } |
| if($length < 2880) |
| return intval($length / 60) . " " . i("hours"); |
| if($length < 64800) |
| return intval($length / 1440) . " " . i("days"); |
| return intval($length / 10080) . " " . i("weeks"); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getReservationLengthCeiling($length) |
| /// |
| /// \param $length - a length in minutes |
| /// |
| /// \return a length in minutes |
| /// |
| /// \brief gets nearest, higher length that would be in array returned by |
| /// getReservationLengths |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getReservationLengthCeiling($length) { |
| if($length < 30) |
| return 30; |
| if($length < 45) |
| return 45; |
| if($length < 60) |
| return 60; |
| if($length < 2880) { |
| for($i = 120; $i < 2880; $i += 120) { |
| if($length < $i) |
| return $i; |
| } |
| } |
| for($i = 2880; $i <= 64800; $i += 1440) { |
| if($length < $i) |
| return $i; |
| } |
| for($i = 70560; $i <= 201600; $i += 10080) { |
| if($length < $i) |
| return $i; |
| } |
| return 201600; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getResourceGroupID($groupname) |
| /// |
| /// \param $groupname - resource group name of the form type/name |
| /// |
| /// \return id of the group |
| /// |
| /// \brief gets the id from the resourcegroup table for $groupname |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getResourceGroupID($groupname) { |
| list($type, $name) = explode('/', $groupname); |
| $type = mysql_real_escape_string($type); |
| $name = mysql_real_escape_string($name); |
| $query = "SELECT g.id " |
| . "FROM resourcegroup g, " |
| . "resourcetype t " |
| . "WHERE g.name = '$name' AND " |
| . "t.name = '$type' AND " |
| . "g.resourcetypeid = t.id"; |
| $qh = doQuery($query, 371); |
| if($row = mysql_fetch_row($qh)) |
| return $row[0]; |
| else |
| return NULL; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getResourceGroupName($groupid) |
| /// |
| /// \param $groupid - resource group id |
| /// |
| /// \return name of the group |
| /// |
| /// \brief gets the name of a resource group from the resourcegroup table for |
| /// $id |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getResourceGroupName($groupid) { |
| $query = "SELECT name " |
| . "FROM resourcegroup " |
| . "WHERE id = $groupid"; |
| $qh = doQuery($query); |
| if($row = mysql_fetch_assoc($qh)) |
| return $row['name']; |
| else |
| return NULL; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getResourceTypeID($name) |
| /// |
| /// \param $name - name of resource type |
| /// |
| /// \return id of the resource type |
| /// |
| /// \brief gets the id from the resourcetype table for $name |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getResourceTypeID($name) { |
| $name = mysql_real_escape_string($name); |
| $query = "SELECT id " |
| . "FROM resourcetype " |
| . "WHERE name = '$name'"; |
| $qh = doQuery($query, 101); |
| if($row = mysql_fetch_row($qh)) |
| return $row[0]; |
| else |
| return NULL; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getResourcePrivs() |
| /// |
| /// \return an array of resource privileges |
| /// |
| /// \brief gets the availabe resource privileges as defined in the resourcepriv |
| /// table |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getResourcePrivs() { |
| $query = "show columns from resourcepriv where field = 'type'"; |
| $qh = doQuery($query, 101); |
| $row = mysql_fetch_assoc($qh); |
| preg_match("/^enum\(([a-zA-Z0-9,']+)\)$/", $row['Type'], $matches); |
| $tmp = str_replace("'", '', $matches[1]); |
| return explode(',', $tmp); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getConfigTypes() |
| /// |
| /// \return array of config types where each key is the id of the type and each |
| /// value is the prettyname of the type |
| /// |
| /// \brief gets ids and names from configtype table |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getConfigTypes() { |
| $query = "SELECT id, prettyname FROM configtype ORDER BY name"; |
| $qh = doQuery($query); |
| $types = array(); |
| while($row = mysql_fetch_assoc($qh)) |
| $types[$row['id']] = $row['prettyname']; |
| return $types; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getConfigDataTypes() |
| /// |
| /// \return array of config data types where each key is the id of the data type |
| /// and each value is the name of the data type |
| /// |
| /// \brief gets ids and names from datatype table |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getConfigDataTypes() { |
| $query = "SELECT id, name FROM datatype ORDER BY name"; |
| $qh = doQuery($query); |
| $types = array(); |
| while($row = mysql_fetch_assoc($qh)) |
| $types[$row['id']] = $row['name']; |
| return $types; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getConfigMapTypes($skipreservation=0) |
| /// |
| /// \param $skipreservation - (optional, default=0) pass 1 to skip the |
| /// 'reservation' config map type |
| /// |
| /// \return array of config map types where each key is the id of the map type |
| /// and each value is the name of the map type |
| /// |
| /// \brief gets ids and names from configmaptype table |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getConfigMapTypes($skipreservation=0) { |
| $query = "SELECT id, prettyname FROM configmaptype "; |
| if($skipreservation) |
| $query .= "WHERE name != 'reservation' "; |
| $query .= "ORDER BY prettyname"; |
| $qh = doQuery($query); |
| $types = array(); |
| while($row = mysql_fetch_assoc($qh)) |
| $types[$row['id']] = $row['prettyname']; |
| return $types; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getMappedConfigs($imageid) |
| /// |
| /// \param $imageid - id of an image |
| /// |
| /// \return array of configs |
| /// |
| /// \brief generates an array of configs mapped to an image, including configs |
| /// mapped to any sub images |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getMappedConfigs($imageid) { |
| global $user; |
| $imgdata = getImages(0, $imageid); |
| $query = "SELECT cm.id, " |
| . "cmt.prettyname AS configmaptype, " |
| . "c.id AS configid, " |
| . "c.name AS config, " |
| . "c.data AS configdata, " |
| . "c.ownerid, " |
| . "CONCAT(u.unityid, '@', ua.name) AS owner, " |
| . "c.configtypeid, " |
| . "ct.prettyname AS configtype, " |
| . "c.optional, " |
| . "cm.configmaptypeid, " |
| . "cm.subid, " |
| . "cm.affiliationid, " |
| . "a.name AS affiliation, " |
| . "cm.configstageid, " |
| . "cs.name AS configstage, " |
| . "csi.imageid AS subimageid, " |
| . "csi.id AS configsubimageid, " |
| . "cm.disabled " |
| . "FROM configmap cm, " |
| . "config c " |
| . "LEFT JOIN configsubimage csi ON (c.id = csi.configid), " |
| . "user u, " |
| . "affiliation ua, " |
| . "configtype ct, " |
| . "configmaptype cmt, " |
| . "affiliation a, " |
| . "configstage cs " |
| . "WHERE cm.configid = c.id AND " |
| . "c.ownerid = u.id AND " |
| . "u.affiliationid = ua.id AND " |
| . "c.configtypeid = ct.id AND " |
| . "cm.configmaptypeid = cmt.id AND " |
| . "cm.affiliationid = a.id AND " |
| . "(cm.affiliationid = {$user['affiliationid']} OR " |
| . "a.name = 'Global') AND " |
| . "cm.configstageid = cs.id AND " |
| . "((cmt.name = 'image' AND " |
| . "cm.subid = $imageid) OR " |
| . "(cmt.name = 'OStype' AND " |
| . "cm.subid = {$imgdata[$imageid]['ostypeid']}) OR " |
| . "(cmt.name = 'OS' AND " |
| . "cm.subid = {$imgdata[$imageid]['osid']}))"; |
| $qh = doQuery($query); |
| $configs = array(); |
| $configids = array(); |
| while($row = mysql_fetch_assoc($qh)) { |
| $row['configmapid'] = $row['id']; |
| if(is_null($row['subimageid'])) |
| $configids[] = $row['configid']; |
| if($row['configtype'] == 'Cluster') { |
| $row['id'] = "{$row['id']}-{$row['configsubimageid']}"; |
| $row['cluster'] = 1; |
| } |
| else |
| $row['cluster'] = 0; |
| $row['configdata'] = htmlspecialchars($row['configdata']); |
| $row['optional'] = (int)$row['optional']; |
| $row['applied'] = true; |
| $row['disabled'] = (int)$row['disabled']; |
| $row['id'] = "0/{$row['id']}"; |
| $configs[$row['id']] = $row; |
| if($row['configtype'] == 'Cluster') { |
| $subconfigs = getMappedSubConfigs(0, $row['configsubimageid'], $row['subimageid']); |
| #printArray($subconfigs); |
| #$configs = array_merge($configs, $subconfigs); |
| $configs = $configs + $subconfigs; |
| } |
| } |
| if(! empty($configids)) { |
| $subconfigs = getMappedSubConfigs(1, $configids, 0); |
| #printArray($subconfigs); |
| #$configs = array_merge($configs, $subconfigs); |
| $configs = $configs + $subconfigs; |
| } |
| return $configs; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getMappedSubConfigs($mode, $arg1, $arg2, $rec) |
| /// |
| /// \param $mode - 0 for subimages, 1 for subconfigs |
| /// \param $arg1 - for subimages, config subimage id; for subconfigs, array of |
| /// configmap subids |
| /// \param $arg2 - for subimages, image id; for subconfigs, search id (TODO?) |
| /// \param $rec - always pass 0; used by function for recursive calls to itself |
| /// |
| /// \return array of sub configs mapped to image |
| /// |
| /// \brief generates array of configs mapped to sub images |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getMappedSubConfigs($mode, $arg1, $arg2, $rec=0) { |
| # $mode - 0: subimages, 1: subconfigs |
| global $user; |
| if($mode == 0) { |
| $configsubimageid = $arg1; |
| $imageid = $arg2; |
| $imgdata = getImages(0, $imageid); |
| } |
| else { |
| $inlist = implode(',', $arg1); |
| $searchid = $arg2; |
| } |
| $query = "SELECT cm.id, " |
| . "cmt.prettyname AS configmaptype, " |
| . "c.id AS configid, " |
| . "c.name AS config, " |
| . "c.data AS configdata, " |
| . "c.ownerid, " |
| . "CONCAT(u.unityid, '@', ua.name) AS owner, " |
| . "c.configtypeid, " |
| . "ct.prettyname AS configtype, " |
| . "c.optional, " |
| . "cm.configmaptypeid, " |
| . "cm.subid, " |
| . "cm.affiliationid, " |
| . "a.name AS affiliation, " |
| . "cm.configstageid, " |
| . "cs.name AS configstage, " |
| . "csi.imageid AS subimageid, " |
| . "csi.id AS configsubimageid, " |
| . "cm.disabled " |
| . "FROM configmap cm, " |
| . "config c " |
| . "LEFT JOIN configsubimage csi ON (c.id = csi.configid), " |
| . "user u, " |
| . "affiliation ua, " |
| . "configtype ct, " |
| . "configmaptype cmt, " |
| . "affiliation a, " |
| . "configstage cs " |
| . "WHERE cm.configid = c.id AND " |
| . "c.ownerid = u.id AND " |
| . "u.affiliationid = ua.id AND " |
| . "c.configtypeid = ct.id AND " |
| . "cm.configmaptypeid = cmt.id AND " |
| . "cm.affiliationid = a.id AND " |
| . "(cm.affiliationid = {$user['affiliationid']} OR " |
| . "a.name = 'Global') AND " |
| . "cm.configstageid = cs.id AND "; |
| if($mode) { |
| $query .= "cmt.name = 'config' AND " |
| . " cm.subid IN ($inlist)"; |
| } |
| else { |
| $query .= "((cmt.name = 'configsubimage' AND " |
| . " cm.subid = $configsubimageid) OR " |
| . " (cmt.name = 'OStype' AND " |
| . " cm.subid = {$imgdata[$imageid]['ostypeid']}) OR " |
| . " (cmt.name = 'OS' AND " |
| . " cm.subid = {$imgdata[$imageid]['osid']}))"; |
| } |
| $qh = doQuery($query); |
| $configs = array(); |
| $configids = array(); |
| while($row = mysql_fetch_assoc($qh)) { |
| $row['configmapid'] = $row['id']; |
| if(is_null($row['subimageid'])) |
| $configids[] = $row['configid']; |
| if($row['configtype'] == 'Cluster') { |
| $row['id'] = "{$row['id']}-{$row['configsubimageid']}"; |
| $row['cluster'] = 1; |
| } |
| else |
| $row['cluster'] = 0; |
| $row['configdata'] = htmlspecialchars($row['configdata']); |
| $row['optional'] = (int)$row['optional']; |
| $row['applied'] = true; |
| $row['disabled'] = (int)$row['disabled']; |
| if($mode == 0) |
| $row['id'] = "$configsubimageid/{$row['id']}"; |
| else |
| $row['id'] = "$searchid/{$row['id']}"; |
| $configs[$row['id']] = $row; |
| if($rec < 20 && $row['configtype'] == 'Cluster') { |
| $subconfigs = getMappedSubConfigs(0, $row['configsubimageid'], $row['subimageid'], ++$rec); |
| $configs = $configs + $subconfigs; |
| } |
| } |
| if($rec < 20 && ! empty($configids)) { |
| if($mode == 0) |
| $subconfigs = getMappedSubConfigs(1, $configids, $configsubimageid, ++$rec); |
| else |
| $subconfigs = getMappedSubConfigs(1, $configids, $searchid, ++$rec); |
| $configs = $configs + $subconfigs; |
| } |
| return $configs; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getImageConfigVariables($configs) |
| /// |
| /// \param $configs - array of configs |
| /// |
| /// \return array of config variables for $configs |
| /// |
| /// \brief builds array of config variables that corespond to $configs |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getImageConfigVariables($configs) { |
| if(empty($configs)) |
| return array(); |
| $configids = array(); |
| foreach($configs as $config) |
| $configids[] = $config['configid']; |
| $inlist = implode(',', $configids); |
| $query = "SELECT cv.id, " |
| . "cv.name, " |
| . "cv.description, " |
| . "cv.configid, " |
| . "cv.`type`, " |
| . "d.name AS datatype, " |
| . "cv.datatypeid, " |
| . "cv.defaultvalue, " |
| . "cv.required, " |
| . "cv.identifier, " |
| . "cv.ask " |
| . "FROM configvariable cv, " |
| . "datatype d " |
| . "WHERE cv.datatypeid = d.id AND " |
| . "cv.configid IN ($inlist) " |
| . "ORDER BY cv.configid"; |
| $data = array(); |
| $qh = doQuery($query); |
| while($row = mysql_fetch_assoc($qh)) { |
| $row['required'] = (int)$row['required']; |
| $row['ask'] = (int)$row['ask']; |
| #$row['defaultvalue'] = htmlspecialchars($row['defaultvalue']); |
| $row['identifier'] = htmlspecialchars($row['identifier']); |
| if(! array_key_exists($row['configid'], $data)) |
| $data[$row['configid']] = array(); |
| $data[$row['configid']][] = $row; |
| } |
| $vars = array(); |
| foreach($configs as $config) { |
| if(array_key_exists($config['configid'], $data)) { |
| foreach($data[$config['configid']] as $var) { |
| $var['id'] = "{$config['id']}/{$var['id']}"; |
| $vars[$var['id']] = $var; |
| } |
| } |
| } |
| return $vars; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getConfigClusters($imageid, $flat=0) |
| /// |
| /// \param $imageid - id of image |
| /// \param $flat - (optional, default=0) pass 1 to return a flat array instead |
| /// of a hierarchical array |
| /// |
| /// \return array of cluster information |
| /// |
| /// \brief builds an array of data of configs related to subimages assigned to |
| /// an image |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getConfigClusters($imageid, $flat=0) { |
| global $user; |
| $query = "SELECT csi.id, " |
| . "c.name, " |
| . "cmt.name AS maptype, " |
| . "cm.subid AS parentimageid, " |
| . "csi.imageid AS childimageid, " |
| . "csi.id AS configsubimageid, " |
| . "i.prettyname AS image, " |
| . "i.OSid AS osid, " |
| . "ot.id AS ostypeid, " |
| . "csi.mininstance, " |
| . "csi.maxinstance " |
| . "FROM config c, " |
| . "configtype ct, " |
| . "configmap cm, " |
| . "configmaptype cmt, " |
| . "configsubimage csi, " |
| . "image i, " |
| . "OS o, " |
| . "OStype ot, " |
| . "affiliation a " |
| . "WHERE ct.name = 'cluster' AND " |
| . "c.configtypeid = ct.id AND " |
| . "cm.configid = c.id AND " |
| . "cm.configmaptypeid = cmt.id AND " |
| . "cmt.name = 'image' AND " |
| . "cm.subid = $imageid AND " |
| . "csi.imageid = i.id AND " |
| . "i.OSid = o.id AND " |
| . "o.type = ot.name AND " |
| . "csi.configid = c.id AND " |
| . "cm.affiliationid = a.id AND " |
| . "(cm.affiliationid = {$user['affiliationid']} OR " |
| . "a.name = 'Global')"; |
| $qh = doQuery($query); |
| $clusters = array(); |
| $subimageids = array(); |
| while($row = mysql_fetch_assoc($qh)) { |
| $children = getConfigClustersRec($row['configsubimageid'], $flat); |
| if(! empty($children)) { |
| if($flat) |
| $clusters = array_merge($clusters, $children); |
| else |
| $row['children'] = $children; |
| } |
| $clusters[] = $row; |
| } |
| return $clusters; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getConfigClustersRec($subimageid, $flat, $rec=0) |
| /// |
| /// \param $subimageid - id of sub image |
| /// \param $flat - pass 1 to return a flat array instead of a hierarchical array |
| /// \param $rec - recursion count |
| /// |
| /// \return array of cluster information |
| /// |
| /// \brief recursive helper function for getConfigClusters |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getConfigClustersRec($subimageid, $flat, $rec=0) { |
| global $user; |
| $query = "SELECT csi.id, " |
| . "c.name, " |
| . "cmt.name AS maptype, " |
| . "cm.subid AS parentsubimageid, " |
| . "csi.imageid AS childimageid, " |
| . "csi.id AS configsubimageid, " |
| . "i.prettyname AS image, " |
| . "i.OSid AS osid, " |
| . "ot.id AS ostypeid, " |
| . "csi.mininstance, " |
| . "csi.maxinstance " |
| . "FROM config c, " |
| . "configtype ct, " |
| . "configmap cm, " |
| . "configmaptype cmt, " |
| . "configsubimage csi, " |
| . "image i, " |
| . "OS o, " |
| . "OStype ot, " |
| . "affiliation a " |
| . "WHERE ct.name = 'cluster' AND " |
| . "c.configtypeid = ct.id AND " |
| . "cm.configid = c.id AND " |
| . "cm.configmaptypeid = cmt.id AND " |
| . "cmt.name = 'configsubimage' AND " |
| . "cm.subid = $subimageid AND " |
| . "csi.imageid = i.id AND " |
| . "i.OSid = o.id AND " |
| . "o.type = ot.name AND " |
| . "csi.configid = c.id AND " |
| . "cm.affiliationid = a.id AND " |
| . "(cm.affiliationid = {$user['affiliationid']} OR " |
| . "a.name = 'Global')"; |
| $qh = doQuery($query); |
| $clusters = array(); |
| while($row = mysql_fetch_assoc($qh)) { |
| if($rec < 20) |
| $children = getConfigClustersRec($row['configsubimageid'], $flat, ++$rec); |
| if($rec < 20 && ! empty($children)) { |
| if($flat) |
| $clusters = array_merge($clusters, $children); |
| else |
| $row['children'] = $children; |
| } |
| $clusters[] = $row; |
| } |
| return $clusters; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getOStypes() |
| /// |
| /// \return array of OS types where each key is the id of an OStype and each |
| /// value is the name |
| /// |
| /// \brief gets data from the OStype table ordered by name |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getOStypes() { |
| $query = "SELECT id, name FROM OStype ORDER BY name"; |
| $qh = doQuery($query); |
| $types = array(); |
| while($row = mysql_fetch_assoc($qh)) |
| $types[$row['id']] = $row['name']; |
| return $types; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getConfigSubimages($configs) |
| /// |
| /// \param $configs - array of configs |
| /// |
| /// \return array of config subimages for $configs |
| /// |
| /// \brief builds array of config information related to subimages of $configs |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getConfigSubimages($configs) { |
| if(empty($configs)) |
| return array(); |
| $inlist = implode(',', array_keys($configs)); |
| $query = "SELECT cs.id, " |
| . "CONCAT(c.name, ' - ', i.prettyname) AS name " |
| . "FROM config c, " |
| . "configtype ct, " |
| . "configsubimage cs, " |
| . "image i " |
| . "WHERE ct.name = 'cluster' AND " |
| . "c.configtypeid = ct.id AND " |
| . "cs.configid = c.id AND " |
| . "cs.imageid = i.id AND " |
| . "c.id IN ($inlist)"; |
| $configs = array(); |
| $qh = doQuery($query); |
| while($row = mysql_fetch_assoc($qh)) |
| $configs[$row['id']] = $row['name']; |
| return $configs; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getNodeInfo($nodeid) |
| /// |
| /// \param $nodeid - an id from the privnode table |
| /// |
| /// \return an array of the node's name and parent or NULL if node not found |
| /// |
| /// \brief gets $nodeid's name and parent and sticks it in an array |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getNodeInfo($nodeid) { |
| global $cache; |
| if(! isset($cache['nodes'])) |
| $cache['nodes'] = array(); |
| if(isset($cache['nodes'][$nodeid])) |
| return $cache['nodes'][$nodeid]; |
| $qh = doQuery("SELECT id, parent, name FROM privnode", 330); |
| while($row = mysql_fetch_assoc($qh)) |
| $cache['nodes'][$row['id']] = $row; |
| if(isset($cache['nodes'][$nodeid])) |
| return $cache['nodes'][$nodeid]; |
| else |
| return NULL; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getNodePath($nodeid) |
| /// |
| /// \param $nodeid - an id from the privnode table |
| /// |
| /// \return string containing node and all of its parents of the form:\n |
| /// VCL > node1 > node2 > node3 |
| /// |
| /// \brief gets the full path of a node |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getNodePath($nodeid) { |
| global $cache; |
| getNodeInfo($nodeid); |
| $path = ''; |
| do { |
| $parent = $cache['nodes'][$nodeid]['parent']; |
| if($path == '') |
| $path = $cache['nodes'][$nodeid]['name']; |
| else |
| $path = "{$cache['nodes'][$nodeid]['name']} > $path"; |
| $nodeid = $parent; |
| } while($parent != DEFAULT_PRIVNODE); |
| return $path; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn sortKeepIndex($a, $b) |
| /// |
| /// \param $a - first item |
| /// \param $b - second item |
| /// |
| /// \return -1 if $a < $b, 0 if $a == $b, 1 if $a > $b |
| /// |
| /// \brief this is just a normal sort, but it is for calling with uasort so |
| /// we don't lose our indices |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function sortKeepIndex($a, $b) { |
| if(is_array($a)) { |
| if(array_key_exists("prettyname", $a)) { |
| if(preg_match('/[0-9]-[0-9]/', $a['prettyname']) || |
| preg_match('/\.edu$|\.com$|\.net$|\.org$/', $a['prettyname']) || |
| preg_match('/[0-9]-[0-9]/', $b['prettyname']) || |
| preg_match('/\.edu$|\.com$|\.net$|\.org$/', $b['prettyname'])) |
| return compareDashedNumbers($a["prettyname"], $b["prettyname"]); |
| return strcasecmp($a["prettyname"], $b["prettyname"]); |
| } |
| elseif(array_key_exists("name", $a)) { |
| if(preg_match('/[0-9]-[0-9]/', $a['name']) || |
| preg_match('/\.edu$|\.com$|\.net$|\.org$/', $a['name']) || |
| preg_match('/[0-9]-[0-9]/', $b['name']) || |
| preg_match('/\.edu$|\.com$|\.net$|\.org$/', $b['name'])) |
| return compareDashedNumbers($a["name"], $b["name"]); |
| return strcasecmp($a["name"], $b["name"]); |
| } |
| else |
| return 0; |
| } |
| elseif(preg_match('/[0-9]-[0-9]/', $a) || |
| preg_match('/\.edu$|\.com$|\.net$|\.org$/', $a) || |
| preg_match('/[0-9]-[0-9]/', $b) || |
| preg_match('/\.edu$|\.com$|\.net$|\.org$/', $b)) |
| return compareDashedNumbers($a, $b); |
| |
| return strcasecmp($a, $b); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn compareDashedNumbers($a, $b) |
| /// |
| /// \param $a - a string |
| /// \param $b - a string |
| /// |
| /// \return -1, 0, 1 if numerical parts of $a <, =, or > $b |
| /// |
| /// \brief compares $a and $b to determine which one should be ordered first; |
| /// has some understand of numerical order in strings |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function compareDashedNumbers($a, $b) { |
| # get hostname and first part of domain name |
| $tmp = explode('.', $a); |
| $h1 = array_shift($tmp); |
| $domain1 = implode('.', $tmp); |
| $letters1 = preg_replace('([^a-zA-Z])', '', $h1); |
| |
| $tmp = explode('.', $b); |
| $h2 = array_shift($tmp); |
| $domain2 = implode('.', $tmp); |
| $letters2 = preg_replace('([^a-zA-Z])', '', $h2); |
| |
| // if different domain names, return based on that |
| /*$cmp = strcasecmp($domain1, $domain2); |
| if($cmp) { |
| return $cmp; |
| }*/ |
| |
| // if non-numeric part is different, return based on that |
| $cmp = strcasecmp($letters1, $letters2); |
| if($cmp) { |
| return $cmp; |
| } |
| |
| // at this point, the only difference is in the numbers |
| $digits1 = preg_replace('([^\d-])', '', $h1); |
| $digits1Arr = explode('-', $digits1); |
| $digits2 = preg_replace('([^\d-])', '', $h2); |
| $digits2Arr = explode('-', $digits2); |
| |
| $len1 = count($digits1Arr); |
| $len2 = count($digits2Arr); |
| for($i = 0; $i < $len1 && $i < $len2; $i++) { |
| if($digits1Arr[$i] < $digits2Arr[$i]) { |
| return -1; |
| } |
| elseif($digits1Arr[$i] > $digits2Arr[$i]) { |
| return 1; |
| } |
| } |
| |
| return 0; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getResourceMapping($resourcetype1, $resourcetype2, |
| /// $resource1inlist, $resource2inlist) |
| /// |
| /// \param $resourcetype1 - get mapping between this type and $resourcetype2 |
| /// \param $resourcetype2 - get mapping between this type and $resourcetype1 |
| /// \param $resource1inlist - (optional) comma delimited list of resource groups |
| /// to limit query to |
| /// \param $resource2inlist - (optional) comma delimited list of resource groups |
| /// to limit query to |
| /// |
| /// \return an array of $resourcetype1 group to $resourcetype2 group mappings |
| /// where each index is a group id from $resourcetype1 and each value is an |
| /// array of $resourcetype2 group ids |
| /// |
| /// \brief builds an array of $resourcetype2 group ids for each $resourcetype1 |
| /// group id |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getResourceMapping($resourcetype1, $resourcetype2, |
| $resource1inlist="", $resource2inlist="") { |
| if(! is_numeric($resourcetype1)) |
| $resourcetype1 = getResourceTypeID($resourcetype1); |
| if(! is_numeric($resourcetype2)) |
| $resourcetype2 = getResourceTypeID($resourcetype2); |
| |
| $return = array(); |
| $query = "SELECT resourcegroupid1, " |
| . "resourcetypeid1, " |
| . "resourcegroupid2, " |
| . "resourcetypeid2 " |
| . "FROM resourcemap " |
| . "WHERE ((resourcetypeid1 = $resourcetype1 AND " |
| . "resourcetypeid2 = $resourcetype2) OR " |
| . "(resourcetypeid1 = $resourcetype2 AND " |
| . "resourcetypeid2 = $resourcetype1)) "; |
| if(! empty($resource1inlist)) |
| $query .= "AND resourcegroupid1 IN ($resource1inlist) "; |
| if(! empty($resource2inlist)) |
| $query .= "AND resourcegroupid2 IN ($resource2inlist) "; |
| $qh = doQuery($query, 101); |
| while($row = mysql_fetch_assoc($qh)) { |
| if($resourcetype1 == $row['resourcetypeid1']) { |
| if(array_key_exists($row["resourcegroupid1"], $return)) |
| array_push($return[$row["resourcegroupid1"]], $row["resourcegroupid2"]); |
| else |
| $return[$row["resourcegroupid1"]] = array($row["resourcegroupid2"]); |
| } |
| else { |
| if(array_key_exists($row["resourcegroupid2"], $return)) |
| array_push($return[$row["resourcegroupid2"]], $row["resourcegroupid1"]); |
| else |
| $return[$row["resourcegroupid2"]] = array($row["resourcegroupid1"]); |
| } |
| } |
| return $return; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getConnectMethods($imageid) |
| /// |
| /// \param $imageid - id of image for which to get available methods |
| /// |
| /// \return an array of connect methods where the key is the id and the value is |
| /// an array with these items:\n |
| /// \b description - description of method\n |
| /// \b autoprovisioned - 0 or 1, whether or not the method can be automatically |
| /// provisioned by the backend |
| /// |
| /// \brief get the available connection methods for a specific image |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getConnectMethods($imageid) { |
| $key = getKey(array('getConnectMethods', $imageid)); |
| if(isset($_SESSION['usersessiondata'][$key])) |
| return $_SESSION['usersessiondata'][$key]; |
| $query = "SELECT DISTINCT c.id, " |
| . "c.description, " |
| . "cm.autoprovisioned " |
| . "FROM connectmethod c, " |
| . "connectmethodmap cm, " |
| . "image i " |
| . "LEFT JOIN OS o ON (o.id = i.OSid) " |
| . "LEFT JOIN OStype ot ON (ot.name = o.type) " |
| . "WHERE i.id = $imageid AND " |
| . "cm.connectmethodid = c.id AND " |
| . "cm.autoprovisioned IS NOT NULL AND " |
| . "(cm.OStypeid = ot.id OR " |
| . "cm.OSid = o.id) " |
| . "ORDER BY c.description"; |
| $methods = array(); |
| $qh = doQuery($query, 101); |
| while($row = mysql_fetch_assoc($qh)) |
| $methods[$row['id']] = $row; |
| $_SESSION['usersessiondata'][$key] = $methods; |
| return $methods; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn timeToNextReservation($request) |
| /// |
| /// \param $request - either a request id or an array returned from |
| /// getRequestInfo |
| /// |
| /// \return minutes from the end of $request until the start of the next |
| /// reservation on the same computer, if there are no reservations following |
| /// this one, -1 is returned |
| /// |
| /// \brief determines the number of minutes between the end of $request and |
| /// the beginning of the next request on the same computer |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function timeToNextReservation($request) { |
| if(! is_array($request)) |
| $request = getRequestInfo($request); |
| $comps = array(); |
| foreach($request['reservations'] as $res) |
| $comps[] = $res['computerid']; |
| $compids = implode(',', $comps); |
| $res = array_shift($request["reservations"]); |
| $query = "SELECT rq.start " |
| . "FROM reservation rs, " |
| . "request rq " |
| . "WHERE rs.computerid IN ($compids) AND " |
| . "rq.start >= '{$request['end']}' AND " |
| . "rs.requestid = rq.id " |
| . "ORDER BY start " |
| . "LIMIT 1"; |
| $qh = doQuery($query, 101); |
| if($row = mysql_fetch_assoc($qh)) { |
| $end = datetimeToUnix($request["end"]); |
| $start = datetimeToUnix($row["start"]); |
| return ($start - $end) / 60; |
| } |
| else |
| return -1; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn weekOfYear($ts) |
| /// |
| /// \param $ts - unix timestamp |
| /// |
| /// \return week number in the year that $ts falls in |
| /// |
| /// \brief determines the week of the year $ts is in where week 0 is the week |
| /// containing Jan 1st |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function weekOfYear($ts) { |
| $year = date('Y', time()); |
| for($i = 0; $i < 7; $i++) { |
| $time = mktime(1, 0, 0, 1, $i + 1, $year); |
| if(date('l', $time) == "Sunday") { |
| if($i) |
| $add = 7 - $i; |
| else |
| $add = 0; |
| break; |
| } |
| } |
| return (int)((date('z', $ts) + $add) / 7); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn cleanSemaphore() |
| /// |
| /// \brief deletes any semaphore entries created by current instantiation of |
| /// this script |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function cleanSemaphore() { |
| global $mysql_link_vcl, $uniqid; |
| if(! is_resource($mysql_link_vcl) || ! get_resource_type($mysql_link_vcl) == 'mysql link') |
| return; |
| $query = "DELETE FROM semaphore " |
| . "WHERE procid = '$uniqid'"; |
| doQuery($query); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn setAttribute($objid, $attrib, $data) |
| /// |
| /// \param $objid - a dom id |
| /// \param $attrib - attribute of dom object to set |
| /// \param $data - what to set $attrib to |
| /// |
| /// \return dojo code to set $attrib to $data for $objid |
| /// |
| /// \brief dojo code to set $attrib to $data for $objid |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function setAttribute($objid, $attrib, $data) { |
| return "if(dojo.byId('$objid')) {dojo.byId('$objid').$attrib = '$data';}; "; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn generateString($length) |
| /// |
| /// \param $length - (optional) length of the string, defaults to 8 |
| /// |
| /// \return a random string of upper and lower case letters and numbers |
| /// |
| /// \brief generates a random string |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function generateString($length=8) { |
| global $passwdArray; |
| $tmp = array_flip($passwdArray); |
| $tmp = array_rand($tmp, $length); |
| return implode('', $tmp); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getVMProfiles(id) |
| /// |
| /// \param $id (optional) - a profile id; if specified, only data about this |
| /// profile will be returned |
| /// |
| /// \return an array of profiles where each key is the profile id and each |
| /// element is an array with these keys:\n |
| /// \b profilename - name of profile\n |
| /// \b name - name of profile (so array can be passed to printSelectInput)\n |
| /// \b image - name of image used for this profile\n |
| /// \b imageid - id of image used for this profile\n |
| /// \b resourcepath\n |
| /// \b folderpath\n |
| /// \b repositorypath - share exported by nas to the vmhost\n |
| /// \b datastorepath - path to where vm data files are stored\n |
| /// \b vmpath - path to where vm configuration files are stored\n |
| /// \b virtualswitch0 - name of first virtual switch\n |
| /// \b virtualswitch1 - name of second virtual switch\n |
| /// \b vmdisk - "dedicated" or "shared" - whether or not vm files are |
| /// stored on local disk or network attached storage\n |
| /// \b username - username associated with this profile\n |
| /// \b pwdlength - length of password field\n |
| /// \b secretid - cryptsecret.secretid for key used to encrypt password\n |
| /// \b eth0generated - boolean telling if the MAC address for eth0 should be |
| /// autogenerated\n |
| /// \b eth1generated - boolean telling if the MAC address for eth1 should be |
| /// autogenerated |
| /// |
| /// \brief gets information about vm profiles and returns it as an array |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getVMProfiles($id="") { |
| $query = "SELECT vp.id, " |
| . "vp.profilename, " |
| . "vp.profilename AS name, " |
| . "i.prettyname AS image, " |
| . "vp.imageid, " |
| . "vp.resourcepath, " |
| . "vp.folderpath, " |
| . "vp.repositorypath, " |
| . "vp.repositoryimagetypeid, " |
| . "t1.name AS repositoryimagetype, " |
| . "vp.datastorepath, " |
| . "vp.datastoreimagetypeid, " |
| . "t2.name AS datastoreimagetype, " |
| . "vp.vmpath, " |
| . "vp.virtualswitch0, " |
| . "vp.virtualswitch1, " |
| . "vp.virtualswitch2, " |
| . "vp.virtualswitch3, " |
| . "vp.vmdisk, " |
| . "vp.username, " |
| . "CHAR_LENGTH(vp.password) as pwdlength, " |
| . "vp.secretid, " |
| . "vp.eth0generated, " |
| . "vp.eth1generated " |
| . "FROM vmprofile vp " |
| . "LEFT JOIN image i ON (vp.imageid = i.id) " |
| . "LEFT JOIN imagetype t1 ON (vp.repositoryimagetypeid = t1.id) " |
| . "LEFT JOIN imagetype t2 ON (vp.datastoreimagetypeid = t2.id)"; |
| if(! empty($id)) |
| $query .= " AND vp.id = $id"; |
| $qh = doQuery($query, 101); |
| $ret = array(); |
| while($row = mysql_fetch_assoc($qh)) |
| $ret[$row['id']] = $row; |
| return $ret; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getENUMvalues($table, $field) |
| /// |
| /// \param $table - name of a table from the database |
| /// \param $field - field in $table |
| /// |
| /// \return array of valid values for $table.$field |
| /// |
| /// \brief gets valid values for $table.$field |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getENUMvalues($table, $field) { |
| $query = "DESC $table"; |
| $qh = doQuery($query); |
| while($row = mysql_fetch_assoc($qh)) { |
| if($row['Field'] == "$field") { |
| $data = preg_replace(array('/^enum\(/', "/'/", '/\)$/'), array('', '', ''), $row['Type']); |
| $types = explode(',', $data); |
| return $types; |
| } |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn addContinuationsEntry($nextmode, $data, $duration, $deleteFromSelf, |
| /// $multicall, $repeatProtect) |
| /// |
| /// \param $nextmode - next mode to go in to |
| /// \param $data (optional, default=array())- array of data to make available |
| /// in $nextmode |
| /// \param $duration (optional, default=SECINWEEK)- how long this continuation |
| /// should be available (in seconds) |
| /// \param $deleteFromSelf (optional, default=1)- set the deletefromid to be |
| /// the id of this continuation |
| /// \param $multicall (optional, default=1) - boolean, if false, entry should be |
| /// deleted after being called once |
| /// \param $repeatProtect (optional, default=0) - boolean, if true, we add |
| /// the current continuationid to $data; this keeps us from having a tree |
| /// structure "loop" with the continuations; this situation occurs when we have |
| /// a page that can lead off in 2 directions, one of which ends up causing us |
| /// to come back to the page - then the continuation in the other direction |
| /// ends up having conflicting parents |
| /// |
| /// \return an encrypted string that can be passed to the client as an |
| /// identifier for where to continue execution |
| /// |
| /// \brief generates a continuation id based on $data and $nextmode; if the id |
| /// already exists in continuations, updates that entry's expiretime; if not, |
| /// adds an entry |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function addContinuationsEntry($nextmode, $data=array(), $duration=SECINWEEK, |
| $deleteFromSelf=1, $multicall=1, |
| $repeatProtect=0) { |
| global $user, $mode, $inContinuation, $continuationid, $cryptkey; |
| if($repeatProtect) |
| $data['______parent'] = $continuationid; |
| $serdata = serialize($data); |
| if(array_key_exists('HTTP_USER_AGENT', $_SERVER)) |
| $contid = md5($mode . $nextmode . $serdata . $user['id'] . $_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT']); |
| else |
| $contid = md5($mode . $nextmode . $serdata . $user['id'] . $_SERVER['REMOTE_ADDR']); |
| $serdata = mysql_real_escape_string($serdata); |
| $expiretime = unixToDatetime(time() + $duration); |
| $query = "SELECT id, " |
| . "parentid " |
| . "FROM continuations " |
| . "WHERE id = '$contid' AND " |
| . "userid = {$user['id']}"; |
| $qh = doQuery($query, 101); |
| if($row = mysql_fetch_assoc($qh)) { |
| # update expiretime |
| $query = "UPDATE continuations " |
| . "SET expiretime = '$expiretime' " |
| . "WHERE id = '$contid' AND " |
| . "userid = {$user['id']}"; |
| doQuery($query, 101); |
| } |
| else { |
| if(! $inContinuation) |
| $parent = 'NULL'; |
| else |
| $parent = "'$continuationid'"; |
| if($deleteFromSelf || ! $inContinuation) { |
| $deletefromid = $contid; |
| $parent = 'NULL'; |
| } |
| else { |
| $query = "SELECT deletefromid " |
| . "FROM continuations " |
| . "WHERE id = '$continuationid' AND " |
| . "userid = {$user['id']}"; |
| $qh = doQuery($query, 101); |
| if(! $row = mysql_fetch_assoc($qh)) |
| abort(108); |
| $deletefromid = $row['deletefromid']; |
| } |
| $query = "INSERT INTO continuations " |
| . "(id, " |
| . "userid, " |
| . "expiretime, " |
| . "frommode, " |
| . "tomode, " |
| . "data, " |
| . "multicall, " |
| . "parentid, " |
| . "deletefromid) " |
| . "VALUES " |
| . "('$contid', " |
| . "{$user['id']}, " |
| . "'$expiretime', " |
| . "'$mode', " |
| . "'$nextmode', " |
| . "'$serdata', " |
| . "$multicall, " |
| . "$parent, " |
| . "'$deletefromid')"; |
| doQuery($query, 101); |
| } |
| $salt = generateString(8); |
| $now = time(); |
| $data = "$salt:$contid:{$user['id']}:$now"; |
| $edata = encryptData($data, $cryptkey, SYMALGO, SYMOPT, SYMLEN); |
| $udata = urlencode($edata); |
| return $udata; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getContinuationsData($data) |
| /// |
| /// \param $data - data as returned by addContinuationsEntry |
| /// |
| /// \return an array with these keys:\n |
| /// \b frommode - current mode\n |
| /// \b nextmode - mode to go to next\n |
| /// \b userid - id from user table\n |
| /// \b data - data saved in the db for this continuation |
| /// |
| /// \brief gets data saved in continuations table associated with $data |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getContinuationsData($data) { |
| global $user, $continuationid, $noHTMLwrappers, $cryptkey; |
| if(array_key_exists('continuation', $_POST)) |
| $edata = urldecode($data); |
| else |
| $edata = $data; |
| if(! ($ddata = decryptData($edata, $cryptkey, SYMALGO, SYMOPT, SYMLEN))) |
| return array('error' => 'invalid input'); |
| $items = explode(':', $ddata); |
| $now = time(); |
| $continuationid = $items[1]; |
| |
| # validate input |
| if((count($items) != 4) || |
| (! preg_match('/^[0-9a-fA-F]+$/', $continuationid)) || |
| (! is_numeric($items[2])) || |
| /*($items[1] != $user['id']) ||*/ |
| (! is_numeric($items[3])) || |
| ($items[3] > $now)) { |
| return array('error' => 'invalid input'); |
| } |
| |
| # get continuation |
| $query = "SELECT UNIX_TIMESTAMP(expiretime) AS expiretime, " |
| . "frommode, " |
| . "tomode, " |
| . "data, " |
| . "multicall, " |
| . "deletefromid " |
| . "FROM continuations " |
| . "WHERE id = '$continuationid' AND " |
| . "userid = {$items[2]}"; |
| $qh = doQuery($query, 101); |
| |
| # return error if it is not there |
| if(! ($row = mysql_fetch_assoc($qh))) |
| return array('error' => 'continuation does not exist'); |
| |
| # return error if it is expired |
| if($row['expiretime'] < $now) { |
| $query = "DELETE FROM continuations " |
| . "WHERE id = '{$row['deletefromid']}' AND " |
| . "userid = {$items[2]}"; |
| doQuery($query, 101, 'vcl', 1); |
| $rt = array('error' => 'expired'); |
| if(in_array($row['tomode'], $noHTMLwrappers)) |
| $rt['noHTMLwrappers'] = 1; |
| else |
| $rt['noHTMLwrappers'] = 0; |
| return $rt; |
| } |
| |
| # remove if multicall is 0 |
| if($row['multicall'] == 0) { |
| $query = "DELETE FROM continuations " |
| . "WHERE id = '{$row['deletefromid']}' AND " |
| . "userid = {$items[2]}"; |
| doQuery($query, 101, 'vcl', 1); |
| } |
| return array('frommode' => $row['frommode'], |
| 'nextmode' => $row['tomode'], |
| 'userid' => $items[2], |
| 'data' => unserialize($row['data'])); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn continuationsError() |
| /// |
| /// \brief prints an error page related to a continuations problem |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function continuationsError() { |
| global $contdata, $printedHTMLheader, $HTMLheader; |
| if(! array_key_exists('noHTMLwrappers', $contdata) || |
| $contdata['noHTMLwrappers'] == 0) { |
| if(empty($HTMLheader)) |
| printHTMLHeader(); |
| if(! $printedHTMLheader) { |
| $printedHTMLheader = 1; |
| print $HTMLheader; |
| } |
| } |
| if(array_key_exists('error', $contdata)) { |
| print "<!-- continuationserror -->\n"; |
| print "<div id=\"continuationserrormessage\">\n"; |
| $subj = rawurlencode(i("Problem With VCL")); |
| $href = "<a href=\"mailto:" . HELPEMAIL . "?Subject=$subj\">" . HELPEMAIL . "</a>"; |
| switch($contdata['error']) { |
| case 'invalid input': |
| print "<h2>" . i("Error: Invalid Input") . "</h2><br>\n"; |
| printf(i("You submitted input invalid for this web site. If you have no idea why this happened and the problem persists, please email %s for further assistance. Please include the steps you took that led up to this problem in your email message."), $href); |
| break; |
| case 'continuation does not exist': |
| case 'expired': |
| print "<h2>" . i("Error: Invalid Input") . "</h2><br>\n"; |
| print i("You submitted expired data to this web site. Please restart the steps you were following without using your browser's <strong>Back</strong> button."); |
| break; |
| default: |
| print "<h2>" . i("Error: Invalid Input") . "</h2><br>\n"; |
| printf(i("An error has occurred. If this problem persists, please email %s for further assistance. Please include the steps you took that led up to this problem in your email message."), $href); |
| } |
| print "</div>\n"; |
| } |
| if(! array_key_exists('noHTMLwrappers', $contdata) || |
| $contdata['noHTMLwrappers'] == 0) |
| printHTMLFooter(); |
| dbDisconnect(); |
| exit; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getShibauthData($id) |
| /// |
| /// \param $id - id for entry in shibauth table |
| /// |
| /// \return NULL if id not found in table or array of data with these keys:\n |
| /// \b userid - id of user that data belongs to\n |
| /// \b ts - datetime of when authdata was created\n |
| /// \b sessid - shibboleth session id\n |
| /// \b Shib-Application-ID - ??\n |
| /// \b Shib-Identity-Provider - ??\n |
| /// \b Shib-AuthnContext-Dec - ??\n |
| /// \b Shib-logouturl - idp's logout url\n |
| /// \b eppn - edu person principal name for user\n |
| /// \b unscoped-affiliation - shibboleth unscoped affiliation\n |
| /// \b affiliation - shibboleth scoped affiliation |
| /// |
| /// \brief gets entry from shibauth table |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getShibauthData($id) { |
| $query = "SELECT id, " |
| . "userid, " |
| . "ts, " |
| . "sessid, " |
| . "data " |
| . "FROM shibauth " |
| . "WHERE id = $id"; |
| $qh = doQuery($query, 101); |
| if($row = mysql_fetch_assoc($qh)) { |
| $data = unserialize($row['data']); |
| unset($row['data']); |
| $data2 = array_merge($row, $data); |
| return $data2; |
| } |
| return NULL; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getVariable($key, $default, $incparams=0) |
| /// |
| /// \param $key - name in variable table |
| /// \param $default - (optional, default=NULL) value to return if $key not found |
| /// \param $incparams - (optional, default=0) return only value or return array |
| /// that includes additional variable parameters |
| /// |
| /// \return value from variable table; $default if $key not found in table; if |
| /// $incparams is 1, returns array with these keys:\n |
| /// \b value - variable value\n |
| /// \b serialization - encoding used to store variable\n |
| /// \b setby - what last set the variable\n |
| /// \b timestamp - when variable was last set |
| /// |
| /// \brief gets data from the variable table for $key |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getVariable($key, $default=NULL, $incparams=0) { |
| if(array_key_exists($key, $_SESSION['variables']) && ! $incparams) |
| return $_SESSION['variables'][$key]; |
| $query = "SELECT serialization, "; |
| if($incparams) |
| $query .= "setby, " |
| . "timestamp, "; |
| $query .= "value "; |
| $query .= "FROM variable " |
| . "WHERE name = '$key'"; |
| $qh = doQuery($query); |
| if($row = mysql_fetch_assoc($qh)) { |
| if($incparams) { |
| switch($row['serialization']) { |
| case 'yaml': |
| $row['value'] = Spyc::YAMLLoad($row['value']); |
| break; |
| case 'phpserialize': |
| $row['value'] = unserialize($row['value']); |
| break; |
| } |
| return $row; |
| } |
| else { |
| switch($row['serialization']) { |
| case 'none': |
| return $row['value']; |
| case 'yaml': |
| return Spyc::YAMLLoad($row['value']); |
| case 'phpserialize': |
| return unserialize($row['value']); |
| } |
| } |
| } |
| elseif(! $incparams) |
| return $default; |
| return array('value' => $default, |
| 'serialization' => 'none', |
| 'setby' => 'none', |
| 'timestamp' => NULL); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getVariablesRegex($pattern) |
| /// |
| /// \param $pattern - pattern to match in variable table |
| /// |
| /// \return array of values from variable table |
| /// |
| /// \brief gets data from the variable table for $pattern matches 'name' from |
| /// table |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getVariablesRegex($pattern) { |
| $query = "SELECT name, " |
| . "serialization, " |
| . "value " |
| . "FROM variable " |
| . "WHERE name REGEXP '$pattern'"; |
| $qh = doQuery($query); |
| $ret = array(); |
| while($row = mysql_fetch_assoc($qh)) { |
| switch($row['serialization']) { |
| case 'none': |
| $ret[$row['name']] = $row['value']; |
| break; |
| case 'yaml': |
| $ret[$row['name']] = Spyc::YAMLLoad($row['value']); |
| break; |
| case 'phpserialize': |
| $ret[$row['name']] = unserialize($row['value']); |
| break; |
| } |
| } |
| return $ret; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn setVariable($key, $data, $serialization) |
| /// |
| /// \param $key - name in variable table |
| /// \param $data - data to save in variable table |
| /// \param $serialization - (optional, default=phpserialize) type of |
| /// serialization to use - none, yaml, or phpserialize |
| /// |
| /// \brief sets data in the variable table for $key; if entry is already in |
| /// variable table and $serialization is not passed in, uses existing |
| /// serialization; if entry is already in variable table and $serialization is |
| /// passed in, uses $serialization; if entry is not already in variable table, |
| /// uses $serialization for serialization with a default of phpserialize |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function setVariable($key, $data, $serialization='') { |
| $update = 0; |
| $query = "SELECT serialization FROM variable WHERE name = '$key'"; |
| $qh = doQuery($query); |
| if($row = mysql_fetch_assoc($qh)) { |
| if($serialization == '') |
| $serialization = $row['serialization']; |
| $update = 1; |
| } |
| elseif($serialization == '') |
| $serialization = 'phpserialize'; |
| $_SESSION['variables'][$key] = $data; |
| switch($serialization) { |
| case 'none': |
| $qdata = mysql_real_escape_string($data); |
| break; |
| case 'yaml': |
| $yaml = Spyc::YAMLDump($data); |
| $qdata = mysql_real_escape_string($yaml); |
| break; |
| case 'phpserialize': |
| $qdata = mysql_real_escape_string(serialize($data)); |
| break; |
| } |
| if($update) |
| $query = "UPDATE variable " |
| . "SET value = '$qdata', " |
| . "serialization = '$serialization', " |
| . "setby = 'webcode', " |
| . "timestamp = NOW() " |
| . "WHERE name = '$key'"; |
| else |
| $query = "INSERT INTO variable " |
| . "(name, " |
| . "serialization, " |
| . "value, " |
| . "setby, " |
| . "timestamp) " |
| . "VALUES " |
| . "('$key', " |
| . "'$serialization', " |
| . "'$qdata', " |
| . "'webcode', " |
| . "NOW())"; |
| doQuery($query); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn deleteVariable($key) |
| /// |
| /// \param $key - name in variable table |
| /// |
| /// \brief deletes a record from the variable table having name $key |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function deleteVariable($key) { |
| if(array_key_exists($key, $_SESSION['variables'])) |
| unset($_SESSION['variables'][$key]); |
| $query = "DELETE FROM variable WHERE name = '$key'"; |
| doQuery($query); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn validateIPv4addr($ip) |
| /// |
| /// \param $ip - an ip address |
| /// |
| /// \return 1 if $ip is valid, 0 if not |
| /// |
| /// \brief validates that $ip is a valid address |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function validateIPv4addr($ip) { |
| $arr = explode('.', $ip); |
| if($arr[0] == 0) |
| return 0; |
| $regip1 = "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"; |
| $regip4 = "$regip1\.$regip1\.$regip1\.$regip1"; |
| return preg_match("/^$regip4$/", $ip); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn validateHostname($name) |
| /// |
| /// \param $name the hostname to validate |
| /// |
| /// \return 1 if valid hostname else 0 |
| /// |
| /// \brief validates a given hostname |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function validateHostname($name) { |
| if(strlen($name) > 255) |
| return 0; |
| // return 0 if dotted numbers only |
| if(preg_match('/^[0-9]+(\.[0-9]+){3}$/', $name)) |
| return 0; |
| return preg_match('/^([-A-Za-z0-9]{1,63})(\.[A-Za-z0-9-_]+)*(\.?[A-Za-z0-9])$/', $name); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn validateEmailAddress($addr) |
| /// |
| /// \param $addr - an email address |
| /// |
| /// \return 1 if $addr is valid, 0 if not |
| /// |
| /// \brief validates that $addr is a valid email address using a regex |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function validateEmailAddress($addr) { |
| return preg_match('/[a-z0-9!#$%&\'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&\'*+\/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/', $addr); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn xmlrpccall() |
| /// |
| /// \brief registers all functions available to xmlrpc, handles the current |
| /// xmlrpc call |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function xmlrpccall() { |
| global $xmlrpc_handle, $HTTP_RAW_POST_DATA, $user; |
| # create xmlrpc handle |
| $xmlrpc_handle = xmlrpc_server_create(); |
| # register functions available via rpc calls |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCtest", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCgetImages", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCaddRequest", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCaddRequestWithEnding", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCgetRequestStatus", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCgetRequestConnectData", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCextendRequest", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCsetRequestEnding", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCendRequest", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCgetRequestIds", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCblockAllocation", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCprocessBlockTime", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCaddUserGroup", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCgetUserGroupAttributes", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCdeleteUserGroup", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCeditUserGroup", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCgetUserGroupMembers", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCaddUsersToGroup", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCremoveUsersFromGroup", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCgetOneClickParams", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCgetOneClicks", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCaddOneClick", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCeditOneClick", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCdeleteOneClick", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCgetIP", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCautoCapture", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCdeployServer", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCgetNodes", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCaddNode", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCremoveNode", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCnodeExists", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCaddResourceGroupPriv", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCremoveResourceGroupPriv", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCgetResourceGroupPrivs", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCaddUserGroupPriv", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCremoveUserGroupPriv", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCgetUserGroupPrivs", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCaddResourceGroup", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCgetResourceGroups", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCremoveResourceGroup", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCgetUserGroups", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCremoveUserGroup", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCaddImageToGroup", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCremoveImageFromGroup", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCgetGroupImages", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCaddImageGroupToComputerGroup", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCremoveImageGroupFromComputerGroup", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCfinishBaseImageCapture", "xmlRPChandler"); |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCcheckCryptSecrets", "xmlRPChandler"); |
| |
| print xmlrpc_server_call_method($xmlrpc_handle, $HTTP_RAW_POST_DATA, ''); |
| xmlrpc_server_destroy($xmlrpc_handle); |
| cleanSemaphore(); |
| dbDisconnect(); |
| exit; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn xmlrpcgetaffiliations() |
| /// |
| /// \brief registers function to handle xmlrpcaffiliations and handles the call |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function xmlrpcgetaffiliations() { |
| global $xmlrpc_handle, $HTTP_RAW_POST_DATA; |
| # create xmlrpc handle |
| $xmlrpc_handle = xmlrpc_server_create(); |
| # register functions available via rpc calls |
| xmlrpc_server_register_method($xmlrpc_handle, "XMLRPCaffiliations", "xmlRPChandler"); |
| |
| print xmlrpc_server_call_method($xmlrpc_handle, $HTTP_RAW_POST_DATA, ''); |
| xmlrpc_server_destroy($xmlrpc_handle); |
| dbDisconnect(); |
| exit; |
| } |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn xmlRPChandler($function, $args, $blah) |
| /// |
| /// \param $function - name of a function to call |
| /// \param $args - array of arguments to pass when calling $function, use empty |
| /// array if $function takes no args |
| /// \param $blah - not used, but required by xmlrpc_server_call_method |
| /// |
| /// \return whatever $function returns |
| /// |
| /// \brief calls $function with $args (if non-empty array) and returns whatever |
| /// $function returns |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function xmlRPChandler($function, $args, $blah) { |
| global $user, $remoteIP; |
| header("Content-type: text/xml"); |
| $apiversion = processInputData($_SERVER['HTTP_X_APIVERSION'], ARG_NUMERIC); |
| if($function == 'XMLRPCaffiliations') |
| $keyid = 0; |
| else |
| $keyid = $user['id']; |
| if(function_exists($function)) { |
| if(! defined('XMLRPCLOGGING') || XMLRPCLOGGING != 0) { |
| $saveargs = mysql_real_escape_string(serialize($args)); |
| $query = "INSERT INTO xmlrpcLog " |
| . "(xmlrpcKeyid, " |
| . "timestamp, " |
| . "IPaddress, " |
| . "method, " |
| . "apiversion, " |
| . "comments) " |
| . "VALUES " |
| . "($keyid, " |
| . "NOW(), " |
| . "'$remoteIP', " |
| . "'$function', " |
| . "$apiversion, " |
| . "'$saveargs')"; |
| doQuery($query, 101); |
| } |
| } |
| else { |
| printXMLRPCerror(2); |
| dbDisconnect(); |
| exit; |
| } |
| |
| if(count($args)) |
| return call_user_func_array($function, $args); |
| else |
| return $function(); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn xmlRPCabort($errcode, $query) |
| /// |
| /// \param $errcode - an error code from $ERRORS |
| /// \param $query - (optional, default="") a query |
| /// |
| /// \brief call this to handle errors for XML RPC connections |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function xmlRPCabort($errcode, $query='') { |
| global $mysql_link_vcl, $mysql_link_acct, $ERRORS, $user, $mode; |
| global $XMLRPCERRORS; |
| if(ONLINEDEBUG && checkUserHasPerm('View Debug Information')) { |
| $msg = ''; |
| if($errcode >= 100 && $errcode < 400) { |
| $msg .= "ERROR (" . mysql_errno($mysql_link_vcl) . ") - "; |
| $msg .= mysql_error($mysql_link_vcl) . " $query "; |
| } |
| $msg .= $ERRORS["$errcode"]; |
| $XMLRPCERRORS[100] = $msg; |
| $faultcode = 100; |
| } |
| else { |
| $message = ""; |
| if($errcode >= 100 && $errcode < 400) { |
| $message .= mysql_error($mysql_link_vcl) . "\n"; |
| $message .= mysql_error($mysql_link_acct) . "\n"; |
| $message .= $query . "\n"; |
| } |
| $message .= "ERROR($errcode): " . $ERRORS["$errcode"] . "\n"; |
| $message .= "Logged in user was " . $user["unityid"] . "\n"; |
| $message .= "Mode was $mode\n\n"; |
| if($errcode == 20) { |
| $urlArray = explode('?', $_SERVER["HTTP_REFERER"]); |
| $message .= "HTTP_REFERER URL - " . $urlArray[0] . "\n"; |
| $message .= "correct URL - " . BASEURL . SCRIPT . "\n"; |
| } |
| $message .= getBacktraceString(FALSE); |
| $mailParams = "-f" . ENVELOPESENDER; |
| mail(ERROREMAIL, "Error with VCL XMLRPC call", $message, '', $mailParams); |
| $faultcode = 1; |
| } |
| printXMLRPCerror($faultcode); |
| cleanSemaphore(); |
| dbDisconnect(); |
| exit; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn printXMLRPCerror($errcode) |
| /// |
| /// \param $errcode - an error code from $XMLRPCERRORS |
| /// |
| /// \brief prints the XML for an RPC error |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function printXMLRPCerror($errcode) { |
| global $XMLRPCERRORS; |
| print "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?" . ">\n"; # splitting the ? and > makes vim syntax highlighting work correctly |
| print "<methodResponse>\n"; |
| print "<fault>\n"; |
| print " <value>\n"; |
| print " <struct>\n"; |
| print " <member>\n"; |
| print " <name>faultString</name>\n"; |
| print " <value>\n"; |
| print " <string>{$XMLRPCERRORS[$errcode]}</string>\n"; |
| print " </value>\n"; |
| print " </member>\n"; |
| print " <member>\n"; |
| print " <name>faultCode</name>\n"; |
| print " <value>\n"; |
| print " <int>$errcode</int>\n"; |
| print " </value>\n"; |
| print " </member>\n"; |
| print " </struct>\n"; |
| print " </value>\n"; |
| print "</fault>\n"; |
| print "</methodResponse>\n"; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn validateAPIgroupInput($items, $exists) |
| /// |
| /// \param $items - array of data to validate; the following items can be |
| /// validated, if 'custom' is included and is 0, owner and managingGroup are |
| /// not validated:\n |
| /// \b name - if specified, affiliation must also be specified\n |
| /// \b affiliation - if specified, name must also be specified\n |
| /// \b owner \n |
| /// \b managingGroup \n |
| /// \b initialMaxTime \n |
| /// \b totalMaxTime \n |
| /// \b maxExtendTime |
| /// \param $exists - 1 to check if $name\@$affiliation exists, 0 to check that |
| /// it does not exist |
| /// |
| /// \return an array to be returned as an error status or $items with these |
| /// extra keys:\n |
| /// \b status - "success"\n |
| /// \b managingGroupID - (if managingGroup in $items) id of managingGroup |
| /// \b managingGroupName - (if managingGroup in $items) name of managingGroup |
| /// \b managingGroupAffilid - (if managingGroup in $items) affiliation id of |
| /// managingGroup |
| /// \b affiliationid - (if affiliation in $items) affiliation id |
| /// |
| /// \brief validates data in $items |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function validateAPIgroupInput($items, $exists) { |
| $custom = 1; |
| if(array_key_exists('custom', $items)) |
| $custom = $items['custom']; |
| # initialMaxTime |
| if(array_key_exists('initialMaxTime', $items)) { |
| if(! is_numeric($items['initialMaxTime']) || |
| $items['initialMaxTime'] < 1 || |
| $items['initialMaxTime'] > 65535) { |
| return array('status' => 'error', |
| 'errorcode' => 21, |
| 'errormsg' => 'submitted initialMaxTime is invalid'); |
| } |
| } |
| # totalMaxTime |
| if(array_key_exists('totalMaxTime', $items)) { |
| if(! is_numeric($items['totalMaxTime']) || |
| $items['totalMaxTime'] < 1 || |
| $items['totalMaxTime'] > 65535) { |
| return array('status' => 'error', |
| 'errorcode' => 22, |
| 'errormsg' => 'submitted totalMaxTime is invalid'); |
| } |
| } |
| # maxExtendTime |
| if(array_key_exists('maxExtendTime', $items)) { |
| if(! is_numeric($items['maxExtendTime']) || |
| $items['maxExtendTime'] < 1 || |
| $items['maxExtendTime'] > 65535) { |
| return array('status' => 'error', |
| 'errorcode' => 23, |
| 'errormsg' => 'submitted maxExtendTime is invalid'); |
| } |
| } |
| # affiliation |
| if(array_key_exists('affiliation', $items)) { |
| $affilid = getAffiliationID($items['affiliation']); |
| if(is_null($affilid)) { |
| return array('status' => 'error', |
| 'errorcode' => 17, |
| 'errormsg' => 'unknown affiliation'); |
| } |
| $items['affiliationid'] = $affilid; |
| } |
| # name |
| if(array_key_exists('name', $items)) { |
| if(! preg_match('/^[-a-zA-Z0-9_\.: ]{3,30}$/', $items['name'])) { |
| return array('status' => 'error', |
| 'errorcode' => 19, |
| 'errormsg' => 'Name must be between 3 and 30 characters ' |
| . 'and can only contain letters, numbers, and ' |
| . 'these characters: - _ . :'); |
| } |
| $doesexist = checkForGroupName($items['name'], 'user', '', $affilid); |
| if($exists && ! $doesexist) { |
| return array('status' => 'error', |
| 'errorcode' => 18, |
| 'errormsg' => 'user group with submitted name and affiliation does not exist'); |
| } |
| elseif(! $exists && $doesexist) { |
| return array('status' => 'error', |
| 'errorcode' => 27, |
| 'errormsg' => 'existing user group with submitted name and affiliation'); |
| } |
| elseif($exists && $doesexist) { |
| $esc_name = mysql_real_escape_string($items['name']); |
| $items['id'] = getUserGroupID($esc_name, $affilid); |
| } |
| } |
| # owner |
| if($custom && array_key_exists('owner', $items)) { |
| if(! validateUserid($items['owner'])) { |
| return array('status' => 'error', |
| 'errorcode' => 20, |
| 'errormsg' => 'submitted owner is invalid'); |
| } |
| } |
| # managingGroup |
| if($custom && array_key_exists('managingGroup', $items)) { |
| $parts = explode('@', $items['managingGroup']); |
| if(count($parts) != 2) { |
| return array('status' => 'error', |
| 'errorcode' => 24, |
| 'errormsg' => 'submitted managingGroup is invalid'); |
| } |
| $mgaffilid = getAffiliationID($parts[1]); |
| if(is_null($mgaffilid) || |
| ! checkForGroupName($parts[0], 'user', '', $mgaffilid)) { |
| return array('status' => 'error', |
| 'errorcode' => 25, |
| 'errormsg' => 'submitted managingGroup does not exist'); |
| } |
| $items['managingGroupID'] = getUserGroupID($parts[0], $mgaffilid); |
| $items['managingGroupName'] = $parts[0]; |
| $items['managingGroupAffilid'] = $mgaffilid; |
| } |
| $items['status'] = 'success'; |
| return $items; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn helpIcon($id) |
| /// |
| /// \param $id - dom id for icon image |
| /// |
| /// \brief returns HTML for a help icon with the dom id set to $id |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function helpIcon($id) { |
| return "<img src=\"images/helpicon.png\" id=\"$id\" />"; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn helpTooltip($id, $text, $width) |
| /// |
| /// \param $id - dom id for Tooltip to connect to |
| /// \param $text - text of Tooltip |
| /// \param $width - (default=400) wrap text in a div with this width in pixels |
| /// |
| /// \brief returns HTML for a dijit Tooltip |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function helpTooltip($id, $text, $width=400) { |
| $h = "<div dojoType=\"dijit.Tooltip\" connectId=\"$id\">\n"; |
| $h .= "<div style=\"max-width: {$width}px;\">\n"; |
| $h .= "$text\n</div>\n"; |
| $h .= "\n</div>\n"; |
| return $h; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn json_encode() |
| /// |
| /// \brief json_encode was introduced in php 5.2, this function was taked from |
| /// the comments of the help page for that function for php < 5.2 |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| if(! function_exists('json_encode')) { |
| function json_encode($a=false) { |
| if(is_null($a)) |
| return 'null'; |
| if($a === false) |
| return 'false'; |
| if($a === true) |
| return 'true'; |
| if(is_scalar($a)) { |
| if (is_float($a)) { |
| // Always use "." for floats. |
| return floatval(str_replace(",", ".", strval($a))); |
| } |
| |
| if (is_string($a)) { |
| static $jsonReplaces = array(array("\\", "/", "\n", "\t", "\r", "\b", "\f", '"'), array('\\\\', '\\/', '\\n', '\\t', '\\r', '\\b', '\\f', '\"')); |
| return '"' . str_replace($jsonReplaces[0], $jsonReplaces[1], $a) . '"'; |
| } |
| else |
| return $a; |
| } |
| $isList = true; |
| for ($i = 0, reset($a); $i < count($a); $i++, next($a)) { |
| if (key($a) !== $i) { |
| $isList = false; |
| break; |
| } |
| } |
| $result = array(); |
| if ($isList) { |
| foreach ($a as $v) $result[] = json_encode($v); |
| return '[' . join(',', $result) . ']'; |
| } |
| else { |
| foreach($a as $k => $v) |
| $result[] = json_encode($k).':'.json_encode($v); |
| return '{' . join(',', $result) . '}'; |
| } |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn sendJSON($arr, $identifier='', $REST=0) |
| /// |
| /// \param $arr - an array of data |
| /// \param $identifier - (optional, default='') set to non-empty string to have |
| /// $identifier printed as the identifier for a dojo datastore |
| /// \param $REST - (optional, default=0) pass 1 to strictly send json encoded |
| /// data with nothing wrapping it |
| /// |
| /// \brief sets the content type and sends $arr in json format |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function sendJSON($arr, $identifier='', $REST=0) { |
| #header('Content-Type: application/json; charset=utf-8'); |
| header('Content-Type: application/json'); |
| if($REST) |
| print json_encode($arr); |
| elseif(! empty($identifier)) |
| print "{} && {identifier: '$identifier', 'items':" . json_encode($arr) . '}'; |
| else |
| print '{} && {"items":' . json_encode($arr) . '}'; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn sendHeaders() |
| /// |
| /// \brief makes any needed header calls for the current mode |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function sendHeaders() { |
| global $mode, $user, $authed, $oldmode, $actionFunction; |
| global $shibauthed; |
| if(! $authed && $mode == "auth") { |
| header("Location: " . BASEURL . SCRIPT . "?mode=selectauth"); |
| dbDisconnect(); |
| exit; |
| } |
| switch($mode) { |
| case 'logout': |
| if($shibauthed) { |
| $shibdata = getShibauthData($shibauthed); |
| // TODO make shib-logouturl comparison caseless |
| if(array_key_exists('Shib-logouturl', $shibdata) && |
| ! empty($shibdata['Shib-logouturl'])) { |
| dbDisconnect(); |
| header("Location: {$shibdata['Shib-logouturl']}"); |
| exit; |
| } |
| } |
| case 'shiblogout': |
| setcookie("ITECSAUTH", "", time() - 10, "/", COOKIEDOMAIN); |
| setcookie("VCLAUTH", "", time() - 10, "/", COOKIEDOMAIN); |
| if($shibauthed) { |
| $msg = ''; |
| $shibdata = getShibauthData($shibauthed); |
| # find and clear shib cookies |
| /*foreach(array_keys($_COOKIE) as $key) { |
| if(preg_match('/^_shibsession[_0-9a-fA-F]+$/', $key)) |
| setcookie($key, "", time() - 10, "/", $_SERVER['SERVER_NAME']); |
| elseif(preg_match('/^_shibstate_/', $key)) |
| setcookie($key, "", time() - 10, "/", $_SERVER['SERVER_NAME']); |
| }*/ |
| doQuery("DELETE FROM shibauth WHERE id = $shibauthed", 101); |
| stopSession(); |
| dbDisconnect(); |
| if(array_key_exists('Shib-logouturl', $shibdata) && |
| ! empty($shibdata['Shib-logouturl'])) { |
| print "<html>\n"; |
| print " <head>\n"; |
| print " <style type=\"text/css\">\n"; |
| print " .red {\n"; |
| print " color: red;\n"; |
| print " }\n"; |
| print " body{\n"; |
| print " margin:0px; color: red;\n"; |
| print " }\n"; |
| print " </style>\n"; |
| print " </head>\n"; |
| print " <body>\n"; |
| print " <span class=red>Done.</span> <a target=\"_top\" href=\"" . BASEURL . "/\">Return to VCL</a>\n"; |
| print " </body>\n"; |
| print "</html>\n"; |
| } |
| else { |
| print "<html>\n"; |
| print "<head>\n"; |
| print "<META HTTP-EQUIV=REFRESH CONTENT=\"5;url=" . BASEURL . "\">\n"; |
| print "<style type=\"text/css\">\n"; |
| print " .hidden {\n"; |
| print " display: none;\n"; |
| print " }\n"; |
| print "</style>\n"; |
| print "</head>\n"; |
| print "<body>\n"; |
| print "Logging out of VCL..."; |
| print "<iframe src=\"https://{$_SERVER['SERVER_NAME']}/Shibboleth.sso/Logout\" class=hidden>\n"; |
| print "</iframe>\n"; |
| if(array_key_exists('Shib-Identity-Provider', $shibdata) && |
| ! empty($shibdata['Shib-Identity-Provider'])) { |
| $tmp = explode('/', $shibdata['Shib-Identity-Provider']); |
| $idp = "{$tmp[0]}//{$tmp[2]}"; |
| print "<iframe src=\"$idp/idp/logout.jsp\" class=hidden>\n"; |
| print "</iframe>\n"; |
| } |
| print "</body>\n"; |
| print "</html>\n"; |
| } |
| exit; |
| } |
| header("Location: " . HOMEURL); |
| stopSession(); |
| dbDisconnect(); |
| exit; |
| } |
| if($mode == "statgraphday" || |
| $mode == "statgraphdayconcuruser" || |
| $mode == "statgraphdayconcurblade" || |
| $mode == "statgraphhour") { |
| $actionFunction(); |
| dbDisconnect(); |
| exit; |
| } |
| if($mode == "viewNodes") { |
| $openNodes = processInputVar("openNodes", ARG_STRING); |
| $activeNode = processInputVar("activeNode", ARG_NUMERIC); |
| if(! empty($openNodes)) { |
| $expire = time() + 31536000; //expire in 1 year |
| setcookie("VCLNODES", $openNodes, $expire, "/", COOKIEDOMAIN); |
| } |
| if(! empty($activeNode)) { |
| $expire = time() + 31536000; //expire in 1 year |
| setcookie("VCLACTIVENODE", $activeNode, $expire, "/", COOKIEDOMAIN); |
| } |
| return; |
| } |
| if($mode == "submitDeleteNode") { |
| $activeNode = processInputVar("activeNode", ARG_NUMERIC); |
| $nodeinfo = getNodeInfo($activeNode); |
| $expire = time() + 31536000; //expire in 1 year |
| setcookie("VCLACTIVENODE", $nodeinfo["parent"], $expire, "/", COOKIEDOMAIN); |
| |
| } |
| if($mode == "sendRDPfile") { |
| header("Cache-Control: max-age=5, must-revalidate"); |
| header('Pragma: cache'); |
| } |
| else |
| header("Cache-Control: no-cache, must-revalidate"); |
| if($mode == 'submitAddGroup' || $mode == 'submitEditGroup') { |
| $data = getContinuationVar(); |
| if($data['type'] == 'resource') { |
| if(! array_key_exists('ownergroup', $data)) |
| $data['ownergroup'] = processInputVar('ownergroup', ARG_NUMERIC, 0); |
| $ownergroupids = explode(',', $data['ownergroupids']); |
| if(in_array($data['ownergroup'], $ownergroupids) && |
| array_key_exists($data['ownergroup'], $user['groups'])) { |
| $expire = time() + 31536000; //expire in 1 year |
| setcookie("VCLOWNERGROUPID", $data['ownergroup'], $expire, "/", COOKIEDOMAIN); |
| } |
| } |
| elseif($data['type'] == 'user') { |
| if(! array_key_exists('editgroupid', $data)) |
| $data['editgroupid'] = processInputVar('editgroupid', ARG_NUMERIC, 0); |
| $editgroupids = explode(',', $data['editgroupids']); |
| if(in_array($data['editgroupid'], $editgroupids)) { |
| $expire = time() + 31536000; //expire in 1 year |
| setcookie("VCLEDITGROUPID", $data['editgroupid'], $expire, "/", COOKIEDOMAIN); |
| } |
| } |
| } |
| header("Expires: Sat, 1 Jan 2000 00:00:00 GMT"); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn printHTMLHeader() |
| /// |
| /// \brief prints the header part of the template |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function printHTMLHeader() { |
| global $mode, $user, $authed, $oldmode, $HTMLheader, $contdata; |
| global $printedHTMLheader, $docreaders, $noHTMLwrappers, $actions; |
| if($printedHTMLheader) |
| return; |
| $refresh = 0; |
| if($authed && $mode == "viewRequests") { |
| $requests = getUserRequests("all", $user["id"]); |
| if($count = count($requests)) { |
| $now = time() + (15 * 60); |
| for($i = 0; $i < $count; $i++) { |
| if(datetimeToUnix($requests[$i]["start"]) < $now && |
| ($requests[$i]["currstateid"] == 13 || |
| ($requests[$i]["currstateid"] == 14 && |
| $requests[$i]["laststateid"] == 13) || |
| $requests[$i]["currstateid"] == 16 || |
| ($requests[$i]["currstateid"] == 14 && |
| $requests[$i]["laststateid"] == 16) || |
| $requests[$i]["currstateid"] == 24 || |
| ($requests[$i]["currstateid"] == 14 && |
| $requests[$i]["laststateid"] == 24) || |
| $requests[$i]["currstateid"] == 3 || |
| ($requests[$i]["currstateid"] == 8 && |
| ! $requests[$i]["useraccountready"]))) { |
| $refresh = 1; |
| } |
| } |
| } |
| } |
| |
| if($mode != 'selectauth' && $mode != 'submitLogin') |
| $HTMLheader .= getHeader($refresh); |
| |
| if(! in_array($mode, $noHTMLwrappers) && |
| (! is_array($contdata) || |
| ! array_key_exists('noHTMLwrappers', $contdata) || |
| $contdata['noHTMLwrappers'] == 0)) { |
| print $HTMLheader; |
| if($mode != 'inmaintenance') |
| print maintenanceNotice(); |
| $printedHTMLheader = 1; |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getNavMenu($inclogout, $inchome, $homeurl) |
| /// |
| /// \param $inclogout - bool flag for printing logout link |
| /// \param $inchome - bool flag for printing home link |
| /// \param $homeurl - (optional, defaults to HOMEURL) url for home link |
| /// to point to |
| /// |
| /// \return string of html to display the navigation menu |
| /// |
| /// \brief build the html for the navigation menu |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getNavMenu($inclogout, $inchome, $homeurl=HOMEURL) { |
| $menudata = getNavMenuData($homeurl); |
| |
| $rt = ''; |
| if($inchome) { |
| $rt .= "<li"; |
| if($menudata['home']['selected']) |
| $rt .= " class=\"selected\""; |
| $rt .= "><a href=\"{$menudata['home']['url']}\">{$menudata['home']['title']}</a></li>\n"; |
| unset($menudata['home']); |
| } |
| foreach($menudata as $page => $item) { |
| if($page == 'authentication') |
| continue; |
| $rt .= "<li"; |
| if($menudata[$page]['selected']) |
| $rt .= " class=\"selected\""; |
| $rt .= "><a href=\"{$menudata[$page]['url']}\">{$menudata[$page]['title']}</a></li>\n"; |
| } |
| if($inclogout) { |
| $rt .= "<li"; |
| if($menudata['authentication']['selected']) |
| $rt .= " class=\"selected\""; |
| $rt .= "><a href=\"{$menudata['authentication']['url']}\">{$menudata['authentication']['title']}</a></li>\n"; |
| } |
| return $rt; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getNavMenuData($homeurl) |
| /// |
| /// \param $homeurl - (optional, defaults to HOMEURL) url for home link |
| /// to point to |
| /// |
| /// \return array of menu items where the keys in the array are the page names |
| /// from the states.php file, and each item is an array with these keys:\n |
| /// \b url - URL menu item should link to\n |
| /// \b title - label for menu item\n |
| /// \b selected - 0 or 1; whether or not the menu item is currently active |
| /// |
| /// \brief builds the data for the main site menu |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getNavMenuData($homeurl=HOMEURL) { |
| global $user, $authed, $mode; |
| if($authed && $mode != 'expiredemouser') { |
| $computermetadata = getUserComputerMetaData(); |
| $requests = getUserRequests("all", $user["id"]); |
| } |
| else |
| $computermetadata = array("platforms" => array(), |
| "schedules" => array()); |
| $menudata = array(); |
| |
| $menudata['home']['url'] = $homeurl; |
| $menudata['home']['title'] = i('HOME'); |
| $menudata['home']['selected'] = checkMenuItemSelected('home'); |
| |
| $menudata['reservations']['url'] = BASEURL . SCRIPT . "?mode=viewRequests"; |
| $menudata['reservations']['title'] = i('Reservations'); |
| $menudata['reservations']['selected'] = checkMenuItemSelected('reservations'); |
| |
| #$menudata['config']['url'] = BASEURL . SCRIPT . "?mode=config"; |
| #$menudata['config']['title'] = i('Manage Configs'); |
| #$menudata['config']['selected'] = checkMenuItemSelected('config'); |
| |
| $menudata['blockAllocations']['url'] = BASEURL . SCRIPT . "?mode=blockAllocations"; |
| $menudata['blockAllocations']['title'] = i('Block Allocations'); |
| $menudata['blockAllocations']['selected'] = checkMenuItemSelected('blockAllocations'); |
| |
| $menudata['userPreferences']['url'] = BASEURL . SCRIPT . "?mode=userpreferences"; |
| $menudata['userPreferences']['title'] = i('User Preferences'); |
| $menudata['userPreferences']['selected'] = checkMenuItemSelected('userPreferences'); |
| |
| if(in_array("groupAdmin", $user["privileges"])) { |
| $menudata['managegroups']['url'] = BASEURL . SCRIPT . "?mode=viewGroups"; |
| $menudata['managegroups']['title'] = i('Manage Groups'); |
| $menudata['managegroups']['selected'] = checkMenuItemSelected('manageGroups'); |
| } |
| |
| if(in_array("imageAdmin", $user["privileges"])) { |
| $menudata['image']['url'] = BASEURL . SCRIPT . "?mode=image"; |
| $menudata['image']['title'] = i('Manage Images'); |
| $menudata['image']['selected'] = checkMenuItemSelected('image'); |
| } |
| |
| if(in_array("scheduleAdmin", $user["privileges"])) { |
| $menudata['schedule']['url'] = BASEURL . SCRIPT . "?mode=schedule"; |
| $menudata['schedule']['title'] = i('Manage Schedules'); |
| $menudata['schedule']['selected'] = checkMenuItemSelected('schedule'); |
| } |
| |
| if(in_array("computerAdmin", $user["privileges"])) { |
| $menudata['computer']['url'] = BASEURL . SCRIPT . "?mode=computer"; |
| $menudata['computer']['title'] = i('Manage Computers'); |
| $menudata['computer']['selected'] = checkMenuItemSelected('computer'); |
| } |
| |
| if(in_array("mgmtNodeAdmin", $user["privileges"])) { |
| $menudata['managementnode']['url'] = BASEURL . SCRIPT . "?mode=managementnode"; |
| $menudata['managementnode']['title'] = i('Management Nodes'); |
| $menudata['managementnode']['selected'] = checkMenuItemSelected('managementnode'); |
| } |
| |
| /*if(in_array("serverProfileAdmin", $user["privileges"]) || |
| in_array("serverCheckOut", $user["privileges"])) { |
| $menudata['serverProfiles']['url'] = BASEURL . SCRIPT . "?mode=serverProfiles"; |
| $menudata['serverProfiles']['title'] = i('Server Profiles'); |
| $menudata['serverProfiles']['selected'] = checkMenuItemSelected('serverProfiles'); |
| }*/ |
| |
| if(count($computermetadata["platforms"]) && |
| count($computermetadata["schedules"])) { |
| $menudata['timeTable']['url'] = BASEURL . SCRIPT . "?mode=pickTimeTable"; |
| $menudata['timeTable']['title'] = i('View Time Table'); |
| $menudata['timeTable']['selected'] = checkMenuItemSelected('timeTable'); |
| } |
| |
| if(in_array("userGrant", $user["privileges"]) || |
| in_array("resourceGrant", $user["privileges"]) || |
| in_array("nodeAdmin", $user["privileges"])) { |
| $menudata['privileges']['url'] = BASEURL . SCRIPT . "?mode=viewNodes"; |
| $menudata['privileges']['title'] = i('Privileges'); |
| $menudata['privileges']['selected'] = checkMenuItemSelected('privileges'); |
| } |
| |
| if(checkUserHasPerm('User Lookup (global)') || |
| checkUserHasPerm('User Lookup (affiliation only)')) { |
| $menudata['userLookup']['url'] = BASEURL . SCRIPT . "?mode=userLookup"; |
| $menudata['userLookup']['title'] = i('User Lookup'); |
| $menudata['userLookup']['selected'] = checkMenuItemSelected('userLookup'); |
| } |
| |
| if(in_array("computerAdmin", $user["privileges"])) { |
| $menudata['vm']['url'] = BASEURL . SCRIPT . "?mode=editVMInfo"; |
| $menudata['vm']['title'] = i('Virtual Hosts'); |
| $menudata['vm']['selected'] = checkMenuItemSelected('vm'); |
| } |
| |
| if(in_array("addomainAdmin", $user["privileges"])) { |
| $menudata['addomain']['url'] = BASEURL . SCRIPT . "?mode=addomain"; |
| $menudata['addomain']['title'] = i('AD Domains'); |
| $menudata['addomain']['selected'] = checkMenuItemSelected('addomain'); |
| } |
| |
| if(checkUserHasPerm('Schedule Site Maintenance')) { |
| $menudata['sitemaintenance']['url'] = BASEURL . SCRIPT . "?mode=siteMaintenance"; |
| $menudata['sitemaintenance']['title'] = i('Site Maintenance'); |
| $menudata['sitemaintenance']['selected'] = checkMenuItemSelected('sitemaintenance'); |
| } |
| |
| $menudata['statistics']['url'] = BASEURL . SCRIPT . "?mode=selectstats"; |
| $menudata['statistics']['title'] = i('Statistics'); |
| $menudata['statistics']['selected'] = checkMenuItemSelected('statistics'); |
| |
| if(checkUserHasPerm('View Dashboard (global)') || |
| checkUserHasPerm('View Dashboard (affiliation only)')) { |
| $menudata['dashboard']['url'] = BASEURL . SCRIPT . "?mode=dashboard"; |
| $menudata['dashboard']['title'] = i('Dashboard'); |
| $menudata['dashboard']['selected'] = checkMenuItemSelected('dashboard'); |
| } |
| |
| $menudata['oneClick']['url'] = BASEURL . SCRIPT . "?mode=newOneClick"; |
| $menudata['oneClick']['title'] = i('VCL gos'); |
| $menudata['oneClick']['selected'] = checkMenuItemSelected('oneClick'); |
| |
| if(checkUserHasPerm('Site Configuration (global)') || |
| checkUserHasPerm('Site Configuration (affiliation only)')) { |
| $menudata['siteconfig']['url'] = BASEURL . SCRIPT . "?mode=siteconfig"; |
| $menudata['siteconfig']['title'] = i('Site Configuration'); |
| $menudata['siteconfig']['selected'] = checkMenuItemSelected('siteconfig'); |
| } |
| |
| $menudata['codeDocumentation']['url'] = DOCUMENTATIONURL; |
| $menudata['codeDocumentation']['title'] = i('Documentation'); |
| $menudata['codeDocumentation']['selected'] = checkMenuItemSelected('codeDocumentation'); |
| |
| $menudata['authentication']['url'] = BASEURL . SCRIPT . "?mode=logout"; |
| $menudata['authentication']['title'] = i('Logout'); |
| $menudata['authentication']['selected'] = checkMenuItemSelected('authentication'); |
| |
| return $menudata; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn checkMenuItemSelected($page) |
| /// |
| /// \param $page - name of a page |
| /// |
| /// \return 1 if $page is selected, 0 if not |
| /// |
| /// \brief determines if the current mode is part of $page |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function checkMenuItemSelected($page) { |
| global $mode, $actions, $inContinuation; |
| $mymode = $mode; |
| if(empty($mymode)) |
| $mymode = "main"; |
| $testval = $actions['pages'][$mymode]; |
| if($inContinuation) { |
| $obj = getContinuationVar('obj'); |
| if(! is_null($obj) && isset($obj->restype)) |
| $testval = $obj->restype; |
| } |
| if($testval == $page) |
| return 1; |
| return 0; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getExtraCSS() |
| /// |
| /// \return an array of extra css files to include |
| /// |
| /// \brief this function is to be called from the theme page.php files to get |
| /// a list of extra css files to be included based on the current mode |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getExtraCSS() { |
| global $mode; |
| switch($mode) { |
| case 'viewNodes': |
| case 'changeUserPrivs': |
| case 'submitAddResourcePriv': |
| case 'changeResourcePrivs': |
| return array('privileges.css'); |
| case 'viewdocs': |
| return array('doxygen.css'); |
| } |
| return array(); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getUsingVCL() |
| /// |
| /// \return string of HTML |
| /// |
| /// \brief generates HTML of list item links from $NOAUTH_HOMENAV in conf.php |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getUsingVCL() { |
| global $NOAUTH_HOMENAV; |
| $rt = ''; |
| foreach($NOAUTH_HOMENAV as $name => $url) |
| $rt .= "<li><a href=\"$url\">" . i($name) . "</a></li>\n"; |
| return $rt; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getDojoHTML($refresh) |
| /// |
| /// \param $refresh - 1 to set page to refresh, 0 not to |
| /// |
| /// \brief builds the header html for dojo related stuff |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getDojoHTML($refresh) { |
| global $mode, $actions, $skin, $locale, $VCLversion; |
| $filename = ''; |
| $dojoRequires = array(); |
| |
| # Below are START and END comments for parsing the content between the tags |
| # to generate a dojo profile.js file for custom dojo layers for each section |
| # of the site. The parser script is generateDojoProfile.js and can be found |
| # in the vcl/sandbox/useful_scripts part of the ASF VCL subversion repo. |
| # To run without the custom layer files, simply comment out the line after |
| # the first switch statement below that sets $customfile to something other |
| # than an empty string. |
| |
| # START DOJO PARSING |
| switch($mode) { |
| case 'viewNodes': |
| case 'changeUserPrivs': |
| case 'submitAddResourcePriv': |
| case 'changeResourcePrivs': |
| $filename = 'vclPrivs.js'; |
| $dojoRequires = array('dojo.parser', |
| 'dojo.data.ItemFileWriteStore', |
| 'dijit.Tree', |
| 'dijit.tree.ForestStoreModel', |
| 'dijit.tree.dndSource', |
| 'dijit.form.Button', |
| 'dijit.form.CheckBox', |
| 'dijit.form.TextBox', |
| 'dijit.Tooltip', |
| 'dijit.Dialog', |
| 'dijit.layout.ContentPane', |
| 'dijit.layout.TabContainer'); |
| break; |
| case 'viewRequests': |
| require_once('storebackend.php'); |
| $filename = 'vclViewRequests.js'; |
| $dojoRequires = array('dojo.parser', |
| 'dijit.form.DateTextBox', |
| 'dijit.form.TimeTextBox', |
| 'dijit.form.Select', |
| 'dijit.form.CheckBox', |
| 'dojox.string.sprintf', |
| 'dijit.Dialog', |
| 'dijit.layout.ContentPane', |
| 'dijit.Menu', |
| 'dijit.form.Button', |
| 'dijit.form.DropDownButton', |
| 'dijit.Tooltip', |
| 'vcldojo.HoverTooltip', |
| 'dojox.layout.FloatingPane', |
| 'dojox.grid.DataGrid', |
| 'dijit.form.FilteringSelect', |
| 'dijit.form.NumberSpinner', |
| 'dijit.form.Textarea', |
| 'dijit.Tree', |
| 'dojo.data.ItemFileWriteStore', |
| 'dojo.data.ObjectStore', |
| 'dojo.store.JsonRest', |
| 'dijit.TitlePane', |
| 'dijit.layout.BorderContainer', |
| 'dojo.store.Memory'); |
| break; |
| case 'viewRequestInfo': |
| $filename = 'vclConnectRequest.js'; |
| $dojoRequires = array('dojo.parser', |
| 'dijit.form.Button', |
| 'dijit.Dialog'); |
| break; |
| case 'blockAllocations': |
| $filename = 'vclViewBlockAllocations.js'; |
| $dojoRequires = array('dojo.parser', |
| 'dijit.form.Button', |
| 'dijit.form.ValidationTextBox', |
| 'dijit.form.FilteringSelect', |
| 'dijit.form.Textarea', |
| 'dojox.grid.DataGrid', |
| 'dijit.Dialog', |
| 'dojox.string.sprintf', |
| 'dojo.data.ItemFileWriteStore', |
| 'dojox.charting.widget.Chart2D', |
| 'dojox.charting.action2d.Tooltip', |
| 'dojox.charting.action2d.Magnify', |
| 'dojox.charting.themes.ThreeD'); |
| break; |
| case 'requestBlockAllocation': |
| case 'newBlockAllocation': |
| case 'editBlockAllocation': |
| $filename = 'vclEditBlockAllocation.js'; |
| $dojoRequires = array('dojo.parser', |
| 'dijit.layout.StackContainer', |
| 'dijit.layout.ContentPane', |
| 'dijit.form.DateTextBox', |
| 'dijit.form.TimeTextBox', |
| 'vcldojo.TimeTextBoxEnd', |
| 'dijit.form.Textarea', |
| 'dijit.form.FilteringSelect', |
| 'dijit.form.NumberSpinner', |
| 'dojox.grid.DataGrid', |
| 'dojox.string.sprintf', |
| 'dijit.Tooltip', |
| 'dijit.Dialog', |
| 'dojo.data.ItemFileWriteStore'); |
| break; |
| case 'viewBlockStatus': |
| case 'selectauth': |
| $filename = 'vclBasic.js'; |
| $dojoRequires = array('dojo.parser'); |
| break; |
| case 'viewBlockAllocatedMachines': |
| $filename = 'vclBlockMachines.js'; |
| $dojoRequires = array('dojo.parser', |
| 'dojox.string.sprintf', |
| 'dijit.form.Button', |
| 'dijit.form.DateTextBox', |
| 'dijit.form.TimeTextBox', |
| 'dojox.charting.widget.Chart2D', |
| 'dojox.charting.action2d.Tooltip', |
| 'dojox.charting.action2d.Magnify', |
| 'dojox.charting.themes.ThreeD'); |
| break; |
| case 'viewGroups': |
| case 'submitEditGroup': |
| case 'submitAddGroup': |
| case 'submitDeleteGroup': |
| $filename = 'vclManageGroups.js'; |
| $dojoRequires = array('dojo.parser', |
| 'dojo.data.ItemFileReadStore', |
| 'dojo.data.ItemFileWriteStore', |
| 'dijit.form.Select', |
| 'dijit.form.Button', |
| 'dijit.form.CheckBox', |
| 'dijit.form.TextBox', |
| 'dojox.grid.DataGrid', |
| 'dijit.TitlePane', |
| 'dijit.Dialog', |
| 'dijit.Tooltip'); |
| break; |
| case 'viewResources': |
| case 'editConfigMap': |
| $filename = 'vclResources.js'; |
| $dojoRequires = array('dojo.parser', |
| 'dojo.data.ItemFileReadStore', |
| 'dojo.data.ItemFileWriteStore', |
| 'dijit.form.Select', |
| 'dijit.form.Button', |
| 'dijit.form.ValidationTextBox', |
| 'dijit.form.CheckBox', |
| 'dijit.form.TextBox', |
| 'dijit.form.NumberSpinner', |
| 'dijit.form.HorizontalSlider', |
| 'dojox.grid.DataGrid', |
| 'dijit.TitlePane', |
| 'dijit.form.FilteringSelect', |
| 'dijit.form.ComboBox', |
| 'dijit.form.Textarea', |
| 'dijit.InlineEditBox', |
| 'dijit.form.TimeTextBox', |
| 'dojox.string.sprintf', |
| 'dijit.form.CheckBox', |
| 'dijit.Tooltip', |
| 'dojox.grid._CheckBoxSelector', |
| 'dijit.Menu', |
| 'dojo.cookie', |
| 'dijit.Dialog'); |
| break; |
| case 'groupMapHTML': |
| $filename = 'vclResourceGroupMap.js'; |
| $dojoRequires = array('dojo.parser', |
| 'dijit.layout.LinkPane', |
| 'dijit.layout.ContentPane', |
| 'dijit.layout.TabContainer', |
| 'dojo.data.ItemFileWriteStore', |
| 'dojox.form.CheckedMultiSelect', |
| 'dojox.grid.DataGrid', |
| 'dijit.form.Button'); |
| break; |
| case 'editVMInfo': |
| $filename = 'vclVirtualHosts.js'; |
| $dojoRequires = array('dojo.parser', |
| 'dijit.InlineEditBox', |
| 'dijit.form.NumberSpinner', |
| 'dijit.form.Button', |
| 'dijit.form.TextBox', |
| 'dijit.form.Textarea', |
| 'dijit.form.FilteringSelect', |
| 'dijit.form.Select', |
| 'dijit.TitlePane', |
| 'dijit.layout.ContentPane', |
| 'dijit.layout.TabContainer', |
| 'dojo.data.ItemFileReadStore', |
| 'dijit.Tooltip', |
| 'dijit.Dialog'); |
| break; |
| case 'siteMaintenance': |
| $filename = 'vclMaintenance.js'; |
| $dojoRequires = array('dojo.parser', |
| 'dijit.form.Button', |
| 'dijit.form.NumberSpinner', |
| 'dijit.form.DateTextBox', |
| 'dijit.form.TimeTextBox', |
| 'dijit.form.TextBox', |
| 'dijit.form.Select', |
| 'dijit.form.Textarea', |
| 'dojox.string.sprintf', |
| 'dijit.Tooltip', |
| 'dijit.Dialog'); |
| break; |
| case 'userpreferences': |
| case 'submitgeneralprefs': |
| $filename = 'vclUserPreferences.js'; |
| $dojoRequires = array('dojo.parser', |
| 'dijit.form.Textarea'); |
| break; |
| case 'viewstats': |
| $filename = 'vclStats.js'; |
| $dojoRequires = array('dojo.parser', |
| 'dojox.charting.Chart2D', |
| 'dojox.charting.action2d.Tooltip', |
| 'dojox.charting.action2d.Magnify', |
| 'dojox.charting.themes.ThreeD'); |
| break; |
| case 'dashboard': |
| $filename = 'vclDashboard.js'; |
| $dojoRequires = array('dojo.parser', |
| 'dijit.Tooltip', |
| 'dijit.form.Button', |
| 'dojox.charting.widget.Chart2D', |
| 'dojox.charting.action2d.Tooltip', |
| 'dojox.charting.action2d.Magnify', |
| 'dojox.charting.themes.ThreeD', |
| 'dojox.string.sprintf'); |
| break; |
| case 'siteconfig': |
| $filename = 'siteconfig.js'; |
| $dojoRequires = array('dojo.parser', |
| 'dijit.Dialog', |
| 'dijit.form.Button', |
| 'dijit.form.Textarea', |
| 'dijit.form.FilteringSelect', |
| 'dijit.form.Select', |
| 'dijit.form.NumberSpinner', |
| 'dijit.form.CheckBox', |
| 'dijit.form.ValidationTextBox', |
| 'dijit.layout.ContentPane', |
| 'dojox.layout.FloatingPane', |
| 'dijit.layout.TabContainer'); |
| break; |
| case 'newOneClick': |
| case 'editOneClick': |
| case 'submitOneClick': |
| case 'submitEditOneClick': |
| case 'deleteOneClick': |
| $filename = 'vclgos.js'; |
| $dojoRequires = array('dojo.parser', |
| 'dijit.layout.ContentPane', |
| 'dijit.form.ValidationTextBox', |
| 'dijit.layout.TabContainer'); |
| break; |
| # TODO clean up |
| /*case 'serverProfiles': |
| $filename = 'vclServerProfiles.js'; |
| $dojoRequires = array('dojo.parser', |
| 'dijit.Dialog', |
| 'dijit.form.Button', |
| 'dijit.form.FilteringSelect', |
| 'dijit.form.Select', |
| 'dijit.form.TextBox', |
| 'dijit.form.ValidationTextBox', |
| 'dijit.form.CheckBox', |
| 'dijit.form.Textarea', |
| 'dijit.layout.ContentPane', |
| 'dijit.layout.TabContainer', |
| 'dojox.string.sprintf', |
| 'dojo.data.ItemFileWriteStore'); |
| break;*/ |
| /*case 'testDojoREST': |
| $filename = ''; |
| $dojoRequires = array('dojo.parser', |
| 'dijit.form.FilteringSelect', |
| 'dijit.form.Button', |
| 'dojo.data.ObjectStore', |
| 'dojo.store.JsonRest'); |
| break;*/ |
| } |
| # END DOJO PARSING |
| if(empty($dojoRequires)) |
| return ''; |
| $customfile = ''; |
| $v = $VCLversion; |
| if(! empty($filename)) |
| $customfile = sprintf("<script type=\"text/javascript\" src=\"dojo/dojo/%s?v=$v\"></script>\n", $filename); |
| $rt = ''; |
| $jslocale = strtolower(str_replace('_', '-', $locale)); |
| $rt .= "<script type=\"text/javascript\">\n"; |
| if(isset($_SESSION['persistdata']) && array_key_exists('tzoffset', $_SESSION['persistdata'])) |
| $rt .= " var tzoffset = {$_SESSION['persistdata']['tzoffset']};\n"; |
| else |
| $rt .= " var tzoffset = 'unset';\n"; |
| $rt .= " setTimeout(init, 100);\n"; |
| $rt .= "</script>\n"; |
| switch($mode) { |
| |
| case "viewRequests": |
| $rt .= "<style type=\"text/css\">\n"; |
| $rt .= " @import \"themes/$skin/css/dojo/$skin.css\";\n"; |
| $rt .= " @import \"dojo/dojox/layout/resources/FloatingPane.css\";\n"; |
| $rt .= " @import \"dojo/dojox/layout/resources/ResizeHandle.css\";\n"; |
| $rt .= " @import \"dojo/dojox/grid/resources/Grid.css\";\n"; |
| $rt .= "</style>\n"; |
| $rt .= "<script type=\"text/javascript\" src=\"js/requests.js?v=$v\"></script>\n"; |
| $rt .= "<script type=\"text/javascript\" src=\"js/resources.js?v=$v\"></script>\n"; |
| $rt .= "<script type=\"text/javascript\" src=\"js/resources/image.js?v=$v\"></script>\n"; |
| # TODO keep this or move functions? |
| $rt .= "<script type=\"text/javascript\" src=\"js/newresservercommon.js?v=$v\"></script>\n"; |
| $rt .= "<script type=\"text/javascript\" src=\"dojo/dojo/dojo.js\"\n"; |
| $rt .= " djConfig=\"parseOnLoad: true, locale: '$jslocale'\">\n"; |
| $rt .= "</script>\n"; |
| $rt .= $customfile; |
| $rt .= "<script type=\"text/javascript\">\n"; |
| $rt .= " dojo.addOnLoad(function() {\n"; |
| $rt .= " dojo.registerModulePath(\"vcldojo\", \"../../js/vcldojo\");\n"; |
| foreach($dojoRequires as $req) |
| $rt .= " dojo.require(\"$req\");\n"; |
| $rt .= " testJS();\n"; |
| $rt .= " document.onmousemove = updateMouseXY;\n"; |
| $rt .= " showScriptOnly();\n"; |
| /*$cont = addContinuationsEntry('AJserverProfileStoreData', array(), 120, 1, 0); |
| $rt .= " populateProfileStore('$cont');\n";*/ |
| $rt .= " });\n"; |
| if($refresh) |
| $rt .= " refresh_timer = setTimeout(resRefresh, 12000);\n"; |
| $rt .= " check_timeout_timer = setTimeout(checkTimeouts, 15000);\n"; |
| $imaging = getContinuationVar('imaging', 0); |
| $rt .= " initViewRequests($imaging);\n"; |
| $rt .= "</script>\n"; |
| return $rt; |
| |
| case 'viewRequestInfo': |
| $rt .= "<style type=\"text/css\">\n"; |
| $rt .= " @import \"themes/$skin/css/dojo/$skin.css\";\n"; |
| $rt .= "</style>\n"; |
| $rt .= "<script type=\"text/javascript\" src=\"js/requests.js?v=$v\"></script>\n"; |
| $rt .= "<script type=\"text/javascript\" src=\"dojo/dojo/dojo.js\"\n"; |
| $rt .= " djConfig=\"parseOnLoad: true, locale: '$jslocale'\">\n"; |
| $rt .= "</script>\n"; |
| $rt .= $customfile; |
| $rt .= "<script type=\"text/javascript\">\n"; |
| $rt .= " dojo.addOnLoad(function() {\n"; |
| foreach($dojoRequires as $req) |
| $rt .= " dojo.require(\"$req\");\n"; |
| $rt .= " });\n"; |
| $rt .= "</script>\n"; |
| return $rt; |
| |
| case 'requestBlockAllocation': |
| case 'newBlockAllocation': |
| case 'editBlockAllocation': |
| case 'blockAllocations': |
| $rt .= "<style type=\"text/css\">\n"; |
| $rt .= " @import \"themes/$skin/css/dojo/$skin.css\";\n"; |
| $rt .= " @import \"dojo/dojox/grid/resources/Grid.css\";\n"; |
| $rt .= "</style>\n"; |
| $rt .= "<script type=\"text/javascript\" src=\"js/blockallocations.js?v=$v\"></script>\n"; |
| $rt .= "<script type=\"text/javascript\" src=\"dojo/dojo/dojo.js\"\n"; |
| $rt .= " djConfig=\"parseOnLoad: true, locale: '$jslocale'\">\n"; |
| $rt .= "</script>\n"; |
| $rt .= $customfile; |
| $rt .= "<script type=\"text/javascript\">\n"; |
| $rt .= " dojo.addOnLoad(function() {\n"; |
| $rt .= " dojo.registerModulePath(\"vcldojo\", \"../../js/vcldojo\");\n"; |
| foreach($dojoRequires as $req) |
| $rt .= " dojo.require(\"$req\");\n"; |
| if($mode == 'editBlockAllocation') { |
| $blockid = getContinuationVar('blockid'); |
| $cont = addContinuationsEntry('AJpopulateBlockStore', array('blockid' => $blockid), SECINDAY, 1, 0); |
| $rt .= " populateBlockStore('$cont');\n"; |
| } |
| $rt .= " });\n"; |
| if($mode == 'editBlockAllocation') |
| $rt .= " var pagemode = 'edit';\n"; |
| else |
| $rt .= " var pagemode = 'new';\n"; |
| $rt .= "</script>\n"; |
| return $rt; |
| |
| case "viewBlockStatus": |
| $rt .= "<style type=\"text/css\">\n"; |
| $rt .= " @import \"themes/$skin/css/dojo/$skin.css\";\n"; |
| $rt .= "</style>\n"; |
| $rt .= "<script type=\"text/javascript\" src=\"js/blockallocations.js?v=$v\"></script>\n"; |
| $rt .= "<script type=\"text/javascript\" src=\"dojo/dojo/dojo.js\"\n"; |
| $rt .= " djConfig=\"parseOnLoad: true, locale: '$jslocale'\">\n"; |
| $rt .= "</script>\n"; |
| $rt .= $customfile; |
| $rt .= "<script type=\"text/javascript\">\n"; |
| $rt .= " dojo.addOnLoad(function() {\n"; |
| foreach($dojoRequires as $req) |
| $rt .= " dojo.require(\"$req\");\n"; |
| $rt .= " });\n"; |
| $rt .= " setTimeout(updateBlockStatus, 30000);\n"; |
| $rt .= "</script>\n"; |
| return $rt; |
| |
| case 'viewBlockAllocatedMachines': |
| $rt .= "<style type=\"text/css\">\n"; |
| $rt .= " @import \"themes/$skin/css/dojo/$skin.css\";\n"; |
| $rt .= "</style>\n"; |
| $rt .= "<script type=\"text/javascript\" src=\"js/blockallocations.js?v=$v\"></script>\n"; |
| $rt .= "<script type=\"text/javascript\" src=\"dojo/dojo/dojo.js\"\n"; |
| $rt .= " djConfig=\"parseOnLoad: true, locale: '$jslocale'\">\n"; |
| $rt .= "</script>\n"; |
| $rt .= $customfile; |
| $rt .= "<script type=\"text/javascript\">\n"; |
| foreach($dojoRequires as $req) |
| $rt .= " dojo.require(\"$req\");\n"; |
| $rt .= " dojo.addOnLoad(function() {\n"; |
| $rt .= " updateAllocatedMachines();\n"; |
| $rt .= " });\n"; |
| $rt .= "</script>\n"; |
| return $rt; |
| |
| case 'groupMapHTML': |
| $rt .= "<style type=\"text/css\">\n"; |
| $rt .= " @import \"themes/$skin/css/dojo/$skin.css\";\n"; |
| $rt .= " @import \"dojo/dojox/form/resources/CheckedMultiSelect.css\";\n"; |
| $rt .= " @import \"dojo/dojox/grid/resources/Grid.css\";\n"; |
| $rt .= "</style>\n"; |
| $rt .= "<script type=\"text/javascript\" src=\"js/resources.js?v=$v\"></script>\n"; |
| $cdata = getContinuationVar(); |
| switch($cdata['obj']->restype) { |
| # could make it generic as follows, but consider security risk |
| # of someone being able to get $cdata['obj']->restype set to anything |
| # $jsfile = "resources/{$cdata['obj']->restype}.js"; |
| # break; |
| case 'config': |
| $jsfile = 'resources/config.js'; |
| break; |
| case 'image': |
| $jsfile = 'resources/image.js'; |
| break; |
| case 'schedule': |
| $jsfile = 'resources/schedule.js'; |
| break; |
| case 'managementnode': |
| $jsfile = 'resources/managementnode.js'; |
| break; |
| case 'computer': |
| $jsfile = 'resources/computer.js'; |
| break; |
| case 'addomain': |
| $jsfile = 'resources/addomain.js'; |
| break; |
| } |
| if(isset($jsfile)) |
| $rt .= "<script type=\"text/javascript\" src=\"js/$jsfile?v=$v\"></script>\n"; |
| $rt .= "<script type=\"text/javascript\" src=\"dojo/dojo/dojo.js\"\n"; |
| $rt .= " djConfig=\"parseOnLoad: true, locale: '$jslocale'\">\n"; |
| $rt .= "</script>\n"; |
| $rt .= $customfile; |
| $rt .= "<script type=\"text/javascript\">\n"; |
| $rt .= " dojo.addOnLoad(function() {\n"; |
| foreach($dojoRequires as $req) |
| $rt .= " dojo.require(\"$req\");\n"; |
| $rt .= " });\n"; |
| $rt .= " dojo.addOnLoad(editGroupMapInit);\n"; |
| $rt .= "</script>\n"; |
| return $rt; |
| |
| case 'viewGroups': |
| case 'submitEditGroup': |
| case 'submitAddGroup': |
| case 'submitDeleteGroup': |
| $rt .= "<style type=\"text/css\">\n"; |
| $rt .= " @import \"themes/$skin/css/dojo/$skin.css\";\n"; |
| $rt .= " @import \"dojo/dojox/grid/resources/Grid.css\";\n"; |
| $rt .= "</style>\n"; |
| $rt .= "<script type=\"text/javascript\" src=\"dojo/dojo/dojo.js\"\n"; |
| $rt .= " djConfig=\"parseOnLoad: true, locale: '$jslocale'\">\n"; |
| $rt .= "</script>\n"; |
| $rt .= $customfile; |
| $rt .= "<script type=\"text/javascript\">\n"; |
| $rt .= " dojo.addOnLoad(function() {\n"; |
| foreach($dojoRequires as $req) |
| $rt .= " dojo.require(\"$req\");\n"; |
| $rt .= " });\n"; |
| $rt .= " dojo.addOnLoad(function() {document.onmousemove = updateMouseXY;});\n"; |
| $rt .= " dojo.ready(function() {\n"; |
| $rt .= " buildUserFilterStores();\n"; |
| $rt .= " buildResourceFilterStores();\n"; |
| $rt .= " if(! usergroupstore.comparatorMap)\n"; |
| $rt .= " usergroupstore.comparatorMap = {};\n"; |
| $rt .= " usergroupstore.comparatorMap['name'] = nocasesort;\n"; |
| $rt .= " if(! resourcegroupstore.comparatorMap)\n"; |
| $rt .= " resourcegroupstore.comparatorMap = {};\n"; |
| $rt .= " resourcegroupstore.comparatorMap['name'] = nocasesort;\n"; |
| $rt .= " });\n"; |
| $rt .= "</script>\n"; |
| $rt .= "<script type=\"text/javascript\" src=\"js/groups.js?v=$v\"></script>\n"; |
| return $rt; |
| |
| case 'viewResources': |
| case 'editConfigMap': |
| $rt .= "<style type=\"text/css\">\n"; |
| $rt .= " @import \"themes/$skin/css/dojo/$skin.css\";\n"; |
| $rt .= " @import \"dojo/dojox/grid/resources/Grid.css\";\n"; |
| $rt .= "</style>\n"; |
| $rt .= "<script type=\"text/javascript\" src=\"dojo/dojo/dojo.js\"\n"; |
| $rt .= " djConfig=\"parseOnLoad: true, locale: '$jslocale'\">\n"; |
| $rt .= "</script>\n"; |
| $rt .= $customfile; |
| $cdata = getContinuationVar(); |
| $rt .= "<script type=\"text/javascript\">\n"; |
| $rt .= " dojo.addOnLoad(function() {\n"; |
| $rt .= " dojo.registerModulePath(\"vcldojo\", \"../../js/vcldojo\");\n"; |
| foreach($dojoRequires as $req) |
| $rt .= " dojo.require(\"$req\");\n"; |
| $rt .= " setTimeout(initViewResources, 100);\n"; |
| if($cdata['obj']->restype == 'computer') |
| $rt .= " initPage();\n"; |
| $rt .= " });\n"; |
| $rt .= "</script>\n"; |
| switch($cdata['obj']->restype) { |
| # could make it generic as follows, but consider security risk |
| # of someone being able to get $cdata['obj']->restype set to anything |
| # $jsfile = "resources/{$cdata['obj']->restype}.js"; |
| # break; |
| case 'config': |
| $jsfile = 'resources/config.js'; |
| break; |
| case 'image': |
| $jsfile = 'resources/image.js'; |
| break; |
| case 'schedule': |
| $jsfile = 'resources/schedule.js'; |
| break; |
| case 'managementnode': |
| $jsfile = 'resources/managementnode.js'; |
| break; |
| case 'computer': |
| $jsfile = 'resources/computer.js'; |
| break; |
| case 'addomain': |
| $jsfile = 'resources/addomain.js'; |
| break; |
| } |
| $rt .= "<script type=\"text/javascript\" src=\"js/resources.js?v=$v\"></script>\n"; |
| if(isset($jsfile)) |
| $rt .= "<script type=\"text/javascript\" src=\"js/$jsfile?v=$v\"></script>\n"; |
| return $rt; |
| |
| /*case "serverProfiles": |
| $rt .= "<style type=\"text/css\">\n"; |
| $rt .= " @import \"themes/$skin/css/dojo/$skin.css\";\n"; |
| $rt .= "</style>\n"; |
| $rt .= "<script type=\"text/javascript\" src=\"js/serverprofiles.js?v=$v\"></script>\n"; |
| $rt .= "<script type=\"text/javascript\" src=\"js/newresservercommon.js?v=$v\"></script>\n"; |
| $rt .= "<script type=\"text/javascript\" src=\"dojo/dojo/dojo.js\"\n"; |
| $rt .= " djConfig=\"parseOnLoad: true, locale: '$jslocale'\">\n"; |
| $rt .= "</script>\n"; |
| $rt .= $customfile; |
| $rt .= "<script type=\"text/javascript\">\n"; |
| $rt .= " dojo.addOnLoad(function() {\n"; |
| foreach($dojoRequires as $req) |
| $rt .= " dojo.require(\"$req\");\n"; |
| $cont = addContinuationsEntry('AJserverProfileStoreData', array(), 120, 1, 0); |
| $rt .= " populateProfileStore('$cont');\n"; |
| $rt .= " });\n"; |
| $rt .= " dojo.addOnLoad(getProfiles);\n"; |
| $rt .= "</script>\n"; |
| return $rt;*/ |
| |
| case 'selectauth': |
| $rt .= "<script type=\"text/javascript\" src=\"dojo/dojo/dojo.js\"></script>\n"; |
| $rt .= $customfile; |
| $rt .= "<script type=\"text/javascript\">\n"; |
| foreach($dojoRequires as $req) |
| $rt .= " dojo.require(\"$req\");\n"; |
| $authtype = processInputVar("authtype", ARG_STRING); |
| $rt .= " dojo.addOnLoad(function() {document.loginform.userid.focus(); document.loginform.userid.select();});\n"; |
| $rt .= "</script>\n"; |
| return $rt; |
| |
| case "editVMInfo": |
| $rt .= "<style type=\"text/css\">\n"; |
| $rt .= " @import \"themes/$skin/css/dojo/$skin.css\";\n"; |
| $rt .= "</style>\n"; |
| $rt .= "<script type=\"text/javascript\" src=\"js/vm.js?v=$v\"></script>\n"; |
| $rt .= "<script type=\"text/javascript\" src=\"dojo/dojo/dojo.js\"\n"; |
| $rt .= " djConfig=\"parseOnLoad: true, locale: '$jslocale'\">\n"; |
| $rt .= "</script>\n"; |
| $rt .= $customfile; |
| $rt .= "<script type=\"text/javascript\">\n"; |
| $rt .= " dojo.addOnLoad(function() {\n"; |
| foreach($dojoRequires as $req) |
| $rt .= " dojo.require(\"$req\");\n"; |
| $rt .= " });\n"; |
| $rt .= "</script>\n"; |
| return $rt; |
| |
| case "viewNodes": |
| $rt .= "<style type=\"text/css\">\n"; |
| $rt .= " @import \"themes/$skin/css/dojo/$skin.css\";\n"; |
| $rt .= "</style>\n"; |
| $rt .= "<script type=\"text/javascript\" src=\"js/privileges.js?v=$v\"></script>\n"; |
| $rt .= "<script type=\"text/javascript\" src=\"dojo/dojo/dojo.js\"\n"; |
| $rt .= " djConfig=\"parseOnLoad: true, locale: '$jslocale'\">\n"; |
| $rt .= "</script>\n"; |
| $rt .= $customfile; |
| $rt .= "<script type=\"text/javascript\">\n"; |
| $rt .= " dojo.addOnLoad(function() {\n"; |
| foreach($dojoRequires as $req) |
| $rt .= " dojo.require(\"$req\");\n"; |
| $rt .= " document.onmousemove = updateMouseXY;\n"; |
| $rt .= " dojo.connect(document, 'onmouseup', mouseRelease);\n"; |
| $rt .= " });\n"; |
| $rt .= "</script>\n"; |
| return $rt; |
| |
| case "siteMaintenance": |
| $rt .= "<style type=\"text/css\">\n"; |
| $rt .= " @import \"themes/$skin/css/dojo/$skin.css\";\n"; |
| $rt .= "</style>\n"; |
| $rt .= "<script type=\"text/javascript\" src=\"js/sitemaintenance.js?v=$v\"></script>\n"; |
| $rt .= "<script type=\"text/javascript\" src=\"dojo/dojo/dojo.js\"\n"; |
| $rt .= " djConfig=\"parseOnLoad: true, locale: '$jslocale'\">\n"; |
| $rt .= "</script>\n"; |
| $rt .= $customfile; |
| $rt .= "<script type=\"text/javascript\">\n"; |
| $rt .= " dojo.addOnLoad(function() {\n"; |
| foreach($dojoRequires as $req) |
| $rt .= " dojo.require(\"$req\");\n"; |
| $rt .= " });\n"; |
| $rt .= "</script>\n"; |
| return $rt; |
| |
| case "viewstats": |
| $rt .= "<style type=\"text/css\">\n"; |
| $rt .= " @import \"themes/$skin/css/dojo/$skin.css\";\n"; |
| $rt .= "</style>\n"; |
| $rt .= "<script type=\"text/javascript\" src=\"js/statistics.js?v=$v\"></script>\n"; |
| $rt .= "<script type=\"text/javascript\" src=\"dojo/dojo/dojo.js\"\n"; |
| $rt .= " djConfig=\"parseOnLoad: true, locale: '$jslocale'\">\n"; |
| $rt .= "</script>\n"; |
| $rt .= $customfile; |
| $rt .= "<script type=\"text/javascript\">\n"; |
| $rt .= " dojo.addOnLoad(function() {\n"; |
| foreach($dojoRequires as $req) |
| $rt .= " dojo.require(\"$req\");\n"; |
| $rt .= " generateGraphs();\n"; |
| $rt .= " });\n"; |
| $rt .= "</script>\n"; |
| return $rt; |
| |
| case "dashboard": |
| $rt .= "<style type=\"text/css\">\n"; |
| $rt .= " @import \"themes/$skin/css/dojo/$skin.css\";\n"; |
| $rt .= " @import \"css/dashboard.css\";\n"; |
| $rt .= "</style>\n"; |
| $rt .= "<script type=\"text/javascript\" src=\"js/dashboard.js?v=$v\"></script>\n"; |
| $rt .= "<script type=\"text/javascript\" src=\"dojo/dojo/dojo.js\"\n"; |
| $rt .= " djConfig=\"parseOnLoad: true, locale: '$jslocale'\">\n"; |
| $rt .= "</script>\n"; |
| $rt .= $customfile; |
| $rt .= "<script type=\"text/javascript\">\n"; |
| $rt .= " dojo.addOnLoad(function() {\n"; |
| foreach($dojoRequires as $req) |
| $rt .= " dojo.require(\"$req\");\n"; |
| $rt .= " updateDashboard();\n"; |
| $rt .= " });\n"; |
| $rt .= "</script>\n"; |
| return $rt; |
| |
| case "siteconfig": |
| $rt .= "<style type=\"text/css\">\n"; |
| $rt .= " @import \"themes/$skin/css/dojo/$skin.css\";\n"; |
| $rt .= " @import \"dojo/dojox/layout/resources/FloatingPane.css\";\n"; |
| $rt .= " @import \"css/siteconfig.css\";\n"; |
| $rt .= "</style>\n"; |
| $rt .= "<script type=\"text/javascript\" src=\"js/siteconfig.js?v=$v\"></script>\n"; |
| $rt .= "<script type=\"text/javascript\" src=\"dojo/dojo/dojo.js\"\n"; |
| $rt .= " djConfig=\"parseOnLoad: true, locale: '$jslocale'\">\n"; |
| $rt .= "</script>\n"; |
| $rt .= $customfile; |
| $rt .= "<script type=\"text/javascript\">\n"; |
| $rt .= " dojo.addOnLoad(function() {\n"; |
| foreach($dojoRequires as $req) |
| $rt .= " dojo.require(\"$req\");\n"; |
| $rt .= " });\n"; |
| $rt .= "</script>\n"; |
| return $rt; |
| |
| /*case 'testDojoREST': |
| $rt .= "<style type=\"text/css\">\n"; |
| $rt .= " @import \"themes/$skin/css/dojo/$skin.css\";\n"; |
| $rt .= "</style>\n"; |
| $rt .= "<script type=\"text/javascript\" src=\"dojo/dojo/dojo.js\"\n"; |
| $rt .= " djConfig=\"parseOnLoad: true, locale: '$jslocale'\">\n"; |
| $rt .= "</script>\n"; |
| $rt .= "<script type=\"text/javascript\">\n"; |
| foreach($dojoRequires as $req) |
| $rt .= " dojo.require(\"$req\");\n"; |
| $rt .= "</script>\n"; |
| return $rt;*/ |
| |
| default: |
| $rt .= "<style type=\"text/css\">\n"; |
| $rt .= " @import \"themes/$skin/css/dojo/$skin.css\";\n"; |
| $rt .= "</style>\n"; |
| $rt .= "<script type=\"text/javascript\" src=\"dojo/dojo/dojo.js\"\n"; |
| $rt .= " djConfig=\"parseOnLoad: true, locale: '$jslocale'\">\n"; |
| $rt .= "</script>\n"; |
| $rt .= $customfile; |
| $rt .= "<script type=\"text/javascript\">\n"; |
| $rt .= " dojo.addOnLoad(function() {\n"; |
| foreach($dojoRequires as $req) |
| $rt .= " dojo.require(\"$req\");\n"; |
| $rt .= " });\n"; |
| $rt .= "</script>\n"; |
| return $rt; |
| } |
| return ''; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn printHTMLFooter() |
| /// |
| /// \brief prints the footer part of the html template |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function printHTMLFooter() { |
| global $mode, $noHTMLwrappers; |
| if(in_array($mode, $noHTMLwrappers)) |
| return; |
| print getFooter(); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn changeLocale() |
| /// |
| /// \brief sets a cookie for the locale and redirects back to the site |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function changeLocale() { |
| global $locale, $authed, $authMechs; |
| if($authed) { |
| $newlocale = getContinuationVar('locale'); |
| $oldmode = getContinuationVar('oldmode'); |
| $authtype = getContinuationVar('authtype', ''); |
| } |
| else { |
| $newlocale = processInputVar('locale', ARG_STRING); |
| $oldmode = processInputVar('oldmode', ARG_STRING); |
| $authtype = processInputVar('authtype', ARG_STRING); |
| if($oldmode != 'selectauth') |
| $oldmode = ''; |
| if(! array_key_exists($authtype, $authMechs)) |
| $authtype = ''; |
| $locales = getFSlocales(); |
| if(! array_key_exists($newlocale, $locales)) { |
| header("Location: " . BASEURL . SCRIPT); |
| dbDisconnect(); |
| exit; |
| } |
| } |
| $locale = $newlocale; |
| setcookie("VCLLOCALE", $locale, (time() + (86400 * 31)), "/", COOKIEDOMAIN); |
| $extra = ''; |
| if($oldmode == 'selectauth' && ! empty($authtype)) |
| $extra = "&authtype=$authtype"; |
| header("Location: " . BASEURL . SCRIPT . "?mode=$oldmode$extra"); |
| dbDisconnect(); |
| exit; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn i($str) |
| /// |
| /// \param $str - string |
| /// |
| /// \return possibly translated $str with any single quotes changed to ' |
| /// |
| /// \brief function name comes from first letter of "internationalize" - calls |
| /// _() on $str and converts any single quotes in returned string to ' |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function i($str) { |
| return preg_replace("/'/", ''', _($str)); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn setVCLLocale() |
| /// |
| /// \brief sets a cookie for the locale; configures php for the locale |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function setVCLLocale() { |
| global $locale; |
| # set a cookie for the locale if it has not been set already |
| if(! array_key_exists('VCLLOCALE', $_COOKIE)) { |
| setcookie("VCLLOCALE", 'en_US', (time() + (86400 * 31)), "/", COOKIEDOMAIN); |
| $locale = DEFAULTLOCALE; |
| } |
| // if a cookie has already been set, just update the expiration time for it |
| else { |
| setcookie("VCLLOCALE", $_COOKIE['VCLLOCALE'], (time() + (86400 * 31)), "/", COOKIEDOMAIN); |
| $locale = $_COOKIE['VCLLOCALE']; |
| } |
| |
| #putenv('LC_ALL=' . $locale); |
| # use UTF8 encoding for any locales other than English (we may just be able |
| # to always use UTF8) |
| if(preg_match('/^en/', $locale)) |
| setlocale(LC_ALL, $locale); |
| else |
| setlocale(LC_ALL, $locale . '.UTF8'); |
| bindtextdomain('vcl', './locale'); |
| textdomain('vcl'); |
| bind_textdomain_codeset('vcl', 'UTF-8'); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getSelectLanguagePulldown() |
| /// |
| /// \return HTML for a select drop down |
| /// |
| /// \brief generates HTML for a select drop down for changing the locale of |
| /// the site |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getSelectLanguagePulldown() { |
| global $locale, $user, $remoteIP, $mode, $authMechs, $authed; |
| $tmp = explode('/', $_SERVER['SCRIPT_FILENAME']); |
| array_pop($tmp); |
| array_push($tmp, 'locale'); |
| |
| $locales = getFSlocales(); |
| |
| if(count($locales) < 1) |
| return ''; |
| |
| if(! is_array($user)) |
| $user['id'] = 0; |
| |
| $rt = "<form name=\"localeform\" class=\"localeform\" action=\"" . BASEURL . SCRIPT . "\" method=post>\n"; |
| if($authed) { |
| $rt .= "<select name=\"continuation\" onChange=\"this.form.submit();\" autocomplete=\"off\">\n"; |
| $cdata = array('IP' => $remoteIP, 'oldmode' => $mode); |
| if($mode == 'selectauth') { |
| $type = processInputVar('authtype', ARG_STRING); |
| if(! empty($type) && array_key_exists($type, $authMechs)) |
| $cdata['authtype'] = $type; |
| } |
| foreach($locales as $dir => $lang) { |
| $cdata['locale'] = $dir; |
| $tmp = explode('/', $dir); |
| $testlocale = array_pop($tmp); |
| $cont = addContinuationsEntry('changeLocale', $cdata, 86400); |
| if($locale == $testlocale) |
| $rt .= "<option value=\"$cont\" selected>{$lang}</option>\n"; |
| else |
| $rt .= "<option value=\"$cont\">{$lang}</option>\n"; |
| } |
| $rt .= "</select>\n"; |
| } |
| else { |
| $rt .= "<select name=\"locale\" onChange=\"this.form.submit();\" autocomplete=\"off\">\n"; |
| foreach($locales as $dir => $lang) { |
| $tmp = explode('/', $dir); |
| $testlocale = array_pop($tmp); |
| if($locale == $testlocale) |
| $rt .= "<option value=\"$dir\" selected>{$lang}</option>\n"; |
| else |
| $rt .= "<option value=\"$dir\">{$lang}</option>\n"; |
| } |
| $rt .= "</select>\n"; |
| if($mode == 'selectauth') { |
| $type = processInputVar('authtype', ARG_STRING); |
| if(! empty($type) && array_key_exists($type, $authMechs)) { |
| $rt .= "<input type=\"hidden\" name=\"authtype\" value=\"$type\">\n"; |
| $rt .= "<input type=\"hidden\" name=\"oldmode\" value=\"selectauth\">\n"; |
| } |
| } |
| $rt .= "<input type=\"hidden\" name=\"mode\" value=\"changeLocale\">\n"; |
| } |
| $rt .= "</form> \n"; |
| return $rt; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getFSlocales() |
| /// |
| /// \return an array of locales supported in the filesystem where the key is |
| /// the locale and the value is the name of the locale/language |
| /// |
| /// \brief looks for supported locales in the filesystem and returns a list of |
| /// them |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function getFSlocales() { |
| if(isset($_SESSION['locales'])) |
| return $_SESSION['locales']; |
| $tmp = explode('/', $_SERVER['SCRIPT_FILENAME']); |
| array_pop($tmp); |
| $mainpath = implode('/', $tmp); |
| array_push($tmp, 'locale'); |
| $localedir = implode('/', $tmp); |
| $dirs = glob("{$localedir}/*"); |
| $locales = array('en_US' => 'English'); |
| foreach($dirs as $dir) { |
| if(! file_exists("{$dir}/LC_MESSAGES/vcl.mo")) |
| continue; |
| if(! file_exists("{$dir}/language")) |
| continue; |
| $fh = fopen("{$dir}/language", 'r'); |
| while($line = fgetss($fh)) { |
| if(preg_match('/(^#)|(^\s*$)/', $line)) { |
| continue; |
| } |
| else |
| break; |
| } |
| fclose($fh); |
| if(! $line) |
| continue; |
| $lang = htmlspecialchars(strip_tags(trim($line))); |
| $tmp = explode('/', $dir); |
| $dir = array_pop($tmp); |
| if($dir == 'po_files') |
| continue; |
| if(! file_exists("{$mainpath}/js/nls/{$dir}/messages.js")) |
| continue; |
| $locales[$dir] = $lang; |
| } |
| $_SESSION['locales'] = $locales; |
| return $locales; |
| } |
| ?> |