From: Marcin Haba Date: Sat, 22 Feb 2020 18:01:56 +0000 (+0100) Subject: baculum: Add additional values to job and volume API endpoints X-Git-Tag: Release-9.6.1~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=72f65e6ed0fa637c4722b143e46d0c4743a42aaf;p=thirdparty%2Fbacula.git baculum: Add additional values to job and volume API endpoints Added to job endpoints: - client - pool - fileset Added to volume endpoints: - storage - pool - scratchpool - recyclepool --- diff --git a/gui/baculum/protected/API/Class/Database.php b/gui/baculum/protected/API/Class/Database.php index 738932668..21ff0fb61 100644 --- a/gui/baculum/protected/API/Class/Database.php +++ b/gui/baculum/protected/API/Class/Database.php @@ -157,5 +157,33 @@ class Database extends APIModule { $pdo = null; return $dbsize; } + + public static function getWhere(array $params) { + $where = ''; + $parameters = array(); + if (count($params) > 0) { + $condition = array(); + foreach ($params as $key => $value) { + $cond = array(); + $vals = array(); + $kval = str_replace('.', '_', $key); + if (is_array($value['vals'])) { + for ($i = 0; $i < count($value['vals']); $i++) { + $cond[] = "{$key} = :{$kval}{$i}"; + $vals[":{$kval}{$i}"] = $value['vals'][$i]; + } + } else { + $cond[] = "$key = :$kval"; + $vals[":$kval"] = $value['vals']; + } + $condition[] = implode(' ' . $value['operator'] . ' ', $cond); + foreach ($vals as $pkey => $pval) { + $parameters[$pkey] = $pval; + } + } + $where = ' WHERE (' . implode(') AND (' , $condition) . ')'; + } + return array('where' => $where, 'params' => $parameters); + } } ?> diff --git a/gui/baculum/protected/API/Class/JobManager.php b/gui/baculum/protected/API/Class/JobManager.php index 18e950a79..4880aa354 100644 --- a/gui/baculum/protected/API/Class/JobManager.php +++ b/gui/baculum/protected/API/Class/JobManager.php @@ -33,52 +33,44 @@ Prado::using('Application.API.Class.Database'); */ class JobManager extends APIModule { - public function getJobs($limit, $params = array()) { - $criteria = new TActiveRecordCriteria; - $order = 'JobId'; + public function getJobs($criteria = array(), $limit_val) { + $sort_col = 'JobId'; $db_params = $this->getModule('api_config')->getConfig('db'); if ($db_params['type'] === Database::PGSQL_TYPE) { - $order = strtolower($order); + $sort_col = strtolower($sort_col); } - $criteria->OrdersBy[$order] = 'desc'; - if(is_int($limit) && $limit > 0) { - $criteria->Limit = $limit; + $order = ' ORDER BY ' . $sort_col . ' DESC'; + $limit = ''; + if(is_int($limit_val) && $limit_val > 0) { + $limit = ' LIMIT ' . $limit_val; } - if (count($params) > 0) { - $condition = array(); - foreach ($params as $key => $value) { - $cond = array(); - $vals = array(); - if (is_array($value['vals'])) { - for ($i = 0; $i < count($value['vals']); $i++) { - $cond[] = "{$key} = :{$key}{$i}"; - $vals[":{$key}{$i}"] = $value['vals'][$i]; - } - } else { - $cond[] = "$key = :$key"; - $vals[":$key"] = $value['vals']; - } - $condition[] = implode(' ' . $value['operator'] . ' ', $cond); - foreach ($vals as $pkey => $pval) { - $criteria->Parameters[$pkey] = $pval; - } - } - $criteria->Condition = '(' . implode(') AND (' , $condition) . ')'; - } - return JobRecord::finder()->findAll($criteria); - } + $where = Database::getWhere($criteria); - public function getJobById($id) { - return JobRecord::finder()->findByjobid($id); - } + $sql = 'SELECT Job.*, +Client.Name as client, +Pool.Name as pool, +FileSet.FileSet as fileset +FROM Job +LEFT JOIN Client USING (ClientId) +LEFT JOIN Pool USING (PoolId) +LEFT JOIN FileSet USING (FilesetId)' +. $where['where'] . $order . $limit; - public function getJobByName($name) { - return JobRecord::finder()->findByname($name); + return JobRecord::finder()->findAllBySql($sql, $where['params']); } - public function deleteJobById($id) { - return JobRecord::finder()->deleteByjobid($id); + public function getJobById($jobid) { + $job = $this->getJobs(array( + 'Job.JobId' => array( + 'vals' => array($jobid), + 'operator' => 'AND' + ) + ), 1); + if (is_array($job) && count($job) > 0) { + $job = array_shift($job); + } + return $job; } /** @@ -214,7 +206,16 @@ class JobManager extends APIModule { $jobs_sql = implode("', '", $allowed_jobs); $jobs_criteria = " AND Job.Name IN ('" . $jobs_sql . "')"; } - $sql = "SELECT DISTINCT Job.* FROM Job, JobMedia WHERE JobMedia.MediaId='$mediaid' AND JobMedia.JobId=Job.JobId $jobs_criteria"; + $sql = "SELECT DISTINCT Job.*, +Client.Name as client, +Pool.Name as pool, +FileSet.FileSet as fileset +FROM Job +LEFT JOIN Client USING (ClientId) +LEFT JOIN Pool USING (PoolId) +LEFT JOIN FileSet USING (FilesetId) +LEFT JOIN JobMedia USING (JobId) +WHERE JobMedia.MediaId='$mediaid' $jobs_criteria"; return JobRecord::finder()->findAllBySql($sql); } @@ -231,7 +232,15 @@ class JobManager extends APIModule { $jobs_sql = implode("', '", $allowed_jobs); $jobs_criteria = " AND Job.Name IN ('" . $jobs_sql . "')"; } - $sql = "SELECT DISTINCT Job.* FROM Client, Job WHERE Client.ClientId='$clientid' AND Client.ClientId=Job.ClientId $jobs_criteria"; + $sql = "SELECT DISTINCT Job.*, +Client.Name as client, +Pool.Name as pool, +FileSet.FileSet as fileset +FROM Job +LEFT JOIN Client USING (ClientId) +LEFT JOIN Pool USING (PoolId) +LEFT JOIN FileSet USING (FilesetId) +WHERE Client.ClientId='$clientid' $jobs_criteria"; return JobRecord::finder()->findAllBySql($sql); } } diff --git a/gui/baculum/protected/API/Class/JobRecord.php b/gui/baculum/protected/API/Class/JobRecord.php index 3645a6799..eda172e69 100644 --- a/gui/baculum/protected/API/Class/JobRecord.php +++ b/gui/baculum/protected/API/Class/JobRecord.php @@ -61,6 +61,11 @@ class JobRecord extends APIDbModule { public $comment; public $filetable; + // Additional values (not from Job table) + public $client; + public $pool; + public $fileset; + public static function finder($className = __CLASS__) { return parent::finder($className); } diff --git a/gui/baculum/protected/API/Class/VolumeManager.php b/gui/baculum/protected/API/Class/VolumeManager.php index ee91351c9..1ffc1393c 100644 --- a/gui/baculum/protected/API/Class/VolumeManager.php +++ b/gui/baculum/protected/API/Class/VolumeManager.php @@ -33,45 +33,88 @@ Prado::using('Application.API.Class.Database'); */ class VolumeManager extends APIModule { - public function getVolumes($limit) { - $criteria = new TActiveRecordCriteria; - $orderPool = 'PoolId'; - $orderVolume = 'VolumeName'; + public function getVolumes($criteria = array(), $limit_val = 0) { + $order_pool_id = 'PoolId'; + $order_volume = 'VolumeName'; $db_params = $this->getModule('api_config')->getConfig('db'); if($db_params['type'] === Database::PGSQL_TYPE) { - $orderPool = strtolower($orderPool); - $orderVolume = strtolower($orderVolume); + $order_pool_id = strtolower($order_pool_id); + $order_volume = strtolower($order_volume); } - $criteria->OrdersBy[$orderPool] = 'asc'; - $criteria->OrdersBy[$orderVolume] = 'asc'; - if(is_int($limit) && $limit > 0) { - $criteria->Limit = $limit; + $order = " ORDER BY $order_pool_id ASC, $order_volume ASC "; + + $limit = ''; + if(is_int($limit_val) && $limit_val > 0) { + $limit = " LIMIT $limit_val "; } - $volumes = VolumeRecord::finder()->findAll($criteria); + + $where = Database::getWhere($criteria); + + $sql = 'SELECT Media.*, +pool1.Name as pool, +pool2.Name as scratchpool, +pool3.Name as recyclepool, +Storage.Name as storage +FROM Media +LEFT JOIN Pool AS pool1 USING (PoolId) +LEFT JOIN Pool AS pool2 ON Media.ScratchPoolId = pool2.PoolId +LEFT JOIN Pool AS pool3 ON Media.RecyclePoolId = pool3.PoolId +LEFT JOIN Storage USING (StorageId) +' . $where['where'] . $order . $limit; + $volumes = VolumeRecord::finder()->findAllBySql($sql, $where['params']); $this->setExtraVariables($volumes); return $volumes; } public function getVolumesByPoolId($poolid) { - $volumes = VolumeRecord::finder()->findAllBypoolid($poolid); + $volumes = $this->getVolumes(array( + 'Media.PoolId' => array( + 'vals' => array($poolid), + 'operator' => 'AND' + ) + )); $this->setExtraVariables($volumes); return $volumes; } public function getVolumeByPoolId($poolid) { - $volume = VolumeRecord::finder()->findBypoolid($poolid); + $volume = $this->getVolumes(array( + 'Media.PoolId' => array( + 'vals' => array($poolid), + 'operator' => 'AND' + ) + ), 1); + if (is_array($volume) && count($volume) > 0) { + $volume = array_shift($volume); + } $this->setExtraVariables($volume); return $volume; } - public function getVolumeByName($volumeName) { - $volume = VolumeRecord::finder()->findByvolumename($volumeName); + public function getVolumeByName($volume_name) { + $volume = $this->getVolumes(array( + 'Media.VolumeName' => array( + 'vals' => array($volume_name), + 'operator' => 'AND' + ) + ), 1); + if (is_array($volume) && count($volume) > 0) { + $volume = array_shift($volume); + } $this->setExtraVariables($volume); return $volume; } - public function getVolumeById($volumeId) { - $volume = VolumeRecord::finder()->findBymediaid($volumeId); + public function getVolumeById($volume_id) { + $volume = $this->getVolumes(array( + 'Media.MediaId' => array( + 'vals' => array($volume_id), + 'operator' => 'AND' + ) + )); + if (is_array($volume) && count($volume) > 0) { + $volume = array_shift($volume); + } $this->setExtraVariables($volume); return $volume; } diff --git a/gui/baculum/protected/API/Class/VolumeRecord.php b/gui/baculum/protected/API/Class/VolumeRecord.php index 8e1127757..80430bd65 100644 --- a/gui/baculum/protected/API/Class/VolumeRecord.php +++ b/gui/baculum/protected/API/Class/VolumeRecord.php @@ -84,6 +84,11 @@ class VolumeRecord extends APIDbModule { public $lastpartbytes; public $cacheretention; + // Additional values (not from Media table) + public $storage; + public $pool; + public $scratchpool; + public $recyclepool; public $whenexpire; public static function finder($className = __CLASS__) { diff --git a/gui/baculum/protected/API/Pages/API/Jobs.php b/gui/baculum/protected/API/Pages/API/Jobs.php index 0c5f47df8..f50920b31 100644 --- a/gui/baculum/protected/API/Pages/API/Jobs.php +++ b/gui/baculum/protected/API/Pages/API/Jobs.php @@ -36,35 +36,38 @@ class Jobs extends BaculumAPIServer { $type = $this->Request->contains('type') && $misc->isValidJobType($this->Request['type']) ? $this->Request['type'] : ''; $jobname = $this->Request->contains('name') && $misc->isValidName($this->Request['name']) ? $this->Request['name'] : ''; $clientid = $this->Request->contains('clientid') ? $this->Request['clientid'] : ''; + if (!empty($clientid) && !$misc->isValidId($clientid)) { $this->output = JobError::MSG_ERROR_CLIENT_DOES_NOT_EXISTS; $this->error = JobError::ERROR_CLIENT_DOES_NOT_EXISTS; return; } + $client = $this->Request->contains('client') ? $this->Request['client'] : ''; if (!empty($client) && !$misc->isValidName($client)) { $this->output = JobError::MSG_ERROR_CLIENT_DOES_NOT_EXISTS; $this->error = JobError::ERROR_CLIENT_DOES_NOT_EXISTS; return; } + $params = array(); $jobstatuses = array_keys($misc->getJobState()); $sts = str_split($jobstatus); for ($i = 0; $i < count($sts); $i++) { if (in_array($sts[$i], $jobstatuses)) { - if (!key_exists('jobstatus', $params)) { - $params['jobstatus'] = array('operator' => 'OR', 'vals' => array()); + if (!key_exists('Job.JobStatus', $params)) { + $params['Job.JobStatus'] = array('operator' => 'OR', 'vals' => array()); } - $params['jobstatus']['vals'][] = $sts[$i]; + $params['Job.JobStatus']['vals'][] = $sts[$i]; } } if (!empty($level)) { - $params['level']['operator'] = ''; - $params['level']['vals'] = $level; + $params['Job.Level']['operator'] = ''; + $params['Job.Level']['vals'] = $level; } if (!empty($type)) { - $params['type']['operator'] = ''; - $params['type']['vals'] = $type; + $params['Job.Type']['operator'] = ''; + $params['Job.Type']['vals'] = $type; } $allowed = array(); $result = $this->getModule('bconsole')->bconsoleCommand($this->director, array('.jobs')); @@ -76,8 +79,8 @@ class Jobs extends BaculumAPIServer { } else { $vals = $result->output; } - $params['name']['operator'] = 'OR'; - $params['name']['vals'] = $vals; + $params['Job.Name']['operator'] = 'OR'; + $params['Job.Name']['vals'] = $vals; $error = false; // Client name and clientid filter @@ -92,8 +95,8 @@ class Jobs extends BaculumAPIServer { $cli = $this->getModule('client')->getClientById($clientid); } if (is_object($cli) && in_array($cli->name, $result->output)) { - $params['clientid']['operator'] = 'AND'; - $params['clientid']['vals'] = array($cli->clientid); + $params['Job.ClientId']['operator'] = 'AND'; + $params['Job.ClientId']['vals'] = array($cli->clientid); } else { $error = true; $this->output = JobError::MSG_ERROR_CLIENT_DOES_NOT_EXISTS; @@ -107,7 +110,7 @@ class Jobs extends BaculumAPIServer { } if ($error === false) { - $jobs = $this->getModule('job')->getJobs($limit, $params); + $jobs = $this->getModule('job')->getJobs($params, $limit); $this->output = $jobs; $this->error = JobError::ERROR_NO_ERRORS; } diff --git a/gui/baculum/protected/API/Pages/API/Volumes.php b/gui/baculum/protected/API/Pages/API/Volumes.php index 20868b3ba..e161c14cc 100644 --- a/gui/baculum/protected/API/Pages/API/Volumes.php +++ b/gui/baculum/protected/API/Pages/API/Volumes.php @@ -30,7 +30,7 @@ class Volumes extends BaculumAPIServer { public function get() { $limit = $this->Request->contains('limit') ? intval($this->Request['limit']) : 0; - $result = $this->getModule('volume')->getVolumes($limit); + $result = $this->getModule('volume')->getVolumes(array(), $limit); $this->output = $result; $this->error = VolumeError::ERROR_NO_ERRORS; } diff --git a/gui/baculum/protected/API/openapi_baculum.json b/gui/baculum/protected/API/openapi_baculum.json index 242eabfea..6128a02e7 100644 --- a/gui/baculum/protected/API/openapi_baculum.json +++ b/gui/baculum/protected/API/openapi_baculum.json @@ -5320,6 +5320,18 @@ "filetable": { "description": "File table", "type": "string" + }, + "client": { + "description": "Client name", + "type": "string" + }, + "pool": { + "description": "Pool name", + "type": "string" + }, + "fileset": { + "description": "FileSet name", + "type": "string" } } }, @@ -5690,6 +5702,22 @@ "description": "Cache retention time", "type": "integer" }, + "storage": { + "description": "Storage name", + "type": "string" + }, + "pool": { + "description": "Pool name", + "type": "string" + }, + "scratchpool": { + "description": "Scratch pool name", + "type": "string" + }, + "recyclepool": { + "description": "Recycle pool name", + "type": "string" + }, "whenexpire": { "description": "Expiration date and time", "type": "string"