Skip to content
This repository was archived by the owner on Sep 19, 2022. It is now read-only.

Commit 92afceb

Browse files
authored
Getting monitoring data through SSH (#140)
* Getting monitoring data through SSH
1 parent 032ca15 commit 92afceb

5 files changed

Lines changed: 73 additions & 65 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ All notable changes to this project will be documented in this file.
55
### Changed
66
- Refactored Disco page. See the config template for example configuration.
77

8+
#### Changed
9+
- Obtaining the data from Nagios is done through SSH instead of a certificate and calling an API
10+
811
#### Added
912
- Added extended PerunEntitlements
1013

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"cesnet/simplesamlphp-module-perunauthorize": "~2.0",
2929
"cesnet/simplesamlphp-module-chartjs": "~2.8.0",
3030
"symfony/var-exporter": "^5.0",
31+
"phpseclib/phpseclib": "~3.0",
3132
"ext-curl": "*",
3233
"ext-json": "*"
3334
}

lib/NagiosStatusConnector.php

Lines changed: 46 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
namespace SimpleSAML\Module\perun;
44

5-
use SimpleSAML\Logger;
5+
use phpseclib3\Crypt\RSA;
6+
use phpseclib3\Net\SSH2;
7+
use SimpleSAML\Error\Exception;
8+
69

710
/**
811
* Class sspmod_perun_NagiosStatusConnector
@@ -11,17 +14,16 @@
1114
*/
1215
class NagiosStatusConnector extends StatusConnector
1316
{
14-
const NAGIOS_URL = 'status.nagios.url';
15-
const NAGIOS_CERT_PATH = 'status.nagios.certificate_path';
16-
const NAGIOS_CERT_PASSWORD = 'status.nagios.certificate_password';
17-
const NAGIOS_CA_PATH = 'status.nagios.ca_path';
18-
const NAGIOS_PEER_VERIFY = 'status.nagios.peer_verification';
19-
20-
private $url;
21-
private $certPath;
22-
private $certPassword;
23-
private $caPath;
24-
private $peerVerification;
17+
protected const STATUS_NAGIOS = 'status_nagios';
18+
protected const HOST = 'host';
19+
protected const KEY_PATH = 'key_path';
20+
protected const LOGIN = 'login';
21+
protected const COMMAND = 'command';
22+
23+
private $host;
24+
private $keyPath;
25+
private $login;
26+
private $command;
2527

2628
/**
2729
* NagiosStatusConnector constructor.
@@ -30,55 +32,50 @@ public function __construct()
3032
{
3133
parent::__construct();
3234

33-
$this->url = $this->configuration->getString(self::NAGIOS_URL, '');
34-
$this->certPath = $this->configuration->getString(self::NAGIOS_CERT_PATH, '');
35-
$this->certPassword = $this->configuration->getString(self::NAGIOS_CERT_PASSWORD, '');
36-
$this->caPath = $this->configuration->getString(self::NAGIOS_CA_PATH, '');
37-
$this->peerVerification = $this->configuration->getBoolean(self::NAGIOS_PEER_VERIFY, false);
38-
39-
if (empty($this->url)) {
40-
throw new \Exception('Required option \'' . self::NAGIOS_URL . '\' is empty!');
41-
} elseif (empty($this->certPath)) {
42-
throw new \Exception('Required option \'' . self::NAGIOS_CERT_PATH . '\' is empty!');
43-
} elseif (empty($this->caPath)) {
44-
throw new \Exception('Required option \'' . self::NAGIOS_CA_PATH . '\' is empty!');
35+
$config = $this->configuration->getConfigItem(self::STATUS_NAGIOS, null);
36+
37+
if (is_null($this->host)) {
38+
throw new Exception('Property \'' . self::STATUS_NAGIOS . '\' is missing or invalid!');
4539
}
46-
}
4740

41+
$this->host = $config->getString(self::HOST, null);
42+
$this->keyPath = $config->getString(self::KEY_PATH, null);
43+
$this->login = $config->getString(self::LOGIN, null);
44+
$this->command = $config->getString(self::COMMAND, null);
45+
46+
if (empty($this->host)) {
47+
throw new Exception('Required option \'' . self::HOST . '\' is empty!');
48+
} elseif (empty($this->keyPath)) {
49+
throw new Exception('Required option \'' . self::KEY_PATH . '\' is empty!');
50+
} elseif (empty($this->login)) {
51+
throw new Exception('Required option \'' . self::LOGIN . '\' is empty!');
52+
} elseif (empty($this->command)) {
53+
throw new Exception('Required option \'' . self::COMMAND . '\' is empty!');
54+
}
55+
}
4856

4957
public function getStatus()
5058
{
5159
$result = [];
52-
$serviceStatuses = [];
53-
54-
$ch = curl_init();
55-
curl_setopt($ch, CURLOPT_URL, $this->url);
56-
curl_setopt($ch, CURLOPT_VERBOSE, true);
57-
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $this->peerVerification);
58-
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
59-
curl_setopt($ch, CURLOPT_SSLCERT, $this->certPath);
60-
curl_setopt($ch, CURLOPT_CAPATH, $this->caPath);
61-
curl_setopt($ch, CURLOPT_SSLKEYPASSWD, $this->certPassword);
62-
63-
$response = curl_exec($ch);
6460

65-
if ($response === false) {
66-
Logger::error(curl_error($ch));
61+
if (!($key = file_get_contents($this->keyPath))) {
62+
throw new Exception('Cannot load ket from path: \'' . $this->keyPath . '\' !');
6763
}
6864

69-
curl_close($ch);
65+
$key = RSA::load($key);
66+
$ssh = new SSH2($this->host);
7067

71-
$jsonResponse = json_decode($response, true);
72-
73-
if (isset($jsonResponse['status']['service_status'])) {
74-
$serviceStatuses = $jsonResponse['status']['service_status'];
68+
if (!$ssh->login($this->login, $key)) {
69+
throw new Exception('Error during ssh connection to \'' . $this->login . '@' . $this->host . '\' !');
7570
}
7671

77-
foreach ($serviceStatuses as $serviceStatus) {
78-
$status = [];
79-
$status['name'] = $serviceStatus['service_display_name'];
80-
$status['status'] = $serviceStatus['status'];
81-
array_push($result, $status);
72+
$output = $ssh->exec($this->command);
73+
$lines = explode("\n", $output);
74+
array_pop($lines);
75+
76+
foreach ($lines as $line) {
77+
$lineParts = explode(";", $line);
78+
$result[$lineParts[0]][$lineParts[1]] = $lineParts[2];
8279
}
8380

8481
return $result;

lib/StatusConnector.php

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ abstract class StatusConnector
1919
const CONFIG_FILE_NAME = 'module_perun.php';
2020
const STATUS_TYPE = 'status.type';
2121

22+
const OK = 0;
23+
const WARNING = 1;
24+
2225
protected $configuration;
2326

2427
/**
@@ -68,11 +71,13 @@ abstract public function getStatus();
6871
*/
6972
public static function getBadgeByStatus($status)
7073
{
71-
if ($status === OK) {
74+
$statusAsInt = intval($status);
75+
76+
if ($statusAsInt === self::OK) {
7277
return '<span class="status label label-success">OK</span>';
73-
} elseif ($status === WARNING) {
78+
} elseif ($statusAsInt === self::WARNING) {
7479
return '<span class="status label label-warning">WARNING</span>';
75-
} elseif ($status === CRITICAL || $status === UNKNOWN) {
80+
} else {
7681
return '<span class="status label label-danger">CRITICAL</span>';
7782
}
7883
}

www/status.php

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,38 @@
11
<?php
22

3-
use SimpleSAML\Module\perun\StatusConnector;
4-
5-
const OK = 'OK';
6-
const WARNING = 'WARNING';
7-
const CRITICAL = 'CRITICAL';
8-
const UNKNOWN = 'UNKNOWN';
93

104
const CONFIG_FILE_NAME = 'module_perun.php';
5+
const STATUS_NAGIOS = 'status_nagios';
116
const SHOWN_SERVICES = 'status.shown_services';
127

8+
const HOST = 'host';
9+
const PROBE_IDENTIFIER = 'probe_identifier';
10+
const STATUS = 'status';
11+
1312
$services = [];
13+
$shownServicesList = [];
1414

1515
$config = SimpleSAML_Configuration::getInstance();
1616
$perunConfig = SimpleSAML_Configuration::getConfig(CONFIG_FILE_NAME);
1717

18-
$shownServicesList = $perunConfig->getArray(SHOWN_SERVICES, []);
18+
$params = $perunConfig->getArray(STATUS_NAGIOS, []);
19+
20+
if (isset($params[SHOWN_SERVICES]) && is_array($params[SHOWN_SERVICES])) {
21+
$shownServicesList = $params[SHOWN_SERVICES];
22+
}
1923

2024
$statusConnector = sspmod_perun_StatusConnector::getInstance();
2125
$services = $statusConnector->getStatus();
2226

2327
$shownServices = [];
2428

25-
2629
if (empty($shownServicesList)) {
2730
$shownServices = $services;
2831
} else {
29-
foreach ($services as $service) {
30-
$serviceName = $service['name'];
31-
if (in_array($serviceName, array_keys($shownServicesList))) {
32-
$service['name'] = $shownServicesList[$serviceName]['name'];
33-
$service['description'] = $shownServicesList[$serviceName]['description'];
32+
foreach ($shownServicesList as $service) {
33+
if (isset($services[$service[HOST]][$service[PROBE_IDENTIFIER]])) {
34+
$host = $services[$service[HOST]];
35+
$service[STATUS] = $host[$service[PROBE_IDENTIFIER]];
3436
array_push($shownServices, $service);
3537
}
3638
}

0 commit comments

Comments
 (0)