File: CZabbixServer.php

package info (click to toggle)
zabbix 1%3A3.0.7%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 60,008 kB
  • ctags: 38,245
  • sloc: php: 125,527; ansic: 120,253; sql: 40,319; sh: 5,620; makefile: 1,138; java: 957; cpp: 211; perl: 41; xml: 29
file content (306 lines) | stat: -rw-r--r-- 7,760 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
<?php
/*
** Zabbix
** Copyright (C) 2001-2016 Zabbix SIA
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
**/


/**
 * A class for interacting with the Zabbix server.
 *
 * Class CZabbixServer
 */
class CZabbixServer {

	/**
	 * Return item queue overview.
	 */
	const QUEUE_OVERVIEW = 'overview';

	/**
	 * Return item queue overview by proxy.
	 */
	const QUEUE_OVERVIEW_BY_PROXY = 'overview by proxy';

	/**
	 * Return a detailed item queue.
	 */
	const QUEUE_DETAILS = 'details';

	/**
	 * Response value if the request has been executed successfully.
	 */
	const RESPONSE_SUCCESS = 'success';

	/**
	 * Response value if an error occurred.
	 */
	const RESPONSE_FAILED = 'failed';

	/**
	 * Zabbix server host name.
	 *
	 * @var string
	 */
	protected $host;

	/**
	 * Zabbix server port number.
	 *
	 * @var string
	 */
	protected $port;

	/**
	 * Request timeout.
	 *
	 * @var int
	 */
	protected $timeout;

	/**
	 * Maximum response size. If the size of the response exceeds this value, an error will be triggered.
	 *
	 * @var int
	 */
	protected $totalBytesLimit;

	/**
	 * Bite count to read from the response with each iteration.
	 *
	 * @var int
	 */
	protected $readBytesLimit = 8192;

	/**
	 * Zabbix server socket resource.
	 *
	 * @var resource
	 */
	protected $socket;

	/**
	 * Error message.
	 *
	 * @var string
	 */
	protected $error;

	/**
	 * Class constructor.
	 *
	 * @param string $host
	 * @param int $port
	 * @param int $timeout
	 * @param int $totalBytesLimit
	 */
	public function __construct($host, $port, $timeout, $totalBytesLimit) {
		$this->host = $host;
		$this->port = $port;
		$this->timeout = $timeout;
		$this->totalBytesLimit = $totalBytesLimit;
	}

	/**
	 * Executes a script on the given host and returns the result.
	 *
	 * @param $scriptId
	 * @param $hostId
	 *
	 * @return bool|array
	 */
	public function executeScript($scriptId, $hostId) {
		return $this->request([
			'request' => 'command',
			'scriptid' => $scriptId,
			'hostid' => $hostId
		]);
	}

	/**
	 * Retrieve item queue information.
	 *
	 * Possible $type values:
	 * - self::QUEUE_OVERVIEW
	 * - self::QUEUE_OVERVIEW_BY_PROXY
	 * - self::QUEUE_DETAILS
	 *
	 * @param string $type
	 * @param string $sid   user session ID
	 *
	 * @return bool|array
	 */
	public function getQueue($type, $sid) {
		return $this->request([
			'request' => 'queue.get',
			'sid' => $sid,
			'type' => $type
		]);
	}

	/**
	 * Returns true if the Zabbix server is running and false otherwise.
	 *
	 * @return bool
	 */
	public function isRunning() {
		return (bool) $this->connect();
	}

	/**
	 * Returns the error message.
	 *
	 * @return string
	 */
	public function getError() {
		return $this->error;
	}

	/**
	 * Executes a given JSON request and returns the result. Returns false if an error has occurred.
	 *
	 * @param array $params
	 *
	 * @return mixed    the output of the script if it has been executed successfully or false otherwise
	 */
	protected function request(array $params) {
		// connect to the server
		if (!$this->connect()) {
			return false;
		}

		// set timeout
		stream_set_timeout($this->socket, $this->timeout);

		// send the command
		if (fwrite($this->socket, CJs::encodeJson($params)) === false) {
			$this->error = _s('Cannot send command, check connection with Zabbix server "%1$s".', $this->host);

			return false;
		}

		// read the response
		$readBytesLimit = ($this->totalBytesLimit && $this->totalBytesLimit < $this->readBytesLimit)
			? $this->totalBytesLimit
			: $this->readBytesLimit;

		$response = '';
		$now = time();
		$i = 0;
		while (!feof($this->socket)) {
			$i++;
			if ((time() - $now) >= $this->timeout) {
				$this->error = _s('Connection timeout of %1$s seconds exceeded when connecting to Zabbix server "%2$s".', $this->timeout, $this->host);

				return false;
			}
			elseif ($this->totalBytesLimit && ($i * $readBytesLimit) >= $this->totalBytesLimit) {
				$this->error = _s('Size of the response received from Zabbix server "%1$s" exceeds the allowed size of %2$s bytes. This value can be increased in the ZBX_SOCKET_BYTES_LIMIT constant in include/defines.inc.php.', $this->host, $this->totalBytesLimit);

				return false;
			}

			if (($out = fread($this->socket, $readBytesLimit)) !== false) {
				$response .= $out;
			}
			else {
				$this->error = _s('Cannot read the response, check connection with the Zabbix server "%1$s".', $this->host);

				return false;
			}
		}

		fclose($this->socket);

		// check if the response is empty
		if (!strlen($response)) {
			$this->error = _s('Empty response received from Zabbix server "%1$s".', $this->host);

			return false;
		}

		$response = CJs::decodeJson($response);
		if (!$response || !$this->validateResponse($response)) {
			$this->error = _s('Incorrect response received from Zabbix server "%1$s".', $this->host);

			return false;
		}

		// request executed successfully
		if ($response['response'] == self::RESPONSE_SUCCESS) {
			return $response['data'];
		}
		// an error on the server side occurred
		else {
			$this->error = $response['info'];

			return false;
		}
	}

	/**
	 * Opens a socket to the Zabbix server. Returns the socket resource if the connection has been established or
	 * false otherwise.
	 *
	 * @return bool|resource
	 */
	protected function connect() {
		if (!$this->socket) {
			if (!$this->host || !$this->port) {
				return false;
			}

			if (!$socket = @fsockopen($this->host, $this->port, $errorCode, $errorMsg, $this->timeout)) {
				switch ($errorMsg) {
					case 'Connection refused':
						$dErrorMsg = _s("Connection to Zabbix server \"%s\" refused. Possible reasons:\n1. Incorrect server IP/DNS in the \"zabbix.conf.php\";\n2. Security environment (for example, SELinux) is blocking the connection;\n3. Zabbix server daemon not running;\n4. Firewall is blocking TCP connection.\n", $this->host);
						break;

					case 'No route to host':
						$dErrorMsg = _s("Zabbix server \"%s\" can not be reached. Possible reasons:\n1. Incorrect server IP/DNS in the \"zabbix.conf.php\";\n2. Incorrect network configuration.\n", $this->host);
						break;

					case 'Connection timed out':
						$dErrorMsg = _s("Connection to Zabbix server \"%s\" timed out. Possible reasons:\n1. Incorrect server IP/DNS in the \"zabbix.conf.php\";\n2. Firewall is blocking TCP connection.\n", $this->host);
						break;

					default:
						$dErrorMsg = _s("Connection to Zabbix server \"%s\" failed. Possible reasons:\n1. Incorrect server IP/DNS in the \"zabbix.conf.php\";\n2. Incorrect DNS server configuration.\n", $this->host);
				}

				$this->error = $dErrorMsg.$errorMsg;
			}

			$this->socket = $socket;
		}

		return $this->socket;
	}

	/**
	 * Returns true if the response received from the Zabbix server is valid.
	 *
	 * @param array $response
	 *
	 * @return bool
	 */
	protected function validateResponse(array $response) {
		return (isset($response['response'])
					&& ($response['response'] == self::RESPONSE_SUCCESS && isset($response['data'])
						|| $response['response'] == self::RESPONSE_FAILED && isset($response['info'])));
	}
}