2024-09-04 22:06:38 +00:00
|
|
|
<?php
|
|
|
|
|
2024-11-29 17:02:40 +00:00
|
|
|
/**
|
|
|
|
* class Agent
|
|
|
|
*
|
|
|
|
* Provides methods to interact with Jilo agents, including retrieving details, managing agents, generating JWT tokens,
|
|
|
|
* and fetching data from agent APIs.
|
|
|
|
*/
|
2024-09-04 22:06:38 +00:00
|
|
|
class Agent {
|
2024-11-29 17:02:40 +00:00
|
|
|
/**
|
|
|
|
* @var PDO|null $db The database connection instance.
|
|
|
|
*/
|
2024-09-04 22:06:38 +00:00
|
|
|
private $db;
|
|
|
|
|
2024-11-29 17:02:40 +00:00
|
|
|
/**
|
|
|
|
* Agent constructor.
|
|
|
|
* Initializes the database connection.
|
|
|
|
*
|
|
|
|
* @param object $database The database object to initialize the connection.
|
|
|
|
*/
|
2024-09-04 22:06:38 +00:00
|
|
|
public function __construct($database) {
|
|
|
|
$this->db = $database->getConnection();
|
|
|
|
}
|
|
|
|
|
2024-11-29 17:02:40 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieves details of a specified agent ID (or all agents) in a specified platform.
|
|
|
|
*
|
|
|
|
* @param int $platform_id The platform ID to filter agents by.
|
|
|
|
* @param int $agent_id The agent ID to filter by. If empty, all agents are returned.
|
|
|
|
*
|
|
|
|
* @return array The list of agent details.
|
|
|
|
*/
|
2024-09-04 22:06:38 +00:00
|
|
|
public function getAgentDetails($platform_id, $agent_id = '') {
|
2024-09-30 08:55:23 +00:00
|
|
|
$sql = 'SELECT
|
|
|
|
ja.id,
|
|
|
|
ja.platform_id,
|
|
|
|
ja.agent_type_id,
|
|
|
|
ja.url,
|
|
|
|
ja.secret_key,
|
2024-10-24 09:11:35 +00:00
|
|
|
ja.check_period,
|
2024-09-30 08:55:23 +00:00
|
|
|
jat.description AS agent_description,
|
|
|
|
jat.endpoint AS agent_endpoint
|
|
|
|
FROM
|
|
|
|
jilo_agents ja
|
|
|
|
JOIN
|
|
|
|
jilo_agent_types jat ON ja.agent_type_id = jat.id
|
2024-09-04 22:06:38 +00:00
|
|
|
WHERE
|
|
|
|
platform_id = :platform_id';
|
2024-09-30 08:55:23 +00:00
|
|
|
|
2024-09-04 22:06:38 +00:00
|
|
|
if ($agent_id !== '') {
|
2024-09-30 08:55:23 +00:00
|
|
|
$sql .= ' AND ja.id = :agent_id';
|
|
|
|
}
|
|
|
|
|
|
|
|
$query = $this->db->prepare($sql);
|
|
|
|
|
|
|
|
$query->bindParam(':platform_id', $platform_id);
|
|
|
|
if ($agent_id !== '') {
|
|
|
|
$query->bindParam(':agent_id', $agent_id);
|
2024-09-04 22:06:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
$query->execute();
|
|
|
|
|
|
|
|
return $query->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
}
|
|
|
|
|
2024-11-29 17:02:40 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieves details of a specified agent by its agent ID.
|
|
|
|
*
|
|
|
|
* @param int $agent_id The agent ID to filter by.
|
|
|
|
*
|
|
|
|
* @return array The agent details.
|
|
|
|
*/
|
2024-10-23 10:06:59 +00:00
|
|
|
public function getAgentIDDetails($agent_id) {
|
|
|
|
$sql = 'SELECT
|
|
|
|
ja.id,
|
|
|
|
ja.platform_id,
|
|
|
|
ja.agent_type_id,
|
|
|
|
ja.url,
|
|
|
|
ja.secret_key,
|
2024-10-24 09:11:35 +00:00
|
|
|
ja.check_period,
|
2024-10-23 10:06:59 +00:00
|
|
|
jat.description AS agent_description,
|
|
|
|
jat.endpoint AS agent_endpoint
|
|
|
|
FROM
|
|
|
|
jilo_agents ja
|
|
|
|
JOIN
|
|
|
|
jilo_agent_types jat ON ja.agent_type_id = jat.id
|
|
|
|
WHERE
|
|
|
|
ja.id = :agent_id';
|
|
|
|
|
|
|
|
$query = $this->db->prepare($sql);
|
|
|
|
$query->bindParam(':agent_id', $agent_id);
|
|
|
|
$query->execute();
|
|
|
|
|
|
|
|
return $query->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
}
|
|
|
|
|
2024-11-29 17:02:40 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieves all agent types.
|
|
|
|
*
|
|
|
|
* @return array List of all agent types.
|
|
|
|
*/
|
2024-10-03 08:28:23 +00:00
|
|
|
public function getAgentTypes() {
|
|
|
|
$sql = 'SELECT *
|
|
|
|
FROM jilo_agent_types
|
|
|
|
ORDER BY id';
|
|
|
|
$query = $this->db->prepare($sql);
|
|
|
|
$query->execute();
|
|
|
|
|
|
|
|
return $query->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
}
|
|
|
|
|
2024-11-29 17:02:40 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieves agent types already configured for a specific platform.
|
|
|
|
*
|
|
|
|
* @param int $platform_id The platform ID to filter agents by.
|
|
|
|
*
|
|
|
|
* @return array List of agent types configured for the platform.
|
|
|
|
*/
|
2024-10-26 12:19:45 +00:00
|
|
|
public function getPlatformAgentTypes($platform_id) {
|
|
|
|
$sql = 'SELECT
|
|
|
|
id,
|
|
|
|
agent_type_id
|
|
|
|
FROM
|
|
|
|
jilo_agents
|
|
|
|
WHERE
|
|
|
|
platform_id = :platform_id';
|
2024-10-26 12:35:16 +00:00
|
|
|
$query = $this->db->prepare($sql);
|
2024-10-26 12:19:45 +00:00
|
|
|
$query->bindParam(':platform_id', $platform_id);
|
|
|
|
$query->execute();
|
|
|
|
|
|
|
|
return $query->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
}
|
|
|
|
|
2024-11-29 17:02:40 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Adds a new agent to the platform.
|
|
|
|
*
|
|
|
|
* @param int $platform_id The platform ID where the agent is to be added.
|
|
|
|
* @param array $newAgent The new agent details to add.
|
|
|
|
*
|
|
|
|
* @return bool|string Returns true on success or an error message on failure.
|
|
|
|
*/
|
2024-09-04 22:06:38 +00:00
|
|
|
public function addAgent($platform_id, $newAgent) {
|
|
|
|
try {
|
|
|
|
$sql = 'INSERT INTO jilo_agents
|
2024-10-25 09:19:54 +00:00
|
|
|
(platform_id, agent_type_id, url, secret_key, check_period)
|
2024-09-04 22:06:38 +00:00
|
|
|
VALUES
|
2024-10-25 09:19:54 +00:00
|
|
|
(:platform_id, :agent_type_id, :url, :secret_key, :check_period)';
|
2024-09-04 22:06:38 +00:00
|
|
|
|
|
|
|
$query = $this->db->prepare($sql);
|
|
|
|
$query->execute([
|
|
|
|
':platform_id' => $platform_id,
|
2024-09-23 09:39:33 +00:00
|
|
|
':agent_type_id' => $newAgent['type_id'],
|
2024-09-04 22:06:38 +00:00
|
|
|
':url' => $newAgent['url'],
|
|
|
|
':secret_key' => $newAgent['secret_key'],
|
2024-10-25 09:19:54 +00:00
|
|
|
':check_period' => $newAgent['check_period'],
|
2024-09-04 22:06:38 +00:00
|
|
|
]);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
} catch (Exception $e) {
|
|
|
|
return $e->getMessage();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-11-29 17:02:40 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Edits an existing agent's details.
|
|
|
|
*
|
|
|
|
* @param int $platform_id The platform ID where the agent exists.
|
|
|
|
* @param array $updatedAgent The updated agent details.
|
|
|
|
*
|
|
|
|
* @return bool|string Returns true on success or an error message on failure.
|
|
|
|
*/
|
2024-09-04 22:06:38 +00:00
|
|
|
public function editAgent($platform_id, $updatedAgent) {
|
|
|
|
try {
|
|
|
|
$sql = 'UPDATE jilo_agents SET
|
2024-09-23 09:39:33 +00:00
|
|
|
agent_type_id = :agent_type_id,
|
2024-09-04 22:06:38 +00:00
|
|
|
url = :url,
|
2024-10-24 09:11:35 +00:00
|
|
|
secret_key = :secret_key,
|
|
|
|
check_period = :check_period
|
2024-09-04 22:06:38 +00:00
|
|
|
WHERE
|
|
|
|
id = :agent_id
|
|
|
|
AND
|
|
|
|
platform_id = :platform_id';
|
|
|
|
|
|
|
|
$query = $this->db->prepare($sql);
|
|
|
|
$query->execute([
|
2024-09-23 09:39:33 +00:00
|
|
|
':agent_type_id' => $updatedAgent['agent_type_id'],
|
2024-09-04 22:06:38 +00:00
|
|
|
':url' => $updatedAgent['url'],
|
|
|
|
':secret_key' => $updatedAgent['secret_key'],
|
2024-10-24 09:11:35 +00:00
|
|
|
':check_period' => $updatedAgent['check_period'],
|
2024-09-04 22:06:38 +00:00
|
|
|
':agent_id' => $updatedAgent['id'],
|
|
|
|
':platform_id' => $platform_id,
|
|
|
|
]);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
} catch (Exception $e) {
|
|
|
|
return $e->getMessage();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-11-29 17:02:40 +00:00
|
|
|
/**
|
|
|
|
* Deletes an agent from the platform.
|
|
|
|
*
|
|
|
|
* @param int $agent_id The agent ID to delete.
|
|
|
|
*
|
|
|
|
* @return bool|string Returns true on success or an error message on failure.
|
|
|
|
*/
|
2024-09-04 22:06:38 +00:00
|
|
|
public function deleteAgent($agent_id) {
|
|
|
|
try {
|
|
|
|
$sql = 'DELETE FROM jilo_agents
|
|
|
|
WHERE
|
|
|
|
id = :agent_id';
|
|
|
|
|
|
|
|
$query = $this->db->prepare($sql);
|
|
|
|
$query->bindParam(':agent_id', $agent_id);
|
|
|
|
|
|
|
|
$query->execute();
|
|
|
|
return true;
|
|
|
|
|
|
|
|
} catch (Exception $e) {
|
|
|
|
return $e->getMessage();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-10-01 07:18:53 +00:00
|
|
|
|
2024-11-29 17:02:40 +00:00
|
|
|
/**
|
|
|
|
* Checks if the agent cache is still valid.
|
|
|
|
*
|
|
|
|
* @param int $agent_id The agent ID to check.
|
|
|
|
*
|
|
|
|
* @return bool Returns true if cache is valid, false otherwise.
|
|
|
|
*/
|
2024-09-26 06:56:24 +00:00
|
|
|
public function checkAgentCache($agent_id) {
|
2024-10-03 07:59:32 +00:00
|
|
|
$agent_cache_name = 'agent' . $agent_id . '_cache';
|
|
|
|
$agent_cache_time = 'agent' . $agent_id . '_time';
|
2024-09-26 06:56:24 +00:00
|
|
|
return isset($_SESSION[$agent_cache_name]) && isset($_SESSION[$agent_cache_time]) && (time() - $_SESSION[$agent_cache_time] < 600);
|
|
|
|
}
|
2024-09-04 22:06:38 +00:00
|
|
|
|
2024-10-01 07:18:53 +00:00
|
|
|
|
2024-11-29 17:02:40 +00:00
|
|
|
/**
|
|
|
|
* Base64 URL encodes the input data. Used for encoding JWT tokens
|
|
|
|
*
|
|
|
|
* @param string $data The data to encode.
|
|
|
|
*
|
|
|
|
* @return string The base64 URL encoded string.
|
|
|
|
*/
|
2024-10-01 07:18:53 +00:00
|
|
|
private function base64UrlEncode($data) {
|
|
|
|
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-11-29 17:02:40 +00:00
|
|
|
/**
|
|
|
|
* Generates a JWT token for a Jilo agent.
|
|
|
|
*
|
|
|
|
* @param array $payload The payload data to include in the token.
|
|
|
|
* @param string $secret_key The secret key used to sign the token.
|
|
|
|
*
|
|
|
|
* @return string The generated JWT token.
|
|
|
|
*/
|
2024-10-01 07:18:53 +00:00
|
|
|
public function generateAgentToken($payload, $secret_key) {
|
|
|
|
|
|
|
|
// header
|
|
|
|
$header = json_encode([
|
|
|
|
'typ' => 'JWT',
|
|
|
|
'alg' => 'HS256'
|
|
|
|
]);
|
|
|
|
$base64Url_header = $this->base64UrlEncode($header);
|
|
|
|
|
|
|
|
// payload
|
|
|
|
$payload = json_encode($payload);
|
|
|
|
$base64Url_payload = $this->base64UrlEncode($payload);
|
|
|
|
|
|
|
|
// signature
|
|
|
|
$signature = hash_hmac('sha256', $base64Url_header . "." . $base64Url_payload, $secret_key, true);
|
|
|
|
$base64Url_signature = $this->base64UrlEncode($signature);
|
|
|
|
|
|
|
|
// build the JWT
|
|
|
|
$jwt = $base64Url_header . "." . $base64Url_payload . "." . $base64Url_signature;
|
|
|
|
|
|
|
|
return $jwt;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-11-29 17:02:40 +00:00
|
|
|
/**
|
|
|
|
* Fetches data from a Jilo agent's API, optionally forcing a refresh of the cache.
|
|
|
|
*
|
|
|
|
* @param int $agent_id The agent ID to fetch data for.
|
|
|
|
* @param bool $force Whether to force-refresh the cache (default: false).
|
|
|
|
*
|
|
|
|
* @return string The API response, or an error message in JSON format.
|
|
|
|
*/
|
2024-09-30 07:07:50 +00:00
|
|
|
public function fetchAgent($agent_id, $force = false) {
|
2024-09-28 07:04:20 +00:00
|
|
|
|
|
|
|
// we need agent details for URL and JWT token
|
2024-10-23 10:06:59 +00:00
|
|
|
$agentDetails = $this->getAgentIDDetails($agent_id);
|
|
|
|
|
|
|
|
// Safe exit in case the agent is not found
|
|
|
|
if (empty($agentDetails)) {
|
|
|
|
return json_encode(['error' => 'Agent not found']);
|
|
|
|
}
|
|
|
|
|
|
|
|
$agent = $agentDetails[0];
|
2024-10-03 07:59:32 +00:00
|
|
|
$agent_cache_name = 'agent' . $agent_id . '_cache';
|
|
|
|
$agent_cache_time = 'agent' . $agent_id . '_time';
|
2024-09-28 07:04:20 +00:00
|
|
|
|
|
|
|
// check if the cache is still valid, unless force-refresh is requested
|
2024-10-23 10:06:59 +00:00
|
|
|
if (!$force && $this->checkAgentCache($agent_id)) {
|
2024-09-28 07:04:20 +00:00
|
|
|
return $_SESSION[$agent_cache_name];
|
|
|
|
}
|
|
|
|
|
2024-10-23 10:06:59 +00:00
|
|
|
// generate the JWT token
|
|
|
|
$payload = [
|
|
|
|
'agent_id' => $agent_id,
|
|
|
|
'timestamp' => time()
|
|
|
|
];
|
|
|
|
$jwt = $this->generateAgentToken($payload, $agent['secret_key']);
|
|
|
|
|
2024-09-28 07:04:20 +00:00
|
|
|
// Make the API request
|
|
|
|
$ch = curl_init();
|
2024-10-23 10:06:59 +00:00
|
|
|
curl_setopt($ch, CURLOPT_URL, $agent['url'] . $agent['agent_endpoint']);
|
2024-09-28 07:04:20 +00:00
|
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
2024-09-30 08:09:01 +00:00
|
|
|
curl_setopt($ch, CURLOPT_TIMEOUT, 10); // timeout 10 seconds
|
2024-10-23 10:06:59 +00:00
|
|
|
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
|
|
|
'Authorization: Bearer ' . $jwt,
|
|
|
|
'Content-Type: application/json'
|
|
|
|
]);
|
2024-09-30 08:09:01 +00:00
|
|
|
|
2024-09-28 07:04:20 +00:00
|
|
|
$response = curl_exec($ch);
|
2024-09-30 08:55:23 +00:00
|
|
|
$curl_error = curl_error($ch);
|
|
|
|
$curl_errno = curl_errno($ch);
|
2024-10-23 10:06:59 +00:00
|
|
|
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
2024-09-30 08:09:01 +00:00
|
|
|
|
2024-09-28 07:04:20 +00:00
|
|
|
curl_close($ch);
|
|
|
|
|
2024-10-23 10:06:59 +00:00
|
|
|
// curl error
|
|
|
|
if ($curl_errno) {
|
2024-09-30 08:55:23 +00:00
|
|
|
return json_encode(['error' => 'curl error: ' . $curl_error]);
|
|
|
|
}
|
|
|
|
|
2024-10-23 10:06:59 +00:00
|
|
|
// response is not 200 OK
|
|
|
|
if ($http_code !== 200) {
|
|
|
|
return json_encode(['error' => 'HTTP error: ' . $http_code]);
|
|
|
|
}
|
|
|
|
|
2024-09-30 08:55:23 +00:00
|
|
|
// other custom error(s)
|
|
|
|
if (strpos($response, 'Auth header not received') !== false) {
|
|
|
|
return json_encode(['error' => 'Auth header not received']);
|
2024-09-28 07:04:20 +00:00
|
|
|
}
|
2024-09-30 08:55:23 +00:00
|
|
|
|
|
|
|
// Cache the result and the timestamp if the response is successful
|
2024-10-23 10:22:55 +00:00
|
|
|
// We decode it so that it's pure JSON and not escaped
|
|
|
|
$_SESSION[$agent_cache_name] = json_decode($response, true);
|
2024-09-30 08:55:23 +00:00
|
|
|
$_SESSION[$agent_cache_time] = time();
|
|
|
|
|
2024-09-28 07:04:20 +00:00
|
|
|
return $response;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-11-29 17:02:40 +00:00
|
|
|
/**
|
|
|
|
* Clears the cached data for a specific agent.
|
|
|
|
*
|
|
|
|
* @param int $agent_id The agent ID for which the cache should be cleared.
|
|
|
|
*/
|
2024-10-03 07:59:32 +00:00
|
|
|
public function clearAgentCache($agent_id) {
|
|
|
|
$_SESSION["agent{$agent_id}_cache"] = '';
|
|
|
|
$_SESSION["agent{$agent_id}_cache_time"] = '';
|
|
|
|
}
|
|
|
|
|
2024-10-11 07:58:08 +00:00
|
|
|
|
2024-11-29 17:02:40 +00:00
|
|
|
/**
|
|
|
|
* Retrieves the latest stored data for a specific platform, agent type, and metric type.
|
|
|
|
*
|
|
|
|
* @param int $platform_id The platform ID.
|
|
|
|
* @param string $agent_type The agent type.
|
|
|
|
* @param string $metric_type The metric type to filter by.
|
|
|
|
*
|
|
|
|
* @return mixed The latest stored data.
|
|
|
|
*/
|
2024-10-11 07:58:08 +00:00
|
|
|
public function getLatestData($platform_id, $agent_type, $metric_type) {
|
2024-11-29 17:02:40 +00:00
|
|
|
// TODO
|
2024-10-11 07:58:08 +00:00
|
|
|
// retrieves data already stored in db from another function (or the jilo-server to-be)
|
|
|
|
}
|
|
|
|
|
2024-09-04 22:06:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
?>
|