├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── composer.json ├── docs └── README.pdf ├── examples ├── composer │ ├── .gitignore │ ├── README.md │ ├── composer.json │ └── simple.php ├── createTrigger.php ├── filter.php ├── filterByHostGroupIds.php ├── filterByHostGroupNames1.php ├── filterByHostGroupNames2.php ├── filterByHostIds.php ├── filterByHostNames.php ├── hostlistNoSslCheck.php ├── simple.php ├── simpleNoSslCheck.php └── simpleToken.php └── src └── ZabbixApi.php /.gitignore: -------------------------------------------------------------------------------- 1 | # ide eclipse, phpstorm 2 | .settings 3 | .buildpath 4 | .project 5 | .idea 6 | 7 | phpdoc 8 | build 9 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## Version 3.3.0 4 | 5 | * Added support for Zabbix 7.2. 6 | * Fixed `connectTimeout` setting the regular timeout instead of the connection timeout. 7 | 8 | ## Version 3.2.0 9 | 10 | * Added custom exception class ZabbixApiException. 11 | * Fixed exception handling issues in function `call()` if other exceptions are thrown by custom handlers. 12 | 13 | ## Version 3.1.0 14 | 15 | * Tested with Zabbix 6.0. 16 | * Added missing namespace in examples. 17 | * Added function `loginToken()` to log in via API tokens. 18 | 19 | ## Version 3.0.2 20 | 21 | * Fixed bug in getApiVersion() with invalid credentials. 22 | * Added example and documentation using composer. See `examples/composer`. 23 | 24 | ## Version 3.0.1 25 | 26 | * Tested with Zabbix 5.0 - 5.4. 27 | * Added support for Zabbix 5.4 API change in `user.login` method. 28 | * Added namespace `IntelliTrend\Zabbix`. 29 | * Added [composer](https://getcomposer.org/) support. 30 | * Moved to [semver](https://semver.org/) version numbers. 31 | 32 | ## No version change 33 | 34 | * Added more examples to filter by hostnames, hostids, hostgroupnames and hostgroupids. 35 | 36 | ## Version 2.8 37 | 38 | * Tested with Zabbix 5.0 and 5.2. 39 | * Ensure that params passed to API call are an array. 40 | * Added library version to debug output. 41 | 42 | ## Version 2.7 43 | 44 | * BREAKING CHANGE: Classfilename renamed from `Zabbixapi.php` to `ZabbixApi.php` to match classname. 45 | * Call to `getAuthKey()` no longer simply returns the `authKey`. If there was no previous call to the Zabbix-API this funcion will call the Zabbix-API to ensure a valid key before returning the key. 46 | * Fixed error message for invalid sslCaFile. 47 | 48 | ## Version 2.6 49 | 50 | * Public release. 51 | * Added check for Curl. 52 | * Added example for filtering and additional params passed to the Zabbix-API. 53 | * Call to `login()` no longer initially calls the Zabbix-API anylonger to verify the `authKey`. 54 | * If debug is enabled via option, or via function before calling `login()`, `login()` issues a call to the Zabbix-API to check wether the session is re-used. 55 | 56 | ## Version 2.5 57 | 58 | * Internal release. 59 | 60 | ## Version 2.4 61 | 62 | * Initial public release. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # License 2 | 3 | This software is licensed under the GNU Lesser General Public License v3.0. 4 | 5 | # Changelog 6 | 7 | See [CHANGELOG.md](/CHANGELOG.md). 8 | 9 | # Zabbix API PHP Client with session caching and SSL support 10 | 11 | There are quite a lot of Zabbix API clients out that work really well with [Zabbix](https://www.zabbix.com). However most of them do not support `session caching` or need tweaks to work with self signed certificates. 12 | 13 | This library aims to solve those problems. It supports the following features: 14 | 15 | * Session caching. 16 | * HTTPS connections with official- and self-signed certificates. 17 | * Works with Linux and Windows PHP implementations. 18 | * Multiple concurrent connections with different user accounts and/or different servers. 19 | * Zabbix versions: 3.0 up to 7.2 20 | * No installation required. 21 | 22 | It is commercially backed up and maintained by [IntelliTrend GmbH](https://www.intellitrend.de), an official Zabbix Partner and Zabbix Training company. 23 | 24 | There was also a lightning talk [Zabbix API – the easy way](https://blog.zabbix.com/zabbix-api-the-easy-way/11748/) about using this library on the Zabbix conference 2020 in Benelux. 25 | 26 | ## Why Session caching? 27 | 28 | ### How authentication via API usally works 29 | 30 | Each time an application uses `user.login`, the Zabbix API creates a so called `AuthKey`. (See [user.login](https://www.zabbix.com/documentation/5.0/manual/api/reference/user/login)). This key is then passed via each request through the `auth` request property. 31 | 32 | In most cases, the API libary does this transparently for the user. However, if the script is called later on again (i.e by a cron job), a new `user.login` is performed, thus creating a new `AuthKey` for that new session. 33 | 34 | Zabbix keeps those session, until a session expired or is logged out. You can check your actual settings through the Zabbix frontend: `Administration/General/Housekeeper - Section Sessions`. The default value is 365days. 35 | 36 | This means, any created session (if there is no logout) will be kept for 365 days. 37 | 38 | Assume we have a set of 10 API scripts that run every hour. This means we will create `10 x 24 = 240` sessions per day. Using more scripts or a smaller interval will of cause increase this number. 39 | 40 | **Note**: Zabbix 5.4 and later support API auth tokens, which won't create sessions when used. Therefore, no session management is required on the client side, either. 41 | 42 | ### The problem with many sessions in the session table 43 | 44 | Everytime a request hits the Zabbix frontend, either per webbrowser or as a JSON RPC API request, Zabbix has to verify the request against the existing sessions. The more sessions to verify, the longer this will take. 45 | 46 | > **Note:** We have seen installations with millions of sessions, where frontend access slowed down considerable by 15sec+ per request. Keep in mind that for example the dashboard not only performs one request, but multiple requests depending on the number of widgets used. 47 | 48 | So the best is to `reuse` a session, until it expires. This is where session caching steps in. 49 | 50 | ## Using session caching with the Zabbix API 51 | 52 | When a new session is created, the AuthKey is saved encrypted to disk. This is similar to using a cookie in a classic webbrowser. If a new request is performed, the existing session is read once and the AuthKey is reused. 53 | 54 | So to follow up the example given before: Calling a script using session-caching, even over a month, will create just `1` session. 55 | 56 | If the AuthKey becomes invalid, the libary automatically performs a new `user.login`, re-executes the failed request and updates the stored session. All of this happens in the background, the user of the libary has not to deal with it. 57 | 58 | ### How does session encryption work, what about multiple sessions? 59 | 60 | Each session has a unique name based on a hash using the `zabbixUserName` and the `zabbixUrl`. 61 | The session itself is encrypted using the `zabbixUserName` and the `zabbixPassword`. 62 | 63 | This way, the libary can be used with different useraccounts and also different zabbix server instances. 64 | 65 | ### Where are sessions stored? 66 | 67 | Sessions are stored by default in the users `tmp` directory. However there is a config option `sessionDir` that allows to override this setting. See the detailed description below. 68 | 69 | # Installation 70 | 71 | > **Note:** The PHP environment **must have CURL** installed. `ZabbixApi.php` has a built-in check for curl and will throw an exception if curl is missing. 72 | 73 | ## Without using composer 74 | 75 | There is no installation required. Simply copy the file `ZabbixApi.php` and use the class. 76 | 77 | ```php 78 | require_once "ZabbixApi.php"; 79 | 80 | use IntelliTrend\Zabbix\ZabbixApi; 81 | 82 | $zbx = new ZabbixApi(); 83 | ``` 84 | 85 | ## Using composer 86 | 87 | ```php 88 | require('vendor/autoload.php'); 89 | 90 | use IntelliTrend\Zabbix\ZabbixApi; 91 | 92 | $zbx = new ZabbixApi(); 93 | ``` 94 | 95 | See `examples/composer` for a full example with details. 96 | 97 | # Usage 98 | 99 | ## Error handling 100 | 101 | The library makes use of `Exceptions`. There is no need to check each response value. Simply wrap the calls in `try/catch blocks`. 102 | 103 | Depending on where an error occurs, different error codes are passed to the exception object, together with the message property. 104 | 105 | * `Zabbix API errors`: The original API error code and message is passed. 106 | * `Connection and SSL errors`: The original CURL error code and message is passed. 107 | * `Library errors`: A constant error code, as defined in the class constant EXCEPTION_CLASS_CODE, and a useful message is passed. Default=1000. 108 | 109 | ## Configuration 110 | 111 | The class is configured when calling the `login` method. Any further Zabbix API call is performed by the `call` method. 112 | 113 | > **Note:** One can run multiple instances at the same time, connecting with different user accounts to the same zabbix server or to another zabbix server. 114 | 115 | ## Basic usage 116 | 117 | Lets start with a very simple example: 118 | 119 | ```php 120 | require_once "ZabbixApi.php"; 121 | use IntelliTrend\Zabbix\ZabbixApi; 122 | $zbx = new ZabbixApi(); 123 | try { 124 | $zbx->login('https://my.zabbixurl.com/zabbix', 'myusername', 'mypassword'); 125 | $result = $zbx->call('host.get', array("countOutput" => true)); 126 | print "Number of hosts:$result\n"; 127 | } catch (Exception $e) { 128 | print "==== Exception ===\n"; 129 | print 'Errorcode: '.$e->getCode()."\n"; 130 | print 'ErrorMessage: '.$e->getMessage()."\n"; 131 | exit; 132 | } 133 | ``` 134 | 135 | Basically this is all needed. The `call` method is transparent to the Zabbix API definition. It takes 2 parameter: `$method` and `$params` as specified for the particular Zabbix API method. 136 | 137 | Instead of a login with a user name and password, you can also use an API token in Zabbix 5.4+: 138 | 139 | ```php 140 | require_once "ZabbixApi.php"; 141 | use IntelliTrend\Zabbix\ZabbixApi; 142 | $zbx = new ZabbixApi(); 143 | try { 144 | $zbx->loginToken('https://my.zabbixurl.com/zabbix', '123456789abcdef123456789abcdef123456789abcdef123456789abcdef1234'); 145 | $result = $zbx->call('host.get', array("countOutput" => true)); 146 | print "Number of hosts:$result\n"; 147 | } catch (Exception $e) { 148 | print "==== Exception ===\n"; 149 | print 'Errorcode: '.$e->getCode()."\n"; 150 | print 'ErrorMessage: '.$e->getMessage()."\n"; 151 | exit; 152 | } 153 | ``` 154 | 155 | For example to retrieve all 'Host Groups' with all properties, we can do this: 156 | 157 | ```php 158 | require_once "ZabbixApi.php"; 159 | use IntelliTrend\Zabbix\ZabbixApi; 160 | $zbx = new ZabbixApi(); 161 | $zabUrl = 'https://my.zabbixurl.com/zabbix'; 162 | $zabUser = 'myusername'; 163 | $zabPassword = 'mypassword'; 164 | try { 165 | $zbx->login($zabUrl, $zabUser, $zabPassword); 166 | $result = $zbx->call('hostgroup.get', array("output" => 'extend')); 167 | foreach ($result as $hostGroup) { 168 | $hostGroupId = $hostGroup['groupid']; 169 | $hostGroupName = $hostGroup['name']; 170 | print "groupid:$hostGroupId, hostGroupName:$hostGroupName\n"; 171 | } 172 | } catch (Exception $e) { 173 | print "==== Exception ===\n"; 174 | print 'Errorcode: '.$e->getCode()."\n"; 175 | print 'ErrorMessage: '.$e->getMessage()."\n"; 176 | exit; 177 | } 178 | ``` 179 | 180 | > **Note:** This second example would not create a new session when calling `login` again after the first example. It would reuse the session from the previous example. `login` returns true when an existing session was found. 181 | 182 | ## Advanced usage and SSL Options 183 | 184 | The basic example works fine, even with HTTPS, given there is a valid certificate the php installation is aware of. But what todo when using self-signed certificates? 185 | 186 | Here we can use the optional `options` argument when calling `login` to setup the SSL options. 187 | 188 | Example - Turn off SSL verification: 189 | 190 | ```php 191 | require_once "ZabbixApi.php"; 192 | use IntelliTrend\Zabbix\ZabbixApi; 193 | $zbx = new ZabbixApi(); 194 | $options = array('sslVerifyPeer' => false, 'sslVerifyHost' => false); 195 | try { 196 | $zbx->login('https://my.zabbixurl.com/zabbix', 'myusername', 'mypassword', $options); 197 | $result = $zbx->call('host.get', array("countOutput" => true)); 198 | print "Number of hosts:$result\n"; 199 | } catch (Exception $e) { 200 | print "==== Exception ===\n"; 201 | print 'Errorcode: '.$e->getCode()."\n"; 202 | print 'ErrorMessage: '.$e->getMessage()."\n"; 203 | exit; 204 | } 205 | ``` 206 | 207 | ## Using filters and field selectors 208 | 209 | It is quite easy to pass filter and field selectors through the API. Basically any params defined by the Zabbix-API can be passed this way. 210 | 211 | Example - Select first 5 hosts filtered by status, maintenance_status and type and add their groups and macros. 212 | 213 | ```php 214 | require_once "ZabbixApi.php"; 215 | use IntelliTrend\Zabbix\ZabbixApi; 216 | $zbx = new ZabbixApi(); 217 | try { 218 | // default is to verify certificate and hostname 219 | $options = array('sslVerifyPeer' => false, 'sslVerifyHost' => false); 220 | $zbx->login('https://my.zabbixurl.com/zabbix', 'myusername', 'mypassword', $options); 221 | 222 | print "====================================================================\n"; 223 | // Get hosts and other information available to this useraccount, but filtered and limited 224 | $limit = 5; 225 | $params = array( 226 | 'output' => array('hostid', 'host', 'name', 'status', 'maintenance_status', 'description'), 227 | 'filter' => array('status' => 0, 'maintenance_status' => 0, 'type' => 1), 228 | 'selectGroups' => array('groupid', 'name'), 229 | 'selectInterfaces' => array('interfaceid', 'main', 'type', 'useip', 'ip', 'dns', 'port'), 230 | 'selectInventory' => array('os', 'contact', 'location'), 231 | 'selectMacros' => array('macro', 'value'), 232 | 'limit' => $limit 233 | ); 234 | 235 | $result = $zbx->call('host.get',$params); 236 | print "==== Filtered hostlist with groups and macros ====\n"; 237 | foreach($result as $host) { 238 | printf("HostId:%d - Host:%s\n", $host['hostid'], $host['host']); 239 | foreach($host['groups'] as $group) { 240 | printf(" - GroupId:%d - Group:%s\n", $group['groupid'], $group['name']); 241 | } 242 | foreach($host['macros'] as $macro) { 243 | printf(" - Macro:%s - Value:%s\n", $macro['macro'], $macro['value']); 244 | } 245 | 246 | } 247 | 248 | } catch (Exception $e) { 249 | print "==== Exception ===\n"; 250 | print 'Errorcode: '.$e->getCode()."\n"; 251 | print 'ErrorMessage: '.$e->getMessage()."\n"; 252 | exit; 253 | } 254 | ``` 255 | 256 | ## Debug Mode 257 | 258 | The class provides a debug mode that ouputs a lot of details. To enable, either use an option or function. 259 | 260 | Debug Option as param in login(): 261 | 262 | ```php 263 | $zbx = new ZabbixApi(); 264 | try { 265 | $options = array('sslVerifyPeer' => false, 'sslVerifyHost' => false, 'debug' => true); 266 | $zbx->login('https://my.zabbixurl.com/zabbix', 'myusername', 'mypassword', $options); 267 | ... 268 | ``` 269 | 270 | Debug Function - can be used any time: 271 | 272 | ```php 273 | # Turn debug on 274 | $zbx = new ZabbixApi(); 275 | $zbx->setDebug(true); 276 | try { 277 | $options = array('sslVerifyPeer' => false, 'sslVerifyHost' => false); 278 | $zbx->login('https://my.zabbixurl.com/zabbix', 'myusername', 'mypassword', $options); 279 | ... 280 | # Can be turned off anytime 281 | $zbx->setDebug(false); 282 | ... 283 | # And turned on again 284 | $zbx->setDebug(true); 285 | ``` 286 | 287 | # Functions reference 288 | 289 | ## Basic functions 290 | 291 | ### login($zabUrl, $zabUser, $zabPassword, $options) 292 | 293 | Initial login. Configures the class and loads a cached session if it exists. It does not executes a request to the remote server to test the credentials or session at this time. This happens automatically during the first call to the Zabbix-API. One can enforce the validation by calling `getAuthKey()` after `login()`. 294 | 295 | > **Note:** If debug is enabled via option, or via function before calling `login()`, `login()` issues a call to the Zabbix-API to check wether the session is re-used. 296 | 297 | * `return` void 298 | * `throws` ZabbixApiException. Invalid options, session issues or connection problems. 299 | * `param` string $zabUrl 300 | * `param` string $zabUser 301 | * `param` string $zabPassword 302 | * `param` array $options - optional settings. 303 | Example: `array('sslVerifyPeer' => false, 'sslVerifyHost' => false);` 304 | * `debug`: boolean - default=false. Show debug information. Also setDebug() can be used. Default is false 305 | * `sessionDir`: string - default=user `tmp` directory. Directory where to store the sessions. 306 | * `sslCaFile`: string - default=use php.ini settings. Filename of external CACertBundle. Useful when using self signed certificates from internal CA. See the CURL or Mozilla websites for those bundles. 307 | * `sslVerifyPeer`: boolean - default=true. Verify certificate. Throws Exception on failure. When false, ignore any verfication errors. 308 | * `sslVerifyHost`: boolean - default=true. Verify Hostname against CN in certificate. Only works if certificate can be validated. 309 | 310 | > **Note:** If sslVerifyPeer=false but the certificate itself is valid and the hostname does not match, then sslVerifyHost=true will raise an exception. 311 | * `useGzip`: boolean - default=true. Use gzip compression for requests. 312 | * `connectTimeout`: integer - default=10. Max. time in seconds to connect to server. 313 | * `timeout`: default=30. Max. time in seconds to process request. 314 | 315 | ### loginToken($zabUrl, $zabToken, $options) 316 | 317 | Alternative login method using an API token, which is set directly as auth token. Options are the same as for `login()`. 318 | 319 | Since session management is not required with API tokens, no cached sessions are loaded or saved. 320 | 321 | * `return` void 322 | * `throws` ZabbixApiException. Invalid options, session issues or connection problems. 323 | * `param` string $zabUrl 324 | * `param` string $zabToken 325 | * `param` array $options - optional settings. 326 | 327 | ### call($method, $params) 328 | 329 | Execute Zabbix API call. Will automatically login/re-login and retry if the call failed using the current authKey read from session. 330 | 331 | > **Note:** Can only be called after login() was called once before at any time. 332 | 333 | * `return` mixed $reusedSession. Decoded Json response from API call or a scalar. See Zabbix API documentation for details. 334 | * `throws` ZabbixApiException. API Error, Session issues or connection problems. 335 | * `param` string $method. Zabbix API method i.e. 'host.get' 336 | * `param` mixed $params. Params as defined in the Zabbix API for that particular method. 337 | 338 | ### logout() 339 | 340 | Logout from Zabbix Server and also delete the authKey from filesystem. 341 | 342 | > **Note:** Only use this method if its really needed, because the session cannot be reused later on. Logouts on API object created with an API token have no effect. 343 | 344 | * `return` void 345 | * `throws` ZabbixApiException. API Error, Session issues or connection problems 346 | 347 | ### setDebug($state) 348 | 349 | Enable / Disable debug output. Can be used any time. 350 | 351 | * `return` void 352 | * `param` boolean $state. True enables debug output. 353 | 354 | ## Convenient functions 355 | 356 | ### getVersion() 357 | 358 | Get version of this library. 359 | 360 | * `return` string $version. 361 | 362 | ### getApiVersion() 363 | 364 | Get Zabbix API version from Zabbix Server. Also useful to check wether the Zabbix Api url is valid. 365 | 366 | > **Note:** Prefer this function over `call('apiinfo.version')`, because it does not try to authenticate and stores the Zabbix Api version for further requests. 367 | 368 | * `return` string $version. Uses API method 'apiinfo.version'. 369 | * `throws` ZabbixApiException. API Error, Session issues or connection problems 370 | 371 | ## Utility functions 372 | 373 | ### getAuthKey() 374 | 375 | Get authKey used for API communication. 376 | 377 | > **Note:** If there was no previous call to the Zabbix-API, this funcion will call the Zabbix-API to ensure a valid authkey. 378 | 379 | * `return` string $authKey. 380 | 381 | ### getSessionDir() 382 | 383 | Get session directory. 384 | 385 | * `return` string $directory. 386 | 387 | ### getSessionFileName() 388 | 389 | Get session FileName storing the encrypted authKey without path. 390 | 391 | * `return` string $fileName. 392 | 393 | ### getSessionFile() 394 | 395 | Get full FileName with path. 396 | 397 | * `return` string $fileName. 398 | 399 | # Tips and Tricks 400 | 401 | ## Common "get" method parameters 402 | 403 | As described in the [Zabbix-Api](https://www.zabbix.com/documentation/current/manual/api/reference_commentary), there several parameter that can be added to a "get" method. 404 | 405 | Find attached a list of some less known but quite useful ones, especially `preservekeys` : 406 | 407 | | Parameter | Type | Description | 408 | | :-------- | :--- | :---------- | 409 | | countOutput | boolean | Return the number of records in the result instead of the actual data. | 410 | | editable | boolean | If set to true return only objects that the user has write permissions to. Default: false. | 411 | | limit | integer | Limit the number of records returned. | 412 | | preservekeys | boolean | Use IDs as keys in the resulting array. | 413 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "intellitrend/zabbixapi", 3 | "description": "Zabbix API client for PHP with session cache and SSL management", 4 | "type": "library", 5 | "require": { 6 | "php": ">=5.6", 7 | "ext-curl": "*" 8 | }, 9 | "license": "LGPL-3.0", 10 | "authors": [ 11 | { 12 | "name": "IntelliTrend", 13 | "email": "support@intellitrend.de", 14 | "homepage": "https://www.intellitrend.de" 15 | } 16 | ], 17 | "support": { 18 | "issues": "https://github.com/intellitrend/zabbixapi-php/issues", 19 | "docs": "https://github.com/intellitrend/zabbixapi-php" 20 | }, 21 | "minimum-stability": "stable", 22 | "autoload": { 23 | "psr-4": { 24 | "IntelliTrend\\Zabbix\\": "/src" 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /docs/README.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intellitrend/zabbixapi-php/9ad0059cfcbc89cae9e1299bd888de5a0ca10d48/docs/README.pdf -------------------------------------------------------------------------------- /examples/composer/.gitignore: -------------------------------------------------------------------------------- 1 | # ide eclipse, phpstorm 2 | .settings 3 | .buildpath 4 | .project 5 | .idea 6 | 7 | phpdoc 8 | build 9 | 10 | vendor 11 | composer.phar 12 | composer.lock 13 | -------------------------------------------------------------------------------- /examples/composer/README.md: -------------------------------------------------------------------------------- 1 | # Example using composer 2 | 3 | The package `intellitrend/zabbixapi` requires composer 2+. 4 | 5 | The following examples assumes `composer.phar` to be in the root of the project directory. Your call to composer might be different. 6 | 7 | You can download the latest version of composer [here](https://getcomposer.org/download/). 8 | 9 | ## Pepare the project that should use the package 10 | 11 | Create a `composer.json` for the project: 12 | 13 | ```json 14 | { 15 | "name": "zabbix-api/demo", 16 | "description": "", 17 | "require": { 18 | "intellitrend/zabbixapi": "v3.3.0" 19 | }, 20 | "autoload": { 21 | "psr-4": { 22 | "IntelliTrend\\Zabbix\\": "/src" 23 | } 24 | } 25 | } 26 | ``` 27 | 28 | ## Run composer 29 | 30 | Run `php .\composer.phar create-project` (requires composer.phar) 31 | 32 | After a successful run, the directory structure looks like this. Composer added the vendor directory and also its own created autoload files: 33 | 34 | ```text 35 | ├───projectfolder 36 | │ └───vendor 37 | │ ├───composer 38 | │ └───intellitrend 39 | │ └───zabbixapi 40 | │ ├───docs 41 | │ ├───examples 42 | │ └───src 43 | ``` 44 | 45 | Note: You can remove the `vendor` directory any time. However then you must run `php .\composer.phar create-project` again. For more composer options see the [documentation](https://getcomposer.org/doc/). 46 | 47 | ## Add the following lines to your application 48 | 49 | ```php 50 | setDebug(true); 23 | // default is to verify certificate and hostname 24 | $zbx->login($zabUrl, $zabUser, $zabPassword); 25 | // loginToken() accepts API tokens as an alternative to login() 26 | // $zbx->loginToken($zabUrl, $zabToken); 27 | // this is similar to: $result = $zbx->call('apiinfo.version'); 28 | $result = $zbx->getApiVersion(); 29 | print "Remote Zabbix API Version:$result\n"; 30 | // get number of host available to this useraccount 31 | $result = $zbx->call('host.get',array("countOutput" => true)); 32 | print "Number of Hosts:$result\n"; 33 | // calling logout will logout from zabbix (deleteing the session) and also delete the local session cache 34 | // if your application is called periodically, the do not logout to benefit from session cache 35 | // $zbx->logout(); 36 | } catch (ZabbixApiException $e) { 37 | print "==== Zabbix API Exception ===\n"; 38 | print 'Errorcode: '.$e->getCode()."\n"; 39 | print 'ErrorMessage: '.$e->getMessage()."\n"; 40 | exit; 41 | } catch (Exception $e) { 42 | print "==== Exception ===\n"; 43 | print 'Errorcode: '.$e->getCode()."\n"; 44 | print 'ErrorMessage: '.$e->getMessage()."\n"; 45 | exit; 46 | } -------------------------------------------------------------------------------- /examples/createTrigger.php: -------------------------------------------------------------------------------- 1 | login($zabUrl, $zabUser, $zabPassword); 19 | 20 | // this is similar to: $result = $zbx->call('apiinfo.version'); 21 | $result = $zbx->getApiVersion(); 22 | print "Remote Zabbix API Version:$result\n"; 23 | 24 | print "====================================================================\n"; 25 | 26 | // create a trigger on host 'Zabbix Server' that fires if the item 'system.cpu.util' is greater than 75 27 | $result = $zbx->call('trigger.create', array( 28 | "priority" => "3", // average 29 | "description" => "High CPU usage on {HOST.NAME}", 30 | "expression" => "last(/Zabbix server/system.cpu.util)>75", // Zabbix 5.4 and after 31 | // "expression" => "{Zabbix server:system.cpu.util.last()}>75", // before Zabbix 5.4 32 | )); 33 | 34 | // print ID of the trigger that was created 35 | print_r($result); 36 | } catch (ZabbixApiException $e) { 37 | print "==== Zabbix API Exception ===\n"; 38 | print 'Errorcode: '.$e->getCode()."\n"; 39 | print 'ErrorMessage: '.$e->getMessage()."\n"; 40 | exit; 41 | } catch (Exception $e) { 42 | print "==== Exception ===\n"; 43 | print 'Errorcode: '.$e->getCode()."\n"; 44 | print 'ErrorMessage: '.$e->getMessage()."\n"; 45 | exit; 46 | } 47 | ?> 48 | -------------------------------------------------------------------------------- /examples/filter.php: -------------------------------------------------------------------------------- 1 | login($zabUrl, $zabUser, $zabPassword); 19 | 20 | //this is similar to: $result = $zbx->call('apiinfo.version'); 21 | $result = $zbx->getApiVersion(); 22 | print "Remote Zabbix API Version:$result\n"; 23 | 24 | print "====================================================================\n"; 25 | // Get hosts and other information available to this useraccount, but filtered and limited 26 | $limit = 5; 27 | $params = array( 28 | 'output' => array('hostid', 'host', 'name', 'status', 'maintenance_status', 'description'), 29 | 'filter' => array('status' => 0, 'maintenance_status' => 0, 'type' => 1), 30 | 'selectGroups' => array('groupid', 'name'), 31 | 'selectInterfaces' => array('interfaceid', 'main', 'type', 'useip', 'ip', 'dns', 'port'), 32 | 'selectInventory' => array('os', 'contact', 'location'), 33 | 'selectMacros' => array('macro', 'value'), 34 | 'limit' => $limit 35 | ); 36 | 37 | $result = $zbx->call('host.get',$params); 38 | print "==== Filtered hostlist with groups and macros ====\n"; 39 | foreach($result as $host) { 40 | printf("HostId:%d - Host:%s\n", $host['hostid'], $host['host']); 41 | foreach($host['groups'] as $group) { 42 | printf(" - GroupId:%d - Group:%s\n", $group['groupid'], $group['name']); 43 | } 44 | foreach($host['macros'] as $macro) { 45 | printf(" - Macro:%s - Value:%s\n", $macro['macro'], $macro['value']); 46 | } 47 | 48 | } 49 | } catch (ZabbixApiException $e) { 50 | print "==== Zabbix API Exception ===\n"; 51 | print 'Errorcode: '.$e->getCode()."\n"; 52 | print 'ErrorMessage: '.$e->getMessage()."\n"; 53 | exit; 54 | } catch (Exception $e) { 55 | print "==== Exception ===\n"; 56 | print 'Errorcode: '.$e->getCode()."\n"; 57 | print 'ErrorMessage: '.$e->getMessage()."\n"; 58 | exit; 59 | } -------------------------------------------------------------------------------- /examples/filterByHostGroupIds.php: -------------------------------------------------------------------------------- 1 | login($zabUrl, $zabUser, $zabPassword); 19 | 20 | //this is similar to: $result = $zbx->call('apiinfo.version'); 21 | $result = $zbx->getApiVersion(); 22 | print "Remote Zabbix API Version:$result\n"; 23 | 24 | print "====================================================================\n"; 25 | // get hosts and other information available to this useraccount, but filtered by hostGroupIds 26 | // note: [] is a more modern way of array() 27 | $hostGroupIds = [4, 12]; 28 | 29 | $params = array( 30 | 'output' => array('hostid', 'host', 'name', 'status', 'maintenance_status', 'description'), 31 | 'groupids' => $hostGroupIds, 32 | 'selectGroups' => array('groupid', 'name'), 33 | 'selectInterfaces' => array('interfaceid', 'main', 'type', 'useip', 'ip', 'dns', 'port'), 34 | 'selectInventory' => array('os', 'contact', 'location'), 35 | 'selectMacros' => array('macro', 'value') 36 | ); 37 | 38 | $result = $zbx->call('host.get',$params); 39 | print "==== Filtered hostlist with groups and macros ====\n"; 40 | foreach($result as $host) { 41 | printf("HostId:%d - Host:%s - Name:%s\n", $host['hostid'], $host['host'], $host['name']); 42 | foreach($host['groups'] as $group) { 43 | printf(" - GroupId:%d - Group:%s\n", $group['groupid'], $group['name']); 44 | } 45 | foreach($host['macros'] as $macro) { 46 | printf(" - Macro:%s - Value:%s\n", $macro['macro'], $macro['value']); 47 | } 48 | 49 | } 50 | } catch (ZabbixApiException $e) { 51 | print "==== Zabbix API Exception ===\n"; 52 | print 'Errorcode: '.$e->getCode()."\n"; 53 | print 'ErrorMessage: '.$e->getMessage()."\n"; 54 | exit; 55 | } catch (Exception $e) { 56 | print "==== Exception ===\n"; 57 | print 'Errorcode: '.$e->getCode()."\n"; 58 | print 'ErrorMessage: '.$e->getMessage()."\n"; 59 | exit; 60 | } -------------------------------------------------------------------------------- /examples/filterByHostGroupNames1.php: -------------------------------------------------------------------------------- 1 | login($zabUrl, $zabUser, $zabPassword); 19 | 20 | // this is similar to: $result = $zbx->call('apiinfo.version'); 21 | $result = $zbx->getApiVersion(); 22 | print "Remote Zabbix API Version:$result\n"; 23 | 24 | print "====================================================================\n"; 25 | // get hostGroups and attach hosts available to this useraccount, filtered by hostGroupNames 26 | // note: [] is a more modern way of array() 27 | // depending how much details about the host is needed, 2 options are available: 28 | // 1. 1 call: Get hostGroups and add corresponding hosts to the result 29 | // 2. 2 Calls: Get hostGroupIds based on theirs names, then get hosts with detailed info 30 | 31 | // here we use method 1 - 1 call 32 | // get hostGroupIds by name and add hosts to result 33 | $hostGroupNames = ['Zabbix servers', 'IntelliTrend/Development']; 34 | 35 | $params = array( 36 | 'output' => array('groupid', 'name'), 37 | 'filter' => array('name' => $hostGroupNames), 38 | 'selectHosts' => array('hostid', 'host', 'name', 'status', 'maintenance_status', 'description') 39 | ); 40 | 41 | $result = $zbx->call('hostgroup.get',$params); 42 | print "==== Hosts filtered by hostGroups - one call ====\n"; 43 | foreach($result as $hostGroup) { 44 | printf("GroupId:%d - Group:%s\n", $hostGroup['groupid'], $hostGroup['name']); 45 | foreach($hostGroup['hosts'] as $host) { 46 | printf(" - HostId:%d - Host:%s - Name:%s\n", $host['hostid'], $host['host'], $host['name']); 47 | } 48 | } 49 | } catch (ZabbixApiException $e) { 50 | print "==== Zabbix API Exception ===\n"; 51 | print 'Errorcode: '.$e->getCode()."\n"; 52 | print 'ErrorMessage: '.$e->getMessage()."\n"; 53 | exit; 54 | } catch (Exception $e) { 55 | print "==== Exception ===\n"; 56 | print 'Errorcode: '.$e->getCode()."\n"; 57 | print 'ErrorMessage: '.$e->getMessage()."\n"; 58 | exit; 59 | } -------------------------------------------------------------------------------- /examples/filterByHostGroupNames2.php: -------------------------------------------------------------------------------- 1 | login($zabUrl, $zabUser, $zabPassword); 19 | 20 | // this is similar to: $result = $zbx->call('apiinfo.version'); 21 | $result = $zbx->getApiVersion(); 22 | print "Remote Zabbix API Version:$result\n"; 23 | 24 | print "====================================================================\n"; 25 | // get hostGroups and attach hosts available to this useraccount, filtered by hostGroupNames 26 | // note: [] is a more modern way of array() 27 | // depending how much details about the host is needed, 2 options are available: 28 | // 1. 1 call: Get hostGroups and add corresponding hosts to the result 29 | // 2. 2 calls: Get hostGroupIds based on theirs names, then get hosts with detailed info 30 | 31 | // here we use method 2 - 2 calls 32 | // note: if a host belongs to other groups as filtered in the 1st call 33 | // these goups are also listed in the 2nd call. 34 | // get hostGroupIds by name and then execute a 2nd call to get the hosts with additional data 35 | $hostGroupNames = ['Zabbix servers', 'IntelliTrend/Development']; 36 | 37 | $params = array( 38 | 'output' => array('groupid', 'name'), 39 | 'filter' => array('name' => $hostGroupNames), 40 | ); 41 | 42 | $result = $zbx->call('hostgroup.get',$params); 43 | print "==== Hosts filtered by hostGroups - 2 calls ====\n"; 44 | print "==== 1. Call: Filtered hostGroups ====\n"; 45 | // save the ids for next call 46 | $hostGroupIds = []; 47 | foreach($result as $hostGroup) { 48 | printf("GroupId:%d - Group:%s\n", $hostGroup['groupid'], $hostGroup['name']); 49 | $hostGroupIds[] = $hostGroup['groupid']; 50 | } 51 | 52 | // get hosts based on the hostGroupIds 53 | $params = array( 54 | 'output' => array('hostid', 'host', 'name', 'status', 'maintenance_status', 'description'), 55 | 'groupids' => $hostGroupIds, 56 | 'selectGroups' => array('groupid', 'name'), 57 | 'selectInterfaces' => array('interfaceid', 'main', 'type', 'useip', 'ip', 'dns', 'port'), 58 | 'selectInventory' => array('os', 'contact', 'location'), 59 | 'selectMacros' => array('macro', 'value') 60 | ); 61 | 62 | $result = $zbx->call('host.get',$params); 63 | print "==== 2. Call: Filtered hostlist with groups and macros ====\n"; 64 | foreach($result as $host) { 65 | printf("HostId:%d - Host:%s - Name:%s\n", $host['hostid'], $host['host'], $host['name']); 66 | foreach($host['groups'] as $group) { 67 | printf(" - GroupId:%d - Group:%s\n", $group['groupid'], $group['name']); 68 | } 69 | foreach($host['macros'] as $macro) { 70 | if (!isset($macro['value'])) { 71 | $macro['value'] = ''; 72 | } 73 | printf(" - Macro:%s - Value:%s\n", $macro['macro'], $macro['value']); 74 | } 75 | 76 | } 77 | } catch (ZabbixApiException $e) { 78 | print "==== Zabbix API Exception ===\n"; 79 | print 'Errorcode: '.$e->getCode()."\n"; 80 | print 'ErrorMessage: '.$e->getMessage()."\n"; 81 | exit; 82 | } catch (Exception $e) { 83 | print "==== Exception ===\n"; 84 | print 'Errorcode: '.$e->getCode()."\n"; 85 | print 'ErrorMessage: '.$e->getMessage()."\n"; 86 | exit; 87 | } -------------------------------------------------------------------------------- /examples/filterByHostIds.php: -------------------------------------------------------------------------------- 1 | login($zabUrl, $zabUser, $zabPassword); 19 | 20 | // this is similar to: $result = $zbx->call('apiinfo.version'); 21 | $result = $zbx->getApiVersion(); 22 | print "Remote Zabbix API Version:$result\n"; 23 | 24 | print "====================================================================\n"; 25 | // get hosts and other information available to this useraccount, but filtered by hostids 26 | // note: [] is a more modern way of array() 27 | $hostIds = [10126, 10127]; 28 | 29 | $params = array( 30 | 'output' => array('hostid', 'host', 'name', 'status', 'maintenance_status', 'description'), 31 | 'hostids' => $hostIds, 32 | 'selectGroups' => array('groupid', 'name'), 33 | 'selectInterfaces' => array('interfaceid', 'main', 'type', 'useip', 'ip', 'dns', 'port'), 34 | 'selectInventory' => array('os', 'contact', 'location'), 35 | 'selectMacros' => array('macro', 'value') 36 | ); 37 | 38 | $result = $zbx->call('host.get',$params); 39 | print "==== Filtered hostlist with groups and macros ====\n"; 40 | foreach($result as $host) { 41 | printf("HostId:%d - Host:%s - Name:%s\n", $host['hostid'], $host['host'], $host['name']); 42 | foreach($host['groups'] as $group) { 43 | printf(" - GroupId:%d - Group:%s\n", $group['groupid'], $group['name']); 44 | } 45 | foreach($host['macros'] as $macro) { 46 | printf(" - Macro:%s - Value:%s\n", $macro['macro'], $macro['value']); 47 | } 48 | 49 | } 50 | } catch (ZabbixApiException $e) { 51 | print "==== Zabbix API Exception ===\n"; 52 | print 'Errorcode: '.$e->getCode()."\n"; 53 | print 'ErrorMessage: '.$e->getMessage()."\n"; 54 | exit; 55 | } catch (Exception $e) { 56 | print "==== Exception ===\n"; 57 | print 'Errorcode: '.$e->getCode()."\n"; 58 | print 'ErrorMessage: '.$e->getMessage()."\n"; 59 | exit; 60 | } -------------------------------------------------------------------------------- /examples/filterByHostNames.php: -------------------------------------------------------------------------------- 1 | login($zabUrl, $zabUser, $zabPassword); 19 | 20 | // this is similar to: $result = $zbx->call('apiinfo.version'); 21 | $result = $zbx->getApiVersion(); 22 | print "Remote Zabbix API Version:$result\n"; 23 | 24 | print "====================================================================\n"; 25 | // get hosts and other information available to this useraccount, but filtered by hostnames 26 | // note: [] is a more modern way of array() 27 | $hostNames = ['Zabbix Server', 'Test Server']; 28 | 29 | $params = array( 30 | 'output' => array('hostid', 'host', 'name', 'status', 'maintenance_status', 'description'), 31 | 'filter' => array('host' => $hostNames), 32 | 'selectGroups' => array('groupid', 'name'), 33 | 'selectInterfaces' => array('interfaceid', 'main', 'type', 'useip', 'ip', 'dns', 'port'), 34 | 'selectInventory' => array('os', 'contact', 'location'), 35 | 'selectMacros' => array('macro', 'value') 36 | ); 37 | 38 | $result = $zbx->call('host.get',$params); 39 | print "==== Filtered hostlist with groups and macros ====\n"; 40 | foreach($result as $host) { 41 | printf("HostId:%d - Host:%s - Name:%s\n", $host['hostid'], $host['host'], $host['name']); 42 | foreach($host['groups'] as $group) { 43 | printf(" - GroupId:%d - Group:%s\n", $group['groupid'], $group['name']); 44 | } 45 | foreach($host['macros'] as $macro) { 46 | printf(" - Macro:%s - Value:%s\n", $macro['macro'], $macro['value']); 47 | } 48 | 49 | } 50 | } catch (ZabbixApiException $e) { 51 | print "==== Zabbix API Exception ===\n"; 52 | print 'Errorcode: '.$e->getCode()."\n"; 53 | print 'ErrorMessage: '.$e->getMessage()."\n"; 54 | exit; 55 | } catch (Exception $e) { 56 | print "==== Exception ===\n"; 57 | print 'Errorcode: '.$e->getCode()."\n"; 58 | print 'ErrorMessage: '.$e->getMessage()."\n"; 59 | exit; 60 | } -------------------------------------------------------------------------------- /examples/hostlistNoSslCheck.php: -------------------------------------------------------------------------------- 1 | getVersion(). "\n"; 19 | try { 20 | // disable validation off certificate and host 21 | $options = array('sslVerifyPeer' => false, 'sslVerifyHost' => false); 22 | $zbx->login($zabUrl, $zabUser, $zabPassword, $options); 23 | 24 | //this is similar to: $result = $zbx->call('apiinfo.version'); 25 | $result = $zbx->getApiVersion(); 26 | print "Remote Zabbix API Version:$result\n"; 27 | 28 | print "Debugging set to on\n"; 29 | $zbx->setDebug(true); 30 | 31 | // Get host count 32 | $params = array( 33 | // count of hosts - no ids, no details 34 | "countOutput" => true 35 | ); 36 | $result = $zbx->call('host.get',$params); 37 | print "Number of Hosts:$result\n"; 38 | 39 | print "Debugging set to off\n"; 40 | $zbx->setDebug(false); 41 | 42 | $limit = 5; 43 | $params = array( 44 | // limit host info to these fields, to get all use "extend" instead of field list 45 | "output" => array("hostid", "host", "name", "status"), 46 | // limit number of hosts returned, otherwise get all hosts you have access to 47 | "limit" => $limit 48 | ); 49 | $result = $zbx->call('host.get',$params); 50 | 51 | 52 | print "Getting hostlist - limited to:$limit\n"; 53 | foreach ($result as $v) { 54 | $hostid = $v['hostid']; 55 | $hostname = $v['host']; 56 | $name = $v['name']; 57 | $status = $v['status']; 58 | print "hostid:$hostid, status:$status, hostname:$hostname, alias:$name\n"; 59 | } 60 | 61 | // logout() would logout from api and also delete the session file locally 62 | //$zbx->logout(); 63 | } catch (ZabbixApiException $e) { 64 | print "==== Zabbix API Exception ===\n"; 65 | print 'Errorcode: '.$e->getCode()."\n"; 66 | print 'ErrorMessage: '.$e->getMessage()."\n"; 67 | exit; 68 | } catch (Exception $e) { 69 | print "==== Exception ===\n"; 70 | print 'Errorcode: '.$e->getCode()."\n"; 71 | print 'ErrorMessage: '.$e->getMessage()."\n"; 72 | exit; 73 | } -------------------------------------------------------------------------------- /examples/simple.php: -------------------------------------------------------------------------------- 1 | login($zabUrl, $zabUser, $zabPassword); 19 | //this is similar to: $result = $zbx->call('apiinfo.version'); 20 | $result = $zbx->getApiVersion(); 21 | print "Remote Zabbix API Version:$result\n"; 22 | // Get number of host available to this useraccount 23 | $result = $zbx->call('host.get',array("countOutput" => true)); 24 | print "Number of Hosts:$result\n"; 25 | } catch (ZabbixApiException $e) { 26 | print "==== Zabbix API Exception ===\n"; 27 | print 'Errorcode: '.$e->getCode()."\n"; 28 | print 'ErrorMessage: '.$e->getMessage()."\n"; 29 | exit; 30 | } catch (Exception $e) { 31 | print "==== Exception ===\n"; 32 | print 'Errorcode: '.$e->getCode()."\n"; 33 | print 'ErrorMessage: '.$e->getMessage()."\n"; 34 | exit; 35 | } -------------------------------------------------------------------------------- /examples/simpleNoSslCheck.php: -------------------------------------------------------------------------------- 1 | false, 'sslVerifyHost' => false); 19 | $zbx->login($zabUrl, $zabUser, $zabPassword, $options); 20 | //this is similar to: $result = $zbx->call('apiinfo.version'); 21 | $result = $zbx->getApiVersion(); 22 | print "Remote Zabbix API Version:$result\n"; 23 | // Get number of host available to this useraccount 24 | $result = $zbx->call('host.get',array("countOutput" => true)); 25 | print "Number of Hosts:$result\n"; 26 | } catch (ZabbixApiException $e) { 27 | print "==== Zabbix API Exception ===\n"; 28 | print 'Errorcode: '.$e->getCode()."\n"; 29 | print 'ErrorMessage: '.$e->getMessage()."\n"; 30 | exit; 31 | } catch (Exception $e) { 32 | print "==== Exception ===\n"; 33 | print 'Errorcode: '.$e->getCode()."\n"; 34 | print 'ErrorMessage: '.$e->getMessage()."\n"; 35 | exit; 36 | } -------------------------------------------------------------------------------- /examples/simpleToken.php: -------------------------------------------------------------------------------- 1 | loginToken($zabUrl, $zabToken); 18 | //this is similar to: $result = $zbx->call('apiinfo.version'); 19 | $result = $zbx->getApiVersion(); 20 | print "Remote Zabbix API Version:$result\n"; 21 | // Get number of host available to this useraccount 22 | $result = $zbx->call('host.get',array("countOutput" => true)); 23 | print "Number of Hosts:$result\n"; 24 | } catch (ZabbixApiException $e) { 25 | print "==== Zabbix API Exception ===\n"; 26 | print 'Errorcode: '.$e->getCode()."\n"; 27 | print 'ErrorMessage: '.$e->getMessage()."\n"; 28 | exit; 29 | } catch (Exception $e) { 30 | print "==== Exception ===\n"; 31 | print 'Errorcode: '.$e->getCode()."\n"; 32 | print 'ErrorMessage: '.$e->getMessage()."\n"; 33 | exit; 34 | } -------------------------------------------------------------------------------- /src/ZabbixApi.php: -------------------------------------------------------------------------------- 1 | 7 | * @copyright IntelliTrend GmbH, http://www.intellitrend.de 8 | * @license GNU Lesser General Public License v3.0 9 | * 10 | * You can redistribute this library and/or modify it under the terms of 11 | * the GNU LGPL as published by the Free Software Foundation, 12 | * either version 3 of the License, or any later version. 13 | * However you must not change author and copyright information. 14 | * 15 | * Implementation based on the offical Zabbix API docs. 16 | * Tested on Linux and Windows. 17 | * 18 | * Requires PHP 5.6+, JSON functions, CURL, Zabbix 3.0+ 19 | * For usage see examples provided in 'examples/' 20 | * 21 | * Errorhandling: 22 | * Errors are handled by exceptions. 23 | * - In case of ZabbxiApi errors, the msg and code is passed to the exception class ZabbixApiException 24 | * - In case of generic API errors, the code passed is defined by the constants: ZabbixApi::EXCEPTION_CLASS_CODE 25 | * - In case of session specfic API errors, the code passed is defined by the constants: ZabbixApi::EXCEPTION_CLASS_CODE_SESSION 26 | */ 27 | 28 | 29 | namespace IntelliTrend\Zabbix; 30 | 31 | class ZabbixApiException extends \Exception { 32 | public function __construct($message, $code = 0, Throwable $previous = null) { 33 | parent::__construct($message, $code, $previous); 34 | } 35 | } 36 | 37 | class ZabbixApi { 38 | 39 | const VERSION = "3.3.0"; 40 | 41 | const EXCEPTION_CLASS_CODE = 1000; 42 | const EXCEPTION_CLASS_CODE_SESSION = 2000; 43 | const SESSION_PREFIX = 'zbx_'; 44 | 45 | protected $zabUrl = ''; 46 | protected $zabUser = ''; 47 | protected $zabPassword = ''; 48 | protected $authKey = ''; 49 | protected $debug = false; 50 | protected $sessionDir = ''; // directory where to store the crypted session 51 | protected $sessionFileName = ''; // fileName of crypted session, depends on zabUrl/zabUser and SESSION_PREFIX 52 | protected $sessionFile = ''; // directory + / + fileName 53 | protected $sslCaFile = ''; // set external CA bundle. If not set use php.ini default settings. See https://curl.haxx.se/docs/caextract.html 54 | protected $sslVerifyPeer = 1; // verify cert 55 | protected $sslVerifyHost = 2; // if cert is valid, check hostname 56 | protected $useGzip = true; 57 | protected $timeout = 30; //max. time in seconds to process request 58 | protected $connectTimeout = 10; //max. time in seconds to connect to server 59 | protected $authKeyIsValid = false; // whether the autkey was actually successfully used in this session 60 | protected $authKeyIsToken = false; // whether the autkey is a token and therefore not bound to a session 61 | protected $authHeader = false; // whether the authkey should be send as header or inside the body 62 | protected $userKey = ''; // name of the username field 63 | protected $zabApiVersion = ''; // Zabbix API version. Updated when calling getApiVersion() or on first _login() attempt. Needed for API change in 5.4 (user -> username) 64 | 65 | 66 | /** 67 | * Constructor 68 | * Check for required Curl module 69 | * @throws ZabbixApiException 70 | */ 71 | public function __construct() { 72 | if (!function_exists('curl_init')) { 73 | throw new ZabbixApiException("Missing Curl support. Install the PHP Curl module.", ZabbixApi::EXCEPTION_CLASS_CODE); 74 | } 75 | } 76 | 77 | 78 | /** 79 | * Login - setup internal structure and validate sessionDir 80 | * 81 | * @param string $zabUrl - Zabbix base URL 82 | * @param string $zabUser - Zabbix user name 83 | * @param string $zabPassword - Zabbix password 84 | * @param array $options - optional settings. Example: array('sessionDir' => '/tmp', 'sslVerifyPeer' => true, 'useGzip' => true, 'debug' => true); 85 | * @throws ZabbixApiException 86 | */ 87 | public function login($zabUrl, $zabUser, $zabPassword, $options = array()) { 88 | 89 | $zabUrl = substr($zabUrl , -1) == '/' ? $zabUrl : $zabUrl .= '/'; 90 | $this->zabUrl = $zabUrl; 91 | 92 | $this->zabUser = $zabUser; 93 | $this->zabPassword = $zabPassword; 94 | 95 | $this->applyOptions($options); 96 | 97 | // if sessionDir is passed as param check if a directory exists. otherwise use the default temp directory 98 | if (array_key_exists('sessionDir', $options)) { 99 | $sessionDir = $options['sessionDir']; 100 | if (!is_dir($sessionDir)) { 101 | throw new ZabbixApiException("Error - sessionDir:$sessionDir is not a valid directory", ZabbixApi::EXCEPTION_CLASS_CODE); 102 | } 103 | if (!is_writable($sessionDir)) { 104 | throw new ZabbixApiException("Error - sessionDir:$sessionDir is not a writeable directory", ZabbixApi::EXCEPTION_CLASS_CODE); 105 | } 106 | $this->sessionDir = $sessionDir; 107 | } 108 | else { 109 | $this->sessionDir = sys_get_temp_dir(); 110 | } 111 | 112 | $sessionFileName = ZabbixApi::SESSION_PREFIX. md5($this->zabUrl . $this->zabUser); 113 | $this->sessionFileName = $sessionFileName; 114 | $this->sessionFile = $this->sessionDir. '/'. $this->sessionFileName; 115 | 116 | if ($this->debug) { 117 | print "DBG login(). Using sessionDir:$this->sessionDir, sessionFileName:$this->sessionFileName\n"; 118 | } 119 | 120 | $sessionAuthKey = $this->readAuthKeyFromSession(); 121 | 122 | // check API version first to set version-specific flags 123 | $this->getApiVersion(); 124 | 125 | // When debug is enabled, we want to see if the session has been reused. This requires a call to the Zabbix-API. 126 | if ($this->debug) { 127 | $this->call('user.get', array('output' => 'userid', 'limit' => 1)); 128 | if ($this->authKey == $sessionAuthKey) { 129 | print "DBG login(). Re-Using existing session\n"; 130 | } else { 131 | print "DBG login(). Creating new session\n"; 132 | } 133 | } 134 | } 135 | 136 | /** 137 | * Login - setup internal structure via API token 138 | * 139 | * @param string $zabUrl - Zabbix base URL 140 | * @param string $zabToken - Zabbix API token 141 | * @param array $options - optional settings. Example: array('sessionDir' => '/tmp', 'sslVerifyPeer' => true, 'useGzip' => true, 'debug' => true); 142 | * @throws ZabbixApiException 143 | */ 144 | public function loginToken($zabUrl, $zabToken, $options = array()) { 145 | 146 | $zabUrl = substr($zabUrl , -1) == '/' ? $zabUrl : $zabUrl .= '/'; 147 | $this->zabUrl = $zabUrl; 148 | 149 | // login fields are unused with tokens 150 | $this->zabUser = ''; 151 | $this->zabPassword = ''; 152 | 153 | $this->applyOptions($options); 154 | 155 | // session files are also not required 156 | $this->sessionDir = ''; 157 | $this->sessionFileName = ''; 158 | $this->sessionFile = ''; 159 | 160 | // use token directly as auth key 161 | $this->authKey = $zabToken; 162 | $this->authKeyIsValid = true; 163 | $this->authKeyIsToken = true; 164 | 165 | // check API version first to set version-specific flags 166 | $this->getApiVersion(); 167 | } 168 | 169 | 170 | /** 171 | * Convenient function to get remote API version 172 | * 173 | * @return string $apiVersion 174 | */ 175 | public function getApiVersion() { 176 | $this->zabApiVersion = $this->callZabbixApi('apiinfo.version'); 177 | // Zabbix version 5.4 changed key 'user' -> 'username' 178 | if (version_compare($this->zabApiVersion, '5.2.0', '>')) { 179 | $this->userKey = 'username'; 180 | } else { 181 | $this->userKey = 'user'; 182 | } 183 | // Zabbix has deprecated the auth field inside body in 6.4 and removed it in 7.2 184 | $this->authHeader = version_compare($this->zabApiVersion, '6.4.0', '>'); 185 | return $this->zabApiVersion; 186 | } 187 | 188 | 189 | /** 190 | * Get version of this library 191 | * 192 | * @return string $version 193 | */ 194 | public function getVersion() { 195 | return Zabbixapi::VERSION; 196 | } 197 | 198 | 199 | /** 200 | * Get authKey used for API communication - Supportfunction, not used internally 201 | * If there was no call to the Zabbix-API before, this function will call the Zabbix-API 202 | * to ensure a valid $authKey. 203 | * @return string $authKey 204 | */ 205 | public function getAuthKey() { 206 | // if there was no login to the Zabbix-API so far, we do not know wether the key is valid 207 | if (!$this->authKeyIsValid && !$this->authKeyIsToken) { 208 | // Simple call that requires Authentication - will update the key if needed. 209 | $this->call('user.get', array('output' => 'userid', 'limit' => 1)); 210 | } 211 | return $this->authKey; 212 | } 213 | 214 | 215 | /** 216 | * Enable / Disable debug 217 | * 218 | * @param boolean $status. True = enable 219 | */ 220 | public function setDebug($status) { 221 | $this->debug = $status && 1; 222 | } 223 | 224 | 225 | /** 226 | * Logout from Zabbix Server and delete the session from filesystem 227 | * 228 | * Only use this method if its really needed, because you cannot reuse the session later on. 229 | */ 230 | public function logout() { 231 | if ($this->debug) { 232 | print "DBG logout(). Delete sessionFile and logout from Zabbix\n"; 233 | } 234 | 235 | // token-based sessions can't logout 236 | if ($this->authKeyIsToken) { 237 | return; 238 | } 239 | 240 | $response = $this->callZabbixApi('user.logout'); 241 | // remove session locally - ignore if session no longer exists 242 | $ret = unlink($this->getSessionFile()); 243 | } 244 | 245 | 246 | /** 247 | * Get session directory 248 | * 249 | * @return string $sessionDir 250 | */ 251 | public function getSessionDir() { 252 | return $this->sessionDir; 253 | } 254 | 255 | /** 256 | * Get session FileName without path 257 | * 258 | * @return string $sessionFileName 259 | */ 260 | public function getSessionFileName() { 261 | return $this->sessionFileName; 262 | } 263 | 264 | 265 | /** 266 | * Get full FileName with path 267 | * 268 | * @return string $sessionFile 269 | */ 270 | public function getSessionFile() { 271 | return $this->sessionFile; 272 | } 273 | 274 | 275 | /** 276 | * High level Zabbix Api call. Will automatically re-login and retry if call failed using the current authKey. 277 | * 278 | * Note: Can only be called after login() was called once before at any time. 279 | * 280 | * @param string $method. Zabbix API method i.e. 'host.get' 281 | * @param mixed $params. Params as defined in the Zabbix API for that particular method 282 | * @return mixed $response. Decoded Json response or scalar 283 | * @throws ZabbixApiException 284 | */ 285 | public function call($method, $params = array()) { 286 | if (!$this->zabUrl) { 287 | throw new ZabbixApiException("Missing Zabbix URL.", ZabbixApi::EXCEPTION_CLASS_CODE); 288 | } 289 | 290 | // for token-based auth, pass through to callZabbixApi 291 | if ($this->authKeyIsToken) { 292 | return $this->callZabbixApi($method, $params); 293 | } 294 | 295 | // for classic login, try to call API with existing auth first 296 | try { 297 | return $this->callZabbixApi($method, $params); 298 | } 299 | catch (ZabbixApiException $e) { 300 | // check for session exception 301 | if ($e->getCode() == ZabbixApi::EXCEPTION_CLASS_CODE_SESSION) { 302 | // renew session and retry call 303 | $this->__login(); 304 | return $this->callZabbixApi($method, $params); 305 | } else { 306 | // re-throw any other exception 307 | throw $e; 308 | } 309 | } 310 | 311 | // technically unreachable, but just in case 312 | return NULL; 313 | } 314 | 315 | 316 | /*************** Protected / Private functions ***************/ 317 | 318 | 319 | /** 320 | * Internal login function to perform the login. Saves authKey to sessionFile on success. 321 | * 322 | * @return boolean $success 323 | */ 324 | protected function __login() { 325 | // Try to login to our API 326 | if ($this->debug) { 327 | print "DBG __login(). Called\n"; 328 | } 329 | $response = $this->callZabbixApi('user.login', array( 'password' => $this->zabPassword, $this->userKey => $this->zabUser)); 330 | 331 | if (isset($response) && strlen($response) == 32) { 332 | $this->authKey = $response; 333 | //on successful login save authKey to session 334 | $this->writeAuthKeyToSession(); 335 | $this->authKeyIsValid = true; 336 | return true; 337 | } 338 | 339 | // login failed 340 | $this->authKey = ''; 341 | $this->authKeyIsValid = false; 342 | return false; 343 | } 344 | 345 | 346 | /** 347 | * Internal call to Zabbix API via RPC/API call 348 | * 349 | * @param string $method 350 | * @param mixed $params 351 | * @return mixed $response. Json decoded response 352 | * @throws ZabbixApiException 353 | */ 354 | protected function callZabbixApi($method, $params = array()) { 355 | $authRequired = $method != 'user.login' && $method != 'apiinfo.version'; 356 | 357 | if (!$this->authKey && $authRequired) { 358 | throw new ZabbixApiException("Not logged in and no authKey", ZabbixApi::EXCEPTION_CLASS_CODE_SESSION); 359 | } 360 | 361 | $request = $this->buildRequest($method, $params, $authRequired && !$this->authHeader); 362 | $rawResponse = $this->executeRequest($this->zabUrl.'api_jsonrpc.php', $request, $authRequired && $this->authHeader); 363 | 364 | if ($this->debug) { 365 | print "DBG callZabbixApi(). Raw response from API: $rawResponse\n"; 366 | } 367 | $response = json_decode($rawResponse, true); 368 | 369 | if ( isset($response['id']) && $response['id'] == 1 && isset($response['result']) ) { 370 | $this->authKeyIsValid = true; 371 | return $response['result']; 372 | } 373 | 374 | if (is_array($response) && array_key_exists('error', $response)) { 375 | $code = $response['error']['code']; 376 | $message = $response['error']['message']; 377 | $data = $response['error']['data']; 378 | $msg = "$message [$data]"; 379 | throw new ZabbixApiException($msg, $code); 380 | } 381 | 382 | $msg = "Error without further information."; 383 | throw new ZabbixApiException($msg); 384 | 385 | } 386 | 387 | 388 | /** 389 | * Build the Zabbix JSON-RPC request 390 | * 391 | * @param string $method 392 | * @param mixed $params 393 | * @param bool $useAuth. Include auth field 394 | * @return string $request. Json encoded request object 395 | * @throws ZabbixApiException 396 | */ 397 | protected function buildRequest($method, $params = array(), $useAuth = true) { 398 | if ($params && !is_array($params)) { 399 | throw new ZabbixApiException("Params passed to API call must be an array", ZabbixApi::EXCEPTION_CLASS_CODE); 400 | } 401 | 402 | $request = array( 403 | 'method' => $method, 404 | 'id' => 1, // since we do not work in parallel, always using the same id should work 405 | 'params' => ( is_array($params) ? $params : array() ), 406 | 'jsonrpc' => "2.0" 407 | ); 408 | 409 | // required up to Zabbix 6.2 410 | if ($useAuth) { 411 | $request['auth'] = $this->authKey; 412 | } 413 | 414 | return json_encode($request); 415 | } 416 | 417 | 418 | /** 419 | * Low level execute the request 420 | * 421 | * @param string $zabUrl. Url pointing to API endpoint 422 | * @param bool $useAuth. Include authorization header 423 | * @param mixed $data. 424 | * @return string $response. Json encoded response from API 425 | */ 426 | protected function executeRequest($zabUrl, $data = '', $useAuth = true) { 427 | $c = curl_init($zabUrl); 428 | // These are required for submitting JSON-RPC requests 429 | 430 | $headers = array(); 431 | $headers[] = 'Content-Type: application/json-rpc'; 432 | $headers[] = 'User-Agent: IntelliTrend/ZabbixApi;Version:'. Zabbixapi::VERSION; 433 | 434 | // required starting with Zabbix 7.2 435 | if ($useAuth) { 436 | $headers[] = 'Authorization: Bearer '.$this->authKey; 437 | } 438 | 439 | $opts = array( 440 | // allow to return a curl handle 441 | CURLOPT_RETURNTRANSFER => true, 442 | // max number of seconds to allow curl to process the request 443 | CURLOPT_TIMEOUT => $this->timeout, 444 | // max number of seconds to establish a connection 445 | CURLOPT_CONNECTTIMEOUT => $this->connectTimeout, 446 | // ensure the certificate itself is valid (signed by a trusted CA, the certificate chain is complete, etc.) 447 | CURLOPT_SSL_VERIFYPEER => $this->sslVerifyPeer, 448 | // 0 or 2. Ensure the host connecting to is the host named in the certificate. 449 | CURLOPT_SSL_VERIFYHOST => $this->sslVerifyHost, 450 | // follow if url has changed 451 | CURLOPT_FOLLOWLOCATION => true, 452 | // no cached connection or responses 453 | CURLOPT_FRESH_CONNECT => true 454 | ); 455 | 456 | 457 | $opts[CURLOPT_HTTPHEADER] = $headers; 458 | 459 | $opts[CURLOPT_CUSTOMREQUEST] = "POST"; 460 | $opts[CURLOPT_POSTFIELDS] = ( is_array($data) ? http_build_query($data) : $data ); 461 | 462 | // use compression 463 | $opts[CURLOPT_ENCODING] = 'gzip'; 464 | 465 | if ($this->debug) { 466 | print "DBG executeRequest(). CURL Params: ". $opts[CURLOPT_POSTFIELDS]. "\n"; 467 | } 468 | 469 | curl_setopt_array($c, $opts); 470 | // pass CAs if set 471 | if ($this->sslCaFile != '') { 472 | curl_setopt($c, CURLOPT_CAINFO, $this->sslCaFile); 473 | } 474 | 475 | $response = @curl_exec($c); 476 | $info = curl_getinfo($c); 477 | $sslErrorMsg = curl_error($c); 478 | 479 | $httpCode = $info['http_code']; 480 | $sslVerifyResult = $info['ssl_verify_result']; 481 | 482 | if ( $httpCode == 0 || $httpCode >= 400) { 483 | throw new ZabbixApiException("Request failed with HTTP-Code:$httpCode, sslVerifyResult:$sslVerifyResult. $sslErrorMsg", $httpCode); 484 | } 485 | 486 | 487 | if ( $sslVerifyResult != 0 && $this->sslVerifyPeer == 1) { 488 | $error = curl_error($c); 489 | throw new ZabbixApiException("Request failed with SSL-Verify-Result:$sslVerifyResult. $sslErrorMsg", $sslVerifyResult); 490 | } 491 | 492 | curl_close($c); 493 | return $response; 494 | } 495 | 496 | 497 | /** 498 | * Read encrypted authKey from session-file, decrpyt and save it in the class instance 499 | * 500 | * @return string authKey. Empty string '' if authKey was not found. 501 | */ 502 | protected function readAuthKeyFromSession() { 503 | $sessionFile = $this->getSessionFile(); 504 | 505 | // if no session exist simply return 506 | $fh = @fopen($sessionFile, "r"); 507 | if ($fh == false) { 508 | if ($this->debug) { 509 | print "DBG readAuthKeyFromSession(). sessionFile not found. sessionFile:$sessionFile\n"; 510 | } 511 | return ''; 512 | } 513 | 514 | $encryptedKey = fread($fh, filesize($sessionFile)); 515 | if (!$encryptedKey) { 516 | return ''; 517 | } 518 | 519 | fclose($fh); 520 | 521 | $authKey = $this->decryptAuthKey($encryptedKey); 522 | 523 | if (!$authKey) { 524 | if ($this->debug) { 525 | print "DBG readAuthKeyFromSession(). Decrypting authKey from sessionFile failed. sessionFile:$sessionFile\n"; 526 | } 527 | $this->authKey = ''; 528 | return NULL; 529 | } 530 | 531 | 532 | if ($this->debug) { 533 | print "DBG readAuthKeyFromSession(). Read authKey:$authKey from sessionFile:$sessionFile\n"; 534 | } 535 | 536 | // save to class instance 537 | $this->authKey = $authKey; 538 | return $authKey; 539 | } 540 | 541 | 542 | /** 543 | * Write authKey encrypted to the session-file 544 | * 545 | * @return true 546 | * @throws exeception 547 | */ 548 | protected function writeAuthKeyToSession() { 549 | //write content 550 | $sessionFile = $this->getSessionFile(); 551 | 552 | $fh = fopen($sessionFile, "w"); 553 | if ($fh == false) { 554 | throw new ZabbixApiException("Cannot open sessionFile. sessionFile:$sessionFile", ZabbixApi::EXCEPTION_CLASS_CODE); 555 | } 556 | 557 | $encryptedKey = $this->encryptAuthKey($this->authKey); 558 | 559 | if (fwrite($fh, $encryptedKey) == false) { 560 | throw new ZabbixApiException("Cannot write encrypted authKey to sessionFile. sessionFile:$sessionFile", ZabbixApi::EXCEPTION_CLASS_CODE); 561 | } 562 | 563 | fclose($fh); 564 | 565 | if ($this->debug) { 566 | print "DBG writeAuthKeyToSession(). Saved encrypted authKey:$encryptedKey to sessionFile:$sessionFile\n"; 567 | } 568 | 569 | return true; 570 | } 571 | 572 | 573 | /** 574 | * Encrypt authKey 575 | * 576 | * @param string $authKey (plain) 577 | * @return string $encryptedKey 578 | */ 579 | protected function encryptAuthKey($authKey) { 580 | $encryptedAuthKey = base64_encode(openssl_encrypt( 581 | $authKey, 582 | "aes-128-cbc", 583 | hash("SHA256", $this->zabUser. $this->zabPassword, true), 584 | OPENSSL_RAW_DATA, 585 | "1356647968472110" 586 | )); 587 | 588 | return $encryptedAuthKey; 589 | } 590 | 591 | 592 | /** 593 | * Decrypt authKey 594 | * 595 | * @param string $encryptedAuthKey 596 | * @return string $authKey. If decryption fails key is empty "" 597 | */ 598 | protected function decryptAuthKey($encryptedAuthKey) { 599 | $authKey = openssl_decrypt(base64_decode($encryptedAuthKey), 600 | "aes-128-cbc", 601 | hash("SHA256", $this->zabUser. $this->zabPassword, true), 602 | OPENSSL_RAW_DATA, 603 | "1356647968472110" 604 | ); 605 | 606 | return $authKey; 607 | } 608 | 609 | /** 610 | * Internal function to apply options from an associative array. 611 | */ 612 | protected function applyOptions($options) { 613 | $validOptions = array('debug', 'sessionDir', 'sslCaFile', 'sslVerifyHost', 'sslVerifyPeer', 'useGzip', 'timeout', 'connectTimeout'); 614 | foreach ($options as $k => $v) { 615 | if (!in_array($k, $validOptions)) { 616 | throw new ZabbixApiException("Invalid option used. option:$k", ZabbixApi::EXCEPTION_CLASS_CODE); 617 | } 618 | } 619 | 620 | 621 | if (array_key_exists('debug', $options)) { 622 | $this->debug = $options['debug'] && true; 623 | } 624 | 625 | if ($this->debug) { 626 | print "DBG login(). Using zabUser:$this->zabUser, zabUrl:$this->zabUrl\n"; 627 | print "DBG login(). Library Version:". ZabbixApi::VERSION. "\n"; 628 | } 629 | 630 | if (array_key_exists('sslCaFile', $options)) { 631 | if (!is_file($options['sslCaFile'])) { 632 | throw new ZabbixApiException("Error - sslCaFile:". $options['sslCaFile']. " is not a valid file", ZabbixApi::EXCEPTION_CLASS_CODE); 633 | } 634 | $this->sslCaFile = $options['sslCaFile']; 635 | } 636 | 637 | if (array_key_exists('sslVerifyPeer', $options)) { 638 | $this->sslVerifyPeer = ($options['sslVerifyPeer']) ? 1 : 0; 639 | } 640 | 641 | if (array_key_exists('sslVerifyHost', $options)) { 642 | $this->sslVerifyHost = ($options['sslVerifyHost']) ? 2 : 0; 643 | } 644 | 645 | if (array_key_exists('useGzip', $options)) { 646 | $this->useGzip = ($options['useGzip']) ? true : false; 647 | } 648 | 649 | if (array_key_exists('timeout', $options)) { 650 | $this->timeout = (intval($options['timeout']) > 0)? $options['timeout'] : 30; 651 | } 652 | 653 | if (array_key_exists('connectTimeout', $options)) { 654 | $this->connectTimeout = (intval($options['connectTimeout']) > 0)? $options['connectTimeout'] : 30; 655 | } 656 | 657 | if ($this->debug) { 658 | print "DBG login(). Using sslVerifyPeer:". $this->sslVerifyPeer . " sslVerifyHost:". $this->sslVerifyHost. " useGzip:". $this->useGzip. " timeout:". $this->timeout. " connectTimeout:". $this->connectTimeout. "\n"; 659 | } 660 | } 661 | } --------------------------------------------------------------------------------