| <?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. |
| */ |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \class Computer |
| /// |
| /// \brief extends Resource class to add things specific to resources of the |
| /// computer type |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| class Computer extends Resource { |
| ///////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn __construct() |
| /// |
| /// \brief calls parent constructor; initializes things for Computer class |
| /// |
| ///////////////////////////////////////////////////////////////////////////// |
| function __construct() { |
| parent::__construct(); |
| $this->restype = 'computer'; |
| $this->restypename = 'Computer'; |
| $this->namefield = 'hostname'; |
| $this->defaultGetDataArgs = array('sort' => 0, |
| 'includedeleted' => 0, |
| 'rscid' => ''); |
| $this->basecdata['obj'] = $this; |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn getData($args) |
| /// |
| /// \param $args - array of arguments that determine what data gets returned; |
| /// must include:\n |
| /// \param $sort - (optional) 1 to sort computers; 0 not to |
| /// \b includedeleted - 0 or 1; include deleted images\n |
| /// \b rscid - only return data for resource with this id; pass 0 for all |
| /// (from computer table) |
| /// |
| /// \return array of data as returned from getImages |
| /// |
| /// \brief wrapper for calling getImages |
| /// |
| ///////////////////////////////////////////////////////////////////////////// |
| function getData($args) { |
| return getComputers($args['sort'], $args['includedeleted'], $args['rscid']); |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn fieldWidth($field) |
| /// |
| /// \param $field - name of a resource field |
| /// |
| /// \return string for setting width of field (includes width= part) |
| /// |
| /// \brief generates the required width for the field; can return an empty |
| /// string if field should default to auto width |
| /// |
| ///////////////////////////////////////////////////////////////////////////// |
| function fieldWidth($field) { |
| switch($field) { |
| case 'currentimg': |
| case 'nextimg': |
| $w = 17; |
| break; |
| case 'notes': |
| $w = 14; |
| break; |
| case 'IPaddress': |
| case 'privateIPaddress': |
| case 'natpublicIPaddress': |
| case 'natinternalIPaddress': |
| $w = 8; |
| break; |
| case 'eth0macaddress': |
| case 'eth1macaddress': |
| $w = 8.5; |
| break; |
| case 'procnumber': |
| $w = 3.5; |
| break; |
| case 'imagerevision': |
| case 'ram': |
| $w = 4.5; |
| break; |
| case 'vmhost': |
| case 'nathost': |
| $w = 8; |
| break; |
| case 'type': |
| $w = 7; |
| break; |
| case 'location': |
| $w = 9; |
| break; |
| case 'predictivemodule': |
| $w = 10; |
| break; |
| case 'provisioning': |
| $w = 11; |
| break; |
| case 'owner': |
| $w = 12; |
| break; |
| default: |
| return ''; |
| } |
| if(preg_match('/MSIE/i', $_SERVER['HTTP_USER_AGENT']) || |
| preg_match('/Trident/i', $_SERVER['HTTP_USER_AGENT']) || |
| preg_match('/Edge/i', $_SERVER['HTTP_USER_AGENT'])) |
| $w = round($w * 11.5) . 'px'; |
| else |
| $w = "{$w}em"; |
| return "width=\"$w\""; |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn fieldDisplayName($field) |
| /// |
| /// \param $field - name of a resource field |
| /// |
| /// \return display value for $field |
| /// |
| /// \brief generates the display value for $field |
| /// |
| ///////////////////////////////////////////////////////////////////////////// |
| function fieldDisplayName($field) { |
| switch($field) { |
| case 'currentimg': |
| return 'Current Image'; |
| case 'imagerevision': |
| return 'Image Revision'; |
| case 'nextimg': |
| return 'Next Image'; |
| case 'ram': |
| return 'RAM'; |
| case 'procnumber': |
| return 'Cores'; |
| case 'procspeed': |
| return 'Processor speed'; |
| case 'network': |
| return 'Network speed'; |
| case 'IPaddress': |
| return 'Public IP Address'; |
| case 'privateIPaddress': |
| return 'Private IP Address'; |
| case 'eth0macaddress': |
| return 'Private MAC Address'; |
| case 'eth1macaddress': |
| return 'Public MAC Address'; |
| case 'vmhost': |
| return 'VM Host'; |
| case 'provisioning': |
| return 'Provisioning Engine'; |
| case 'predictivemodule': |
| return 'Predictive Loading Module'; |
| case 'natenabled': |
| return 'Connect Using NAT'; |
| case 'nathost': |
| return 'NAT Host'; |
| case 'nathostenabled': |
| return 'Use as NAT Host'; |
| case 'natpublicIPaddress': |
| return 'NAT Public IP Address'; |
| case 'natinternalIPaddress': |
| return 'NAT Internal IP Address'; |
| } |
| return ucfirst($field); |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn extraSelectAdminOptions() |
| /// |
| /// \return html |
| /// |
| /// \brief generates HTML for option to create/update an image |
| /// |
| ///////////////////////////////////////////////////////////////////////////// |
| function extraSelectAdminOptions() { |
| $h = ''; |
| $h .= "<br>(Computer Utilities are now incorporated into Edit Computer "; |
| $h .= "Profiles)<br>\n"; |
| return $h; |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn extraResourceFilters() |
| /// |
| /// \return html |
| /// |
| /// \brief generates HTML for computer utilities drop down and filtering by |
| /// computer group |
| /// |
| ///////////////////////////////////////////////////////////////////////////// |
| function extraResourceFilters() { |
| $h = ''; |
| |
| # selected items menu |
| $h .= "<div dojoType=\"dijit.form.DropDownButton\">\n"; |
| $h .= "<span>" . i("Actions for selected computers") . "</span>\n"; |
| $h .= "<div dojoType=\"dijit.Menu\" id=\"actionmenu\">\n"; |
| |
| # change NAT |
| $h .= " <div dojoType=\"dijit.PopupMenuItem\">\n"; |
| $h .= " <span>Change NAT</span>\n"; |
| $h .= " <div dojoType=\"dijit.layout.ContentPane\"\n"; |
| $h .= " style=\"background-color: white; padding: 5px; border: 1px solid black;\">\n"; |
| $extra = array('onChange' => "toggleNAT('newnatenabled', 'newnathostid');"); |
| $h .= labeledFormItem('newnatenabled', i('Connect Using NAT'), 'check', '', '', '1', '', '', $extra); |
| $nathosts = getNAThosts(0, 1); |
| $disabled = array('disabled' => 'true'); |
| $h .= labeledFormItem('newnathostid', i('NAT Host'), 'select', $nathosts, |
| '', '', '', '', $disabled); |
| $cdata = $this->basecdata; |
| $cont = addContinuationsEntry('AJcompNATchange', $cdata); |
| $h .= " <input type=\"hidden\" id=\"natchangecont\" value=\"$cont\"><br>\n"; |
| $h .= dijitButton('newnathostbtn', 'Confirm NAT Change', 'confirmNATchange();', 0); |
| $h .= " </div>\n"; |
| $h .= " </div>\n"; |
| |
| # change predictive loading module |
| $premodules = getPredictiveModules(); |
| $h .= " <div dojoType=\"dijit.PopupMenuItem\">\n"; |
| $h .= " <span>Change Predictive Loading Module</span>\n"; |
| $h .= " <div dojoType=\"dijit.layout.ContentPane\"\n"; |
| $h .= " style=\"background-color: white; padding: 5px; border: 1px solid black;\">\n"; |
| $h .= " Change Predictive Loading Module to:<br>\n"; |
| $h .= selectInputAutoDijitHTML('', $premodules, 'newpredictivemoduleid'); |
| $cdata = $this->basecdata; |
| $cont = addContinuationsEntry('AJcompPredictiveModuleChange', $cdata); |
| $h .= " <input type=\"hidden\" id=\"predictivemodulechangecont\" value=\"$cont\"><br>\n"; |
| $h .= dijitButton('', 'Confirm Predictive Loading Module Change', 'confirmPredictiveModuleChange();', 0); |
| $h .= " </div>\n"; |
| $h .= " </div>\n"; |
| |
| # change provisioning engine |
| $provisioning = getProvisioning(); |
| $h .= " <div dojoType=\"dijit.PopupMenuItem\">\n"; |
| $h .= " <span>Change Provisioning Engine</span>\n"; |
| $h .= " <div dojoType=\"dijit.layout.ContentPane\"\n"; |
| $h .= " style=\"background-color: white; padding: 5px; border: 1px solid black;\">\n"; |
| $h .= " Change Provisioning Engine to:<br>\n"; |
| $h .= selectInputAutoDijitHTML('', $provisioning, 'newprovisioningid'); |
| $cdata = $this->basecdata; |
| $cont = addContinuationsEntry('AJcompProvisioningChange', $cdata); |
| $h .= " <input type=\"hidden\" id=\"provisioningchangecont\" value=\"$cont\"><br>\n"; |
| $h .= dijitButton('', 'Confirm Provisioning Engine Change', 'confirmProvisioningChange();', 0); |
| $h .= " </div>\n"; |
| $h .= " </div>\n"; |
| |
| # change schedule |
| $resources = getUserResources(array("scheduleAdmin"), array("manageGroup")); |
| if(count($resources['schedule'])) { |
| $h .= " <div dojoType=\"dijit.PopupMenuItem\">\n"; |
| $h .= " <span>Change Schedule</span>\n"; |
| $h .= " <div dojoType=\"dijit.layout.ContentPane\"\n"; |
| $h .= " style=\"background-color: white; padding: 5px; border: 1px solid black;\">\n"; |
| $h .= " Change schedule to:<br>\n"; |
| $h .= selectInputAutoDijitHTML('', $resources['schedule'], 'newscheduleid'); |
| $cont = addContinuationsEntry('AJcompScheduleChange', $this->basecdata); |
| $h .= " <input type=\"hidden\" id=\"schedulecont\" value=\"$cont\"><br>\n"; |
| $h .= dijitButton('', 'Confirm Schedule Change', 'confirmScheduleChange();', 0); |
| $h .= " </div>\n"; |
| $h .= " </div>\n"; |
| } |
| |
| # change state |
| $states = array("2" => "available", |
| "23" => "hpc", |
| "10" => "maintenance", |
| "20" => "convert to vmhostinuse"); |
| $h .= " <div dojoType=\"dijit.PopupMenuItem\">\n"; |
| $h .= " <span>Change State</span>\n"; |
| $h .= " <div dojoType=\"dijit.layout.ContentPane\"\n"; |
| $h .= " style=\"background-color: white; padding: 5px; border: 1px solid black;\">\n"; |
| $h .= " Change state to:<br>\n"; |
| $h .= selectInputAutoDijitHTML('', $states, 'newstateid'); |
| $cdata = $this->basecdata; |
| $cdata['states'] = $states; |
| $cont = addContinuationsEntry('AJcompStateChange', $cdata); |
| $h .= " <input type=\"hidden\" id=\"statechangecont\" value=\"$cont\"><br>\n"; |
| $h .= dijitButton('', 'Confirm State Change', 'confirmStateChange();', 0); |
| $h .= " </div>\n"; |
| $h .= " </div>\n"; |
| |
| # delete |
| $h .= " <div dojoType=\"dijit.MenuItem\"\n"; |
| $h .= " onClick=\"confirmDelete\">\n"; |
| $h .= " Delete Computers\n"; |
| $cont = addContinuationsEntry('AJdeleteComputers', $this->basecdata); |
| $h .= " <input type=\"hidden\" id=\"deletecont\" value=\"$cont\"><br>\n"; |
| $h .= " </div>\n"; |
| |
| # generate /etc/hosts data |
| $h .= " <div dojoType=\"dijit.MenuItem\"\n"; |
| $h .= " onClick=\"hostsData\">\n"; |
| $h .= " Generate /etc/hosts Data\n"; |
| $cont = addContinuationsEntry('AJhostsData', $this->basecdata); |
| $h .= " <input type=\"hidden\" id=\"hostsdatacont\" value=\"$cont\"><br>\n"; |
| $h .= " </div>\n"; |
| |
| # generate private dhcpd data |
| $h .= " <div dojoType=\"dijit.PopupMenuItem\">\n"; |
| $h .= " <span>Generate Private dhcpd Data</span>\n"; |
| $h .= " <div dojoType=\"dijit.layout.ContentPane\"\n"; |
| $h .= " style=\"background-color: white; padding: 5px; border: 1px solid black;\">\n"; |
| $h .= " Enter the Management Node Private IP Address:<br>\n"; |
| $h .= " <input type=\"text\" dojoType=\"dijit.form.TextBox\" id=\"mnprivipaddr\" "; |
| $h .= "required=\"false\"><br><br>\n"; |
| $h .= " Select which NIC is used for the Private interface:<br>\n"; |
| $h .= " <input type=\"radio\" name=\"prnic\" value=\"eth0\" id=\"preth0rdo\" "; |
| $h .= "checked=\"checked\"><label for=\"eth0rdo\">eth0</label><br>\n"; |
| $h .= " <input type=\"radio\" name=\"prnic\" value=\"eth1\" id=\"preth1rdo\">"; |
| $h .= "<label for=\"eth1rdo\">eth1</label><br>\n"; |
| $h .= dijitButton('', 'Generate Data', "generateDHCPdata('private');", 0); |
| $cont = addContinuationsEntry('AJgenerateDHCPdata', $this->basecdata); |
| $h .= " <input type=\"hidden\" id=\"privatedhcpcont\" value=\"$cont\">\n"; |
| $h .= " </div>\n"; |
| $h .= " </div>\n"; |
| |
| # generate public dhcpd data |
| $h .= " <div dojoType=\"dijit.PopupMenuItem\">\n"; |
| $h .= " <span>Generate Public dhcpd Data</span>\n"; |
| $h .= " <div dojoType=\"dijit.layout.ContentPane\"\n"; |
| $h .= " style=\"background-color: white; padding: 5px; border: 1px solid black;\">\n"; |
| $h .= " Select which NIC is used for the Public interface:<br>\n"; |
| $h .= " <input type=\"radio\" name=\"punic\" value=\"eth0\" id=\"pueth0rdo\">"; |
| $h .= "<label for=\"eth0rdo\">eth0</label><br>\n"; |
| $h .= " <input type=\"radio\" name=\"punic\" value=\"eth1\" id=\"pueth1rdo\" "; |
| $h .= "checked=\"checked\"><label for=\"eth1rdo\">eth1</label><br>\n"; |
| $h .= dijitButton('', 'Generate Data', "generateDHCPdata('public');", 0); |
| $h .= " <input type=\"hidden\" id=\"publicdhcpcont\" value=\"$cont\">\n"; # use previous continuation |
| $h .= " </div>\n"; |
| $h .= " </div>\n"; |
| |
| # reload |
| $resources = getUserResources(array("imageAdmin", "imageCheckOut")); |
| if(count($resources['image'])) { |
| $h .= " <div dojoType=\"dijit.PopupMenuItem\">\n"; |
| $h .= " <span>Reload with an Image</span>\n"; |
| $h .= " <div dojoType=\"dijit.layout.ContentPane\"\n"; |
| $h .= " style=\"background-color: white; padding: 5px; border: 1px solid black;\">\n"; |
| $h .= " Reload computers with the following image:<br>\n"; |
| $extra = 'autoComplete="false"'; |
| $h .= selectInputAutoDijitHTML('', $resources['image'], 'reloadimageid', $extra); |
| $cont = addContinuationsEntry('AJreloadComputers', $this->basecdata); |
| $h .= " <input type=\"hidden\" id=\"reloadcont\" value=\"$cont\"><br>\n"; |
| $h .= dijitButton('', 'Confirm Reload Computers', 'confirmReload();', 0); |
| $h .= " </div>\n"; |
| $h .= " </div>\n"; |
| } |
| |
| # show reservations |
| $h .= " <div dojoType=\"dijit.MenuItem\"\n"; |
| $h .= " onClick=\"showReservations\">\n"; |
| $h .= " Reservation Information\n"; |
| $cont = addContinuationsEntry('AJshowReservations', $this->basecdata); |
| $h .= " <input type=\"hidden\" id=\"showreservationscont\" value=\"$cont\"><br>\n"; |
| $h .= " </div>\n"; |
| |
| # show reservation history |
| $h .= " <div dojoType=\"dijit.MenuItem\"\n"; |
| $h .= " onClick=\"showReservationHistory\">\n"; |
| $h .= " Reservation History\n"; |
| $cont = addContinuationsEntry('AJshowReservationHistory', $this->basecdata); |
| $h .= " <input type=\"hidden\" id=\"showreservationhistorycont\" value=\"$cont\"><br>\n"; |
| $h .= " </div>\n"; |
| |
| $h .= "</div>\n"; # close Menu |
| $h .= "</div>\n"; # close DropDownButton |
| |
| # computer groups |
| $tmp = getUserResources(array($this->restype . 'Admin'), array('manageGroup'), 1); |
| $groups = $tmp[$this->restype]; |
| $cont = addContinuationsEntry('AJfilterCompGroups', $this->basecdata); |
| $h .= "<input type=\"hidden\" id=\"filtercompgroupscont\" value=\"$cont\">\n"; |
| $h .= "<div dojoType=\"dijit.form.DropDownButton\">\n"; |
| $h .= " <span>Selected Computer Groups</span>\n"; |
| $h .= " <div dojoType=\"dijit.TooltipDialog\" id=\"connectmethodttd\">\n"; |
| $size = 10; |
| if(count($groups) < 10) |
| $size = count($groups); |
| $h .= selectInputHTML('', $groups, 'filtercompgroups', |
| "onChange=\"delayedCompGroupFilterSelection();\" size=\"$size\"", |
| -1, 0, 1); |
| $h .= " </div>\n"; # tooltip dialog |
| $h .= "</div>\n"; # drop down button |
| |
| # refresh button |
| $h .= dijitButton('', 'Refresh Computer Data', 'refreshcompdata(0);'); |
| |
| # span to list count of computer in table |
| $h .= "<span id=\"computercount\"></span>\n"; |
| |
| $h .= "<div dojoType=dijit.Dialog\n"; |
| $h .= " id=\"confirmactiondlg\"\n"; |
| $h .= " duration=250\n"; |
| $h .= " autofocus=false\n"; |
| $h .= " draggable=true>\n"; |
| #$h .= "<div id=\"actionmsg\"></div>\n"; |
| $h .= "<div dojoType=\"dijit.layout.ContentPane\" id=\"actionmsg\"\n"; |
| $h .= " style=\"background-color: white; padding: 5px;\">\n"; |
| $h .= "</div>\n"; |
| $h .= "<div id=\"complist\" style=\"overflow: auto;\"></div>\n"; |
| $h .= "<input type=\"hidden\" id=\"submitcont\">\n"; |
| $h .= "<div style=\"text-align: center;\">\n"; |
| $h .= "<span id=\"submitactionbtnspan\">\n"; |
| $h .= dijitButton('submitactionbtn', 'Submit', 'submitAction();', 0); |
| $h .= "</span>\n"; |
| $h .= dijitButton('cancelactionbtn', 'Cancel', 'cancelAction();', 0); |
| $h .= "</div>\n"; # btn div |
| $h .= "</div>\n"; # confirmactiondlg |
| |
| $h .= "<div dojoType=dijit.Dialog\n"; |
| $h .= " id=\"noschedulenoadd\"\n"; |
| $h .= " title=\"Cannot Add Computers\"\n"; |
| $h .= " duration=250\n"; |
| $h .= " autofocus=false\n"; |
| $h .= " draggable=true>\n"; |
| $h .= "All computers must have a schedule assigned to them. You do not<br>\n"; |
| $h .= "have to any schedules or no schedules exist. You must be granted<br>\n"; |
| $h .= "access to or create at least one schedule to be able to add computers.<br><br>\n"; |
| $h .= "<div style=\"text-align: center;\">\n"; |
| $h .= dijitButton('', 'Close', 'dijit.byId("noschedulenoadd").hide();', 0); |
| $h .= "</div>\n"; # btn div |
| $h .= "</div>\n"; # noschedulenoadd |
| |
| # filter table |
| $h .= "<div id=\"extrafiltersdiv\" style=\"height: 65px;\"></div>\n"; |
| return $h; |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn AJfilterCompGroups |
| /// |
| /// \brief generates regular expressions to match ids of all computers in the |
| /// submitted computer groups |
| /// |
| ///////////////////////////////////////////////////////////////////////////// |
| function AJfilterCompGroups() { |
| $groupids = processInputVar('groupids', ARG_STRING); |
| if(! preg_match('/^[0-9,]+$/', $groupids)) { |
| $ret = array('status' => 'error', |
| 'errormsg' => "Invalid data submitted."); |
| sendJSON($ret); |
| return; |
| } |
| $groupids = explode(',', $groupids); |
| $tmp = getUserResources(array($this->restype . 'Admin'), array('manageGroup'), 1); |
| $groups = $tmp[$this->restype]; |
| $groupnames = array(); |
| foreach($groupids as $id) { |
| if(array_key_exists($id, $groups)) |
| $groupnames[] = $groups[$id]; |
| } |
| $comps = getResourcesFromGroups($groupnames, 'computer', 1); |
| $regids = "^" . implode('$|^', array_keys($comps)) . "$"; |
| $arr = array('status' => 'success', |
| 'regids' => $regids); |
| sendJSON($arr); |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn addEditDialogHTML($add) |
| /// |
| /// \param $add - unused for this class |
| /// |
| /// \brief generates HTML for dialog used to edit resource |
| /// |
| ///////////////////////////////////////////////////////////////////////////// |
| function addEditDialogHTML($add) { |
| global $user; |
| # dialog for on page editing |
| $h = ''; |
| $h .= "<div dojoType=dijit.Dialog\n"; |
| $h .= " id=\"addeditdlg\"\n"; |
| $h .= " title=\"Edit {$this->restypename}\"\n"; |
| $h .= " duration=250\n"; |
| $h .= " draggable=true>\n"; |
| $h .= "<div id=\"addeditdlgcontent\">\n"; |
| $h .= "<div id=\"computerdlgcontent\">\n"; |
| # id |
| $h .= "<input type=\"hidden\" id=\"editresid\">\n"; |
| |
| $types = array("blade" => "Bare Metal", "lab" => "Lab", "virtualmachine" => "Virtual Machine"); |
| $provisioning = getProvisioning(); |
| $provtypes = getProvisioningTypes(); |
| $states = array('blade' => array(2 => 'available', |
| 10 => 'maintenance', |
| 20 => 'vmhostinuse'), |
| 'lab' => array(2 => 'available', |
| 10 => 'maintenance'), |
| 'virtualmachine' => array(10 => 'maintenance')); |
| |
| $h .= "<script type=\"text/javascript\">\n"; |
| $h .= "var options = {\n"; |
| $options = array(); |
| foreach($types as $type => $tmp) { |
| $opt = ''; |
| $opt .= " $type: {\n"; |
| $opt .= " provisioning: [\n"; |
| $arr = array(); |
| foreach($provtypes[$type] as $key => $val) |
| $arr[] = " {value: '$key', label: '$val'}"; |
| $opt .= implode(",\n", $arr); |
| $opt .= "\n ],\n"; |
| $opt .= " states: [\n"; |
| $arr = array(); |
| foreach($states[$type] as $key => $val) |
| $arr[] = " {value: '$key', label: '$val'}"; |
| $opt .= implode(",\n", $arr); |
| $opt .= "\n ]\n"; |
| $opt .= " }"; |
| $options[] = $opt; |
| } |
| $h .= implode(",\n", $options); |
| $h .= "\n}\n"; |
| $h .= "</script>\n"; |
| |
| # add single or multiple |
| $h .= "<div id=\"singlemultiplediv\" class=\"hidden\">\n"; |
| /*$h .= "<label for=\"addsingle\">Add Single Computer</label><span "; |
| $h .= "class=\"labeledform\"><input type=\"radio\" name=\"mode\" "; |
| $h .= "id=\"addsingle\" checked=\"checked\" onclick=\"toggleAddSingle();\">"; |
| $h .= "</span><br><br>\n"; |
| $h .= "<label for=\"addmultiple\">Add Multiple Computers</label><span "; |
| $h .= "class=\"labeledform\"><input type=\"radio\" name=\"mode\" "; |
| $h .= "id=\"addmultiple\" onclick=\"toggleAddMultiple();\"><br><br>\n";*/ |
| $extra = array('onChange' => 'toggleSingleMultiple();'); |
| $modes = array('single' => 'Single Computer', |
| 'multiple' => 'Multiple Computers'); |
| $h .= labeledFormItem('mode', i('Add') . ' ', 'select', $modes, 1, '', '', '', $extra); |
| $h .= "<br>\n"; |
| $h .= "</div>\n"; # singlemultiplediv |
| |
| # add multiple note |
| $h .= "<div id=\"multiplenotediv\" class=\"hidden\">\n"; |
| $h .= "<b>NOTE</b>: 'Start IP' and 'End IP' can only differ in the number "; |
| $h .= "after the last '.'. The<br>hostnames will be generated from the "; |
| $h .= "'Hostname' field. The hostnames for each<br>computer can only differ "; |
| $h .= "by the value of a number in the first part of the hostname.<br>Place "; |
| $h .= "a '%' character in the 'Hostname' field where that number will be. "; |
| $h .= "Then fill in<br>'Start value' and 'End value' with the first and last "; |
| $h .= "values to be used in the hostname.<br><br>"; |
| $h .= "</div>\n"; # multiplenotediv |
| |
| # div for canceling moving blade to vmhostinuse |
| $h .= "<div class=\"highlightnoticewarn hidden\" id=\"cancelvmhostinusediv\">\n"; |
| $h .= "<span id=\"tohostfuturespan\">\n"; |
| $h .= "NOTICE: This computer is scheduled to start being reloaded as a vmhost at<br>"; |
| $h .= "<span id=\"tohostfuturetimespan\"></span>"; |
| $h .= ". You may cancel this scheduled<br>reload by clicking the button below."; |
| $h .= "<br><br></span>\n"; |
| $h .= "<span id=\"tohostnowspan\">\n"; |
| $h .= "NOTICE: This computer is currently being reloaded as a vmhost. You may cancel this<br>"; |
| $h .= "process by clicking on the button below. After canceling the reload, it may take several<br>"; |
| $h .= "minutes for the cancellation process to complete."; |
| $h .= "<br><br></span>\n"; |
| $h .= "<input type=\"hidden\" id=\"tohostcancelcont\">\n"; |
| $h .= "<button dojoType=\"dijit.form.Button\">\n"; |
| $h .= " Cancel Scheduled Reload\n"; |
| $h .= " <script type=\"dojo/method\" event=onClick>\n"; |
| $h .= " cancelScheduledtovmhostinuse();\n"; |
| $h .= " </script>\n"; |
| $h .= "</button>\n"; |
| $h .= "</div>\n"; # cancelvmhostinusediv |
| $h .= "<div class=\"highlightnoticenotify hidden\" id=\"cancelvmhostinuseokdiv\"></div>\n"; |
| |
| # hostname |
| $errmsg = i("Name can only contain letters, numbers, dashes(-), periods(.), and underscores(_). It can be from 1 to 36 characters long."); |
| $h .= labeledFormItem('name', i('Name') . '*', 'text', '^([a-zA-Z0-9_][-a-zA-Z0-9_\.]{1,35})$', |
| 1, '', $errmsg); |
| |
| # start/end |
| $h .= "<div id=\"startenddiv\" class=\"hidden\">\n"; |
| $extra = array('smallDelta' => 1, 'largeDelta' => 10); |
| $h .= labeledFormItem('startnum', i('Start') . '*', 'spinner', '{min:0,max:255,places:0}', 1); |
| $h .= labeledFormItem('endnum', i('End') . '*', 'spinner', '{min:0,max:255,places:0}', 1); |
| $h .= "</div>\n"; # startenddiv |
| |
| # owner |
| $extra = array('onKeyPress' => 'setOwnerChecking'); |
| $h .= labeledFormItem('owner', i('Owner') . '*', 'text', '', 1, |
| "{$user['unityid']}@{$user['affiliation']}", i('Unknown user'), |
| 'checkOwner', $extra); |
| $cont = addContinuationsEntry('AJvalidateUserid'); |
| $h .= "<input type=\"hidden\" id=\"valuseridcont\" value=\"$cont\">\n"; |
| |
| # type |
| $extra = array('onChange' => 'selectType();'); |
| $h .= labeledFormItem('type', i('Type'), 'select', $types, 1, '', '', '', $extra); |
| |
| # single computer fields |
| $h .= "<div id=\"singleipmacdiv\">\n"; |
| # public IP |
| $ipreg = '(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'; |
| $ipreg1 = "^$ipreg$"; |
| $errmsg = i("Invalid Public IP address specified - must be a valid IPV4 address"); |
| $h .= labeledFormItem('ipaddress', i('Public IP Address') . '*', 'text', $ipreg1, 1, '', $errmsg); |
| |
| # private IP |
| $errmsg = i("Invalid Private IP address specified - must be a valid IPV4 address"); |
| $h .= labeledFormItem('privateipaddress', i('Private IP Address'), 'text', $ipreg1, 0, '', $errmsg); |
| |
| # Public MAC |
| $macreg = '^([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$'; |
| $errmsg = i("Invalid Public MAC address specified"); |
| $h .= labeledFormItem('publicmac', i('Public MAC Address'), 'text', $macreg, 0, '', $errmsg); |
| |
| # private MAC |
| $errmsg = i("Invalid Private MAC address specified"); |
| $h .= labeledFormItem('privatemac', i('Private MAC Address'), 'text', $macreg, 0, '', $errmsg); |
| |
| $h .= "</div>\n"; # singleipmacdiv |
| |
| # multi computer fields |
| $h .= "<div id=\"multiipmacdiv\" class=\"hidden\">\n"; |
| # start public IP |
| $errmsg = i("Invalid Start Public IP Address specified - must be a valid IPV4 address"); |
| $h .= labeledFormItem('startpubipaddress', i('Start Public IP Address') . '*', 'text', $ipreg1, 1, '', $errmsg); |
| |
| # end public IP |
| $errmsg = i("Invalid End Public IP Address specified - must be a valid IPV4 address"); |
| $h .= labeledFormItem('endpubipaddress', i('End Public IP Address') . '*', 'text', $ipreg1, 1, '', $errmsg); |
| |
| # start private IP |
| $errmsg = i("Invalid Start Private IP Address specified - must be a valid IPV4 address"); |
| $h .= labeledFormItem('startprivipaddress', i('Start Private IP Address') . '*', 'text', $ipreg1, 1, '', $errmsg); |
| |
| # end private IP |
| $errmsg = i("Invalid End Private IP Address specified - must be a valid IPV4 address"); |
| $h .= labeledFormItem('endprivipaddress', i('End Private IP Address') . '*', 'text', $ipreg1, 1, '', $errmsg); |
| |
| # start MAC |
| $errmsg = i("Invalid Start MAC Address specified"); |
| $h .= labeledFormItem('startmac', i('Start MAC Address'), 'text', $macreg, 0, '', $errmsg); |
| |
| $h .= "</div>\n"; # multiipsdiv |
| |
| # provisioning engine |
| $extra = array('onChange' => 'selectProvisioning();'); |
| $h .= labeledFormItem('provisioningid', i('Provisioning Engine'), 'selectonly', $provisioning, 1, '', '', '', $extra); |
| |
| # state |
| $extra = array('onChange' => 'selectState();'); |
| $states = array(2 => 'available', |
| 23 => 'hpc', |
| 10 => 'maintenance', |
| 20 => 'vmhostinuse'); |
| $h .= labeledFormItem('stateid', i('State'), 'selectonly', $states, 1, '', '', '', $extra); |
| |
| # maintenance notes |
| $h .= "<div id=\"notesspan\">\n"; |
| $h .= labeledFormItem('notes', i('Reason for Maintenance'), 'textarea'); |
| $h .= "</div>\n"; |
| |
| # VMhost profile |
| $profiles = getVMProfiles(); |
| uasort($profiles, 'sortKeepIndex'); |
| $h .= "<div id=\"vmprofilespan\">\n"; |
| $h .= labeledFormItem('vmprofileid', i('VM Host Profile'), 'select', $profiles); |
| $h .= "</div>\n"; |
| |
| # platform |
| $platforms = getPlatforms(); |
| $h .= labeledFormItem('platformid', i('Platform'), 'select', $platforms); |
| |
| # schedule |
| $tmp = getUserResources(array("scheduleAdmin"), array("manageGroup")); |
| $schedules = $tmp["schedule"]; |
| $h .= labeledFormItem('scheduleid', i('Schedule'), 'selectonly', $schedules); |
| |
| # current image |
| $h .= "<div id=\"curimgspan\">\n"; |
| $h .= "<label for=\"curimg\">Current Image:</label>\n"; |
| $h .= "<span class=\"labeledform\" id=\"curimg\"></span><br>\n"; |
| $h .= "</div>\n"; |
| |
| # ram |
| $extra = array('smallDelta' => 1024, 'largeDelta' => 4096); |
| $h .= labeledFormItem('ram', i('RAM (MB)') . '*', 'spinner', '{min:500,max:16777215,places:0}', 1); |
| |
| # cores |
| $extra = array('smallDelta' => 1, 'largeDelta' => 4); |
| $h .= labeledFormItem('cores', i('Cores') . '*', 'spinner', '{min:1,max:255,places:0}', 1); |
| |
| # proc speed |
| $extra = array('smallDelta' => 100, 'largeDelta' => 1000); |
| $h .= labeledFormItem('procspeed', i('Processor Speed (MHz)') . '*', 'spinner', '{min:500,max:10000,places:0}', 1); |
| |
| # network speed |
| $tmpArr = array("10" => "10", "100" => "100", "1000" => "1000", "10000" => "10000", "100000" => "100000"); |
| $h .= labeledFormItem('network', i('Network'), 'select', $tmpArr); |
| |
| # predictive loading module |
| $vals = getPredictiveModules(); |
| $h .= labeledFormItem('predictivemoduleid', i('Predictive Loading Module'), 'select', $vals); |
| |
| # NAT |
| $h .= "<div class=\"boxedoptions\">\n"; |
| # use NAT |
| $extra = array('onChange' => "toggleNAT('natenabled', 'nathostid');"); |
| $h .= labeledFormItem('natenabled', i('Connect Using NAT'), 'check', '', '', '1', '', '', $extra); |
| # which NAT host |
| $nathosts = getNAThosts(0, 1); |
| $h .= labeledFormItem('nathostid', i('NAT Host'), 'selectonly', $nathosts); |
| $h .= "</div>\n"; # NAT |
| |
| # NAT Host |
| $h .= "<div id=\"nathost\" class=\"boxedoptions\">\n"; |
| # use as NAT host |
| $extra = array('onChange' => "toggleNAThost();"); |
| $h .= labeledFormItem('nathostenabled', i('Use as NAT Host'), 'check', '', '', '1', '', '', $extra); |
| # public IP |
| $errmsg = i("Invalid NAT Public IP address specified - must be a valid IPV4 address"); |
| $h .= labeledFormItem('natpublicipaddress', i('NAT Public IP Address'), 'text', $ipreg1, 1, '', $errmsg); |
| # internal IP |
| $errmsg = i("Invalid NAT Internal IP address specified - must be a valid IPV4 address"); |
| $h .= labeledFormItem('natinternalipaddress', i('NAT Internal IP Address'), 'text', $ipreg1, 1, '', $errmsg); |
| $h .= "</div>\n"; # NAT Host |
| |
| # compid |
| $h .= "<div id=\"compidspan\">\n"; |
| $h .= "<label for=\"compid\">Computer ID:</label>\n"; |
| $h .= "<span class=\"labeledform\" id=\"compid\"></span><br>\n"; |
| $h .= "</div>\n"; |
| |
| # location |
| $errmsg = i("Location can be up to 255 characters long and may contain letters, numbers, spaces, and these characters: - , . _ @ # ( )"); |
| $h .= labeledFormItem('location', i('Location'), 'text', |
| '^([-a-zA-Z0-9_\. ,@#\(\)]{0,255})$', 0, '', $errmsg); |
| |
| $h .= "</div>\n"; # computerdlgcontent |
| $h .= "</div>\n"; # addeditdlgcontent |
| |
| $h .= "<div id=\"addeditdlgerrmsg\" class=\"nperrormsg\"></div>\n"; |
| |
| $h .= "<div id=\"editdlgbtns\" align=\"center\">\n"; |
| $h .= dijitButton('addeditbtn', "Confirm", "saveResource();"); |
| $h .= dijitButton('', "Cancel", "dijit.byId('addeditdlg').hide();"); |
| $h .= "</div>\n"; # editdlgbtns |
| $h .= "</div>\n"; # dialog |
| |
| $h .= "<div dojoType=dijit.Dialog\n"; |
| $h .= " id=\"groupingnote\"\n"; |
| $h .= " title=\"Computer Grouping\"\n"; |
| $h .= " duration=250\n"; |
| $h .= " draggable=true>\n"; |
| $h .= "Computer(s) successfully added. Each computer needs<br>to be a member of a computer resource group. The<br>following dialog<br>will allow you to add the new<br>computer(s) to a group.<br><br>\n"; |
| $h .= "<div align=\"center\">\n"; |
| $h .= dijitButton('', "Close", "dijit.byId('groupingnote').hide();"); |
| $h .= "</div>\n"; # btn div |
| $h .= "</div>\n"; # groupingnote |
| |
| $h .= "<div dojoType=dijit.Dialog\n"; |
| $h .= " id=\"groupdlg\"\n"; |
| $h .= " title=\"Computer Grouping\"\n"; |
| $h .= " duration=250\n"; |
| $h .= " draggable=true>\n"; |
| $h .= "<div id=\"groupdlgcontent\"></div>\n"; |
| $h .= "<div align=\"center\">\n"; |
| $script = " dijit.byId('groupdlg').hide();\n"; |
| $script .= " checkFirstAdd();\n"; |
| $h .= dijitButton('', "Close", $script); |
| $h .= "</div>\n"; # btn div |
| $h .= "</div>\n"; # groupdlg |
| return $h; |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn AJeditResource() |
| /// |
| /// \brief sends data for editing a resource |
| /// |
| ///////////////////////////////////////////////////////////////////////////// |
| function AJeditResource() { |
| $rscid = processInputVar('rscid', ARG_NUMERIC); |
| $resources = getUserResources(array($this->restype . 'Admin'), array('administer'), 0, 1); |
| if(! array_key_exists($rscid, $resources[$this->restype])) { |
| $ret = array('status' => 'noaccess'); |
| sendJSON($ret); |
| return; |
| } |
| $this->jsondata['showcancel'] = 0; |
| $query = "SELECT UNIX_TIMESTAMP(rq.start) AS start " |
| . "FROM request rq, " |
| . "reservation rs, " |
| . "state ls, " |
| . "state cs " |
| . "WHERE rs.requestid = rq.id AND " |
| . "rs.computerid = $rscid AND " |
| . "rq.laststateid = ls.id AND " |
| . "rq.stateid = cs.id AND " |
| . "ls.name = 'tovmhostinuse' AND " |
| . "cs.name NOT IN ('failed', 'maintenance', 'complete', 'deleted') AND " |
| . "rq.end > NOW() " |
| . "ORDER BY rq.start " |
| . "LIMIT 1"; |
| $qh = doQuery($query); |
| if($row = mysqli_fetch_assoc($qh)) { |
| $cdata = $this->basecdata; |
| $cdata['compid'] = $rscid; |
| $cont = addContinuationsEntry('AJcanceltovmhostinuse', $cdata, 300, 1, 0); |
| $this->jsondata['tohostcancelcont'] = $cont; |
| $this->jsondata['showcancel'] = 1; |
| $this->jsondata['tohoststart'] = date('g:i A \o\n l, F jS, Y', $row['start']); |
| if($row['start'] > time()) |
| $this->jsondata['tohostfuture'] = 1; |
| else |
| $this->jsondata['tohostfuture'] = 0; |
| } |
| parent::AJeditResource(); |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn AJsaveResource() |
| /// |
| /// \brief saves changes to resource |
| /// |
| ///////////////////////////////////////////////////////////////////////////// |
| function AJsaveResource() { |
| global $user; |
| $add = getContinuationVar('add', 0); |
| $data = $this->validateResourceData(); |
| if($data['error']) { |
| $ret = array('status' => 'error', 'msg' => $data['errormsg']); |
| sendJSON($ret); |
| return; |
| } |
| |
| $promptuser = 0; |
| $promptuserfail = 0; |
| $multirefresh = 0; |
| |
| if($add) { |
| if(! $data['rscid'] = $this->addResource($data)) { |
| sendJSON(array('status' => 'adderror', |
| 'errormsg' => 'Error encountered while trying to create new computer(s).<br>Please contact an admin for assistance.')); |
| return; |
| } |
| } |
| else { |
| $olddata = getContinuationVar('olddata'); |
| $updates = array(); |
| # hostname |
| if($data['name'] != $olddata['hostname']) |
| $updates[] = "hostname = '{$data['name']}'"; |
| |
| # ownerid |
| $ownerid = getUserlistID($data['owner']); |
| if($ownerid != $olddata['ownerid']) |
| $updates[] = "ownerid = $ownerid"; |
| |
| # cores |
| if($data['cores'] != $olddata['procnumber']) |
| $updates[] = "procnumber = '{$data['cores']}'"; |
| |
| # eth0macaddress |
| if($data['eth0macaddress'] != $olddata['eth0macaddress']) { |
| if($data['eth0macaddress'] == '') |
| $updates[] = "eth0macaddress = NULL"; |
| else |
| $updates[] = "eth0macaddress = '{$data['eth0macaddress']}'"; |
| } |
| |
| # eth1macaddress |
| if($data['eth1macaddress'] != $olddata['eth1macaddress']) { |
| if($data['eth1macaddress'] == '') |
| $updates[] = "eth1macaddress = NULL"; |
| else |
| $updates[] = "eth1macaddress = '{$data['eth1macaddress']}'"; |
| } |
| |
| # use NAT |
| if($data['natenabled'] != $olddata['natenabled']) { |
| if($data['natenabled']) { |
| $query = "INSERT INTO nathostcomputermap " |
| . "(computerid, " |
| . "nathostid) " |
| . "VALUES ({$data['rscid']}, " |
| . "{$data['nathostid']})"; |
| doQuery($query); |
| } |
| else { |
| $query = "DELETE FROM nathostcomputermap " |
| . "WHERE computerid = {$data['rscid']}"; |
| doQuery($query); |
| } |
| } |
| elseif($data['natenabled'] && |
| $olddata['nathostid'] != $data['nathostid']) { |
| $query = "UPDATE nathostcomputermap " |
| . "SET nathostid = {$data['nathostid']} " |
| . "WHERE computerid = {$data['rscid']}"; |
| doQuery($query); |
| } |
| |
| # NAT host |
| if($data['nathostenabled'] != $olddata['nathostenabled']) { |
| if($data['nathostenabled']) { |
| $query = "INSERT INTO nathost " |
| . "(resourceid, " |
| . "publicIPaddress, " |
| . "internalIPaddress) " |
| . "VALUES " |
| . "({$olddata['resourceid']}, " |
| . "'{$data['natpublicIPaddress']}', " |
| . "'{$data['natinternalIPaddress']}') " |
| . "ON DUPLICATE KEY UPDATE " |
| . "publicIPaddress = '{$data['natpublicIPaddress']}', " |
| . "internalIPaddress = '{$data['natinternalIPaddress']}'"; |
| doQuery($query); |
| } |
| else { |
| $query = "DELETE FROM nathost " |
| . "WHERE resourceid = {$olddata['resourceid']}"; |
| doQuery($query); |
| } |
| } |
| elseif($data['nathostenabled'] && |
| ($olddata['natpublicIPaddress'] != $data['natpublicIPaddress'] || |
| $olddata['natinternalIPaddress'] != $data['natinternalIPaddress'])) { |
| $query = "UPDATE nathost " |
| . "SET publicIPaddress = '{$data['natpublicIPaddress']}', " |
| . "internalIPaddress = '{$data['natinternalIPaddress']}' " |
| . "WHERE resourceid = {$olddata['resourceid']}"; |
| doQuery($query); |
| } |
| |
| # other fields |
| $fields = array('type', 'IPaddress', 'privateIPaddress', |
| 'provisioningid', 'platformid', 'scheduleid', 'ram', |
| 'procspeed', 'network', 'predictivemoduleid', 'location'); |
| foreach($fields as $field) { |
| if($data[$field] != $olddata[$field]) |
| $updates[] = "`$field` = '{$data[$field]}'"; |
| } |
| |
| # stateid - if moving from vmhostinuse or reloading with a new image, |
| # make sure no reservations for VMs |
| if($olddata['stateid'] == 10 && $data['stateid'] == 20) { |
| $query = "SELECT vm.id " |
| . "FROM computer vm, " |
| . "vmhost v " |
| . "WHERE v.computerid = {$data['rscid']} AND " |
| . "vm.vmhostid = v.id AND " |
| . "vm.notes = 'maintenance with host {$data['rscid']}' AND " |
| . "vm.stateid = 10"; |
| $qh = doQuery($query); |
| $vmids = array(); |
| while($row = mysqli_fetch_assoc($qh)) |
| $vmids[] = $row['id']; |
| $allids = implode(',', $vmids); |
| if($data['provisioning'] != 'none') { |
| $profiles = getVMProfiles(); |
| if(! array_key_exists('vmprofileid', $olddata) || |
| $olddata['vmprofileid'] == '' || |
| $profiles[$olddata['vmprofileid']]['imageid'] != |
| $profiles[$data['vmprofileid']]['imageid']) { |
| # VCL provisioned, different image |
| # schedule VM host to be reloaded |
| $profiles = getVMProfiles($data['vmprofileid']); |
| $imageid = $profiles[$data['vmprofileid']]['imageid']; |
| $start = getReloadStartTime(); |
| $rc = $this->scheduleTovmhostinuse($data['rscid'], $imageid, $start, |
| $data['vmprofileid'], $olddata['vmprofileid']); |
| |
| if($rc == 0) { |
| $msg = ''; |
| if(count($updates)) |
| $msg .= "Computer information changes were saved.<br>\nHowever, a "; |
| else |
| $msg .= "A "; |
| $msg .= "problem was encountered while attempting to reload the "; |
| $msg .= "computer with the selected VM Host Profile. Please try "; |
| $msg .= "again at a later time.\n"; |
| $msg = preg_replace("/(.{1,76}([ \n]|$))/", '\1<br>', $msg); |
| $promptuserfail = 1; |
| $title = 'VM Host Reload Failed'; |
| } |
| else { |
| if(count($vmids)) |
| $this->scheduleVMsToAvailable($vmids); |
| $multirefresh = 3; |
| } |
| } |
| else { |
| # VCL provisioned, same image |
| $msg = ''; |
| if(count($updates)) |
| $msg .= "Computer information changes saved.<br><br>\nHowever, this "; |
| else |
| $msg .= "This "; |
| $msg .= "computer was previously in the vmhostinuse state. "; |
| $msg .= "You can:<br><br>\n"; |
| $msg .= "<input type=\"radio\" name=\"mode\" value=\"vmhostinuse\" "; |
| $msg .= "id=\"modedirect\" checked=\"checked\"><label "; |
| $msg .= "for=\"modereload\">Move it directly back to vmhostinuse\n"; |
| $msg .= "</label><br>\n"; |
| $msg .= "<input type=\"radio\" name=\"mode\" value=\"reload\" "; |
| $msg .= "id=\"modereload\"><label for=\"modereload\">Have it reloaded "; |
| $msg .= "and then placed back into vmhostinuse</label><br><br>\n"; |
| $promptuser = 1; |
| $cdata = $this->basecdata; |
| $cdata['compid'] = $data['rscid']; |
| $cdata['imageid'] = $profiles[$data['vmprofileid']]['imageid']; |
| $cdata['oldprofileid'] = $olddata['vmprofileid']; |
| $cdata['vmprofileid'] = $data['vmprofileid']; |
| $cdata['newstateid'] = $data['stateid']; |
| $cdata['oldstateid'] = $olddata['stateid']; |
| $cdata['vmids'] = $vmids; |
| $promptcont = addContinuationsEntry('AJsubmitComputerStateLater', $cdata, SECINDAY, 1, 0); |
| $btntxt = 'Submit'; |
| $title = 'State Change Option'; |
| } |
| $data['stateid'] = $olddata['stateid']; # prevent state from being updated directly |
| } |
| else { |
| if(count($vmids)) { |
| $query = "UPDATE computer " |
| . "SET stateid = 2, " |
| . "notes = '' " |
| . "WHERE id in ($allids)"; |
| doQuery($query); |
| $multirefresh = 1; |
| } |
| if(! array_key_exists('vmprofileid', $olddata) || |
| $olddata['vmprofileid'] == '') { |
| $query = "INSERT INTO vmhost " |
| . "(computerid, " |
| . "vmprofileid) " |
| . "VALUES ({$data['rscid']}, " |
| . "{$data['vmprofileid']})"; |
| doQuery($query); |
| } |
| elseif($olddata['vmprofileid'] != $data['vmprofileid']) { |
| $query = "UPDATE vmhost " |
| . "SET vmprofileid = {$data['vmprofileid']} " |
| . "WHERE computerid = {$data['rscid']} AND " |
| . "vmprofileid = {$olddata['vmprofileid']}"; |
| doQuery($query); |
| } |
| } |
| } |
| elseif($olddata['stateid'] != 20 && $data['stateid'] == 20) { |
| # check for reservations |
| moveReservationsOffComputer($data['rscid']); |
| cleanSemaphore(); |
| $reloadstart = getCompFinalReservationTime($data['rscid'], 21); |
| $checkstart = getExistingChangeStateStartTime($data['rscid'], 21); |
| if($data['provisioning'] != 'none') { |
| # VCL provisioned |
| $profiles = getVMProfiles($data['vmprofileid']); |
| $imageid = $profiles[$data['vmprofileid']]['imageid']; |
| if($reloadstart) { |
| if($checkstart && $checkstart < $reloadstart) |
| $reloadstart = $checkstart; |
| # reservations, must wait until end time |
| $end = date('n/j/y g:i a', $reloadstart); |
| $msg = ''; |
| if(count($updates)) |
| $msg .= "Computer information changes saved.<br>\nHowever, this "; |
| else |
| $msg .= "This "; |
| $msg .= "computer is currently allocated until $end and cannot "; |
| $msg .= "be reloaded until then. You can:\n"; |
| $msg .= "<ul><li>Cancel and try later</li>\n"; |
| $msg .= "<li>Schedule the computer to be reloaded with the selected "; |
| $msg .= "profile at $end</li></ul>\n"; |
| $msg = preg_replace("/(.{1,76}([ \n]|$))/", '\1<br>', $msg); |
| $msg = preg_replace("|$end|", "<strong>$end</strong>", $msg, 1); |
| $promptuser = 1; |
| $cdata = $this->basecdata; |
| $cdata['maintenanceonly'] = 0; |
| $cdata['compid'] = $data['rscid']; |
| $cdata['reloadstart'] = $reloadstart; |
| $cdata['imageid'] = $imageid; |
| $cdata['oldprofileid'] = $olddata['vmprofileid']; |
| $cdata['vmprofileid'] = $data['vmprofileid']; |
| $cdata['newstateid'] = $data['stateid']; |
| $cdata['oldstateid'] = $olddata['stateid']; |
| $promptcont = addContinuationsEntry('AJsubmitComputerStateLater', $cdata, SECINDAY, 1, 0); |
| $btntxt = 'Schedule Reload'; |
| $title = 'Delayed State Change'; |
| } |
| else { |
| # no reservations |
| $start = getReloadStartTime(); |
| $checkstart = getExistingChangeStateStartTime($data['rscid'], 21); |
| if($checkstart && $checkstart < $start) |
| $start = $checkstart; |
| $rc = $this->scheduleTovmhostinuse($data['rscid'], $imageid, $start, |
| $data['vmprofileid'], $olddata['vmprofileid']); |
| |
| if($rc == 0) { |
| $msg = ''; |
| if(count($updates)) |
| $msg .= "Computer information changes were saved.<br>\nHowever, a "; |
| else |
| $msg .= "A "; |
| $msg .= "problem was encountered while attempting to reload the "; |
| $msg .= "computer with the selected VM Host Profile. Please try "; |
| $msg .= "again at a later time.\n"; |
| $msg = preg_replace("/(.{1,76}([ \n]|$))/", '\1<br>', $msg); |
| $promptuserfail = 1; |
| $title = 'VM Host Reload Failed'; |
| } |
| else |
| $multirefresh = 3; |
| } |
| $data['stateid'] = $olddata['stateid']; # prevent state from being updated directly |
| } |
| else { |
| # manually provisioned |
| if($reloadstart) { |
| # reservations, must wait until end time |
| $end = date('n/j/y g:i a', $reloadstart); |
| $msg = ''; |
| if(count($updates)) |
| $msg .= "Computer information changes saved.<br>\nHowever, this "; |
| else |
| $msg .= "This "; |
| $msg .= "computer is currently allocated until $end and cannot "; |
| $msg .= "be converted to a VM host until then. You can:\n"; |
| $msg .= "<ul><li>Cancel and do nothing</li>\n"; |
| $msg .= "<li>Schedule the computer to go in to maintenance at $end "; |
| $msg .= "and manually move it to vmhostinuse after that</li></ul>\n"; |
| $msg = preg_replace("/(.{1,76}([ \n]|$))/", '\1<br>', $msg); |
| $msg = preg_replace("|$end|", "<strong>$end</strong>", $msg, 1); |
| $promptuser = 1; |
| $cdata = $this->basecdata; |
| $cdata['maintenanceonly'] = 1; |
| $cdata['reloadstart'] = $reloadstart; |
| $cdata['imageid'] = getImageId('noimage'); |
| $cdata['compid'] = $data['rscid']; |
| $cdata['newstateid'] = $data['stateid']; |
| $cdata['oldstateid'] = $olddata['stateid']; |
| $promptcont = addContinuationsEntry('AJsubmitComputerStateLater', $cdata, SECINDAY, 1, 0); |
| $btntxt = 'Schedule State Change'; |
| $title = 'Delayed State Change'; |
| $data['stateid'] = $olddata['stateid']; # prevent state from being updated yet |
| } |
| else { |
| # no reservations |
| $this->updateVmhostProfile($data['rscid'], $data['vmprofileid'], $olddata['vmprofileid']); |
| } |
| } |
| } |
| elseif($olddata['stateid'] == 20 && $data['stateid'] == 2) { |
| # only valid condition for VCL provisioned |
| # check for reservations |
| moveReservationsOffVMs($data['rscid']); |
| cleanSemaphore(); |
| $reloadstart = getCompFinalVMReservationTime($data['rscid'], 1); |
| if($reloadstart == -1) { |
| $msg = ''; |
| if(count($updates)) |
| $msg .= "Computer information changes were saved.<br>\nHowever, a "; |
| else |
| $msg .= "A "; |
| $msg .= "problem was encountered while attempting to move VMs "; |
| $msg .= "off of the computer. Please try again at a later time.\n"; |
| $msg = preg_replace("/(.{1,76}([ \n]|$))/", '\1<br>', $msg); |
| $promptuserfail = 1; |
| $title = 'Change to Available Failed'; |
| $data['stateid'] = $olddata['stateid']; |
| } |
| elseif($reloadstart > 0) { |
| cleanSemaphore(); |
| $end = date('n/j/y g:i a', $reloadstart); |
| $msg = ''; |
| if(count($updates)) |
| $msg .= "Computer information changes saved.<br>\nHowever, this "; |
| else |
| $msg .= "This "; |
| $msg .= "computer currently has VMs with reservations on them until "; |
| $msg .= "$end and cannot be moved to the available state until then. "; |
| $msg .= "You can:\n"; |
| $msg .= "<ul><li>Cancel and do nothing</li>\n"; |
| $msg .= "<li>Schedule the VMs to be removed at $end and the computer "; |
| $msg .= "to be moved to available that</li></ul>\n"; |
| $msg = preg_replace("/(.{1,76}([ \n]|$))/", '\1<br>', $msg); |
| $msg = preg_replace("|$end|", "<strong>$end</strong>", $msg, 1); |
| $promptuser = 1; |
| $cdata = $this->basecdata; |
| $cdata['reloadstart'] = $reloadstart; |
| $cdata['imageid'] = getImageId('noimage'); |
| $cdata['compid'] = $data['rscid']; |
| $cdata['newstateid'] = $data['stateid']; |
| $cdata['oldstateid'] = $olddata['stateid']; |
| $promptcont = addContinuationsEntry('AJsubmitComputerStateLater', $cdata, SECINDAY, 1, 0); |
| $btntxt = 'Schedule State Change'; |
| $title = 'Delayed State Change'; |
| $data['stateid'] = $olddata['stateid']; # prevent state from being updated yet |
| } |
| else { |
| # schedule tomaintenance reservations for VMs |
| # might be better to just directly move the VMs to the maintenance state |
| $vclreloadid = getUserlistID('vclreload@Local'); |
| $imageid = getImageId('noimage'); |
| $revid = getProductionRevisionid($imageid); |
| $start = getReloadStartTime(); |
| $end = $start + SECINMONTH; |
| $startdt = unixToDatetime($start); |
| $enddt = unixToDatetime($end); |
| $query = "SELECT vm.id " |
| . "FROM computer vm, " |
| . "vmhost v " |
| . "WHERE v.computerid = {$data['rscid']} AND " |
| . "vm.vmhostid = v.id"; |
| $qh = doQuery($query); |
| $fail = 0; |
| while($row = mysqli_fetch_assoc($qh)) { |
| if(! simpleAddRequest($row['id'], $imageid, $revid, $startdt, |
| $enddt, 18, $vclreloadid)) { |
| $fail = 1; |
| break; |
| } |
| else |
| $multirefresh = 2; |
| } |
| cleanSemaphore(); |
| if($fail) { |
| $data['stateid'] = $olddata['stateid']; # prevent state from being updated yet |
| $msg = ''; |
| if(count($updates)) |
| $msg .= "Computer information changes were saved.<br>\nHowever, a "; |
| else |
| $msg .= "A "; |
| $msg .= "problem was encountered while attempting to remove VMs "; |
| $msg .= "from the computer. Please try again at a later time.\n"; |
| $msg = preg_replace("/(.{1,76}([ \n]|$))/", '\1<br>', $msg); |
| $promptuserfail = 1; |
| $title = 'Change State to Available Failed'; |
| } |
| } |
| } |
| elseif($olddata['stateid'] == 20 && $data['stateid'] == 10) { |
| # VCL provisioned and manually provisioned are the same |
| # check for reservations |
| moveReservationsOffVMs($data['rscid']); |
| cleanSemaphore(); |
| $reloadstart = getCompFinalVMReservationTime($data['rscid'], 1, 1); |
| if($reloadstart == -1) { |
| $msg = ''; |
| if(count($updates)) |
| $msg .= "Computer information changes were saved.<br>\nHowever, a "; |
| else |
| $msg .= "A "; |
| $msg .= "problem was encountered while attempting to place assigned VMs "; |
| $msg .= "into the maintenance state. Please try again at a later time.\n"; |
| $msg = preg_replace("/(.{1,76}([ \n]|$))/", '\1<br>', $msg); |
| $promptuserfail = 1; |
| $title = 'Change to Maintenance Failed'; |
| } |
| elseif($reloadstart > 0) { |
| cleanSemaphore(); |
| if(unixToDatetime($reloadstart) == '2038-01-01 00:00:00') { |
| $msg = ''; |
| if(count($updates)) |
| $msg .= "Computer information changes saved.<br>\nHowever, this "; |
| else |
| $msg .= "This "; |
| $msg .= "computer currently has VMs assigned to it that have server "; |
| $msg .= "reservations with indefinite endings. The computer cannot "; |
| $msg .= "be moved to the maintenance state while these reservations exist."; |
| $msg = preg_replace("/(.{1,76}([ \n]|$))/", '\1<br>', $msg); |
| $promptuserfail = 1; |
| $title = 'Change to Maintenance Failed'; |
| $data['stateid'] = $olddata['stateid']; # prevent state from being updated |
| } |
| else { |
| $end = date('n/j/y g:i a', $reloadstart); |
| $msg = ''; |
| if(count($updates)) |
| $msg .= "Computer information changes saved.<br>\nHowever, this "; |
| else |
| $msg .= "This "; |
| $msg .= "computer currently has VMs with reservations on them until "; |
| $msg .= "$end and cannot be moved to the maintenance state until then. "; |
| $msg .= "You can:\n"; |
| $msg .= "<ul><li>Cancel and do nothing</li>\n"; |
| $msg .= "<li>Schedule the computer and VMs to be moved into the "; |
| $msg .= "maintenance state at $end</li></ul>\n"; |
| $msg = preg_replace("/(.{1,76}([ \n]|$))/", '\1<br>', $msg); |
| $msg = preg_replace("|$end|", "<strong>$end</strong>", $msg, 1); |
| $promptuser = 1; |
| $cdata = $this->basecdata; |
| $cdata['reloadstart'] = $reloadstart; |
| $cdata['imageid'] = getImageId('noimage'); |
| $cdata['compid'] = $data['rscid']; |
| $cdata['newstateid'] = $data['stateid']; |
| $cdata['oldstateid'] = $olddata['stateid']; |
| $promptcont = addContinuationsEntry('AJsubmitComputerStateLater', $cdata, SECINDAY, 1, 0); |
| $btntxt = 'Schedule State Change'; |
| $title = 'Delayed State Change'; |
| $data['stateid'] = $olddata['stateid']; # prevent state from being updated yet |
| } |
| } |
| else { |
| $query = "UPDATE computer c " |
| . "INNER JOIN vmhost v ON (c.vmhostid = v.id) " |
| . "SET c.stateid = 10, " |
| . "c.notes = 'maintenance with host {$data['rscid']}' " |
| . "WHERE v.computerid = {$data['rscid']}"; |
| doQuery($query); |
| cleanSemaphore(); |
| $multirefresh = 1; |
| } |
| } |
| elseif($olddata['stateid'] == 10 && $data['stateid'] == 2) { |
| if(is_numeric($olddata['vmprofileid'])) { |
| $vclreloadid = getUserlistID('vclreload@Local'); |
| $imageid = getImageId('noimage'); |
| $revid = getProductionRevisionid($imageid); |
| $start = getReloadStartTime(); |
| $end = $start + SECINMONTH; |
| $startdt = unixToDatetime($start); |
| $enddt = unixToDatetime($end); |
| # move VMs to reload state so vcld will not skip them due to being in maintenance |
| $query = "UPDATE computer c, " |
| . "vmhost v " |
| . "SET c.stateid = 19, " |
| . "c.notes = '' " |
| . "WHERE v.computerid = {$data['rscid']} AND " |
| . "c.vmhostid = v.id"; |
| doQuery($query); |
| $query = "SELECT vm.id " |
| . "FROM computer vm, " |
| . "vmhost v " |
| . "WHERE v.computerid = {$data['rscid']} AND " |
| . "vm.vmhostid = v.id"; |
| $qh = doQuery($query); |
| $fails = array(); |
| while($row = mysqli_fetch_assoc($qh)) { |
| if(! simpleAddRequest($row['id'], $imageid, $revid, $startdt, |
| $enddt, 18, $vclreloadid)) { |
| $fails[] = $row['id']; |
| } |
| else |
| $multirefresh = 2; |
| } |
| if(count($fails)) { |
| # just directly remove any VMs that failed to be scheduled |
| $query = "UPDATE computer " |
| . "SET stateid = 10, " |
| . "vmhostid = NULL, " |
| . "notes = '' " |
| . "WHERE id IN (" . implode(',', $fails) . ")"; |
| doQuery($query); |
| } |
| } |
| } |
| elseif($olddata['stateid'] == 20 && $data['stateid'] == 20 && |
| $olddata['vmprofileid'] != $data['vmprofileid']) { |
| if($data['provisioning'] != 'none') { |
| $profiles = getVMProfiles($data['vmprofileid']); |
| if($profiles[$olddata['vmprofileid']]['imageid'] == |
| $profiles[$data['vmprofileid']]['imageid']) { |
| $query = "UPDATE vmhost " |
| . "SET vmprofileid = {$data['vmprofileid']} " |
| . "WHERE computerid = {$data['rscid']} AND " |
| . "vmprofileid = {$olddata['vmprofileid']}"; |
| doQuery($query); |
| } |
| else { |
| moveReservationsOffVMs($data['rscid']); |
| cleanSemaphore(); |
| $reloadstart = getCompFinalVMReservationTime($data['rscid'], 1); |
| if($reloadstart == -1) { |
| $msg = ''; |
| if(count($updates)) |
| $msg .= "Computer information changes were saved.<br>\nHowever, a "; |
| else |
| $msg .= "A "; |
| $msg .= "problem was encountered while attempting to place assigned "; |
| $msg .= "VMs into the maintenance state while reloading the computer. "; |
| $msg .= "Please try again at a later time.\n"; |
| $msg = preg_replace("/(.{1,76}([ \n]|$))/", '\1<br>', $msg); |
| $promptuserfail = 1; |
| $title = 'Change VM Host Profile Failed'; |
| } |
| elseif($reloadstart > 0) { |
| cleanSemaphore(); |
| $end = date('n/j/y g:i a', $reloadstart); |
| $msg = ''; |
| if(count($updates)) |
| $msg .= "Computer information changes saved.<br>\nHowever, this "; |
| else |
| $msg .= "This "; |
| $msg .= "computer must be reloaded to change to the selected VM Host "; |
| $msg .= "Profile and there are VMs on it with reservations until $end. "; |
| $msg .= "You can:\n"; |
| $msg .= "<ul><li>Cancel and do nothing</li>\n"; |
| $msg .= "<li>Schedule the VMs to be removed and the computer to be "; |
| $msg .= "reloaded at $end</li></ul>\n"; |
| $msg = preg_replace("/(.{1,76}([ \n]|$))/", '\1<br>', $msg); |
| $msg = preg_replace("|$end|", "<strong>$end</strong>", $msg, 1); |
| $promptuser = 1; |
| $cdata = $this->basecdata; |
| $cdata['reloadstart'] = $reloadstart; |
| $cdata['imageid'] = $profiles[$data['vmprofileid']]['imageid']; |
| $cdata['compid'] = $data['rscid']; |
| $cdata['newstateid'] = $data['stateid']; |
| $cdata['oldstateid'] = $olddata['stateid']; |
| $cdata['oldprofileid'] = $olddata['vmprofileid']; |
| $cdata['vmprofileid'] = $data['vmprofileid']; |
| $promptcont = addContinuationsEntry('AJsubmitComputerStateLater', $cdata, SECINDAY, 1, 0); |
| $btntxt = 'Schedule Reload'; |
| $title = 'Delayed VM Host Profile Change'; |
| } |
| else { |
| # schedule VMs to be removed |
| $vclreloadid = getUserlistID('vclreload@Local'); |
| $imageid = getImageId('noimage'); |
| $revid = getProductionRevisionid($imageid); |
| $start = getReloadStartTime(); |
| $end = $start + SECINMONTH; |
| $startdt = unixToDatetime($start); |
| $enddt = unixToDatetime($end); |
| $query = "SELECT vm.id " |
| . "FROM computer vm, " |
| . "vmhost v " |
| . "WHERE v.computerid = {$data['rscid']} AND " |
| . "vm.vmhostid = v.id"; |
| $qh = doQuery($query); |
| $fails = array(); |
| $cnt = 0; |
| while($row = mysqli_fetch_assoc($qh)) { |
| $cnt++; |
| if(! simpleAddRequest($row['id'], $imageid, $revid, $startdt, |
| $enddt, 18, $vclreloadid)) { |
| $fails[] = $row['id']; |
| } |
| } |
| if(count($fails)) { |
| # just directly remove any VMs that failed to be scheduled |
| $query = "UPDATE computer " |
| . "SET stateid = 10, " |
| . "vmhostid = NULL, " |
| . "notes = '' " |
| . "WHERE id IN (" . implode(',', $fails) . ")"; |
| doQuery($query); |
| } |
| cleanSemaphore(); |
| |
| # schedule host to be reloaded |
| if($cnt) |
| $start = time() + 120; # allow 2 minutes for VMs to be removed |
| $rc = $this->scheduleTovmhostinuse($data['rscid'], |
| $profiles[$data['vmprofileid']]['imageid'], |
| $start, $data['vmprofileid'], |
| $olddata['vmprofileid']); |
| |
| if($rc == 0) { |
| $msg = ''; |
| if(count($updates)) |
| $msg .= "Computer information changes were saved.<br>\nHowever, a "; |
| else |
| $msg .= "A "; |
| $msg .= "problem was encountered while attempting to reload the "; |
| $msg .= "computer with the selected VM Host Profile. Please try "; |
| $msg .= "again at a later time.\n"; |
| $msg = preg_replace("/(.{1,76}([ \n]|$))/", '\1<br>', $msg); |
| $promptuserfail = 1; |
| $title = 'VM Host Reload Failed'; |
| } |
| else |
| $multirefresh = 3; |
| } |
| } |
| } |
| else { |
| $query = "UPDATE vmhost " |
| . "SET vmprofileid = {$data['vmprofileid']} " |
| . "WHERE computerid = {$data['rscid']} AND " |
| . "vmprofileid = {$olddata['vmprofileid']}"; |
| doQuery($query); |
| } |
| } |
| elseif($olddata['stateid'] != 10 && $data['stateid'] == 10) { |
| moveReservationsOffComputer($data['rscid']); |
| cleanSemaphore(); |
| $reloadstart = getCompFinalReservationTime($data['rscid']); |
| if($reloadstart) { |
| $end = date('n/j/y g:i a', $reloadstart); |
| $msg = ''; |
| if(count($updates)) |
| $msg .= "Computer information changes saved.<br>\nHowever, this "; |
| else |
| $msg .= "This "; |
| $msg .= "computer has reservations on it until $end. You can:\n"; |
| $msg .= "<ul><li>Cancel and do nothing</li>\n"; |
| $msg .= "<li>Schedule the computer to be moved to maintenance at "; |
| $msg .= "$end</li></ul>\n"; |
| $msg = preg_replace("/(.{1,76}([ \n]|$))/", '\1<br>', $msg); |
| $msg = preg_replace("|$end|", "<strong>$end</strong>", $msg, 1); |
| $promptuser = 1; |
| $cdata = $this->basecdata; |
| $cdata['reloadstart'] = $reloadstart; |
| $cdata['imageid'] = getImageId('noimage'); |
| $cdata['compid'] = $data['rscid']; |
| $cdata['newstateid'] = $data['stateid']; |
| $cdata['oldstateid'] = $olddata['stateid']; |
| $promptcont = addContinuationsEntry('AJsubmitComputerStateLater', $cdata, SECINDAY, 1, 0); |
| $btntxt = 'Schedule Maintenance'; |
| $title = 'Delayed Maintenance'; |
| } |
| # else let UPDATE move it to maintenance |
| } |
| |
| # notes (do these at the end because we don't want to update notes if |
| # state prevented from being changed) |
| # staying in maintenance |
| if($olddata['stateid'] == 10 && $data['stateid'] == 10) { |
| $testnotes = $olddata['notes']; |
| # check for notes being changed |
| if(! is_null($testnotes) && strpos($testnotes, '@') === true) { |
| $tmp = explode('@', $olddata['notes']); |
| $testnotes = $tmp[1]; |
| } |
| if($testnotes != $data['notes']) { |
| $ts = unixToDatetime(time()); |
| $updates[] = "notes = '{$user['unityid']} $ts@{$data['notes']}'"; |
| } |
| } |
| # changing to maintenance |
| elseif($data['stateid'] == 10) { |
| $ts = unixToDatetime(time()); |
| $updates[] = "notes = '{$user['unityid']} $ts@{$data['notes']}'"; |
| } |
| # removing from maintenance |
| elseif($olddata['stateid'] == 10 && $data['stateid'] != 10) { |
| $updates[] = "notes = ''"; |
| } |
| |
| # stateid |
| if($data['stateid'] != $olddata['stateid']) |
| $updates[] = "stateid = {$data['stateid']}"; |
| |
| if(count($updates)) { |
| $query = "UPDATE computer SET " |
| . implode(', ', $updates) |
| . " WHERE id = {$data['rscid']}"; |
| doQuery($query); |
| } |
| } |
| |
| # clear user resource cache for this type |
| $key = getKey(array(array($this->restype . "Admin"), array("administer"), 0, 1, 0, 0)); |
| unset($_SESSION['userresources'][$key]); |
| $key = getKey(array(array($this->restype . "Admin"), array("administer"), 0, 0, 0, 0)); |
| unset($_SESSION['userresources'][$key]); |
| $key = getKey(array(array($this->restype . "Admin"), array("manageGroup"), 0, 1, 0, 0)); |
| unset($_SESSION['userresources'][$key]); |
| $key = getKey(array(array($this->restype . "Admin"), array("manageGroup"), 0, 0, 0, 0)); |
| unset($_SESSION['userresources'][$key]); |
| |
| $args = $this->defaultGetDataArgs; |
| $arr = array('status' => 'success'); |
| if(is_array($data['rscid'])) { |
| $tmp = $this->getData($args); |
| $arr['addmode'] = 'multiple'; |
| $arr['data'] = array(); |
| foreach($data['rscid'] as $compid) { |
| $tmp[$compid]['name'] = $tmp[$compid]['hostname']; |
| $arr['data'][] = $tmp[$compid]; |
| } |
| $arr['grouphelp'] = "Select groups from the list on the right and click the " |
| . "Add button to add the new computer set to those groups.<br><br>"; |
| $cdata = $this->basecdata; |
| $cdata['newids'] = $data['rscid']; |
| $cdata['mode'] = 'add'; |
| $arr['addcont'] = addContinuationsEntry('AJaddRemGroupResource', $cdata); |
| $cdata['mode'] = 'remove'; |
| $arr['remcont'] = addContinuationsEntry('AJaddRemGroupResource', $cdata); |
| } |
| else { |
| if($add) |
| $arr['addmode'] = 'single'; |
| $args['rscid'] = $data['rscid']; |
| $tmp = $this->getData($args); |
| $data = $tmp[$data['rscid']]; |
| $arr['data'] = $data; |
| $arr['data']['name'] = $arr['data']['hostname']; |
| } |
| if($add) { |
| $arr['action'] = 'add'; |
| $arr['nogroups'] = 0; |
| $groups = getUserResources(array($this->restype . 'Admin'), array('manageGroup'), 1); |
| if(count($groups[$this->restype])) |
| $arr['groupingHTML'] = $this->groupByResourceHTML(); |
| else |
| $arr['nogroups'] = 1; |
| } |
| else |
| $arr['action'] = 'edit'; |
| if($promptuser) { |
| $arr['promptuser'] = 1; |
| $arr['btntxt'] = $btntxt; |
| $arr['title'] = $title; |
| $arr['msg'] = $msg; |
| $arr['cont'] = $promptcont; |
| } |
| elseif($promptuserfail) { |
| $arr['promptuserfail'] = 1; |
| $arr['title'] = $title; |
| $arr['msg'] = $msg; |
| } |
| if($multirefresh) |
| $arr['multirefresh'] = $multirefresh; |
| sendJSON($arr); |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn validateResourceData() |
| /// |
| /// \return array with these fields:\n |
| /// \b rscid - id of resource (from computer table)\n |
| /// \b name - hostname of computer\n |
| /// \b startnum - start number when doing multiple add\n |
| /// \b endnum - end number when doing multiple add\n |
| /// \b owner\n |
| /// \b type - type of computer\n |
| /// \b IPaddress - public IP address\n |
| /// \b privateIPaddress - private IP address\n |
| /// \b eth0macaddress - public MAC address\n |
| /// \b eth1macaddress - private MAC address\n |
| /// \b startpubipaddress - start public IP address when doing multiple add\n |
| /// \b endpubipaddress - end public IP address when doing multiple add\n |
| /// \b startprivipaddress - start private IP address when doing multiple |
| /// add\n |
| /// \b endprivipaddress - end private IP address when doing multiple add\n |
| /// \b startmac - start MAC address when doing multiple add\n |
| /// \b provisioningid - id of provisioning engine for computer(s)\n |
| /// \b stateid - id for state of computer\n |
| /// \b notes - maintenance notes when setting computer to maintenance state\n |
| /// \b vmprofileid - id of vmprofile when setting to vmhostinuse state\n |
| /// \b platformid - id of platform\n |
| /// \b scheduleid - id of schedule\n |
| /// \b ram\n |
| /// \b cores\n |
| /// \b procspeed\n |
| /// \b network\n |
| /// \b predictivemoduleid - id of module to use when preloading nodes\n |
| /// \b natenabled - 1 to use NAT for this computer, 0 not to\n |
| /// \b nathostid - id of NAT host for this computer\n |
| /// \b location - free string describing location\n |
| /// \b mode - 'edit' or 'add'\n |
| /// \b addmode - 'single' or 'multiple'\n |
| /// \b startpubiplong - numeric value for start public IP address when doing |
| /// multiple add\n |
| /// \b endpubiplong - numeric value for end public IP address when doing |
| /// multiple add\n |
| /// \b startpriviplong - numeric value for start private IP address when |
| /// doing multiple add\n |
| /// \b endpriviplong - numeric value for end private IP address when doing |
| /// multiple add\n |
| /// \b error - 0 if submitted data validates; 1 if anything is invalid\n |
| /// \b errormsg - if error = 1; string of error messages separated by html |
| /// break tags |
| /// |
| /// \brief validates form input from editing or adding a computer |
| /// |
| ///////////////////////////////////////////////////////////////////////////// |
| function validateResourceData() { |
| global $user; |
| |
| $return = array('error' => 0); |
| |
| $return['rscid'] = getContinuationVar('rscid', 0); |
| $return['name'] = processInputVar('name', ARG_STRING, ''); |
| $return['startnum'] = processInputVar('startnum', ARG_NUMERIC); |
| $return['endnum'] = processInputVar('endnum', ARG_NUMERIC); |
| $return['owner'] = processInputVar('owner', ARG_STRING, "{$user['unityid']}@{$user['affiliation']}"); |
| $return['type'] = processInputVar('type', ARG_STRING, ''); |
| $return['IPaddress'] = processInputVar('ipaddress', ARG_STRING, ''); |
| $return['privateIPaddress'] = processInputVar('privateipaddress', ARG_STRING, ''); |
| $return['eth0macaddress'] = processInputVar('privatemac', ARG_STRING, ''); |
| $return['eth1macaddress'] = processInputVar('publicmac', ARG_STRING, ''); |
| $return['startpubipaddress'] = processInputVar('startpubipaddress', ARG_STRING, ''); |
| $return['endpubipaddress'] = processInputVar('endpubipaddress', ARG_STRING, ''); |
| $return['startprivipaddress'] = processInputVar('startprivipaddress', ARG_STRING, ''); |
| $return['endprivipaddress'] = processInputVar('endprivipaddress', ARG_STRING, ''); |
| $return['startmac'] = processInputVar('startmac', ARG_STRING, ''); |
| $return['provisioningid'] = processInputVar('provisioningid', ARG_NUMERIC); |
| $return['stateid'] = processInputVar('stateid', ARG_NUMERIC); |
| $return['notes'] = processInputVar('notes', ARG_STRING, ''); |
| $return['vmprofileid'] = processInputVar('vmprofileid', ARG_NUMERIC); |
| $return['platformid'] = processInputVar('platformid', ARG_NUMERIC); |
| $return['scheduleid'] = processInputVar('scheduleid', ARG_NUMERIC); |
| $return['ram'] = processInputVar('ram', ARG_NUMERIC); |
| $return['cores'] = processInputVar('cores', ARG_NUMERIC); |
| $return['procspeed'] = processInputVar('procspeed', ARG_NUMERIC); |
| $return['network'] = processInputVar('network', ARG_NUMERIC); |
| $return['predictivemoduleid'] = processInputVar('predictivemoduleid', ARG_NUMERIC); |
| $return['natenabled'] = processInputVar('natenabled', ARG_NUMERIC); |
| $return['nathostid'] = processInputVar('nathostid', ARG_NUMERIC); |
| $return['nathostenabled'] = processInputVar('nathostenabled', ARG_NUMERIC); |
| $return['natpublicIPaddress'] = processInputVar('natpublicipaddress', ARG_STRING, ''); |
| $return['natinternalIPaddress'] = processInputVar('natinternalipaddress', ARG_STRING, ''); |
| $return['location'] = processInputVar('location', ARG_STRING, ''); |
| $addmode = processInputVar('addmode', ARG_STRING); |
| |
| if(! is_null($addmode) && $addmode != 'single' && $addmode != 'multiple') { |
| $return['error'] = 1; |
| $return['errormsg'] = "Invalid Add mode submitted"; |
| return $return; |
| } |
| |
| $olddata = getContinuationVar('olddata'); |
| |
| if($return['rscid'] == 0) |
| $return['mode'] = 'add'; |
| else |
| $return['mode'] = 'edit'; |
| |
| $errormsg = array(); |
| |
| # hostname |
| $hostreg = '/^[a-zA-Z0-9_][-a-zA-Z0-9_\.]{1,49}$/'; |
| if($return['mode'] == 'add' && $addmode == 'multiple') |
| $hostreg = '/^[a-zA-Z0-9_%][-a-zA-Z0-9_\.%]{1,49}$/'; |
| if(! preg_match($hostreg, $return['name'])) { |
| $return['error'] = 1; |
| $errormsg[] = "Hostname can only contain letters, numbers, dashes(-), periods(.), and underscores(_). It can be from 1 to 50 characters long"; |
| } |
| elseif($this->checkForHostname($return['name'], $return['rscid'])) { |
| $return['error'] = 1; |
| $errormsg[] = "A computer already exists with this hostname."; |
| } |
| # add multiple |
| if($return['mode'] == 'add' && $addmode == 'multiple') { |
| # ensure % in hostname |
| if(! preg_match('/%/', $return['name'])) { |
| $return['error'] = 1; |
| $errormsg[] = "Name must contain % when adding multiple computers"; |
| } |
| # startnum/endnum |
| if($return['startnum'] < 0 || $return['startnum'] > 255) { |
| $return['error'] = 1; |
| $errormsg[] = "Start must be from 0 to 255"; |
| } |
| if($return['endnum'] < 0 || $return['endnum'] > 255) { |
| $return['error'] = 1; |
| $errormsg[] = "End must be from 0 to 255"; |
| } |
| if($return['startnum'] >= 0 && $return['startnum'] <= 255 && |
| $return['endnum'] >= 0 && $return['endnum'] <= 255 && |
| $return['startnum'] > $return['endnum']) { |
| $return['error'] = 1; |
| $errormsg[] = "Start must be >= End"; |
| } |
| $checkhosts = array(); |
| for($i = $return['startnum']; $i <= $return['endnum']; $i++) |
| $checkhosts[] = str_replace('%', $i, $return['name']); |
| $allhosts = implode("','", $checkhosts); |
| $query = "SELECT hostname FROM computer " |
| . "WHERE hostname IN ('$allhosts') AND " |
| . "deleted = 0"; |
| $qh = doQuery($query); |
| $exists = array(); |
| while($row = mysqli_fetch_assoc($qh)) |
| $exists[] = $row['hostname']; |
| if(count($exists)) { |
| $hosts = implode(', ', $exists); |
| $return['error'] = 1; |
| $errormsg[] = "There are already computers with these hostnames: $hosts"; |
| } |
| } |
| else { |
| $return['startnum'] = 0; |
| $return['endnum'] = 0; |
| } |
| # owner |
| if(! validateUserid($return['owner'])) { |
| $return['error'] = 1; |
| $errormsg[] = "Submitted owner is not valid"; |
| } |
| # type |
| if(! preg_match('/^(blade|lab|virtualmachine)$/', $return['type'])) { |
| $return['error'] = 1; |
| $errormsg[] = "Submitted type is not valid"; |
| } |
| # edit or add single |
| if($return['rscid'] || ($return['mode'] == 'add' && $addmode == 'single')) { |
| # ipaddress |
| if(! validateIPv4addr($return['IPaddress'])) { |
| $return['error'] = 1; |
| $errormsg[] = "Invalid Public IP address. Must be w.x.y.z with each of " |
| . "w, x, y, and z being between 1 and 255 (inclusive)"; |
| } |
| # private ipaddress |
| if(strlen($return['privateIPaddress']) && |
| ! validateIPv4addr($return['privateIPaddress'])) { |
| $return['error'] = 1; |
| $errormsg[] = "Invalid Private IP address. Must be w.x.y.z with each of " |
| . "w, x, y, and z being between 1 and 255 (inclusive)"; |
| } |
| # eth0macaddress |
| if(strlen($return['eth0macaddress'])) { |
| if(! preg_match('/^(([A-Fa-f0-9]){2}:){5}([A-Fa-f0-9]){2}$/', $return["eth0macaddress"])) { |
| $return['error'] = 1; |
| $errormsg[] = "Invalid Private MAC address. Must be XX:XX:XX:XX:XX:XX " |
| . "with each pair of XX being from 00 to FF (inclusive)"; |
| } |
| elseif($this->checkForMACaddress($return['eth0macaddress'], 0, $return['rscid'])) { |
| $return['error'] = 1; |
| $errormsg[] = "There is already a computer with this Private MAC address."; |
| } |
| } |
| # eth1macaddress |
| if(strlen($return['eth1macaddress'])) { |
| if(! preg_match('/^(([A-Fa-f0-9]){2}:){5}([A-Fa-f0-9]){2}$/', $return["eth1macaddress"])) { |
| $return['error'] = 1; |
| $errormsg[] = "Invalid Public MAC address. Must be XX:XX:XX:XX:XX:XX " |
| . "with each pair of XX being from 00 to FF (inclusive)"; |
| } |
| elseif($this->checkForMACaddress($return['eth1macaddress'], 1, $return['rscid'])) { |
| $return['error'] = 1; |
| $errormsg[] = "There is already a computer with this Public MAC address."; |
| } |
| } |
| } |
| else { |
| $return['IPaddress'] = ''; |
| $return['privateIPaddress'] = ''; |
| $return['eth0macaddress'] = ''; |
| $return['eth1macaddress'] = ''; |
| } |
| # add multiple |
| if($return['mode'] == 'add' && $addmode == 'multiple') { |
| if(! validateIPv4addr($return['startpubipaddress'])) { |
| $return['error'] = 1; |
| $errormsg[] = "Invalid Start Public IP address. Must be w.x.y.z with each of " |
| . "w, x, y, and z being between 1 and 255 (inclusive)"; |
| } |
| if(! validateIPv4addr($return['endpubipaddress'])) { |
| $return['error'] = 1; |
| $errormsg[] = "Invalid End Public IP address. Must be w.x.y.z with each of " |
| . "w, x, y, and z being between 1 and 255 (inclusive)"; |
| } |
| if(! validateIPv4addr($return['startprivipaddress'])) { |
| $return['error'] = 1; |
| $errormsg[] = "Invalid Start Private IP address. Must be w.x.y.z with each of " |
| . "w, x, y, and z being between 1 and 255 (inclusive)"; |
| } |
| if(! validateIPv4addr($return['endprivipaddress'])) { |
| $return['error'] = 1; |
| $errormsg[] = "Invalid End Private IP address. Must be w.x.y.z with each of " |
| . "w, x, y, and z being between 1 and 255 (inclusive)"; |
| } |
| $startpubiplong = ip2long($return['startpubipaddress']); |
| $endpubiplong = ip2long($return['endpubipaddress']); |
| if($startpubiplong > $endpubiplong) { |
| $return['error'] = 1; |
| $errormsg[] = "Start Public IP Address must be lower or equal to End Public IP Address"; |
| } |
| elseif(($endpubiplong - $startpubiplong) != ($return['endnum'] - $return['startnum'])) { |
| $return['error'] = 1; |
| $errormsg[] = "Public IP Address range does not equal Start/End range"; |
| } |
| $startpriviplong = ip2long($return['startprivipaddress']); |
| $endpriviplong = ip2long($return['endprivipaddress']); |
| if($startpriviplong > $endpriviplong) { |
| $return['error'] = 1; |
| $errormsg[] = "Start Private IP Address must be lower or equal to End Private IP Address"; |
| } |
| elseif(($endpriviplong - $startpriviplong) != ($return['endnum'] - $return['startnum'])) { |
| $return['error'] = 1; |
| $errormsg[] = "Private IP Address range does not equal Start/End range"; |
| } |
| $return['startpubiplong'] = $startpubiplong; |
| $return['endpubiplong'] = $endpubiplong; |
| $return['startpriviplong'] = $startpriviplong; |
| $return['endpriviplong'] = $endpriviplong; |
| $cnt = $endpubiplong - $startpubiplong + 1; |
| if($return['startmac'] != '') { |
| if(! preg_match('/^(([A-Fa-f0-9]){2}:){5}([A-Fa-f0-9]){2}$/', $return['startmac'])) { |
| $return['error'] = 1; |
| $errormsg[] = "Invalid Start MAC address. Must be XX:XX:XX:XX:XX:XX " |
| . "with each pair of XX being from 00 to FF (inclusive)"; |
| } |
| elseif($this->checkMultiAddMacs($return['startmac'], $cnt, $msg, $macs)) { |
| $return['error'] = 1; |
| $errormsg[] = $msg; |
| } |
| $return['macs'] = $macs; |
| } |
| else |
| $return['macs'] = array(); |
| } |
| else { |
| $return['startpubipaddress'] = ''; |
| $return['endpubipaddress'] = ''; |
| $return['startprivipaddress'] = ''; |
| $return['endprivipaddress'] = ''; |
| $return['startmac'] = ''; |
| } |
| # provisioningid |
| $provisioning = getProvisioning(); |
| if(! array_key_exists($return['provisioningid'], $provisioning)) { |
| $return['error'] = 1; |
| $errormsg[] = "Invalid Provisioning Engine selected"; |
| } |
| else |
| $return['provisioning'] = $provisioning[$return['provisioningid']]['name']; |
| # stateid 2 - available, 10 - maintenance, 20 - vmhostinuse |
| if(! preg_match('/^(2|10|20)$/', $return['stateid']) && |
| ($return['mode'] == 'add' || $return['stateid'] != $olddata['stateid'])) { |
| $return['error'] = 1; |
| $errormsg[] = "Invalid value submitted for State"; |
| } |
| # validate type/provisioning combinations |
| $provtypes = getProvisioningTypes(); |
| if(($return['mode'] == 'add' || $olddata['provisioningid'] != $return['provisioningid']) && |
| ! array_key_exists($return['provisioningid'], $provtypes[$return['type']])) { |
| $return['error'] = 1; |
| $errormsg[] = "Invalid Provisioning Engine selected for computer type"; |
| } |
| # validate type/provisioning/state combinations |
| if($return['mode'] == 'add' || $olddata['stateid'] != $return['stateid']) { |
| if($return['type'] == 'lab') { |
| if($return['stateid'] != 2 && $return['stateid'] != 10) { |
| $return['error'] = 1; |
| $errormsg[] = "Invalid state submitted for computer type Lab"; |
| } |
| } |
| elseif($return['type'] == 'virtualmachine') { |
| if($return['stateid'] != 10 && |
| ($return['mode'] == 'add' || ! is_numeric($olddata['vmhostid']) || $return['stateid'] != 2)) { |
| $return['error'] = 1; |
| $errormsg[] = "Invalid state submitted for computer type Virtual Machine"; |
| } |
| } |
| elseif($return['type'] == 'blade') { |
| if($provisioning[$return['provisioningid']]['name'] == 'none' && |
| $return['stateid'] != 10 && $return['stateid'] != 20) { |
| $return['error'] = 1; |
| $errormsg[] = "Invalid state submitted for computer type Bare Metal"; |
| } |
| } |
| } |
| # notes |
| if($return['stateid'] == 10) { |
| if(! preg_match('/^([-a-zA-Z0-9_\. ,#\(\)=\+:;]{0,5000})$/', $return['notes'])) { |
| $return['error'] = 1; |
| $errormsg[] = "Maintenance reason can be up to 5000 characters long and may only<br>contain letters, numbers, spaces and these characters: - , . _ # ( ) = + : ;"; |
| } |
| } |
| else |
| $return['notes'] = ''; |
| # vmprofileid |
| $profiles = getVMProfiles(); |
| if($return['type'] == 'blade' && $return['stateid'] == 20 && |
| ! array_key_exists($return['vmprofileid'], $profiles)) { |
| $return['error'] = 1; |
| $errormsg[] = "Invalid value submitted for VM Host Profile"; |
| } |
| # platformid |
| $platforms = getPlatforms(); |
| if(! array_key_exists($return['platformid'], $platforms)) { |
| $return['error'] = 1; |
| $errormsg[] = "Invalid value submitted for Platform"; |
| } |
| # scheduleid |
| $schedules = getSchedules(); |
| if(! array_key_exists($return['scheduleid'], $schedules)) { |
| $return['error'] = 1; |
| $errormsg[] = "Invalid value submitted for Schedule"; |
| } |
| # ram |
| if($return['ram'] < 500 || $return['ram'] > 16777215) { |
| $return['error'] = 1; |
| $errormsg[] = "Invalid value submitted for RAM"; |
| } |
| # cores |
| if($return['cores'] < 1 || $return['cores'] > 255) { |
| $return['error'] = 1; |
| $errormsg[] = "Invalid value submitted for Cores"; |
| } |
| # procspeed |
| if($return['procspeed'] < 500 || $return['procspeed'] > 10000) { |
| $return['error'] = 1; |
| $errormsg[] = "Invalid value submitted for Processor Speed"; |
| } |
| # network |
| if(! preg_match('/^(10|100|1000|10000|100000)$/', $return['network'])) { |
| $return['error'] = 1; |
| $errormsg[] = "Invalid value submitted for Network"; |
| } |
| # predictivemoduleid |
| $premodules = getPredictiveModules(); |
| if(! array_key_exists($return['predictivemoduleid'], $premodules)) { |
| $return['error'] = 1; |
| $errormsg[] = "Invalid value submitted for Predictive Loading Module"; |
| } |
| $naterror = 0; |
| # natenabled |
| if($return['natenabled'] != 0 && $return['natenabled'] != 1) { |
| $return['error'] = 1; |
| $errormsg[] = "Invalid value for Connect Using NAT"; |
| $naterror = 1; |
| } |
| # nathostid |
| $nathosts = getNAThosts(); |
| if(($return['natenabled'] && $return['nathostid'] == 0) || |
| ($return['nathostid'] != 0 && ! array_key_exists($return['nathostid'], $nathosts))) { |
| $return['error'] = 1; |
| $errormsg[] = "Invalid value submitted for NAT Host"; |
| $naterror = 1; |
| } |
| # nat change - check for active reservations |
| $vclreloadid = getUserlistID('vclreload@Local'); |
| if($return['mode'] == 'edit') { |
| if($olddata['nathostid'] == '') |
| $olddata['nathostid'] = 0; |
| if(! $naterror && ($olddata['natenabled'] != $return['natenabled'] || |
| $olddata['nathostid'] != $return['nathostid'])) { |
| $query = "SELECT rq.id " |
| . "FROM request rq, " |
| . "reservation rs " |
| . "WHERE rs.requestid = rq.id AND " |
| . "rs.computerid = {$return['rscid']} AND " |
| . "rq.start <= NOW() AND " |
| . "rq.end > NOW() AND " |
| . "rq.stateid NOT IN (1,5,11,12) AND " |
| . "rq.laststateid NOT IN (1,5,11,12) AND " |
| . "rq.userid != $vclreloadid"; |
| $qh = doQuery($query); |
| if(mysqli_num_rows($qh)) { |
| $return['error'] = 1; |
| $errormsg[] = "This computer has an active reservation. NAT settings cannot be changed for computers having<br>active reservations."; |
| } |
| } |
| } |
| $nathosterror = 0; |
| # nathostenabled |
| if($return['nathostenabled'] != 0 && $return['nathostenabled'] != 1) { |
| $return['error'] = 1; |
| $errormsg[] = "Invalid value for Use as NAT Host"; |
| $nathosterror = 1; |
| } |
| # natpublicIPaddress |
| if($return['nathostenabled'] && |
| ($return['mode'] == 'edit' || $addmode == 'single')) { |
| if(! validateIPv4addr($return['natpublicIPaddress'])) { |
| $return['error'] = 1; |
| $errormsg[] = "Invalid NAT Public IP address. Must be w.x.y.z with each of " |
| . "w, x, y, and z being between 1 and 255 (inclusive)"; |
| $nathosterror = 1; |
| } |
| # natinternalIPaddress |
| if(! validateIPv4addr($return['natinternalIPaddress'])) { |
| $return['error'] = 1; |
| $errormsg[] = "Invalid NAT Internal IP address. Must be w.x.y.z with each of " |
| . "w, x, y, and z being between 1 and 255 (inclusive)"; |
| $nathosterror = 1; |
| } |
| } |
| # nat host change - check for active reservations |
| if(! $nathosterror && $return['mode'] == 'edit') { |
| if($olddata['nathostenabled'] != $return['nathostenabled'] || |
| $olddata['natpublicIPaddress'] != $return['natpublicIPaddress'] || |
| $olddata['natinternalIPaddress'] != $return['natinternalIPaddress']) { |
| $query = "SELECT rq.id " |
| . "FROM request rq, " |
| . "reservation rs, " |
| . "nathostcomputermap nhcm, " |
| . "nathost nh " |
| . "WHERE rs.requestid = rq.id AND " |
| . "rs.computerid = nhcm.computerid AND " |
| . "nhcm.nathostid = nh.id AND " |
| . "nh.resourceid = {$olddata['resourceid']} AND " |
| . "rq.start <= NOW() AND " |
| . "rq.end > NOW() AND " |
| . "rq.stateid NOT IN (1,5,11,12) AND " |
| . "rq.laststateid NOT IN (1,5,11,12) AND " |
| . "rq.userid != $vclreloadid"; |
| $qh = doQuery($query); |
| if(mysqli_num_rows($qh)) { |
| $return['error'] = 1; |
| $errormsg[] = "This computer is the NAT host for other computers that have active reservations. NAT host<br>settings cannot be changed while providing NAT for active reservations."; |
| } |
| } |
| } |
| # location |
| if(! preg_match('/^([-a-zA-Z0-9_\. ,@#\(\)]{0,255})$/', $return['location'])) { |
| $return['error'] = 1; |
| $errormsg[] = "Invalid value submitted for Location"; |
| } |
| |
| if($return['mode'] == 'add') |
| $return['addmode'] = $addmode; |
| |
| if($return['error']) |
| $return['errormsg'] = implode('<br>', $errormsg); |
| |
| return $return; |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn checkForHostname($hostname, $compid) |
| /// |
| /// \param $hostname - a computer hostname |
| /// \param $compid - (optional) a computer id to ignore |
| /// |
| /// \return 1 if $hostname is already in the computer table, 0 if not |
| /// |
| /// \brief checks for $hostname being somewhere in the computer table except |
| /// for $compid |
| /// |
| ///////////////////////////////////////////////////////////////////////////// |
| function checkForHostname($hostname, $compid='') { |
| $query = "SELECT id FROM computer " |
| . "WHERE hostname = '$hostname' AND " |
| . "deleted = 0"; |
| if(! empty($compid)) |
| $query .= " AND id != $compid"; |
| $qh = doQuery($query); |
| if(mysqli_num_rows($qh)) |
| return 1; |
| return 0; |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn checkForMACaddress($mac, $num, $compid) |
| /// |
| /// \param $mac - computer mac address |
| /// \param $num - which mac address to check - 0 or 1 |
| /// \param $compid - (optional) a computer id to ignore |
| /// |
| /// \return 1 if $mac/$num is already in the computer table, 0 if not |
| /// |
| /// \brief checks for $mac being somewhere in the computer table except |
| /// for $compid |
| /// |
| ///////////////////////////////////////////////////////////////////////////// |
| function checkForMACaddress($mac, $num, $compid='') { |
| if($num == 0) |
| $field = 'eth0macaddress'; |
| else |
| $field = 'eth1macaddress'; |
| $query = "SELECT id FROM computer " |
| . "WHERE $field = '$mac' AND " |
| . "deleted = 0"; |
| if(! empty($compid)) |
| $query .= " AND id != $compid"; |
| $qh = doQuery($query); |
| if(mysqli_num_rows($qh)) |
| return 1; |
| return 0; |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn checkForIPaddress($ipaddress, $type, $compid) |
| /// |
| /// \param $ipaddress - a computer ip address |
| /// \param $type - 'public' or 'private' - which IP address to check |
| /// \param $compid - (optional) a computer id to ignore |
| /// |
| /// \return 1 if $ipaddress is already in the computer table, 0 if not |
| /// |
| /// \brief checks for $ipaddress being somewhere in the computer table except |
| /// for $compid |
| /// |
| ///////////////////////////////////////////////////////////////////////////// |
| function checkForIPaddress($ipaddress, $type, $compid='') { |
| if($type == 'public') |
| $field = 'IPaddress'; |
| else |
| $field = 'privateIPaddress'; |
| $query = "SELECT id FROM computer " |
| . "WHERE $field = '$ipaddress'"; |
| if(! empty($compid)) |
| $query .= " AND id != $compid"; |
| $qh = doQuery($query); |
| if(mysqli_num_rows($qh)) |
| return 1; |
| return 0; |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn addResource($data) |
| /// |
| /// \param $data - array of needed data for adding a new resource |
| /// |
| /// \return id of new resource |
| /// |
| /// \brief handles adding a new computer and other associated data to the |
| /// database |
| /// |
| ///////////////////////////////////////////////////////////////////////////// |
| function addResource($data) { |
| global $user; |
| $ownerid = getUserlistID($data['owner']); |
| $noimageid = getImageId('noimage'); |
| $norevid = getProductionRevisionid($noimageid); |
| $keys = array('hostname', 'ownerid', |
| 'type', 'IPaddress', |
| 'privateIPaddress', 'eth0macaddress', |
| 'eth1macaddress', 'provisioningid', |
| 'stateid', 'platformid', |
| 'scheduleid', 'RAM', |
| 'procnumber', 'procspeed', |
| 'network', 'currentimageid', |
| 'imagerevisionid', 'location', |
| 'predictivemoduleid'); |
| if($data['addmode'] == 'single') { |
| $eth0 = "'{$data['eth0macaddress']}'"; |
| if($data['eth0macaddress'] == '') |
| $eth0 = 'NULL'; |
| $eth1 = "'{$data['eth1macaddress']}'"; |
| if($data['eth1macaddress'] == '') |
| $eth1 = 'NULL'; |
| $values = array("'{$data['name']}'", $ownerid, |
| "'{$data['type']}'", "'{$data['IPaddress']}'", |
| "'{$data['privateIPaddress']}'", $eth0, |
| $eth1, $data['provisioningid'], |
| $data['stateid'], $data['platformid'], |
| $data['scheduleid'], $data['ram'], |
| $data['cores'], $data['procspeed'], |
| $data['network'], $noimageid, |
| $norevid, "'{$data['location']}'", |
| $data['predictivemoduleid']); |
| |
| $query = "INSERT INTO computer (" |
| . implode(', ', $keys) . ") VALUES (" |
| . implode(', ', $values) . ")"; |
| doQuery($query); |
| |
| $rscid = dbLastInsertID(); |
| |
| # vmhost entry |
| if($data['stateid'] == '20') { |
| $query = "INSERT INTO vmhost " |
| . "(computerid, " |
| . "vmprofileid) " |
| . "VALUES ($rscid, " |
| . "{$data['vmprofileid']})"; |
| doQuery($query); |
| } |
| |
| # NAT |
| if($data['natenabled']) { |
| $query = "INSERT INTO nathostcomputermap " |
| . "(computerid, " |
| . "nathostid) " |
| . "VALUES ($rscid, " |
| . "{$data['nathostid']})"; |
| doQuery($query); |
| } |
| |
| // add entry in resource table |
| $query = "INSERT INTO resource " |
| . "(resourcetypeid, " |
| . "subid) " |
| . "VALUES (12, " |
| . "$rscid)"; |
| doQuery($query); |
| |
| $resourceid = dbLastInsertID(); |
| |
| # NAT host |
| if($data['nathostenabled']) { |
| $query = "INSERT INTO nathost " |
| . "(resourceid, " |
| . "publicIPaddress, " |
| . "internalIPaddress) " |
| . "VALUES " |
| . "($resourceid, " |
| . "'{$data['natpublicIPaddress']}', " |
| . "'{$data['natinternalIPaddress']}')"; |
| doQuery($query); |
| } |
| |
| return $rscid; |
| } |
| else { |
| # add multiple computers |
| $alldis = array(); |
| for($i = $data['startnum'], $cnt = 0; $i <= $data['endnum']; $i++, $cnt++) { |
| $hostname = str_replace('%', $i, $data["name"]); |
| $pubip = long2ip($data['startpubiplong'] + $cnt); |
| $privip = long2ip($data['startpriviplong'] + $cnt); |
| if(count($data['macs'])) { |
| $eth0 = "'" . $data['macs'][$cnt * 2] . "'"; |
| $eth1 = "'" . $data['macs'][($cnt * 2) + 1] . "'"; |
| } |
| else { |
| $eth0 = 'NULL'; |
| $eth1 = 'NULL'; |
| } |
| $values = array("'$hostname'", $ownerid, |
| "'{$data['type']}'", "'$pubip'", |
| "'$privip'", $eth0, |
| $eth1, $data['provisioningid'], |
| $data['stateid'], $data['platformid'], |
| $data['scheduleid'], $data['ram'], |
| $data['cores'], $data['procspeed'], |
| $data['network'], $noimageid, |
| $norevid, "'{$data['location']}'", |
| $data['predictivemoduleid']); |
| |
| $query = "INSERT INTO computer (" |
| . implode(', ', $keys) . ") VALUES (" |
| . implode(', ', $values) . ")"; |
| doQuery($query); |
| |
| $rscid = dbLastInsertID(); |
| |
| # vmhost entry |
| if($data['stateid'] == '20') { |
| $query = "INSERT INTO vmhost " |
| . "(computerid, " |
| . "vmprofileid) " |
| . "VALUES ($rscid, " |
| . "{$data['vmprofileid']})"; |
| doQuery($query); |
| } |
| |
| # NAT |
| if($data['natenabled']) { |
| $query = "INSERT INTO nathostcomputermap " |
| . "(computerid, " |
| . "nathostid) " |
| . "VALUES ($rscid, " |
| . "{$data['nathostid']})"; |
| doQuery($query); |
| } |
| |
| // add entry in resource table |
| $query = "INSERT INTO resource " |
| . "(resourcetypeid, " |
| . "subid) " |
| . "VALUES (12, " |
| . "$rscid)"; |
| doQuery($query); |
| |
| $allids[] = $rscid; |
| } |
| return $allids; |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn AJcanceltovmhostinuse() |
| /// |
| /// \brief cancels any reservations to place the computer in the vmhostinuse |
| /// state |
| /// |
| //////////////////////////////////////////////////////////////////////////////// |
| function AJcanceltovmhostinuse() { |
| global $mysqli_link_vcl; |
| $compid = getContinuationVar('compid'); |
| $type = 'none'; |
| $query = "DELETE FROM request " |
| . "WHERE start > NOW() AND " |
| . "stateid = 21 AND " |
| . "id IN (SELECT requestid " |
| . "FROM reservation " |
| . "WHERE computerid = $compid)"; |
| doQuery($query); |
| if(mysqli_affected_rows($mysqli_link_vcl)) |
| $type = 'future'; |
| $query = "UPDATE request rq, " |
| . "reservation rs, " |
| . "state ls " |
| . "SET rq.stateid = 1 " |
| . "WHERE rs.requestid = rq.id AND " |
| . "rs.computerid = $compid AND " |
| . "rq.start <= NOW() AND " |
| . "rq.laststateid = ls.id AND " |
| . "ls.name = 'tovmhostinuse'"; |
| doQuery($query); |
| if(mysqli_affected_rows($mysqli_link_vcl)) |
| $type = 'current'; |
| $query = "SELECT rq.start " |
| . "FROM request rq, " |
| . "reservation rs, " |
| . "state ls, " |
| . "state cs " |
| . "WHERE rs.requestid = rq.id AND " |
| . "rs.computerid = $compid AND " |
| . "rq.laststateid = ls.id AND " |
| . "rq.stateid = cs.id AND " |
| . "ls.name = 'tovmhostinuse' AND " |
| . "cs.name NOT IN ('failed', 'maintenance', 'complete', 'deleted') AND " |
| . "rq.end > NOW() " |
| . "ORDER BY rq.start"; |
| $qh = doQuery($query); |
| if(mysqli_num_rows($qh)) |
| $arr = array('status' => 'failed'); |
| else { |
| if($type == 'now') |
| $msg = "The reservation currently being processed to place this " |
| . "computer in the vmhostinuse state has been flagged for " |
| . "deletion. As soon as the deletion can be processed, the " |
| . "computer will be set to the available state."; |
| else |
| $msg = "The reservation scheduled to place this computer in the " |
| . "vmhostinuse state has been deleted."; |
| $arr = array('status' => 'success', 'msg' => $msg); |
| } |
| sendJSON($arr); |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn scheduleTovmhostinuse($compid, $imageid, $start, $vmprofileid, |
| /// $oldvmprofileid) |
| /// |
| /// \param $compid - id of a computer |
| /// \param $imageid - id of an image |
| /// \param $start - start time in unix timestamp format |
| /// \param $vmprofileid - id of vmprofile |
| /// \param $oldvmprofileid - id of possible previous vmprofile |
| /// |
| /// \return 0 on failure, 1 on success |
| /// |
| /// \brief schedules or updates a reservation to move a host to the |
| /// vmhostinuse state |
| /// |
| ///////////////////////////////////////////////////////////////////////////// |
| function scheduleTovmhostinuse($compid, $imageid, $start, $vmprofileid, |
| $oldvmprofileid) { |
| # create a reload reservation to load machine with image |
| # corresponding to selected vm profile |
| $vclreloadid = getUserlistID('vclreload@Local'); |
| $revid = getProductionRevisionid($imageid); |
| $end = $start + SECINYEAR; # don't want anyone making a future reservation for this machine |
| $startdt = unixToDatetime($start); |
| $enddt = unixToDatetime($end); |
| $failed = 0; |
| |
| $mnid = findManagementNode($compid, $startdt, 'now'); |
| if($mnid == 0) |
| return 0; |
| |
| # check for existing tovmhostinuse reservation |
| $query = "SELECT rq.id, " |
| . "rq.start, " |
| . "rq.end, " |
| . "rs.imageid " |
| . "FROM request rq, " |
| . "reservation rs " |
| . "WHERE rs.requestid = rq.id AND " |
| . "rs.computerid = $compid AND " |
| . "rq.stateid = 21 AND " |
| . "rq.start > NOW() " |
| . "ORDER BY rq.start " |
| . "LIMIT 1"; |
| $qh = doQuery($query); |
| if($row = mysqli_fetch_assoc($qh)) { |
| if(! retryGetSemaphore($imageid, $revid, $mnid, $compid, $startdt, $enddt, $row['id'])) |
| return 0; |
| # update existing reservation |
| $updates = array(); |
| $startts = datetimeToUnix($row['start']); |
| if($start < $startts) |
| $updates[] = "rq.start = '$startdt'"; |
| elseif($start > $startts) |
| $this->startchange = $startts; |
| if($row['imageid'] != $imageid) |
| $updates[] = "rs.imageid = $imageid"; |
| if(count($updates)) { |
| $query = "UPDATE request rq, " |
| . "reservation rs " |
| . "SET " . implode(',', $updates) |
| ." WHERE rs.requestid = rq.id AND " |
| . "rq.id = {$row['id']}"; |
| doQuery($query); |
| } |
| } |
| else { |
| if(! retryGetSemaphore($imageid, $revid, $mnid, $compid, $startdt, $enddt)) |
| return 0; |
| # add new reservation |
| if(! (simpleAddRequest($compid, $imageid, $revid, $startdt, $enddt, 21, |
| $vclreloadid))) |
| return 0; |
| } |
| |
| cleanSemaphore(); |
| |
| $this->updateVmhostProfile($compid, $vmprofileid, $oldvmprofileid); |
| |
| return 1; |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn updateVmhostProfile($compid, $newprofileid, $oldprofileid) |
| /// |
| /// \param $compid - id of computer |
| /// \param $newprofileid - id of new vmprofile |
| /// \param $oldprofileid - id of possible previous vmprofile |
| /// |
| /// \brief updates a vmhost entry's vmprofileid or creates a new vmhost entry |
| /// |
| ///////////////////////////////////////////////////////////////////////////// |
| function updateVmhostProfile($compid, $newprofileid, $oldprofileid) { |
| if(is_numeric($oldprofileid)) { |
| if($oldprofileid != $newprofileid) { |
| # update existing entry |
| $query = "UPDATE vmhost " |
| . "SET vmprofileid = $newprofileid " |
| . "WHERE computerid = $compid AND " |
| . "vmprofileid = $oldprofileid"; |
| doQuery($query); |
| } |
| } |
| else { |
| # create vmhost entry |
| $query = "INSERT INTO vmhost " |
| . "(computerid, " |
| . "vmprofileid) " |
| . "VALUES ($compid, " |
| . "$newprofileid)"; |
| doQuery($query); |
| } |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| /// |
| /// \fn AJsubmitComputerStateLater() |
| /// |
| /// \brief schedules a computer to be converted to another state at a future |
| /// time |
| /// |
| ///////////////////////////////////////////////////////////////////////////// |
| function AJsubmitComputerStateLater() { |
| $compid = getContinuationVar('compid'); |
| $maintenanceonly = getContinuationVar('maintenanceonly', 0); |
| $start = getContinuationVar('reloadstart'); |
| $end = $start + SECINYEAR; |
| $startdt = unixToDatetime($start); |
| $enddt = unixToDatetime($end); |
| $vmprofileid = getContinuationVar('vmprofileid', 0); |
| $oldprofileid = getContinuationVar('oldprofileid', 0); |
| $newstateid = getContinuationVar('newstateid', 0); |
| $oldstateid = getContinuationVar('oldstateid', 0); |
| $imageid = getContinuationVar('imageid'); |
| $revid = getProductionRevisionid($imageid); |
| $mode = processInputVar('mode', ARG_STRING); |
| $msg = ''; |
| $refreshcount = 0; |
| |
| if($oldstateid == 10 && $newstateid == 20 && |
| ! is_null($mode) && $mode != 'direct' && $mode != 'reload') { |
| $errmsg = "Invalid information submitted"; |
| $ret = array('status' => 'error', |
| 'errormsg' => $errmsg); |
| sendJSON($ret); |
| return; |
| } |
| |
| $delayed = 0; |
| |
| # maintenance directly back to vmhostinuse |
| if($mode == 'direct') { |
| $vmids = getContinuationVar('vmids'); |
| if(count($vmids)) { |
| $allids = implode(',', $vmids); |
| $query = "UPDATE computer " |
| . "SET stateid = 2, " |
| . "notes = '' " |
| . "WHERE id in ($allids)"; |
| doQuery($query); |
| } |
| $query = "UPDATE computer " |
| . "SET stateid = 20, " |
| . "notes = '' " |
| . "WHERE id = $compid"; |
| doQuery($query); |
| $msg .= "The computer has been moved back to the vmhostinuse state and "; |
| $msg .= "the appropriate VMs have been moved to the available state."; |
| $title = "Change to vmhostinuse"; |
| $refreshcount = 1; |
| } |
| # maintenance back to vmhostinuse with a reload |
| elseif($mode == 'reload') { |
| $vmids = getContinuationVar('vmids'); |
| if(count($vmids)) |
| $this->scheduleVMsToAvailable($vmids); |
| $start = getReloadStartTime(); |
| $rc = $this->scheduleTovmhostinuse($compid, $imageid, $start, |
| $vmprofileid, $oldprofileid); |
| |
| if($rc == 0) { |
| $errmsg .= "A problem was encountered while attempting to reload the "; |
| $errmsg .= "computer with the selected VM Host Profile. Please try "; |
| $errmsg .= "again at a later time.\n"; |
| $errmsg = preg_replace("/(.{1,76}([ \n]|$))/", '\1<br>', $errmsg); |
| $ret = array('status' => 'error', |
| 'errormsg' => $errmsg); |
| sendJSON($ret); |
| return; |
| } |
| $msg .= "The computer has been scheduled to go back to the vmhostinuse "; |
| $msg .= "state and the appropriate VMs have been scheduled to go back "; |
| $msg .= "to the available state at %s."; |
| $title = "Change to vmhostinuse"; |
| } |
| # anything else to vmhostinuse |
| elseif($oldstateid != 20 && $newstateid == 20) { |
| moveReservationsOffComputer($compid); |
| cleanSemaphore(); |
| |
| $mnid = findManagementNode($compid, unixToDatetime($start), 'future'); |
| $tmp = getCompFinalReservationTime($compid, 21); |
| $checkstart = getExistingChangeStateStartTime($compid, 21); |
| if(! $checkstart && $checkstart != $start && $tmp > $start) { |
| $delayed = 1; |
| $start = $tmp; |
| $end = $start + SECINYEAR; |
| $startdt = unixToDatetime($start); |
| $enddt = unixToDatetime($end); |
| } |
| $vclreloadid = getUserlistID('vclreload@Local'); |
| if($maintenanceonly) { |
| if(! retryGetSemaphore($imageid, $revid, $mnid, $compid, $start, $end)) { |
| $errmsg = "An error was encountered while trying to schedule this<br>\n"; |
| $errmsg .= "computer for the maintenance state. Please try again later.\n"; |
| $ret = array('status' => 'error', |
| 'errormsg' => $errmsg); |
| sendJSON($ret); |
| return; |
| } |
| # create a tomaintenance reservation |
| if(! (simpleAddRequest($compid, $imageid, $revid, $startdt, $enddt, |
| 18, $vclreloadid))) { |
| $errmsg = "An error was encountered while trying to schedule this<br>\n"; |
| $errmsg .= "computer for the maintenance state. Please try again later.\n"; |
| $ret = array('status' => 'error', |
| 'errormsg' => $errmsg); |
| sendJSON($ret); |
| cleanSemaphore(); |
| return; |
| } |
| $msg .= "The computer has been scheduled to be moved to the "; |
| $msg .= "maintenance state at %s."; |
| $title = "Change to maintenance state"; |
| } |
| else { |
| # create a reload reservation to load machine with image |
| # corresponding to selected vm profile |
| $rc = $this->scheduleTovmhostinuse($compid, $imageid, $start, |
| $vmprofileid, $oldprofileid); |
| if(isset($this->startchange)) { |
| $start = $this->startchange; |
| $delayed = 1; |
| } |
| if($rc == 0) { |
| $errmsg = "An error was encountered while trying to convert this "; |
| $errmsg .= "computer to a VM host server. Please try again later."; |
| $errmsg = preg_replace("/(.{1,76}([ \n]|$))/", '\1<br>', $errmsg); |
| $ret = array('status' => 'error', |
| 'errormsg' => $errmsg); |
| sendJSON($ret); |
| return; |
| } |
| $msg .= "The computer has been scheduled to be moved to the "; |
| $msg .= "vmhostinuse state at %s."; |
| $title = "Change to vmhostinuse state"; |
| } |
| cleanSemaphore(); |
| } |
| # vmhostinuse to available |
| elseif($oldstateid == 20 && $newstateid == 2) { |
| $tmp = getCompFinalVMReservationTime($compid, 1); |
| if($tmp == -1) { |
| $errmsg .= "A problem was encountered while attempting to schedule "; |
| $errmsg .= "assigned VMs to be removed from the computer. Please "; |
| $errmsg .= "try again at a later time.\n"; |
| $errmsg = preg_replace("/(.{1,76}([ \n]|$))/", '\1<br>', $errmsg); |
| $ret = array('status' => 'error', |
| 'errormsg' => $errmsg); |
| sendJSON($ret); |
| return; |
| } |
| elseif($tmp > $start) { |
| $delayed = 1; |
| $start = $tmp; |
| $end = $start + SECINYEAR; |
| $startdt = unixToDatetime($start); |
| $enddt = unixToDatetime($end); |
| } |
| $vclreloadid = getUserlistID('vclreload@Local'); |
| $query = "SELECT vm.id " |
| . "FROM computer vm, " |
| . "vmhost v " |
| . "WHERE v.computerid = $compid AND " |
| . "vm.vmhostid = v.id"; |
| $qh = doQuery($query); |
| $fail = 0; |
| while($row = mysqli_fetch_assoc($qh)) { |
| if(! simpleAddRequest($row['id'], $imageid, $revid, $startdt, |
| $enddt, 18, $vclreloadid)) { |
| $fail = 1; |
| break; |
| } |
| } |
| cleanSemaphore(); |
| if($fail) { |
| $errmsg = "A problem was encountered while attempting to remove VMs "; |
| $errmsg .= "from the computer. Please try again at a later time.\n"; |
| $errmsg = preg_replace("/(.{1,76}([ \n]|$))/", '\1<br>', $errmsg); |
| |