Files
EasySoft-ZenTaoPMS/module/zanode/model.php
T
2022-11-24 08:13:33 +00:00

464 lines
14 KiB
PHP

<?php
/**
* The model file of vm module of ZenTaoCMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author xiawenlong <xiawenlong@cnezsoft.com>
* @package ops
* @version $Id$
* @link http://www.zentao.net
*/
class zanodemodel extends model
{
const STATUS_CREATED = 'created';
const STATUS_LAUNCH = 'launch';
const STATUS_FAIL_CREATE = 'vm_fail_create';
const STATUS_RUNNING = 'running';
const STATUS_SHUTOFF = 'shutoff';
const STATUS_BUSY = 'busy';
const STATUS_READY = 'ready';
const STATUS_UNKNOWN = 'unknown';
const STATUS_DESTROY = 'destroy';
const STATUS_DESTROY_FAIL = 'vim_destroy_fail';
const KVM_CREATE_PATH = '/api/v1/kvm/create';
const KVM_TOKEN_PATH = '/api/v1/vnc/getToken';
/**
* Create an Node.
*
* @param object $data
* @access public
* @return void
*/
public function create()
{
$data = fixer::input('post')->get();
/* Batch check fields. */
$this->lang->vm = $this->lang->zanode;
$data->type = 'node';
$this->dao->update(TABLE_ZAHOST)->data($data)
->batchCheck($this->config->zanode->create->requiredFields, 'notempty')
->check('name', 'unique');
if(dao::isError()) return false;
if(!preg_match("/^(?!_)(?!-)(?!\.)[a-zA-Z0-9\_\.\-]+$/", $data->name))
{
dao::$errors[] = $this->lang->zanode->nameValid;
return false;
}
/* Get image. */
$image = $this->getImageByID($data->image);
/* Get host info. */
$host = $this->getHostByID($data->parent);
/* Gen mac address */
$mac = $this->genmac();
/* Prepare create params. */
$agnetUrl = 'http://' . $host->extranet . ':' . $this->config->zanode->defaultPort;
$param = array(
'os' => $image->os,
'path' => $image->path,
'name' => $data->name,
'cpu' => (int)$data->cpu,
'disk' => (int)$data->disk,
'memory' => (int)$data->memory,
);
$result = json_decode(commonModel::http($agnetUrl . static::KVM_CREATE_PATH, json_encode($param), null));
if(empty($result))
{
dao::$errors[] = $this->lang->zanode->notFoundAgent;
return false;
}
if($result->code != 'success')
{
dao::$errors[] = $this->lang->zanode->createVmFail;
return false;
}
/* Prepare create execution node data. */
$data->image = $data->image;
$data->parent = $host->id;
$data->mac = $mac;
$data->status = static::STATUS_RUNNING;
$data->createdBy = $this->app->user->account;
$data->createdDate = helper::now();
$data->vnc = (int)$result->data->vnc;
/* Save execution node. */
$this->dao->insert(TABLE_ZAHOST)->data($data)->autoCheck()->exec();
if(dao::isError()) return false;
$nodeID = $this->dao->lastInsertID();
/* update action log. */
$this->loadModel('action')->create('zanode', $nodeID, 'Created');
return true;
}
/**
* Action Node.
*
* @param int $id
* @param string $type
* @return string
*/
public function handleNode($id, $type)
{
$node = $this->getNodeByID($id);
$host = $this->getHostByID($node->parent);
/* Prepare create params. */
$agnetUrl = 'http://' . $host->extranet . ':' . $this->config->zanode->defaultPort;
$path = '/api/v1/kvm/' . $node->name . '/' . $type;
$param = array('vmUniqueName' => $node->name);
$result = commonModel::http($agnetUrl . $path, $param);
$data = json_decode($result, true);
if(empty($data)) return $this->lang->zanode->notFoundAgent;
if($data['code'] != 'success') return zget($this->lang->zanode->apiError, $data['code'], $data['msg']);
if($type != 'reboot')
{
$status = $type == 'suspend' ? 'suspend' : 'running';
$this->dao->update(TABLE_ZAHOST)->set('status')->eq($status)->where('id')->eq($id)->exec();
}
$this->loadModel('action')->create('zanode', $id, ucfirst($type));
return;
}
/**
* Destroy Node.
*
* @param int $id
* @access public
* @return void
*/
public function destroy($id)
{
$node = $this->getNodeByID($id);
$host = $this->getHostByID($node->parent);
$req = array( 'name' => $node->name );
/* Prepare create params. */
if($host)
{
$agnetUrl = 'http://' . $host->extranet . ':' . $this->config->zanode->defaultPort;
$result = commonModel::http($agnetUrl . '/api/v1/kvm/remove', json_encode($req));
$data = json_decode($result, true);
if(empty($data)) return $this->lang->zanode->notFoundAgent;
if($data['code'] != 'success') return zget($this->lang->zanode->apiError, $data['code'], $data['msg']);
}
/* delete execution node. */
$this->dao->update(TABLE_ZAHOST)
->set('deleted')->eq(1)
->where('id')->eq($id)
->exec();
$this->loadModel('action')->create('zanode', $id, 'destroy');
return;
}
/**
* Get execution node created action record by node ID.
*
* @param int $id
* @access public
* @return object
*/
public function getNodeCreateActionByID($id)
{
return $this->dao->select('*')->from(TABLE_ACTION)
->where('objectType')->eq('zanode')
->andWhere('objectID')->eq($id)
->andWhere('action')->eq('created')
->fetch();
}
/**
* Callback update host data.
*
* @access public
* @return mixed
*/
public function updateHostByCallback()
{
$data = array();
$data['status'] = isset($_POST['status']) ? $_POST['status'] : '';
$data['agentPort'] = isset($_POST['port']) ? $_POST['port'] : '';
$ip = isset($_POST['ip']) ? $_POST['ip'] : '';
if(empty($ip)) return false;
$host = $this->getHostByIP($ip);
if(empty($host)) return 'Not Found';
$this->dao->update(TABLE_ZAHOST)->data($data)
->where('id')->eq($host->id)
->exec();
return true;
}
/**
* Update Node.
*
* @param int $id
* @return void
*/
public function update($id)
{
$oldHost = $this->getNodeById($id);
$hostInfo = fixer::input('post')->get();
$hostInfo->editedBy = $this->app->user->account;
$hostInfo->editedDate = helper::now();
$this->dao->update(TABLE_ZAHOST)->data($hostInfo)
->batchCheck($this->config->zanode->edit->requiredFields, 'notempty');
if(dao::isError()) return false;
$this->dao->update(TABLE_ZAHOST)->data($hostInfo)->autoCheck()
->where('id')->eq($id)->exec();
return common::createChanges($oldHost, $hostInfo);
}
/**
* Get vm list.
*
* @param string $browseType
* @param int $param
* @param string $orderBy
* @param object $pager
* @return void
*/
public function getListByQuery($browseType = 'all', $param = 0, $orderBy = 't1.id_desc', $pager = null)
{
$query = '';
if($browseType == 'bysearch')
{
if($param)
{
$query = $this->loadModel('search')->getQuery($param);
if($query)
{
$this->session->set('nodeQuery', $query->sql);
$this->session->set('nodeForm', $query->form);
}
else
{
$this->session->set('nodeQuery', ' 1 = 1');
}
}
else
{
if($this->session->zanodeQuery == false) $this->session->set('zanodeQuery', ' 1 = 1');
}
$query = $this->session->zanodeQuery;
$query = str_replace('`id`', 't1.`id`', $query);
$query = str_replace('`name`', 't1.`name`', $query);
$query = str_replace('`status`', 't1.`status`', $query);
$query = str_replace('`os`', 't1.`os`', $query);
$query = str_replace('`parent`', 't1.`parent`', $query);
$query = str_replace('`hostID`', 't2.`id`', $query);
}
return $this->dao->select('t1.*, t1.name as hostName, t2.extranet,t3.osName')->from(TABLE_ZAHOST)->alias('t1')
->leftJoin(TABLE_ZAHOST)->alias('t2')->on('t1.parent = t2.id')
->leftJoin(TABLE_IMAGE)->alias('t3')->on('t3.id = t1.image')
->where('t1.deleted')->eq(0)
->andWhere("t1.type")->eq("node")
->andWhere("(t1.createdBy = '{$this->app->user->account}')")
->beginIF($query)->andWhere($query)->fi()
->orderBy($orderBy)
->page($pager)
->fetchAll();
}
/**
* Get node list by hostID.
*
* @param string $browseType
* @param int $param
* @param string $orderBy
* @param object $pager
* @return void
*/
public function getListByHost($hostID, $orderBy = 'id_desc')
{
return $this->dao->select('id, name, vnc, cpuCores, memory, diskSize, osName, status')->from(TABLE_ZAHOST)
->where('deleted')->eq(0)
->andWhere("parent")->eq($hostID)
->orderBy($orderBy)
->fetchAll();
}
/**
* Get Host by id.
*
* @param int $id
* @access public
* @return object
*/
public function getHostByID($id)
{
return $this->dao->select('*')->from(TABLE_ZAHOST)
->where('id')->eq($id)
->fetch();
}
/**
* Get Host by IP.
*
* @param string $ip
* @access public
* @return object
*/
public function getHostByIP($ip)
{
return $this->dao->select('*')->from(TABLE_ZAHOST)
->where('extranet')->eq($ip)
->fetch();
}
/**
* Get Image.
*
* @param int $id
* @access public
* @return object
*/
public function getImageByID($id)
{
return $this->dao->select('*')->from(TABLE_IMAGE)
->where('id')->eq($id)
->fetch();
}
/**
* Get Node image list.
*
* @param string $orderBy
* @param int $pager
* @access public
* @return array
*/
public function getimageList($orderBy = 'id_desc', $pager = null)
{
return $this->dao->select('*')->from(TABLE_IMAGE)->orderBy($orderBy)->page($pager)->fetchAll();
}
/**
* Get Node by id.
*
* @param int $id
* @return object
*/
public function getNodeByID($id)
{
return $this->dao->select('t1.*, t1.name as hostName, t2.extranet as ip,t3.osName')->from(TABLE_ZAHOST)->alias('t1')
->leftJoin(TABLE_ZAHOST)->alias('t2')->on('t1.parent = t2.id')
->leftJoin(TABLE_IMAGE)->alias('t3')->on('t3.id = t1.image')
->where('t1.id')->eq($id)
->fetch();
}
/**
* Get Node by mac address.
*
* @param string $mac
* @return object
*/
public function getNodeByMac($mac)
{
return $this->dao->select('*')->from(TABLE_ZAHOST)
->where('mac')->eq($mac)
->andWhere("type")->eq('node')
->fetch();
}
/**
* Generage unique mac address.
*
* @return void
*/
private function genmac()
{
$buf = array(
0x1C,
0x1C,
0x1C,
mt_rand(0x00, 0x7f),
mt_rand(0x00, 0xff),
mt_rand(0x00, 0xff)
);
$mac = join(':',array_map(function($v)
{
return sprintf("%02X",$v);
},$buf));
$Node = $this->getNodeByMac($mac);
if(empty($Node))
{
return $mac;
}
$this->genmac();
}
/**
* Get vnc url.
*
* @param int $vmID
* @access public
* @return void
*/
public function getVncUrl($vmID)
{
$vm = $this->getNodeByID($vmID);
if(empty($vm) or empty($vm->parent) or empty($vm->vnc)) return false;
$host = $this->getHostByID($vm->parent);
if(empty($host)) return false;
$agnetUrl = 'http://' . $host->extranet . ':' . $host->agentPort . static::KVM_TOKEN_PATH;
$result = json_decode(commonModel::http("$agnetUrl?port={$vm->vnc}"));
if(empty($result) or $result->code != 'success') return false;
$returnData = new stdClass();
$returnData->hostIP = $host->extranet;
$returnData->agentPort = $host->agentPort;
$returnData->vnc = $vm->vnc;
$returnData->token = $result->data->token;
return $returnData;
}
public function buildOperateMenu($node)
{
if($node->deleted) return '';
$menu = '';
$params = "id=$node->id";
$menu .= $this->buildMenu('zanode', 'edit', $params, $node, 'view');
$params = "id=$node->id";
$menu .= $this->buildMenu('zanode', 'delete', $params, $node, 'view', 'trash', 'hiddenwin');
return $menu;
}
}