<?php /* ** Copyright (C) 2001-2025 Zabbix SIA ** ** This program is free software: you can redistribute it and/or modify it under the terms of ** the GNU Affero General Public License as published by the Free Software Foundation, version 3. ** ** 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 Affero General Public License for more details. ** ** You should have received a copy of the GNU Affero General Public License along with this program. ** If not, see <https://www.gnu.org/licenses/>. **/ require_once __DIR__.'/../include/CAPITest.php'; /** * @backup ids * * @onBefore prepareTestData * @onAfter clearData */ class testProxy extends CAPITest { /** * Non-existent ID, type, status etc. */ private const INVALID_NUMBER = 999999; /** * @var array */ private static array $data = [ 'proxy_groupids' => [], 'proxyids' => [], 'groupids' => [], 'hostids' => [], 'actionids' => [], 'druleids' => [], // Created proxies during proxy.create test (deleted at the end). 'created' => [] ]; /** * Prepare data for tests. Create proxy groups, proxies, host groups, hosts, actions, discovery rules. */ public function prepareTestData(): void { $this->prepareTestDataProxyGroups(); $this->prepareTestDataProxies(); $this->prepareTestDataHostGroups(); $this->prepareTestDataHosts(); $this->prepareTestDataActions(); $this->prepareTestDataDiscoveryRules(); } /** * Create proxy groups. */ private function prepareTestDataProxyGroups(): void { $proxy_groups = [ 'empty' => [ 'name' => 'API test proxy - empty' ], 'with_1_proxy' => [ 'name' => 'API test proxy - with 1 proxy' ], 'with_3_proxies' => [ 'name' => 'API test proxy - with 3 proxies' ] ]; $db_proxy_groups = CDataHelper::call('proxygroup.create', array_values($proxy_groups)); $this->assertArrayHasKey('proxy_groupids', $db_proxy_groups, __FUNCTION__.'() failed: Could not create proxy groups.' ); self::$data['proxy_groupids'] = array_combine(array_keys($proxy_groups), $db_proxy_groups['proxy_groupids']); } /** * Create proxies. */ private function prepareTestDataProxies(): void { $proxies = [ 'active_defaults' => [ 'name' => 'API test proxy - active with defaults', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE ], 'active_psk' => [ 'name' => 'API test proxy - active with PSK-based connections from proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'tls_accept' => HOST_ENCRYPTION_PSK, 'tls_psk_identity' => 'Test PSK', 'tls_psk' => '9b8eafedfaae00cece62e85d5f4792c7d9c9bcc851b23216a1d300311cc4f7cb' ], 'active_cert' => [ 'name' => 'API test proxy - active with certificate-based connections from proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'tls_accept' => HOST_ENCRYPTION_CERTIFICATE ], 'active_any' => [ 'name' => 'API test proxy - active with any connections from proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'tls_accept' => HOST_ENCRYPTION_NONE + HOST_ENCRYPTION_PSK + HOST_ENCRYPTION_CERTIFICATE, 'tls_psk_identity' => 'Test PSK', 'tls_psk' => '9b8eafedfaae00cece62e85d5f4792c7d9c9bcc851b23216a1d300311cc4f7cb' ], 'passive_defaults' => [ 'name' => 'API test proxy - passive with defaults', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => '127.0.0.1', 'port' => '10050' ], 'passive_dns' => [ 'name' => 'API test proxy - passive with DNS name', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => 'localhost', 'port' => '10050' ], 'passive_ip' => [ 'name' => 'API test proxy - passive with IP address', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => '127.0.0.1', 'port' => '10050' ], 'passive_psk' => [ 'name' => 'API test proxy - passive with PSK-based connections to proxy', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => '127.0.0.1', 'port' => '10050', 'tls_connect' => HOST_ENCRYPTION_PSK, 'tls_psk_identity' => 'proxyidentity', 'tls_psk' => '486a9e7b43740b3619e42636cb1c24bf' ], 'passive_cert' => [ 'name' => 'API test proxy - passive with certificate-based connections to proxy', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => '127.0.0.1', 'port' => '10050', 'tls_connect' => HOST_ENCRYPTION_CERTIFICATE ], 'without_proxy_group' => [ 'name' => 'API test proxy - without proxy group', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE ], 'with_proxy_group' => [ 'name' => 'API test proxy - with proxy group', 'proxy_groupid' => self::$data['proxy_groupids']['with_1_proxy'], 'local_address' => 'localhost', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE ], 'with_proxy_group_1' => [ 'name' => 'API test proxy - with proxy group 1', 'proxy_groupid' => self::$data['proxy_groupids']['with_3_proxies'], 'local_address' => 'proxy1.lan', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE ], 'with_proxy_group_2' => [ 'name' => 'API test proxy - with proxy group 2', 'proxy_groupid' => self::$data['proxy_groupids']['with_3_proxies'], 'local_address' => 'proxy2.lan', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE ], 'with_proxy_group_3' => [ 'name' => 'API test proxy - with proxy group 3', 'proxy_groupid' => self::$data['proxy_groupids']['with_3_proxies'], 'local_address' => 'proxy3.lan', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE ], 'with_custom_timeouts' => [ 'name' => 'API test proxy - with custom timeouts', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '10s', 'timeout_simple_check' => '10s', 'timeout_snmp_agent' => '10s', 'timeout_external_check' => '10s', 'timeout_db_monitor' => '10s', 'timeout_http_agent' => '10s', 'timeout_ssh_agent' => '10s', 'timeout_telnet_agent' => '10s', 'timeout_script' => '10s', 'timeout_browser' => '10s' ], 'version_undefined' => [ 'name' => 'API test proxy - version undefined', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE ], 'version_current' => [ 'name' => 'API test proxy - version current', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE ], 'version_outdated' => [ 'name' => 'API test proxy - version outdated', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE ], 'version_unsupported' => [ 'name' => 'API test proxy - version unsupported', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE ], 'version_current_with_custom_timeouts' => [ 'name' => 'API test proxy - version current and custom timeouts enabled', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '10s', 'timeout_simple_check' => '10s', 'timeout_snmp_agent' => '10s', 'timeout_external_check' => '10s', 'timeout_db_monitor' => '10s', 'timeout_http_agent' => '10s', 'timeout_ssh_agent' => '10s', 'timeout_telnet_agent' => '10s', 'timeout_script' => '10s', 'timeout_browser' => '10s' ], 'state_unknown' => [ 'name' => 'API test proxy - state unknown', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE ], 'state_offline' => [ 'name' => 'API test proxy - state offline', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE ], 'state_online' => [ 'name' => 'API test proxy - state online', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE ], 'used_in_action' => [ 'name' => 'API test proxy - used in action', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE ], 'used_in_discovery_rule' => [ 'name' => 'API test proxy - used in discovery rule', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE ], 'filter_tests' => [ 'name' => 'Filtered proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'allowed_addresses' => '192.168.15.15', 'tls_accept' => HOST_ENCRYPTION_NONE | HOST_ENCRYPTION_PSK | HOST_ENCRYPTION_CERTIFICATE, 'tls_psk_identity' => 'Test PSK', 'tls_psk' => '9b8eafedfaae00cece62e85d5f4792c7d9c9bcc851b23216a1d300311cc4f7cb' ] ]; $db_proxies = CDataHelper::call('proxy.create', array_values($proxies)); $this->assertArrayHasKey('proxyids', $db_proxies, __FUNCTION__.'() failed: Could not create proxies.'); self::$data['proxyids'] = array_combine(array_keys($proxies), $db_proxies['proxyids']); // Manually update "proxy_rtdata" table. $proxy_rtdata = [ 'version_current' => [ 'lastaccess' => 1693391880, 'version' => 70000, 'compatibility' => ZBX_PROXY_VERSION_CURRENT ], 'version_outdated' => [ 'lastaccess' => 1693391875, 'version' => 60400, 'compatibility' => ZBX_PROXY_VERSION_OUTDATED ], 'version_unsupported' => [ 'lastaccess' => 1693391870, 'version' => 60201, 'compatibility' => ZBX_PROXY_VERSION_UNSUPPORTED ], 'version_current_with_custom_timeouts' => [ 'lastaccess' => 1693391895, 'version' => 70000, 'compatibility' => ZBX_PROXY_VERSION_CURRENT ], 'state_unknown' => [ 'state' => ZBX_PROXY_STATE_UNKNOWN ], 'state_offline' => [ 'state' => ZBX_PROXY_STATE_OFFLINE ], 'state_online' => [ 'state' => ZBX_PROXY_STATE_ONLINE ] ]; $upd_proxy_rtdata = []; foreach ($proxy_rtdata as $id_placeholder => $rtdata) { $upd_proxy_rtdata[] = [ 'values' => $rtdata, 'where' => ['proxyid' => self::$data['proxyids'][$id_placeholder]] ]; } DB::update('proxy_rtdata', $upd_proxy_rtdata); } /** * Create host groups. */ private function prepareTestDataHostGroups(): void { $db_hostgroups = CDataHelper::call('hostgroup.create', [ 'name' => 'API test proxy - host group' ]); $this->assertArrayHasKey('groupids', $db_hostgroups, __FUNCTION__.'() failed: Could not create host groups.'); self::$data['groupids'] = $db_hostgroups['groupids']; } /** * Create hosts. */ private function prepareTestDataHosts(): void { $hosts = [ 'monitored_by_server_1' => [ 'host' => 'host_monitored_by_server_1', 'name' => 'API test proxy - monitored by server 1', 'groups' => [ [ 'groupid' => self::$data['groupids'][0] ] ] ], 'monitored_by_server_2' => [ 'host' => 'host_monitored_by_server_2', 'name' => 'API test proxy - monitored by server 2', 'groups' => [ [ 'groupid' => self::$data['groupids'][0] ] ] ], 'monitored_by_proxy_without_group' => [ 'host' => 'host_monitored_by_proxy_without_group', 'name' => 'API test proxy - monitored by proxy without group', 'monitored_by' => ZBX_MONITORED_BY_PROXY, 'proxyid' => self::$data['proxyids']['without_proxy_group'], 'groups' => [ [ 'groupid' => self::$data['groupids'][0] ] ] ], 'monitored_by_proxy_with_group' => [ 'host' => 'host_monitored_by_proxy_with_group', 'name' => 'API test proxy - monitored by proxy with group', 'monitored_by' => ZBX_MONITORED_BY_PROXY, 'proxyid' => self::$data['proxyids']['with_proxy_group'], 'groups' => [ [ 'groupid' => self::$data['groupids'][0] ] ] ], 'monitored_by_empty_proxy_group' => [ 'host' => 'host_monitored_by_empty_proxy_group', 'name' => 'API test proxy - monitored by empty proxy group', 'monitored_by' => ZBX_MONITORED_BY_PROXY_GROUP, 'proxy_groupid' => self::$data['proxy_groupids']['empty'], 'groups' => [ [ 'groupid' => self::$data['groupids'][0] ] ] ], 'monitored_by_proxy_group' => [ 'host' => 'host_monitored_by_proxy_group', 'name' => 'API test proxy - monitored by proxy group', 'monitored_by' => ZBX_MONITORED_BY_PROXY_GROUP, 'proxy_groupid' => self::$data['proxy_groupids']['with_3_proxies'], 'groups' => [ [ 'groupid' => self::$data['groupids'][0] ] ] ] ]; $db_hosts = CDataHelper::call('host.create', array_values($hosts)); $this->assertArrayHasKey('hostids', $db_hosts, __FUNCTION__.'() failed: Could not create hosts.'); self::$data['hostids'] = array_combine(array_keys($hosts), $db_hosts['hostids']); // Manually insert data into "host_proxy" table. $host_proxy = [ [ 'hostid' => self::$data['hostids']['monitored_by_proxy_group'], 'proxyid' => self::$data['proxyids']['with_proxy_group_2'] ] ]; DB::insert('host_proxy', $host_proxy); } /** * Create actions. */ private function prepareTestDataActions(): void { $actions = [ 'name' => 'API test proxy - discovery action', 'eventsource' => EVENT_SOURCE_DISCOVERY, 'filter' => [ 'evaltype' => CONDITION_EVAL_TYPE_AND_OR, 'conditions' => [ [ 'conditiontype' => ZBX_CONDITION_TYPE_PROXY, 'operator' => CONDITION_OPERATOR_EQUAL, 'value' => self::$data['proxyids']['used_in_action'] ] ] ], 'operations' => [ [ 'operationtype' => OPERATION_TYPE_MESSAGE, 'opmessage_grp' => [ [ 'usrgrpid' => 7 ] ], 'opmessage' => [ 'mediatypeid' => 0, 'default_msg' => 1 ] ] ] ]; $db_actions = CDataHelper::call('action.create', $actions); $this->assertArrayHasKey('actionids', $db_actions, __FUNCTION__.'() failed: Could not create actions.'); self::$data['actionids'] = $db_actions['actionids']; } /** * Create discovery rules. */ private function prepareTestDataDiscoveryRules(): void { $drules = [ 'name' => 'API test proxy - discovery rule', 'iprange' => '192.168.1.1-255', 'proxyid' => self::$data['proxyids']['used_in_discovery_rule'], 'dchecks' => [ [ 'type' => SVC_AGENT, 'key_' => 'system.uname', 'ports' => 10050, 'uniq' => 0 ] ] ]; $db_drules = CDataHelper::call('drule.create', $drules); $this->assertArrayHasKey('druleids', $db_drules, __FUNCTION__.'() failed: Could not create discovery rules.'); self::$data['druleids'] = $db_drules['druleids']; } /** * Data provider for proxy.get. Array contains invalid proxy parameters. * * @return array */ public static function getProxyGetDataInvalid(): array { return [ // Check unexpected params. 'Test proxy.get: unexpected parameter' => [ 'request' => [ 'abc' => 'abc' ], 'expected_result' => [], 'expected_error' => 'Invalid parameter "/": unexpected parameter "abc".' ], // Check "proxyids" field. 'Test proxy.get: invalid "proxyids" (empty string)' => [ 'request' => [ 'proxyids' => '' ], 'expected_result' => [], 'expected_error' => 'Invalid parameter "/proxyids": an array is expected.' ], 'Test proxy.get: invalid "proxyids" (array with empty string)' => [ 'request' => [ 'proxyids' => [''] ], 'expected_result' => [], 'expected_error' => 'Invalid parameter "/proxyids/1": a number is expected.' ], // Check "proxy_groupids" field. 'Test proxy.get: invalid "proxy_groupids" (empty string)' => [ 'request' => [ 'proxy_groupids' => '' ], 'expected_result' => [], 'expected_error' => 'Invalid parameter "/proxy_groupids": an array is expected.' ], 'Test proxy.get: invalid "proxy_groupids" (array with empty string)' => [ 'request' => [ 'proxy_groupids' => [''] ], 'expected_result' => [], 'expected_error' => 'Invalid parameter "/proxy_groupids/1": a number is expected.' ], // Check filter. 'Test proxy.get: invalid "filter" (empty string)' => [ 'request' => [ 'filter' => '' ], 'expected_result' => [], 'expected_error' => 'Invalid parameter "/filter": an array is expected.' ], // Check unexpected parameters that exist in object, but not in filter. 'Test proxy.get: unexpected parameter in "filter"' => [ 'request' => [ 'filter' => [ 'description' => 'description' ] ], 'expected_result' => [], 'expected_error' => 'Invalid parameter "/filter": unexpected parameter "description".' ], 'Test proxy.get filter: invalid param `hostid`' => [ 'request' => [ 'output' => ['name'], 'filter' => [ 'hostid' => 123 ] ], 'expected_result' => [], 'expected_error' => 'Invalid parameter "/filter": unexpected parameter "hostid".' ], 'Test proxy.get filter: invalid param `tls_psk`' => [ 'request' => [ 'output' => ['name'], 'filter' => [ 'tls_psk' => 'Test PSK' ] ], 'expected_result' => [], 'expected_error' => 'Invalid parameter "/filter": unexpected parameter "tls_psk".' ], 'Test proxy.get filter: invalid param `tls_psk_identity`' => [ 'request' => [ 'output' => ['name'], 'filter' => [ 'tls_psk_identity' => 'Test PSK' ] ], 'expected_result' => [], 'expected_error' => 'Invalid parameter "/filter": unexpected parameter "tls_psk_identity".' ], 'Test proxy.get filter: allowed_addresses' => [ 'request' => [ 'output' => ['name'], 'filter' => [ 'allowed_addresses' => '192.168.15.15' ] ], 'expected_result' => [ ['name' => 'Filtered proxy'] ], 'expected_error' => null ], 'Test proxy.get filter: tls_accept' => [ 'request' => [ 'output' => ['name'], 'filter' => [ 'tls_accept' => HOST_ENCRYPTION_NONE | HOST_ENCRYPTION_PSK | HOST_ENCRYPTION_CERTIFICATE ], 'search' => [ 'name' => 'Filtered' ] ], 'expected_result' => [ ['name' => 'Filtered proxy'] ], 'expected_error' => null ], // Check "search" option. 'Test proxy.get: invalid "search" (string)' => [ 'request' => [ 'search' => 'abc' ], 'expected_result' => [], 'expected_error' => 'Invalid parameter "/search": an array is expected.' ], // Check unexpected parameters that exist in object, but not in search. 'Test proxy.get: unexpected parameter in "search"' => [ 'request' => [ 'search' => [ 'proxyid' => 'proxyid' ] ], 'expected_result' => [], 'expected_error' => 'Invalid parameter "/search": unexpected parameter "proxyid".' ], // Check "output" option. 'Test proxy.get: invalid parameter "output" (string)' => [ 'request' => [ 'output' => 'abc' ], 'expected_result' => [], 'expected_error' => 'Invalid parameter "/output": value must be "extend".' ], 'Test proxy.get: unexpected parameter in "output"' => [ 'request' => [ 'output' => ['abc'] ], 'expected_result' => [], 'expected_error' => 'Invalid parameter "/output/1": value must be one of "proxyid", "name", "proxy_groupid", "local_address", "local_port", "operating_mode", "allowed_addresses", "address", "port", "description", "tls_connect", "tls_accept", "tls_issuer", "tls_subject", "custom_timeouts", "timeout_zabbix_agent", "timeout_simple_check", "timeout_snmp_agent", "timeout_external_check", "timeout_db_monitor", "timeout_http_agent", "timeout_ssh_agent", "timeout_telnet_agent", "timeout_script", "timeout_browser", "lastaccess", "version", "compatibility", "state".' ], // Check write-only fields are not returned. 'Test proxy.get: write-only field "tls_psk_identity"' => [ 'request' => [ 'output' => ['tls_psk_identity'] ], 'expected_result' => [], 'expected_error' => 'Invalid parameter "/output/1": value must be one of "proxyid", "name", "proxy_groupid", "local_address", "local_port", "operating_mode", "allowed_addresses", "address", "port", "description", "tls_connect", "tls_accept", "tls_issuer", "tls_subject", "custom_timeouts", "timeout_zabbix_agent", "timeout_simple_check", "timeout_snmp_agent", "timeout_external_check", "timeout_db_monitor", "timeout_http_agent", "timeout_ssh_agent", "timeout_telnet_agent", "timeout_script", "timeout_browser", "lastaccess", "version", "compatibility", "state".' ], 'Test proxy.get: write-only field "tls_psk"' => [ 'request' => [ 'output' => ['tls_psk'] ], 'expected_result' => [], 'expected_error' => 'Invalid parameter "/output/1": value must be one of "proxyid", "name", "proxy_groupid", "local_address", "local_port", "operating_mode", "allowed_addresses", "address", "port", "description", "tls_connect", "tls_accept", "tls_issuer", "tls_subject", "custom_timeouts", "timeout_zabbix_agent", "timeout_simple_check", "timeout_snmp_agent", "timeout_external_check", "timeout_db_monitor", "timeout_http_agent", "timeout_ssh_agent", "timeout_telnet_agent", "timeout_script", "timeout_browser", "lastaccess", "version", "compatibility", "state".' ], // Check "selectAssignedHosts" option. 'Test proxy.get: invalid parameter "selectAssignedHosts" (string)' => [ 'request' => [ 'selectAssignedHosts' => 'abc' ], 'expected_result' => [], 'expected_error' => 'Invalid parameter "/selectAssignedHosts": value must be one of "extend", "count".' ], 'Test proxy.get: unexpected parameter in "selectAssignedHosts"' => [ 'request' => [ 'selectAssignedHosts' => ['abc'] ], 'expected_result' => [], 'expected_error' => 'Invalid parameter "/selectAssignedHosts/1": value must be one of "hostid", "host", "monitored_by", "status", "ipmi_authtype", "ipmi_privilege", "ipmi_username", "ipmi_password", "maintenanceid", "maintenance_status", "maintenance_type", "maintenance_from", "name", "flags", "description", "tls_connect", "tls_accept", "tls_issuer", "tls_subject", "inventory_mode", "active_available".' ], // Check "selectHosts" option. 'Test proxy.get: invalid parameter "selectHosts" (string)' => [ 'request' => [ 'selectHosts' => 'abc' ], 'expected_result' => [], 'expected_error' => 'Invalid parameter "/selectHosts": value must be one of "extend", "count".' ], 'Test proxy.get: unexpected parameter in "selectHosts"' => [ 'request' => [ 'selectHosts' => ['abc'] ], 'expected_result' => [], 'expected_error' => 'Invalid parameter "/selectHosts/1": value must be one of "hostid", "host", "monitored_by", "status", "ipmi_authtype", "ipmi_privilege", "ipmi_username", "ipmi_password", "maintenanceid", "maintenance_status", "maintenance_type", "maintenance_from", "name", "flags", "description", "tls_connect", "tls_accept", "tls_issuer", "tls_subject", "inventory_mode", "active_available".' ], // Check common fields that are not flags, but require strict validation. 'Test proxy.get: invalid parameter "searchByAny" (string)' => [ 'request' => [ 'searchByAny' => 'abc' ], 'expected_result' => [], 'expected_error' => 'Invalid parameter "/searchByAny": a boolean is expected.' ], 'Test proxy.get: invalid parameter "searchWildcardsEnabled" (string)' => [ 'request' => [ 'searchWildcardsEnabled' => 'abc' ], 'expected_result' => [], 'expected_error' => 'Invalid parameter "/searchWildcardsEnabled": a boolean is expected.' ], 'Test proxy.get: invalid parameter "sortfield" (boolean)' => [ 'request' => [ 'sortfield' => false ], 'expected_result' => [], 'expected_error' => 'Invalid parameter "/sortfield": an array is expected.' ], 'Test proxy.get: invalid parameter "sortfield"' => [ 'request' => [ 'sortfield' => 'abc' ], 'expected_result' => [], 'expected_error' => 'Invalid parameter "/sortfield/1": value must be one of "proxyid", "name", "operating_mode".' ], 'Test proxy.get: invalid parameter "sortorder" (boolean)' => [ 'request' => [ 'sortorder' => false ], 'expected_result' => [], 'expected_error' => 'Invalid parameter "/sortorder": an array or a character string is expected.' ], 'Test proxy.get: invalid parameter "sortorder" (not in range)' => [ 'request' => [ 'sortorder' => 'abc' ], 'expected_result' => [], 'expected_error' => 'Invalid parameter "/sortorder": value must be one of "'.ZBX_SORT_UP.'", "'.ZBX_SORT_DOWN.'".' ], 'Test proxy.get: invalid parameter "limit" (boolean)' => [ 'request' => [ 'limit' => false ], 'expected_result' => [], 'expected_error' => 'Invalid parameter "/limit": an integer is expected.' ], 'Test proxy.get: invalid parameter "editable" (string)' => [ 'request' => [ 'editable' => 'abc' ], 'expected_result' => [], 'expected_error' => 'Invalid parameter "/editable": a boolean is expected.' ], 'Test proxy.get: invalid parameter "preservekeys" (string)' => [ 'request' => [ 'preservekeys' => 'abc' ], 'expected_result' => [], 'expected_error' => 'Invalid parameter "/preservekeys": a boolean is expected.' ] ]; } /** * Data provider for proxy.get. Array contains valid proxy parameters. * * @return array */ public static function getProxyGetDataValid(): array { return [ // Check validity of "proxyids" without getting any results. 'Test proxy.get: empty "proxyids"' => [ 'request' => [ 'proxyids' => [] ], 'expected_result' => [], 'expected_error' => null ], // Check no fields are returned on empty selection. 'Test proxy.get: empty "output"' => [ 'request' => [ 'output' => [], 'proxyids' => ['active_defaults', 'passive_defaults'] ], 'expected_result' => [ [], [] ], 'expected_error' => null ], // Check fields from "proxy_rtdata" table are returned. 'Test proxy.get: "lastaccess", "version", "compatibility"' => [ 'request' => [ 'output' => ['lastaccess', 'version', 'compatibility'], 'proxyids' => ['version_current', 'version_outdated', 'version_unsupported'] ], 'expected_result' => [ [ 'lastaccess' => '1693391880', 'version' => '70000', 'compatibility' => '1' ], [ 'lastaccess' => '1693391875', 'version' => '60400', 'compatibility' => '2' ], [ 'lastaccess' => '1693391870', 'version' => '60201', 'compatibility' => '3' ] ], 'expected_error' => null ], 'Test proxy.get: "state"' => [ 'request' => [ 'output' => ['name', 'state'], 'proxyids' => ['state_unknown', 'state_offline', 'state_online'] ], 'expected_result' => [ [ 'name' => 'API test proxy - state unknown', 'state' => '0' ], [ 'name' => 'API test proxy - state offline', 'state' => '1' ], [ 'name' => 'API test proxy - state online', 'state' => '2' ] ], 'expected_error' => null ], // Filter by "proxyid". 'Test proxy.get: filter by "proxyid"' => [ 'request' => [ 'output' => ['name'], 'filter' => [ 'proxyid' => 'active_defaults' ] ], 'expected_result' => [ [ 'name' => 'API test proxy - active with defaults' ] ], 'expected_error' => null ], // Filter by "proxy_groupid". 'Test proxy.get: filter by "proxy_groupid"' => [ 'request' => [ 'output' => ['name'], 'filter' => [ 'proxy_groupid' => 'with_1_proxy' ] ], 'expected_result' => [ [ 'name' => 'API test proxy - with proxy group' ] ], 'expected_error' => null ], // Filter by proxy operating mode. 'Test proxy.get: filter by "operating_mode"' => [ 'request' => [ 'output' => ['name', 'operating_mode'], 'proxyids' => ['active_defaults', 'passive_defaults'], 'filter' => [ 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE ] ], 'expected_result' => [ [ 'name' => 'API test proxy - active with defaults', 'operating_mode' => (string) PROXY_OPERATING_MODE_ACTIVE ] ], 'expected_error' => null ], // Filter by "custom_timeouts". 'Test proxy.get: filter by "with_custom_timeouts"' => [ 'request' => [ 'output' => ['name', 'custom_timeouts', 'timeout_zabbix_agent'], 'proxyids' => ['active_defaults', 'passive_defaults', 'with_custom_timeouts'], 'filter' => [ 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED ] ], 'expected_result' => [ [ 'name' => 'API test proxy - with custom timeouts', 'custom_timeouts' => (string) ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '10s' ] ], 'expected_error' => null ], // Filter by "timeout_zabbix_agent". 'Test proxy.get: filter by "timeout_zabbix_agent"' => [ 'request' => [ 'output' => ['name', 'timeout_zabbix_agent'], 'proxyids' => ['active_defaults', 'passive_defaults', 'with_custom_timeouts'], 'filter' => [ 'timeout_zabbix_agent' => '10s' ] ], 'expected_result' => [ [ 'name' => 'API test proxy - with custom timeouts', 'timeout_zabbix_agent' => '10s' ] ], 'expected_error' => null ], // Filter by Zabbix version. 'Test proxy.get: filter by "version"' => [ 'request' => [ 'output' => ['name', 'version'], 'proxyids' => ['version_current', 'version_outdated', 'version_unsupported'], 'filter' => [ 'version' => ['60200', '60400', '70000'] ] ], 'expected_result' => [ [ 'name' => 'API test proxy - version current', 'version' => '70000' ], [ 'name' => 'API test proxy - version outdated', 'version' => '60400' ] ], 'expected_error' => null ], // Filter by version compatibility. 'Test proxy.get: filter by "compatibility"' => [ 'request' => [ 'output' => ['name', 'compatibility'], 'proxyids' => ['version_current', 'version_outdated', 'version_unsupported'], 'filter' => [ 'compatibility' => [ZBX_PROXY_VERSION_OUTDATED, ZBX_PROXY_VERSION_UNSUPPORTED] ] ], 'expected_result' => [ [ 'name' => 'API test proxy - version outdated', 'compatibility' => (string) ZBX_PROXY_VERSION_OUTDATED ], [ 'name' => 'API test proxy - version unsupported', 'compatibility' => (string) ZBX_PROXY_VERSION_UNSUPPORTED ] ], 'expected_error' => null ], // Filter by "state". 'Test proxy.get: filter by "state"' => [ 'request' => [ 'output' => ['name', 'state'], 'proxyids' => ['state_unknown', 'state_offline', 'state_online'], 'filter' => [ 'state' => [ZBX_PROXY_STATE_OFFLINE, ZBX_PROXY_STATE_ONLINE] ] ], 'expected_result' => [ [ 'name' => 'API test proxy - state offline', 'state' => (string) ZBX_PROXY_STATE_OFFLINE ], [ 'name' => 'API test proxy - state online', 'state' => (string) ZBX_PROXY_STATE_ONLINE ] ], 'expected_error' => null ], // Search by proxy name. 'Test proxy.get: search by "name"' => [ 'request' => [ 'output' => ['name'], 'search' => [ 'name' => 'API test proxy - active' ], 'sortfield' => 'proxyid' ], 'expected_result' => [ ['name' => 'API test proxy - active with defaults'], ['name' => 'API test proxy - active with PSK-based connections from proxy'], ['name' => 'API test proxy - active with certificate-based connections from proxy'], ['name' => 'API test proxy - active with any connections from proxy'] ], 'expected_error' => null ], // Filtering by incorrect data types. 'Test proxy.get: invalid "operating_mode" (string) in "filter"' => [ 'request' => [ 'filter' => [ 'operating_mode' => 'abc' ] ], 'expected_result' => [], 'expected_error' => null ], 'Test proxy.get: invalid "operating_mode" in "filter"' => [ 'request' => [ 'filter' => [ 'operating_mode' => self::INVALID_NUMBER ] ], 'expected_result' => [], 'expected_error' => null ], 'Test proxy.get: invalid "lastaccess" (string) in "filter"' => [ 'request' => [ 'filter' => [ 'lastaccess' => 'abc' ] ], 'expected_result' => [], 'expected_error' => null ], 'Test proxy.get: invalid "lastaccess" (array with string) in "filter"' => [ 'request' => [ 'filter' => [ 'lastaccess' => ['abc'] ] ], 'expected_result' => [], 'expected_error' => null ], 'Test proxy.get: invalid "lastaccess" (not in range) in "filter"' => [ 'request' => [ 'filter' => [ 'lastaccess' => [-1] ] ], 'expected_result' => [], 'expected_error' => null ], 'Test proxy.get: invalid "lastaccess" (too large) in "filter"' => [ 'request' => [ 'filter' => [ 'lastaccess' => [ZBX_MAX_DATE + 1] ] ], 'expected_result' => [], 'expected_error' => null ], 'Test proxy.get: invalid "compatibility" (string) for "filter"' => [ 'request' => [ 'filter' => [ 'compatibility' => 'abc' ] ], 'expected_result' => [], 'expected_error' => null ], 'Test proxy.get: invalid "compatibility" (not in range) for "filter"' => [ 'request' => [ 'filter' => [ 'compatibility' => 999999 ] ], 'expected_result' => [], 'expected_error' => null ], // Check "selectAssignedHosts". 'Test proxy.get: selectAssignedHosts=[] excludes hostid' => [ 'request' => [ 'output' => [], 'proxyids' => 'with_proxy_group_2', 'selectAssignedHosts' => [] ], 'expected_result' => [[ 'assignedHosts' => [ [] ] ]], 'expected_error' => null ], 'Test proxy.get: selectAssignedHosts="extend" excludes proxyid, proxy_groupid, assigned_proxyid' => [ 'request' => [ 'output' => [], 'proxyids' => 'with_proxy_group_2', 'selectAssignedHosts' => API_OUTPUT_EXTEND ], 'expected_result' => [[ 'assignedHosts' => [[ 'hostid' => 'monitored_by_proxy_group', 'host' => 'host_monitored_by_proxy_group', 'monitored_by' => (string) ZBX_MONITORED_BY_PROXY_GROUP, 'status' => DB::getDefault('hosts', 'status'), 'ipmi_authtype' => DB::getDefault('hosts', 'ipmi_authtype'), 'ipmi_privilege' => DB::getDefault('hosts', 'ipmi_privilege'), 'ipmi_username' => DB::getDefault('hosts', 'ipmi_username'), 'ipmi_password' => DB::getDefault('hosts', 'ipmi_password'), 'maintenanceid' => '0', 'maintenance_status' => DB::getDefault('hosts', 'maintenance_status'), 'maintenance_type' => DB::getDefault('hosts', 'maintenance_type'), 'maintenance_from' => DB::getDefault('hosts', 'maintenance_from'), 'name' => 'API test proxy - monitored by proxy group', 'flags' => DB::getDefault('hosts', 'flags'), 'description' => DB::getDefault('hosts', 'description'), 'tls_connect' => DB::getDefault('hosts', 'tls_connect'), 'tls_accept' => DB::getDefault('hosts', 'tls_accept'), 'tls_issuer' => DB::getDefault('hosts', 'tls_issuer'), 'tls_subject' => DB::getDefault('hosts', 'tls_subject'), 'inventory_mode' => (string) HOST_INVENTORY_DISABLED, 'active_available' => '0' ]] ]], 'expected_error' => null ], 'Test proxy.get: selectAssignedHosts="count"' => [ 'request' => [ 'output' => [], 'proxyids' => 'with_proxy_group_2', 'selectAssignedHosts' => API_OUTPUT_COUNT ], 'expected_result' => [[ 'assignedHosts' => '1' ]], 'expected_error' => null ], // Check "selectHosts". 'Test proxy.get: selectHosts=[] excludes hostid' => [ 'request' => [ 'output' => [], 'proxyids' => 'without_proxy_group', 'selectHosts' => [] ], 'expected_result' => [[ 'hosts' => [ [] ] ]], 'expected_error' => null ], 'Test proxy.get: selectHosts="extend" excludes proxyid, proxy_groupid, assigned_proxyid' => [ 'request' => [ 'output' => [], 'proxyids' => 'without_proxy_group', 'selectHosts' => API_OUTPUT_EXTEND ], 'expected_result' => [[ 'hosts' => [[ 'hostid' => 'monitored_by_proxy_without_group', 'host' => 'host_monitored_by_proxy_without_group', 'monitored_by' => (string) ZBX_MONITORED_BY_PROXY, 'status' => DB::getDefault('hosts', 'status'), 'ipmi_authtype' => DB::getDefault('hosts', 'ipmi_authtype'), 'ipmi_privilege' => DB::getDefault('hosts', 'ipmi_privilege'), 'ipmi_username' => DB::getDefault('hosts', 'ipmi_username'), 'ipmi_password' => DB::getDefault('hosts', 'ipmi_password'), 'maintenanceid' => '0', 'maintenance_status' => DB::getDefault('hosts', 'maintenance_status'), 'maintenance_type' => DB::getDefault('hosts', 'maintenance_type'), 'maintenance_from' => DB::getDefault('hosts', 'maintenance_from'), 'name' => 'API test proxy - monitored by proxy without group', 'flags' => DB::getDefault('hosts', 'flags'), 'description' => DB::getDefault('hosts', 'description'), 'tls_connect' => DB::getDefault('hosts', 'tls_connect'), 'tls_accept' => DB::getDefault('hosts', 'tls_accept'), 'tls_issuer' => DB::getDefault('hosts', 'tls_issuer'), 'tls_subject' => DB::getDefault('hosts', 'tls_subject'), 'inventory_mode' => (string) HOST_INVENTORY_DISABLED, 'active_available' => '0' ]] ]], 'expected_error' => null ], 'Test proxy.get: selectHosts="count"' => [ 'request' => [ 'output' => [], 'proxyids' => 'without_proxy_group', 'selectHosts' => API_OUTPUT_COUNT ], 'expected_result' => [[ 'hosts' => '1' ]], 'expected_error' => null ], // Check "selectProxyGroup". 'Test proxy.get: selectProxyGroup' => [ 'request' => [ 'output' => [], 'proxyids' => ['without_proxy_group', 'with_proxy_group'], 'selectProxyGroup' => ['name'] ], 'expected_result' => [ [ 'proxyGroup' => [] ], [ 'proxyGroup' => [ 'name' => 'API test proxy - with 1 proxy' ] ] ], 'expected_error' => null ] ]; } /** * Test proxy.get with all options. * * @dataProvider getProxyGetDataInvalid * @dataProvider getProxyGetDataValid */ public function testProxy_Get(array $request, array $expected_result, ?string $expected_error): void { // Replace ID placeholders with real IDs. $request = self::resolveIds($request); foreach ($expected_result as &$proxy) { $proxy = self::resolveIds($proxy); } unset($proxy); $result = $this->call('proxy.get', $request, $expected_error); if ($expected_error === null) { $this->assertSame($expected_result, $result['result']); } } /** * Data provider for proxy.create. Array contains invalid proxies. * * @return array */ public static function getProxyCreateDataInvalid(): array { return [ 'Test proxy.create: empty request' => [ 'proxy' => [], 'expected_error' => 'Invalid parameter "/": cannot be empty.' ], 'Test proxy.create: unexpected parameter' => [ 'proxy' => [ 'abc' => 'abc' ], 'expected_error' => 'Invalid parameter "/1": unexpected parameter "abc".' ], // Check "name". 'Test proxy.create: missing "name"' => [ 'proxy' => [ 'description' => '' ], 'expected_error' => 'Invalid parameter "/1": the parameter "name" is missing.' ], 'Test proxy.create: invalid "name" (null)' => [ 'proxy' => [ 'name' => null ], 'expected_error' => 'Invalid parameter "/1/name": a character string is expected.' ], 'Test proxy.create: invalid "name" (boolean)' => [ 'proxy' => [ 'name' => false ], 'expected_error' => 'Invalid parameter "/1/name": a character string is expected.' ], 'Test proxy.create: invalid "name" (empty string)' => [ 'proxy' => [ 'name' => '' ], 'expected_error' => 'Invalid parameter "/1/name": cannot be empty.' ], 'Test proxy.create: invalid "name" (UTF-8 string)' => [ 'proxy' => [ 'name' => 'АПИ прокси УТФ-8' ], 'expected_error' => 'Invalid parameter "/1/name": invalid host name.' ], 'Test proxy.create: invalid "name" (does not match naming pattern)' => [ 'proxy' => [ 'name' => 'API create proxy?' ], 'expected_error' => 'Invalid parameter "/1/name": invalid host name.' ], 'Test proxy.create: invalid "name" (too long)' => [ 'proxy' => [ 'name' => str_repeat('a', DB::getFieldLength('proxy', 'name') + 1) ], 'expected_error' => 'Invalid parameter "/1/name": value is too long.' ], 'Test proxy.create: multiple proxies with the same "name"' => [ 'proxy' => [ [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE ], [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => '127.0.0.1', 'port' => '12345' ] ], 'expected_error' => 'Invalid parameter "/2": value (name)=(API create proxy) already exists.' ], 'Test proxy.create: invalid "name" (duplicate)' => [ 'proxy' => [ 'name' => 'API test proxy - active with defaults', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE ], 'expected_error' => 'Proxy "API test proxy - active with defaults" already exists.' ], // Check "proxy_groupid". 'Test proxy.create: invalid "proxy_groupid" (null)' => [ 'proxy' => [ 'name' => 'API create proxy', 'proxy_groupid' => null ], 'expected_error' => 'Invalid parameter "/1/proxy_groupid": a number is expected.' ], 'Test proxy.create: invalid "proxy_groupid" (boolean)' => [ 'proxy' => [ 'name' => 'API create proxy', 'proxy_groupid' => false ], 'expected_error' => 'Invalid parameter "/1/proxy_groupid": a number is expected.' ], 'Test proxy.create: invalid "proxy_groupid" (empty string)' => [ 'proxy' => [ 'name' => 'API create proxy', 'proxy_groupid' => '' ], 'expected_error' => 'Invalid parameter "/1/proxy_groupid": a number is expected.' ], 'Test proxy.create: invalid "proxy_groupid" (non-existent)' => [ 'proxy' => [ 'name' => 'API create proxy', 'proxy_groupid' => self::INVALID_NUMBER, 'local_address' => 'localhost', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE ], 'expected_error' => 'Invalid parameter "/1/proxy_groupid": object does not exist, or you have no permissions to it.' ], // Check "local_address". 'Test proxy.create: invalid "local_address" (null)' => [ 'proxy' => [ 'name' => 'API create proxy', 'proxy_groupid' => 'empty', 'local_address' => null ], 'expected_error' => 'Invalid parameter "/1/local_address": a character string is expected.' ], 'Test proxy.create: invalid "local_address" (boolean)' => [ 'proxy' => [ 'name' => 'API create proxy', 'proxy_groupid' => 'empty', 'local_address' => false ], 'expected_error' => 'Invalid parameter "/1/local_address": a character string is expected.' ], 'Test proxy.create: invalid "local_address" (empty string)' => [ 'proxy' => [ 'name' => 'API create proxy', 'proxy_groupid' => 'empty', 'local_address' => '' ], 'expected_error' => 'Invalid parameter "/1/local_address": cannot be empty.' ], 'Test proxy.create: invalid "local_address" (user macro)' => [ 'proxy' => [ 'name' => 'API create proxy', 'proxy_groupid' => 'empty', 'local_address' => '{$MACRO}' ], 'expected_error' => 'Invalid parameter "/1/local_address": an IP or DNS is expected.' ], 'Test proxy.create: invalid "local_address" (too long)' => [ 'proxy' => [ 'name' => 'API create proxy', 'proxy_groupid' => 'empty', 'local_address' => str_repeat('a', DB::getFieldLength('proxy', 'local_address') + 1) ], 'expected_error' => 'Invalid parameter "/1/local_address": value is too long.' ], // Check "local_port". 'Test proxy.create: invalid "local_port" (null)' => [ 'proxy' => [ 'name' => 'API create proxy', 'proxy_groupid' => 'empty', 'local_address' => 'localhost', 'local_port' => null ], 'expected_error' => 'Invalid parameter "/1/local_port": a number is expected.' ], 'Test proxy.create: invalid "local_port" (boolean)' => [ 'proxy' => [ 'name' => 'API create proxy', 'proxy_groupid' => 'empty', 'local_address' => 'localhost', 'local_port' => false ], 'expected_error' => 'Invalid parameter "/1/local_port": a number is expected.' ], 'Test proxy.create: invalid "local_port" (empty string)' => [ 'proxy' => [ 'name' => 'API create proxy', 'proxy_groupid' => 'empty', 'local_address' => 'localhost', 'local_port' => '' ], 'expected_error' => 'Invalid parameter "/1/local_port": cannot be empty.' ], 'Test proxy.create: invalid "local_port" (too small)' => [ 'proxy' => [ 'name' => 'API create proxy', 'proxy_groupid' => 'empty', 'local_address' => 'localhost', 'local_port' => -1 ], 'expected_error' => 'Invalid parameter "/1/local_port": value must be one of 0-65535.' ], 'Test proxy.create: invalid "local_port" (too large)' => [ 'proxy' => [ 'name' => 'API create proxy', 'proxy_groupid' => 'empty', 'local_address' => 'localhost', 'local_port' => self::INVALID_NUMBER ], 'expected_error' => 'Invalid parameter "/1/local_port": value must be one of 0-65535.' ], 'Test proxy.create: invalid "local_port" (too long)' => [ 'proxy' => [ 'name' => 'API create proxy', 'proxy_groupid' => 'empty', 'local_address' => 'localhost', 'local_port' => str_repeat('a', DB::getFieldLength('proxy', 'local_port') + 1) ], 'expected_error' => 'Invalid parameter "/1/local_port": value is too long.' ], // Check "operating_mode". 'Test proxy.create: missing "operating_mode"' => [ 'proxy' => [ 'name' => 'API create proxy' ], 'expected_error' => 'Invalid parameter "/1": the parameter "operating_mode" is missing.' ], 'Test proxy.create: invalid "operating_mode" (null)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => null ], 'expected_error' => 'Invalid parameter "/1/operating_mode": an integer is expected.' ], 'Test proxy.create: invalid "operating_mode" (boolean)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => false ], 'expected_error' => 'Invalid parameter "/1/operating_mode": an integer is expected.' ], 'Test proxy.create: invalid "operating_mode" (string)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/operating_mode": an integer is expected.' ], 'Test proxy.create: invalid "operating_mode" (not in range)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => self::INVALID_NUMBER ], 'expected_error' => 'Invalid parameter "/1/operating_mode": value must be one of '. implode(', ', [PROXY_OPERATING_MODE_ACTIVE, PROXY_OPERATING_MODE_PASSIVE]).'.' ], // Check "description". 'Test proxy.create: invalid "description" (null)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'description' => null ], 'expected_error' => 'Invalid parameter "/1/description": a character string is expected.' ], 'Test proxy.create: invalid "description" (boolean)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'description' => false ], 'expected_error' => 'Invalid parameter "/1/description": a character string is expected.' ], 'Test proxy.create: invalid "description" (too long)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'description' => str_repeat('a', DB::getFieldLength('proxy', 'description') + 1) ], 'expected_error' => 'Invalid parameter "/1/description": value is too long.' ], // Check "allowed_addresses". 'Test proxy.create: invalid "allowed_addresses" (null)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'allowed_addresses' => null ], 'expected_error' => 'Invalid parameter "/1/allowed_addresses": a character string is expected.' ], 'Test proxy.create: invalid "allowed_addresses" (boolean)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'allowed_addresses' => false ], 'expected_error' => 'Invalid parameter "/1/allowed_addresses": a character string is expected.' ], 'Test proxy.create: invalid "allowed_addresses" (IP address range)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'allowed_addresses' => '192.168.0-255.0/30' ], 'expected_error' => 'Invalid parameter "/1/allowed_addresses": incorrect address starting from "/30".' ], 'Test proxy.create: invalid "allowed_addresses" (IPv6 address range)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'allowed_addresses' => '::ff-0ffff' ], 'expected_error' => 'Invalid parameter "/1/allowed_addresses": incorrect address starting from "::ff-0ffff".' ], 'Test proxy.create: invalid "allowed_addresses" (user macro)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'allowed_addresses' => '{$MACRO}' ], 'expected_error' => 'Invalid parameter "/1/allowed_addresses": incorrect address starting from "{$MACRO}".' ], 'Test proxy.create: invalid "allowed_addresses" (too long)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'allowed_addresses' => str_repeat('a', DB::getFieldLength('proxy', 'allowed_addresses') + 1) ], 'expected_error' => 'Invalid parameter "/1/allowed_addresses": value is too long.' ], // Check "interface". 'Test proxy.create: invalid parameter "interface"' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'interface' => [ 'use_ip' => INTERFACE_USE_IP, 'ip' => '127.0.0.1', 'dns' => 'localhost', 'port' => '10050' ] ], 'expected_error' => 'Invalid parameter "/1": unexpected parameter "interface".' ], // Check "address". 'Test proxy.create: invalid "address" (null) for passive proxy' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => null ], 'expected_error' => 'Invalid parameter "/1/address": a character string is expected.' ], 'Test proxy.create: invalid "address" (boolean) for passive proxy' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => false ], 'expected_error' => 'Invalid parameter "/1/address": a character string is expected.' ], 'Test proxy.create: invalid "address" (empty string) for passive proxy' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => '' ], 'expected_error' => 'Invalid parameter "/1/address": cannot be empty.' ], 'Test proxy.create: invalid parameter "address" (string) for passive proxy' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => 'http://' ], 'expected_error' => 'Invalid parameter "/1/address": an IP or DNS is expected.' ], 'Test proxy.create: invalid "address" (too long) for passive proxy' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => str_repeat('a', DB::getFieldLength('proxy', 'address') + 1) ], 'expected_error' => 'Invalid parameter "/1/address": value is too long.' ], 'Test proxy.create: invalid "address" (not empty) for active proxy' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'address' => 'localhost' ], 'expected_error' => 'Invalid parameter "/1/address": value must be "127.0.0.1".' ], // Check "port". 'Test proxy.create: empty "port" (null) for passive proxy' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => '127.0.0.1', 'port' => null ], 'expected_error' => 'Invalid parameter "/1/port": a number is expected.' ], 'Test proxy.create: invalid "port" (boolean) for passive proxy' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => '127.0.0.1', 'port' => false ], 'expected_error' => 'Invalid parameter "/1/port": a number is expected.' ], 'Test proxy.create: invalid "port" (empty string) for passive proxy' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => '127.0.0.1', 'port' => '' ], 'expected_error' => 'Invalid parameter "/1/port": cannot be empty.' ], 'Test proxy.create: invalid "port" (string) for passive proxy' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => '127.0.0.1', 'port' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/port": an integer is expected.' ], 'Test proxy.create: invalid "port" (not in range) for passive proxy' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => '127.0.0.1', 'port' => self::INVALID_NUMBER ], 'expected_error' => 'Invalid parameter "/1/port": value must be one of 0-'.ZBX_MAX_PORT_NUMBER.'.' ], 'Test proxy.create: invalid "port" (not empty int) for active proxy' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'port' => 12345 ], 'expected_error' => 'Invalid parameter "/1/port": a character string is expected.' ], 'Test proxy.create: invalid "port" (not empty string) for active proxy' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'port' => '12345' ], 'expected_error' => 'Invalid parameter "/1/port": value must be "10051".' ], // Check "tls_connect". 'Test proxy.create: invalid "tls_connect" (string)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'tls_connect' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/tls_connect": an integer is expected.' ], 'Test proxy.create: invalid "tls_connect" (not in range) for active proxy' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'tls_connect' => self::INVALID_NUMBER ], 'expected_error' => 'Invalid parameter "/1/tls_connect": value must be '.HOST_ENCRYPTION_NONE.'.' ], 'Test proxy.create: invalid "tls_connect" (not in range) for passive proxy' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => '127.0.0.1', 'port' => '10050', 'tls_connect' => self::INVALID_NUMBER ], 'expected_error' => 'Invalid parameter "/1/tls_connect": value must be one of '. implode(', ', [HOST_ENCRYPTION_NONE, HOST_ENCRYPTION_PSK, HOST_ENCRYPTION_CERTIFICATE]).'.' ], // Check "tls_accept". 'Test proxy.create: invalid "tls_accept" (string)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'tls_accept' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/tls_accept": an integer is expected.' ], 'Test proxy.create: invalid "tls_accept" (not in range) for active proxy' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'tls_accept' => self::INVALID_NUMBER ], 'expected_error' => 'Invalid parameter "/1/tls_accept": value must be one of '.HOST_ENCRYPTION_NONE.'-'. (HOST_ENCRYPTION_NONE | HOST_ENCRYPTION_PSK | HOST_ENCRYPTION_CERTIFICATE).'.' ], 'Test proxy.create: invalid "tls_accept" (not in range) for passive proxy' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => '127.0.0.1', 'port' => '10050', 'tls_accept' => self::INVALID_NUMBER ], 'expected_error' => 'Invalid parameter "/1/tls_accept": value must be '.HOST_ENCRYPTION_NONE.'.' ], // Check "tls_psk_identity". 'Test proxy.create: invalid "tls_psk_identity" (boolean)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'tls_psk_identity' => false ], 'expected_error' => 'Invalid parameter "/1/tls_psk_identity": a character string is expected.' ], 'Test proxy.create: invalid "tls_psk_identity" (string) for active proxy #1' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'tls_psk_identity' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/tls_psk_identity": value must be empty.' ], 'Test proxy.create: invalid "tls_psk_identity" (string) for active proxy #2' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'tls_accept' => HOST_ENCRYPTION_NONE, 'tls_psk_identity' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/tls_psk_identity": value must be empty.' ], 'Test proxy.create: invalid "tls_psk_identity" (string) for active proxy #3' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'tls_accept' => HOST_ENCRYPTION_CERTIFICATE, 'tls_psk_identity' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/tls_psk_identity": value must be empty.' ], 'Test proxy.create: invalid "tls_psk_identity" (string) for passive proxy #1' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => '127.0.0.1', 'port' => '10050', 'tls_psk_identity' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/tls_psk_identity": value must be empty.' ], 'Test proxy.create: invalid "tls_psk_identity" (string) for passive proxy #2' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => '127.0.0.1', 'port' => '10050', 'tls_connect' => HOST_ENCRYPTION_NONE, 'tls_psk_identity' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/tls_psk_identity": value must be empty.' ], 'Test proxy.create: invalid "tls_psk_identity" (string) for passive proxy #3' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => '127.0.0.1', 'port' => '10050', 'tls_connect' => HOST_ENCRYPTION_CERTIFICATE, 'tls_psk_identity' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/tls_psk_identity": value must be empty.' ], 'Test proxy.create: invalid "tls_psk_identity" required for active proxy' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'tls_accept' => HOST_ENCRYPTION_PSK ], 'expected_error' => 'Invalid parameter "/1": the parameter "tls_psk_identity" is missing.' ], 'Test proxy.create: invalid "tls_psk_identity" (empty string) for active proxy' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'tls_accept' => HOST_ENCRYPTION_PSK, 'tls_psk_identity' => '' ], 'expected_error' => 'Invalid parameter "/1/tls_psk_identity": cannot be empty.' ], 'Test proxy.create: invalid "tls_psk_identity" required for passive proxy' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => '127.0.0.1', 'port' => '10050', 'tls_connect' => HOST_ENCRYPTION_PSK ], 'expected_error' => 'Invalid parameter "/1": the parameter "tls_psk_identity" is missing.' ], 'Test proxy.create: invalid "tls_psk_identity" (empty string) for passive proxy' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => '127.0.0.1', 'port' => '10050', 'tls_connect' => HOST_ENCRYPTION_PSK, 'tls_psk_identity' => '' ], 'expected_error' => 'Invalid parameter "/1/tls_psk_identity": cannot be empty.' ], 'Test proxy.create: invalid "tls_psk_identity" (too long) for active proxy' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'tls_accept' => HOST_ENCRYPTION_PSK, 'tls_psk_identity' => str_repeat('a', DB::getFieldLength('proxy', 'tls_psk_identity') + 1) ], 'expected_error' => 'Invalid parameter "/1/tls_psk_identity": value is too long.' ], 'Test proxy.create: invalid "tls_psk_identity" (too long) for passive proxy' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => '127.0.0.1', 'port' => '10050', 'tls_connect' => HOST_ENCRYPTION_PSK, 'tls_psk_identity' => str_repeat('a', DB::getFieldLength('proxy', 'tls_psk_identity') + 1) ], 'expected_error' => 'Invalid parameter "/1/tls_psk_identity": value is too long.' ], // Check "tls_psk". 'Test proxy.create: invalid "tls_psk" (boolean) for active proxy' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'tls_psk' => false ], 'expected_error' => 'Invalid parameter "/1/tls_psk": a character string is expected.' ], 'Test proxy.create: invalid "tls_psk" (string) for active proxy #1' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'tls_psk' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/tls_psk": value must be empty.' ], 'Test proxy.create: invalid "tls_psk" (string) for active proxy #2' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'tls_accept' => HOST_ENCRYPTION_NONE, 'tls_psk' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/tls_psk": value must be empty.' ], 'Test proxy.create: invalid "tls_psk" (string) for active proxy #3' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'tls_accept' => HOST_ENCRYPTION_CERTIFICATE, 'tls_psk' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/tls_psk": value must be empty.' ], 'Test proxy.create: invalid "tls_psk" (string) for passive proxy #1' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => '127.0.0.1', 'port' => '10050', 'tls_connect' => HOST_ENCRYPTION_NONE, 'tls_psk' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/tls_psk": value must be empty.' ], 'Test proxy.create: invalid "tls_psk" (string) for passive proxy #2' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => '127.0.0.1', 'port' => '10050', 'tls_connect' => HOST_ENCRYPTION_CERTIFICATE, 'tls_psk' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/tls_psk": value must be empty.' ], 'Test proxy.create: invalid "tls_psk" (too short) for active proxy' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'tls_accept' => HOST_ENCRYPTION_PSK, 'tls_psk_identity' => 'test', 'tls_psk' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/tls_psk": minimum length is 32 characters.' ], 'Test proxy.create: invalid "tls_psk" (too short) for passive proxy' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => '127.0.0.1', 'port' => '10050', 'tls_connect' => HOST_ENCRYPTION_PSK, 'tls_psk_identity' => 'test', 'tls_psk' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/tls_psk": minimum length is 32 characters.' ], 'Test proxy.create: invalid "tls_psk" (not PSK) for active proxy' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'tls_accept' => HOST_ENCRYPTION_PSK, 'tls_psk_identity' => 'test', 'tls_psk' => str_repeat('a', 33) ], 'expected_error' => 'Invalid parameter "/1/tls_psk": an even number of hexadecimal characters is expected.' ], 'Test proxy.create: invalid "tls_psk" (not PSK) for passive proxy' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => '127.0.0.1', 'port' => '10050', 'tls_connect' => HOST_ENCRYPTION_PSK, 'tls_psk_identity' => 'test', 'tls_psk' => str_repeat('a', 33) ], 'expected_error' => 'Invalid parameter "/1/tls_psk": an even number of hexadecimal characters is expected.' ], 'Test proxy.create: invalid "tls_psk" multiple values not allowed for same "tls_psk_identity" PROXY_OPERATING_MODE_ACTIVE' => [ 'proxy' => [ [ 'name' => 'tls_psk1.example.com', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'tls_accept' => HOST_ENCRYPTION_PSK, 'tls_psk_identity' => 'public', 'tls_psk' => '5fce1b3e34b520afeffb37ce08c7cd66' ], [ 'name' => 'tls_psk2.example.com', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'tls_accept' => HOST_ENCRYPTION_PSK, 'tls_psk_identity' => 'public', 'tls_psk' => 'fb48829a6f9ebbb70294a75ca0916772' ] ], 'expected_error' => 'Invalid parameter "/2/tls_psk": another tls_psk value is already associated with given tls_psk_identity.' ], 'Test proxy.create: invalid "tls_psk" multiple values not allowed for same "tls_psk_identity" PROXY_OPERATING_MODE_PASSIVE' => [ 'proxy' => [ [ 'name' => 'tls_psk3.example.com', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => '127.0.0.1', 'port' => '10050', 'tls_connect' => HOST_ENCRYPTION_PSK, 'tls_psk_identity' => 'public', 'tls_psk' => '5fce1b3e34b520afeffb37ce08c7cd66' ], [ 'name' => 'tls_psk4.example.com', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => '127.0.0.1', 'port' => '10050', 'tls_connect' => HOST_ENCRYPTION_PSK, 'tls_psk_identity' => 'public', 'tls_psk' => 'fb48829a6f9ebbb70294a75ca0916772' ] ], 'expected_error' => 'Invalid parameter "/2/tls_psk": another tls_psk value is already associated with given tls_psk_identity.' ], 'Test proxy.create: invalid "tls_psk" multiple values not allowed for same "tls_psk_identity" PROXY_OPERATING_MODE_*' => [ 'proxy' => [ [ 'name' => 'tls_psk5.example.com', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'tls_accept' => HOST_ENCRYPTION_PSK, 'tls_psk_identity' => 'public', 'tls_psk' => '5fce1b3e34b520afeffb37ce08c7cd66' ], [ 'name' => 'tls_psk6.example.com', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => '127.0.0.1', 'port' => '10050', 'tls_connect' => HOST_ENCRYPTION_PSK, 'tls_psk_identity' => 'public', 'tls_psk' => 'fb48829a6f9ebbb70294a75ca0916772' ] ], 'expected_error' => 'Invalid parameter "/2/tls_psk": another tls_psk value is already associated with given tls_psk_identity.' ], 'Test proxy.create: invalid "tls_psk" multiple values not allowed for same "tls_psk_identity"' => [ 'proxy' => [ [ 'name' => 'tls_psk7.example.com', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'tls_accept' => HOST_ENCRYPTION_PSK, 'tls_psk_identity' => 'proxyidentity', 'tls_psk' => '9b8eafedfaae00cece62e85d5f4792c7' ] ], 'expected_error' => 'Invalid parameter "/1/tls_psk": another tls_psk value is already associated with given tls_psk_identity.' ], // Check "tls_issuer". 'Test proxy.create: invalid "tls_issuer" (boolean) for active proxy' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'tls_issuer' => false ], 'expected_error' => 'Invalid parameter "/1/tls_issuer": a character string is expected.' ], 'Test proxy.create: invalid "tls_issuer" (not empty) for active proxy #1' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'tls_accept' => HOST_ENCRYPTION_NONE, 'tls_issuer' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/tls_issuer": value must be empty.' ], 'Test proxy.create: invalid "tls_issuer" (not empty) for active proxy #2' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'tls_accept' => HOST_ENCRYPTION_PSK, 'tls_psk_identity' => 'proxyidentity', 'tls_psk' => '486a9e7b43740b3619e42636cb1c24bf', 'tls_issuer' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/tls_issuer": value must be empty.' ], 'Test proxy.create: invalid "tls_issuer" (not empty) for passive proxy #1' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => '127.0.0.1', 'port' => '10050', 'tls_connect' => HOST_ENCRYPTION_NONE, 'tls_issuer' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/tls_issuer": value must be empty.' ], 'Test proxy.create: invalid "tls_issuer" (not empty) for passive proxy #2' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => '127.0.0.1', 'port' => '10050', 'tls_connect' => HOST_ENCRYPTION_PSK, 'tls_psk_identity' => 'proxyidentity', 'tls_psk' => '486a9e7b43740b3619e42636cb1c24bf', 'tls_issuer' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/tls_issuer": value must be empty.' ], 'Test proxy.create: invalid "tls_issuer" (too long) for active proxy' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'tls_accept' => HOST_ENCRYPTION_CERTIFICATE, 'tls_issuer' => str_repeat('a', DB::getFieldLength('proxy', 'tls_issuer') + 1) ], 'expected_error' => 'Invalid parameter "/1/tls_issuer": value is too long.' ], 'Test proxy.create: invalid "tls_issuer" (too long) for passive proxy' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => '127.0.0.1', 'port' => '10050', 'tls_connect' => HOST_ENCRYPTION_CERTIFICATE, 'tls_issuer' => str_repeat('a', DB::getFieldLength('proxy', 'tls_issuer') + 1) ], 'expected_error' => 'Invalid parameter "/1/tls_issuer": value is too long.' ], // Check "tls_subject". 'Test proxy.create: invalid "tls_subject" (not empty) for active proxy #1' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'tls_accept' => HOST_ENCRYPTION_NONE, 'tls_subject' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/tls_subject": value must be empty.' ], 'Test proxy.create: invalid "tls_subject" (not empty) for active proxy #2' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'tls_accept' => HOST_ENCRYPTION_PSK, 'tls_psk_identity' => 'proxyidentity', 'tls_psk' => '486a9e7b43740b3619e42636cb1c24bf', 'tls_subject' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/tls_subject": value must be empty.' ], 'Test proxy.create: invalid "tls_subject" (not empty) for passive proxy #1' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => '127.0.0.1', 'port' => '10050', 'tls_connect' => HOST_ENCRYPTION_NONE, 'tls_subject' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/tls_subject": value must be empty.' ], 'Test proxy.create: invalid "tls_subject" (not empty) for passive proxy #2' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => '127.0.0.1', 'port' => '10050', 'tls_connect' => HOST_ENCRYPTION_PSK, 'tls_psk_identity' => 'proxyidentity', 'tls_psk' => '486a9e7b43740b3619e42636cb1c24bf', 'tls_subject' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/tls_subject": value must be empty.' ], 'Test proxy.create: invalid "tls_subject" (too long) for active proxy' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'tls_accept' => HOST_ENCRYPTION_CERTIFICATE, 'tls_subject' => str_repeat('a', DB::getFieldLength('proxy', 'tls_subject') + 1) ], 'expected_error' => 'Invalid parameter "/1/tls_subject": value is too long.' ], 'Test proxy.create: invalid "tls_subject" (too long) for passive proxy' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_PASSIVE, 'address' => '127.0.0.1', 'port' => '10050', 'tls_connect' => HOST_ENCRYPTION_CERTIFICATE, 'tls_subject' => str_repeat('a', DB::getFieldLength('proxy', 'tls_subject') + 1) ], 'expected_error' => 'Invalid parameter "/1/tls_subject": value is too long.' ], // Check "custom_timeouts". 'Test proxy.create: invalid "custom_timeouts" (null)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => null ], 'expected_error' => 'Invalid parameter "/1/custom_timeouts": an integer is expected.' ], 'Test proxy.create: invalid "custom_timeouts" (boolean)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => false ], 'expected_error' => 'Invalid parameter "/1/custom_timeouts": an integer is expected.' ], 'Test proxy.create: invalid "custom_timeouts" (string)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/custom_timeouts": an integer is expected.' ], 'Test proxy.create: invalid "custom_timeouts" (too small)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => -1 ], 'expected_error' => 'Invalid parameter "/1/custom_timeouts": value must be one of '. implode(', ', [ZBX_PROXY_CUSTOM_TIMEOUTS_DISABLED, ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED]).'.' ], 'Test proxy.create: invalid "custom_timeouts" (too large)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => self::INVALID_NUMBER ], 'expected_error' => 'Invalid parameter "/1/custom_timeouts": value must be one of '. implode(', ', [ZBX_PROXY_CUSTOM_TIMEOUTS_DISABLED, ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED]).'.' ], // Check "timeout_zabbix_agent". 'Test proxy.create: invalid "timeout_zabbix_agent" (null) if custom timeouts are disabled' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'timeout_zabbix_agent' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_zabbix_agent": a character string is expected.' ], 'Test proxy.create: invalid "timeout_zabbix_agent" (boolean) if custom timeouts are disabled' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'timeout_zabbix_agent' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_zabbix_agent": a character string is expected.' ], 'Test proxy.create: invalid "timeout_zabbix_agent" (not empty) if custom timeouts are disabled' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'timeout_zabbix_agent' => '5s' ], 'expected_error' => 'Invalid parameter "/1/timeout_zabbix_agent": value must be empty.' ], 'Test proxy.create: invalid "timeout_zabbix_agent" (null)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_zabbix_agent": a character string is expected.' ], 'Test proxy.create: invalid "timeout_zabbix_agent" (boolean)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_zabbix_agent": a character string is expected.' ], 'Test proxy.create: invalid "timeout_zabbix_agent" (empty string)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '' ], 'expected_error' => 'Invalid parameter "/1/timeout_zabbix_agent": cannot be empty.' ], 'Test proxy.create: invalid "timeout_zabbix_agent" (not a time unit)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/timeout_zabbix_agent": a time unit is expected.' ], 'Test proxy.create: invalid "timeout_zabbix_agent" (too small)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => -1 ], 'expected_error' => 'Invalid parameter "/1/timeout_zabbix_agent": value must be one of 1-600.' ], 'Test proxy.create: invalid "timeout_zabbix_agent" (too large)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => self::INVALID_NUMBER ], 'expected_error' => 'Invalid parameter "/1/timeout_zabbix_agent": value must be one of 1-600.' ], // Check "timeout_simple_check". 'Test proxy.create: invalid "timeout_simple_check" (null) if custom timeouts are disabled' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'timeout_simple_check' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_simple_check": a character string is expected.' ], 'Test proxy.create: invalid "timeout_simple_check" (boolean) if custom timeouts are disabled' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'timeout_simple_check' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_simple_check": a character string is expected.' ], 'Test proxy.create: invalid "timeout_simple_check" (not empty) if custom timeouts are disabled' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'timeout_simple_check' => '5s' ], 'expected_error' => 'Invalid parameter "/1/timeout_simple_check": value must be empty.' ], 'Test proxy.create: "timeout_simple_check" is missing' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s' ], 'expected_error' => 'Invalid parameter "/1": the parameter "timeout_simple_check" is missing.' ], 'Test proxy.create: invalid "timeout_simple_check" (null)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_simple_check": a character string is expected.' ], 'Test proxy.create: invalid "timeout_simple_check" (boolean)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_simple_check": a character string is expected.' ], 'Test proxy.create: invalid "timeout_simple_check" (empty string)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '' ], 'expected_error' => 'Invalid parameter "/1/timeout_simple_check": cannot be empty.' ], 'Test proxy.create: invalid "timeout_simple_check" (not a time unit)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/timeout_simple_check": a time unit is expected.' ], 'Test proxy.create: invalid "timeout_simple_check" (too small)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => -1 ], 'expected_error' => 'Invalid parameter "/1/timeout_simple_check": value must be one of 1-600.' ], 'Test proxy.create: invalid "timeout_simple_check" (too large)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => self::INVALID_NUMBER ], 'expected_error' => 'Invalid parameter "/1/timeout_simple_check": value must be one of 1-600.' ], // Check "timeout_snmp_agent". 'Test proxy.create: invalid "timeout_snmp_agent" (null) if custom timeouts are disabled' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'timeout_snmp_agent' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_snmp_agent": a character string is expected.' ], 'Test proxy.create: invalid "timeout_snmp_agent" (boolean) if custom timeouts are disabled' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'timeout_snmp_agent' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_snmp_agent": a character string is expected.' ], 'Test proxy.create: invalid "timeout_snmp_agent" (not empty) if custom timeouts are disabled' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'timeout_snmp_agent' => '5s' ], 'expected_error' => 'Invalid parameter "/1/timeout_snmp_agent": value must be empty.' ], 'Test proxy.create: "timeout_snmp_agent" is missing' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s' ], 'expected_error' => 'Invalid parameter "/1": the parameter "timeout_snmp_agent" is missing.' ], 'Test proxy.create: invalid "timeout_snmp_agent" (null)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_snmp_agent": a character string is expected.' ], 'Test proxy.create: invalid "timeout_snmp_agent" (boolean)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_snmp_agent": a character string is expected.' ], 'Test proxy.create: invalid "timeout_snmp_agent" (empty string)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '' ], 'expected_error' => 'Invalid parameter "/1/timeout_snmp_agent": cannot be empty.' ], 'Test proxy.create: invalid "timeout_snmp_agent" (not a time unit)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/timeout_snmp_agent": a time unit is expected.' ], 'Test proxy.create: invalid "timeout_snmp_agent" (too small)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => -1 ], 'expected_error' => 'Invalid parameter "/1/timeout_snmp_agent": value must be one of 1-600.' ], 'Test proxy.create: invalid "timeout_snmp_agent" (too large)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => self::INVALID_NUMBER ], 'expected_error' => 'Invalid parameter "/1/timeout_snmp_agent": value must be one of 1-600.' ], // Check "timeout_external_check". 'Test proxy.create: invalid "timeout_external_check" (null) if custom timeouts are disabled' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'timeout_external_check' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_external_check": a character string is expected.' ], 'Test proxy.create: invalid "timeout_external_check" (boolean) if custom timeouts are disabled' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'timeout_external_check' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_external_check": a character string is expected.' ], 'Test proxy.create: invalid "timeout_external_check" (not empty) if custom timeouts are disabled' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'timeout_external_check' => '5s' ], 'expected_error' => 'Invalid parameter "/1/timeout_external_check": value must be empty.' ], 'Test proxy.create: "timeout_external_check" is missing' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s' ], 'expected_error' => 'Invalid parameter "/1": the parameter "timeout_external_check" is missing.' ], 'Test proxy.create: invalid "timeout_external_check" (null)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_external_check": a character string is expected.' ], 'Test proxy.create: invalid "timeout_external_check" (boolean)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_external_check": a character string is expected.' ], 'Test proxy.create: invalid "timeout_external_check" (empty string)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '' ], 'expected_error' => 'Invalid parameter "/1/timeout_external_check": cannot be empty.' ], 'Test proxy.create: invalid "timeout_external_check" (not a time unit)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/timeout_external_check": a time unit is expected.' ], 'Test proxy.create: invalid "timeout_external_check" (too small)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => -1 ], 'expected_error' => 'Invalid parameter "/1/timeout_external_check": value must be one of 1-600.' ], 'Test proxy.create: invalid "timeout_external_check" (too large)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => self::INVALID_NUMBER ], 'expected_error' => 'Invalid parameter "/1/timeout_external_check": value must be one of 1-600.' ], // Check "timeout_db_monitor". 'Test proxy.create: invalid "timeout_db_monitor" (null) if custom timeouts are disabled' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'timeout_db_monitor' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_db_monitor": a character string is expected.' ], 'Test proxy.create: invalid "timeout_db_monitor" (boolean) if custom timeouts are disabled' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'timeout_db_monitor' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_db_monitor": a character string is expected.' ], 'Test proxy.create: invalid "timeout_db_monitor" (not empty) if custom timeouts are disabled' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'timeout_db_monitor' => '5s' ], 'expected_error' => 'Invalid parameter "/1/timeout_db_monitor": value must be empty.' ], 'Test proxy.create: "timeout_db_monitor" is missing' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s' ], 'expected_error' => 'Invalid parameter "/1": the parameter "timeout_db_monitor" is missing.' ], 'Test proxy.create: invalid "timeout_db_monitor" (null)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_db_monitor": a character string is expected.' ], 'Test proxy.create: invalid "timeout_db_monitor" (boolean)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_db_monitor": a character string is expected.' ], 'Test proxy.create: invalid "timeout_db_monitor" (empty string)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '' ], 'expected_error' => 'Invalid parameter "/1/timeout_db_monitor": cannot be empty.' ], 'Test proxy.create: invalid "timeout_db_monitor" (not a time unit)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/timeout_db_monitor": a time unit is expected.' ], 'Test proxy.create: invalid "timeout_db_monitor" (too small)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => -1 ], 'expected_error' => 'Invalid parameter "/1/timeout_db_monitor": value must be one of 1-600.' ], 'Test proxy.create: invalid "timeout_db_monitor" (too large)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => self::INVALID_NUMBER ], 'expected_error' => 'Invalid parameter "/1/timeout_db_monitor": value must be one of 1-600.' ], // Check "timeout_http_agent". 'Test proxy.create: invalid "timeout_http_agent" (null) if custom timeouts are disabled' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'timeout_http_agent' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_http_agent": a character string is expected.' ], 'Test proxy.create: invalid "timeout_http_agent" (boolean) if custom timeouts are disabled' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'timeout_http_agent' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_http_agent": a character string is expected.' ], 'Test proxy.create: invalid "timeout_http_agent" (not empty) if custom timeouts are disabled' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'timeout_http_agent' => '5s' ], 'expected_error' => 'Invalid parameter "/1/timeout_http_agent": value must be empty.' ], 'Test proxy.create: "timeout_http_agent" is missing' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s' ], 'expected_error' => 'Invalid parameter "/1": the parameter "timeout_http_agent" is missing.' ], 'Test proxy.create: invalid "timeout_http_agent" (null)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_http_agent": a character string is expected.' ], 'Test proxy.create: invalid "timeout_http_agent" (boolean)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_http_agent": a character string is expected.' ], 'Test proxy.create: invalid "timeout_http_agent" (empty string)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '' ], 'expected_error' => 'Invalid parameter "/1/timeout_http_agent": cannot be empty.' ], 'Test proxy.create: invalid "timeout_http_agent" (not a time unit)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/timeout_http_agent": a time unit is expected.' ], 'Test proxy.create: invalid "timeout_http_agent" (too small)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => -1 ], 'expected_error' => 'Invalid parameter "/1/timeout_http_agent": value must be one of 1-600.' ], 'Test proxy.create: invalid "timeout_http_agent" (too large)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => self::INVALID_NUMBER ], 'expected_error' => 'Invalid parameter "/1/timeout_http_agent": value must be one of 1-600.' ], // Check "timeout_ssh_agent". 'Test proxy.create: invalid "timeout_ssh_agent" (null) if custom timeouts are disabled' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'timeout_ssh_agent' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_ssh_agent": a character string is expected.' ], 'Test proxy.create: invalid "timeout_ssh_agent" (boolean) if custom timeouts are disabled' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'timeout_ssh_agent' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_ssh_agent": a character string is expected.' ], 'Test proxy.create: invalid "timeout_ssh_agent" (not empty) if custom timeouts are disabled' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'timeout_ssh_agent' => '5s' ], 'expected_error' => 'Invalid parameter "/1/timeout_ssh_agent": value must be empty.' ], 'Test proxy.create: "timeout_ssh_agent" is missing' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s' ], 'expected_error' => 'Invalid parameter "/1": the parameter "timeout_ssh_agent" is missing.' ], 'Test proxy.create: invalid "timeout_ssh_agent" (null)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_ssh_agent": a character string is expected.' ], 'Test proxy.create: invalid "timeout_ssh_agent" (boolean)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_ssh_agent": a character string is expected.' ], 'Test proxy.create: invalid "timeout_ssh_agent" (empty string)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '' ], 'expected_error' => 'Invalid parameter "/1/timeout_ssh_agent": cannot be empty.' ], 'Test proxy.create: invalid "timeout_ssh_agent" (not a time unit)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/timeout_ssh_agent": a time unit is expected.' ], 'Test proxy.create: invalid "timeout_ssh_agent" (too small)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => -1 ], 'expected_error' => 'Invalid parameter "/1/timeout_ssh_agent": value must be one of 1-600.' ], 'Test proxy.create: invalid "timeout_ssh_agent" (too large)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => self::INVALID_NUMBER ], 'expected_error' => 'Invalid parameter "/1/timeout_ssh_agent": value must be one of 1-600.' ], // Check "timeout_telnet_agent". 'Test proxy.create: invalid "timeout_telnet_agent" (null) if custom timeouts are disabled' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'timeout_telnet_agent' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_telnet_agent": a character string is expected.' ], 'Test proxy.create: invalid "timeout_telnet_agent" (boolean) if custom timeouts are disabled' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'timeout_telnet_agent' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_telnet_agent": a character string is expected.' ], 'Test proxy.create: invalid "timeout_telnet_agent" (not empty) if custom timeouts are disabled' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'timeout_telnet_agent' => '5s' ], 'expected_error' => 'Invalid parameter "/1/timeout_telnet_agent": value must be empty.' ], 'Test proxy.create: "timeout_telnet_agent" is missing' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s' ], 'expected_error' => 'Invalid parameter "/1": the parameter "timeout_telnet_agent" is missing.' ], 'Test proxy.create: invalid "timeout_telnet_agent" (null)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_telnet_agent": a character string is expected.' ], 'Test proxy.create: invalid "timeout_telnet_agent" (boolean)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_telnet_agent": a character string is expected.' ], 'Test proxy.create: invalid "timeout_telnet_agent" (empty string)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => '' ], 'expected_error' => 'Invalid parameter "/1/timeout_telnet_agent": cannot be empty.' ], 'Test proxy.create: invalid "timeout_telnet_agent" (not a time unit)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/timeout_telnet_agent": a time unit is expected.' ], 'Test proxy.create: invalid "timeout_telnet_agent" (too small)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => -1 ], 'expected_error' => 'Invalid parameter "/1/timeout_telnet_agent": value must be one of 1-600.' ], 'Test proxy.create: invalid "timeout_telnet_agent" (too large)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => self::INVALID_NUMBER ], 'expected_error' => 'Invalid parameter "/1/timeout_telnet_agent": value must be one of 1-600.' ], // Check "timeout_script". 'Test proxy.create: invalid "timeout_script" (null) if custom timeouts are disabled' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'timeout_script' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_script": a character string is expected.' ], 'Test proxy.create: invalid "timeout_script" (boolean) if custom timeouts are disabled' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'timeout_script' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_script": a character string is expected.' ], 'Test proxy.create: invalid "timeout_script" (not empty) if custom timeouts are disabled' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'timeout_script' => '5s' ], 'expected_error' => 'Invalid parameter "/1/timeout_script": value must be empty.' ], 'Test proxy.create: "timeout_script" is missing' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => '5s' ], 'expected_error' => 'Invalid parameter "/1": the parameter "timeout_script" is missing.' ], 'Test proxy.create: invalid "timeout_script" (null)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => '5s', 'timeout_script' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_script": a character string is expected.' ], 'Test proxy.create: invalid "timeout_script" (boolean)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => '5s', 'timeout_script' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_script": a character string is expected.' ], 'Test proxy.create: invalid "timeout_script" (empty string)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => '5s', 'timeout_script' => '' ], 'expected_error' => 'Invalid parameter "/1/timeout_script": cannot be empty.' ], 'Test proxy.create: invalid "timeout_script" (not a time unit)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => '5s', 'timeout_script' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/timeout_script": a time unit is expected.' ], 'Test proxy.create: invalid "timeout_script" (too small)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => '5s', 'timeout_script' => -1 ], 'expected_error' => 'Invalid parameter "/1/timeout_script": value must be one of 1-600.' ], 'Test proxy.create: invalid "timeout_script" (too large)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => '5s', 'timeout_script' => self::INVALID_NUMBER ], 'expected_error' => 'Invalid parameter "/1/timeout_script": value must be one of 1-600.' ], // Check "timeout_browser". 'Test proxy.create: invalid "timeout_browser" (null) if custom timeouts are disabled' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'timeout_browser' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_browser": a character string is expected.' ], 'Test proxy.create: invalid "timeout_browser" (boolean) if custom timeouts are disabled' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'timeout_browser' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_browser": a character string is expected.' ], 'Test proxy.create: invalid "timeout_browser" (not empty) if custom timeouts are disabled' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'timeout_browser' => '5s' ], 'expected_error' => 'Invalid parameter "/1/timeout_browser": value must be empty.' ], 'Test proxy.create: "timeout_browser" is missing' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => '5s', 'timeout_script' => '5s' ], 'expected_error' => 'Invalid parameter "/1": the parameter "timeout_browser" is missing.' ], 'Test proxy.create: invalid "timeout_browser" (null)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => '5s', 'timeout_script' => '5s', 'timeout_browser' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_browser": a character string is expected.' ], 'Test proxy.create: invalid "timeout_browser" (boolean)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => '5s', 'timeout_script' => '5s', 'timeout_browser' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_browser": a character string is expected.' ], 'Test proxy.create: invalid "timeout_browser" (empty string)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => '5s', 'timeout_script' => '5s', 'timeout_browser' => '' ], 'expected_error' => 'Invalid parameter "/1/timeout_browser": cannot be empty.' ], 'Test proxy.create: invalid "timeout_browser" (not a time unit)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => '5s', 'timeout_script' => '5s', 'timeout_browser' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/timeout_browser": a time unit is expected.' ], 'Test proxy.create: invalid "timeout_browser" (too small)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => '5s', 'timeout_script' => '5s', 'timeout_browser' => -1 ], 'expected_error' => 'Invalid parameter "/1/timeout_browser": value must be one of 1-600.' ], 'Test proxy.create: invalid "timeout_browser" (too large)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => '5s', 'timeout_script' => '5s', 'timeout_browser' => self::INVALID_NUMBER ], 'expected_error' => 'Invalid parameter "/1/timeout_browser": value must be one of 1-600.' ], // Check "hosts". 'Test proxy.create: invalid "hosts" (null)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'hosts' => null ], 'expected_error' => 'Invalid parameter "/1/hosts": an array is expected.' ], 'Test proxy.create: invalid "hosts" (boolean)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'hosts' => false ], 'expected_error' => 'Invalid parameter "/1/hosts": an array is expected.' ], 'Test proxy.create: invalid "hosts" (string)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'hosts' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/hosts": an array is expected.' ], 'Test proxy.create: invalid "hosts" (array with string)' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'hosts' => ['abc'] ], 'expected_error' => 'Invalid parameter "/1/hosts/1": an array is expected.' ], 'Test proxy.create: missing "hostid" for "hosts"' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'hosts' => [ [] ] ], 'expected_error' => 'Invalid parameter "/1/hosts/1": the parameter "hostid" is missing.' ], 'Test proxy.create: unexpected parameter for "hosts"' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'hosts' => [ ['abc' => ''] ] ], 'expected_error' => 'Invalid parameter "/1/hosts/1": unexpected parameter "abc".' ], 'Test proxy.create: invalid "hostid" (empty string) for "hosts"' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'hosts' => [ ['hostid' => ''] ] ], 'expected_error' => 'Invalid parameter "/1/hosts/1/hostid": a number is expected.' ], 'Test proxy.create: invalid "hostid" (non-existent) for "hosts"' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'hosts' => [ ['hostid' => self::INVALID_NUMBER] ] ], 'expected_error' => 'Invalid parameter "/1/hosts/1/hostid": object does not exist, or you have no permissions to it.' ], 'Test proxy.create: invalid "hostid" (duplicate) for "hosts"' => [ 'proxy' => [ 'name' => 'API create proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'hosts' => [ ['hostid' => 0], ['hostid' => 0] ] ], 'expected_error' => 'Invalid parameter "/1/hosts/2": value (hostid)=(0) already exists.' ] ]; } /** * Data provider for proxy.create. Array contains valid proxies. * * @return array */ public static function getProxyCreateDataValid(): array { return [ 'Test proxy.create: single proxy' => [ 'proxy' => [ 'name' => 'API create single proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE ], 'expected_error' => null ], 'Test proxy.create: multiple proxies' => [ 'proxy' => [ [ 'name' => 'API create first proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE ], [ 'name' => 'API create second proxy', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE ] ], 'expected_error' => null ], // Check "custom_timeouts". 'Test proxy.create: with "custom_timeouts" disabled' => [ 'proxy' => [ 'name' => 'API create proxy with custom timeouts disabled', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_DISABLED ], 'expected_error' => null ], 'Test proxy.create: with "custom_timeouts" enabled (user macros)' => [ 'proxy' => [ 'name' => 'API create proxy with custom timeouts enabled', 'operating_mode' => PROXY_OPERATING_MODE_ACTIVE, 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '{$TIMEOUT.ZABBIX.AGENT}', 'timeout_simple_check' => '{$TIMEOUT.SIMPLE.CHECK}', 'timeout_snmp_agent' => '{$TIMEOUT.SNMP.AGENT}', 'timeout_external_check' => '{$TIMEOUT.EXTERNAL.CHECK}', 'timeout_db_monitor' => '{$TIMEOUT.DB.MONITOR}', 'timeout_http_agent' => '{$TIMEOUT.HTTP.AGENT}', 'timeout_ssh_agent' => '{$TIMEOUT.SSH.AGENT}', 'timeout_telnet_agent' => '{$TIMEOUT.TELNET.AGENT}', 'timeout_script' => '{$TIMEOUT.SCRIPT}', 'timeout_browser' => '{$TIMEOUT.BROWSER}' ], 'expected_error' => null ] ]; } /** * Test proxy.create with errors like missing fields, optional invalid fields and valid fields. * * @dataProvider getProxyCreateDataInvalid * @dataProvider getProxyCreateDataValid */ public function testProxy_Create(array $proxies, ?string $expected_error): void { // Accept single and multiple proxies just like API method. Work with multidimensional array in result. if (!array_key_exists(0, $proxies)) { $proxies = zbx_toArray($proxies); } // Replace ID placeholders with real IDs. foreach ($proxies as &$proxy) { $proxy = self::resolveIds($proxy); } unset($proxy); $sql_proxies = 'SELECT NULL FROM proxy p'; $old_hash_proxies = CDBHelper::getHash($sql_proxies); $result = $this->call('proxy.create', $proxies, $expected_error); if ($expected_error === null) { // Something was changed in DB. $this->assertNotSame($old_hash_proxies, CDBHelper::getHash($sql_proxies)); $this->assertEquals(count($proxies), count($result['result']['proxyids'])); // Add proxy IDs to create array, so they can be deleted after tests are complete. self::$data['created'] = array_merge(self::$data['created'], $result['result']['proxyids']); $db_defaults = DB::getDefaults('proxy'); $timeout_fields = ['timeout_zabbix_agent', 'timeout_simple_check', 'timeout_snmp_agent', 'timeout_external_check', 'timeout_db_monitor', 'timeout_http_agent', 'timeout_ssh_agent', 'timeout_telnet_agent', 'timeout_script', 'timeout_browser' ]; // Check individual fields according to each proxy operating_mode. foreach ($result['result']['proxyids'] as $num => $proxyid) { $proxy = $proxies[$num]; $db_proxies = $this->getProxies([$proxyid]); $db_proxy = $db_proxies[$proxyid]; // Required fields. $this->assertNotEmpty($db_proxy['name']); $this->assertSame($proxy['name'], $db_proxy['name']); $this->assertEquals($proxy['operating_mode'], $db_proxy['operating_mode']); if ($db_proxy['proxy_groupid'] == 0) { foreach (['local_address', 'local_port'] as $field) { if (array_key_exists($field, $proxy)) { $this->assertSame($proxy[$field], $db_proxy[$field]); } else { $this->assertSame($db_defaults[$field], $db_proxy[$field]); } } } else { foreach (['local_address', 'local_port'] as $field) { if (array_key_exists($field, $proxy)) { $this->assertSame($proxy[$field], $db_proxy[$field]); } $this->assertNotEmpty($db_proxy[$field]); } } foreach (['description', 'allowed_addresses'] as $field) { if (array_key_exists($field, $proxy)) { $this->assertSame($proxy[$field], $db_proxy[$field]); } else { $this->assertSame($db_defaults[$field], $db_proxy[$field]); } } foreach (['tls_connect', 'tls_accept'] as $field) { if (array_key_exists($field, $proxy)) { $this->assertEquals($proxy[$field], $db_proxy[$field]); } else { $this->assertEquals($db_defaults[$field], $db_proxy[$field]); } } if ($db_proxy['operating_mode'] == PROXY_OPERATING_MODE_ACTIVE) { foreach (['address', 'port'] as $field) { if (array_key_exists($field, $proxy)) { $this->assertSame($proxy[$field], $db_proxy[$field]); } else { $this->assertSame($db_defaults[$field], $db_proxy[$field]); } } foreach (['tls_issuer', 'tls_subject'] as $field) { if ($db_proxy['tls_accept'] & HOST_ENCRYPTION_CERTIFICATE && array_key_exists($field, $proxy)) { $this->assertSame($proxy[$field], $db_proxy[$field]); } else { $this->assertSame($db_defaults[$field], $db_proxy[$field]); } } foreach (['tls_psk_identity', 'tls_psk'] as $field) { if ($db_proxy['tls_accept'] & HOST_ENCRYPTION_PSK && array_key_exists($field, $proxy)) { $this->assertNotEmpty($db_proxy[$field]); $this->assertSame($proxy[$field], $db_proxy[$field]); } else { $this->assertSame($db_defaults[$field], $db_proxy[$field]); } } } elseif ($db_proxy['operating_mode'] == PROXY_OPERATING_MODE_PASSIVE) { foreach (['address', 'port'] as $field) { $this->assertNotEmpty($db_proxy[$field]); $this->assertSame($proxy[$field], $db_proxy[$field]); } foreach (['tls_issuer', 'tls_subject'] as $field) { if ($db_proxy['tls_connect'] == HOST_ENCRYPTION_CERTIFICATE && array_key_exists($field, $proxy)) { $this->assertSame($proxy[$field], $db_proxy[$field]); } else { $this->assertSame($db_defaults[$field], $db_proxy[$field]); } } foreach (['tls_psk_identity', 'tls_psk'] as $field) { if ($db_proxy['tls_connect'] == HOST_ENCRYPTION_PSK && array_key_exists($field, $proxy)) { $this->assertNotEmpty($db_proxy[$field]); $this->assertSame($proxy[$field], $db_proxy[$field]); } else { $this->assertSame($db_defaults[$field], $db_proxy[$field]); } } } if (array_key_exists('custom_timeouts', $proxy)) { $this->assertEquals($proxy['custom_timeouts'], $db_proxy['custom_timeouts']); } else { $this->assertEquals($db_defaults['custom_timeouts'], $db_proxy['custom_timeouts']); } if ($db_proxy['custom_timeouts'] == ZBX_PROXY_CUSTOM_TIMEOUTS_DISABLED) { foreach ($timeout_fields as $field) { if (array_key_exists($field, $proxy)) { $this->assertSame($proxy[$field], $db_proxy[$field]); } else { $this->assertSame($db_defaults[$field], $db_proxy[$field]); } } } elseif ($db_proxy['custom_timeouts'] == ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED) { foreach ($timeout_fields as $field) { $this->assertNotEmpty($db_proxy[$field]); $this->assertSame($proxy[$field], $db_proxy[$field]); } } if (array_key_exists('hosts', $proxy)) { $this->assertEqualsCanonicalizing($proxy['hosts'], $db_proxy['hosts']); } else { $this->assertEmpty($db_proxy['hosts']); } } } else { $this->assertSame($old_hash_proxies, CDBHelper::getHash($sql_proxies)); } } /** * Data provider for proxy.update. Array contains invalid proxy parameters. * * @return array */ public static function getProxyUpdateDataInvalid(): array { return [ 'Test proxy.update: empty request' => [ 'proxy' => [], 'expected_error' => 'Invalid parameter "/": cannot be empty.' ], // Check "proxyid". 'Test proxy.update: missing "proxyid"' => [ 'proxy' => [ 'name' => 'API update proxy' ], 'expected_error' => 'Invalid parameter "/1": the parameter "proxyid" is missing.' ], 'Test proxy.update: invalid "proxyid" (empty string)' => [ 'proxy' => [ 'proxyid' => '' ], 'expected_error' => 'Invalid parameter "/1/proxyid": a number is expected.' ], 'Test proxy.update: invalid "proxyid" (non-existent)' => [ 'proxy' => [ 'proxyid' => self::INVALID_NUMBER ], 'expected_error' => 'No permissions to referred object or it does not exist!' ], 'Test proxy.update: multiple proxies with the same "proxyid"' => [ 'proxy' => [ ['proxyid' => 0], ['proxyid' => 0] ], 'expected_error' => 'Invalid parameter "/2": value (proxyid)=(0) already exists.' ], // Check "name". 'Test proxy.update: invalid "name" (boolean)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'name' => false ], 'expected_error' => 'Invalid parameter "/1/name": a character string is expected.' ], 'Test proxy.update: invalid "name" (empty string)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'name' => '' ], 'expected_error' => 'Invalid parameter "/1/name": cannot be empty.' ], 'Test proxy.update: invalid "name" (too long)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'name' => str_repeat('a', DB::getFieldLength('proxy', 'name') + 1) ], 'expected_error' => 'Invalid parameter "/1/name": value is too long.' ], // Check "proxy_groupid". 'Test proxy.update: invalid "proxy_groupid" (null)' => [ 'proxy' => [ 'proxyid' => 'without_proxy_group', 'proxy_groupid' => null ], 'expected_error' => 'Invalid parameter "/1/proxy_groupid": a number is expected.' ], 'Test proxy.update: invalid "proxy_groupid" (boolean)' => [ 'proxy' => [ 'proxyid' => 'without_proxy_group', 'proxy_groupid' => false ], 'expected_error' => 'Invalid parameter "/1/proxy_groupid": a number is expected.' ], 'Test proxy.update: invalid "proxy_groupid" (empty string)' => [ 'proxy' => [ 'proxyid' => 'without_proxy_group', 'proxy_groupid' => '' ], 'expected_error' => 'Invalid parameter "/1/proxy_groupid": a number is expected.' ], 'Test proxy.update: invalid "proxy_groupid" (non-existent)' => [ 'proxy' => [ 'proxyid' => 'without_proxy_group', 'proxy_groupid' => self::INVALID_NUMBER, 'local_address' => 'localhost' ], 'expected_error' => 'Invalid parameter "/1/proxy_groupid": object does not exist, or you have no permissions to it.' ], // Check "local_address". 'Test proxy.update: invalid "local_address" (null)' => [ 'proxy' => [ 'proxyid' => 'without_proxy_group', 'proxy_groupid' => 'empty', 'local_address' => null ], 'expected_error' => 'Invalid parameter "/1/local_address": a character string is expected.' ], 'Test proxy.update: invalid "local_address" (boolean)' => [ 'proxy' => [ 'proxyid' => 'without_proxy_group', 'proxy_groupid' => 'empty', 'local_address' => false ], 'expected_error' => 'Invalid parameter "/1/local_address": a character string is expected.' ], // Check "local_port". 'Test proxy.update: invalid "local_port" (null)' => [ 'proxy' => [ 'proxyid' => 'without_proxy_group', 'proxy_groupid' => 'empty', 'local_address' => 'localhost', 'local_port' => null ], 'expected_error' => 'Invalid parameter "/1/local_port": a number is expected.' ], 'Test proxy.update: invalid "local_port" (boolean)' => [ 'proxy' => [ 'proxyid' => 'without_proxy_group', 'proxy_groupid' => 'empty', 'local_address' => 'localhost', 'local_port' => false ], 'expected_error' => 'Invalid parameter "/1/local_port": a number is expected.' ], // Check "operating_mode". 'Test proxy.update: invalid "operating_mode" (string)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'operating_mode' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/operating_mode": an integer is expected.' ], 'Test proxy.update: invalid "operating_mode" (not in range)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'operating_mode' => self::INVALID_NUMBER ], 'expected_error' => 'Invalid parameter "/1/operating_mode": value must be one of '. implode(', ', [PROXY_OPERATING_MODE_ACTIVE, PROXY_OPERATING_MODE_PASSIVE]).'.' ], // Check "allowed_address". 'Test proxy.update: invalid "allowed_addresses" (boolean)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'allowed_addresses' => false ], 'expected_error' => 'Invalid parameter "/1/allowed_addresses": a character string is expected.' ], 'Test proxy.update: invalid "allowed_addresses" (IP address range)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'allowed_addresses' => '192.168.0-255.0/30' ], 'expected_error' => 'Invalid parameter "/1/allowed_addresses": incorrect address starting from "/30".' ], 'Test proxy.update: invalid "allowed_addresses" (IPv6 address range)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'allowed_addresses' => '::ff-0ffff' ], 'expected_error' => 'Invalid parameter "/1/allowed_addresses": incorrect address starting from "::ff-0ffff".' ], 'Test proxy.update: invalid "allowed_addresses" (user macro)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'allowed_addresses' => '{$MACRO}' ], 'expected_error' => 'Invalid parameter "/1/allowed_addresses": incorrect address starting from "{$MACRO}".' ], 'Test proxy.update: invalid "allowed_addresses" (too long)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'allowed_addresses' => str_repeat('a', DB::getFieldLength('proxy', 'allowed_addresses') + 1) ], 'expected_error' => 'Invalid parameter "/1/allowed_addresses": value is too long.' ], // Check "address". 'Test proxy.update: invalid "address" (boolean)' => [ 'proxy' => [ 'proxyid' => 'passive_defaults', 'address' => false ], 'expected_error' => 'Invalid parameter "/1/address": a character string is expected.' ], 'Test proxy.update: invalid "address" (string) for passive proxy' => [ 'proxy' => [ 'proxyid' => 'passive_defaults', 'address' => 'http://' ], 'expected_error' => 'Invalid parameter "/1/address": an IP or DNS is expected.' ], 'Test proxy.update: invalid "address" (too long) for passive proxy' => [ 'proxy' => [ 'proxyid' => 'passive_defaults', 'address' => str_repeat('a', DB::getFieldLength('proxy', 'address') + 1) ], 'expected_error' => 'Invalid parameter "/1/address": value is too long.' ], 'Test proxy.update: invalid "address" (not empty for active proxy)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'address' => 'localhost' ], 'expected_error' => 'Invalid parameter "/1/address": value must be "127.0.0.1".' ], // Check "port". 'Test proxy.update: invalid "port" (not in range)' => [ 'proxy' => [ 'proxyid' => 'passive_defaults', 'port' => self::INVALID_NUMBER ], 'expected_error' => 'Invalid parameter "/1/port": value must be one of 0-'.ZBX_MAX_PORT_NUMBER.'.' ], 'Test proxy.update: invalid "port" (boolean) for passive proxy' => [ 'proxy' => [ 'proxyid' => 'passive_defaults', 'port' => false ], 'expected_error' => 'Invalid parameter "/1/port": a number is expected.' ], 'Test proxy.update: invalid "port" (too long) for passive proxy' => [ 'proxy' => [ 'proxyid' => 'passive_defaults', 'port' => str_repeat('a', DB::getFieldLength('proxy', 'port') + 1) ], 'expected_error' => 'Invalid parameter "/1/port": value is too long.' ], 'Test proxy.update: invalid "port" (string) for passive proxy' => [ 'proxy' => [ 'proxyid' => 'passive_defaults', 'port' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/port": an integer is expected.' ], 'Test proxy.update: invalid "port" (not empty int for active proxy)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'port' => 12345 ], 'expected_error' => 'Invalid parameter "/1/port": a character string is expected.' ], 'Test proxy.update: invalid "port" (not empty string for active proxy)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'port' => '12345' ], 'expected_error' => 'Invalid parameter "/1/port": value must be "10051".' ], // Check "description". 'Test proxy.update: invalid "description" (boolean)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'description' => false ], 'expected_error' => 'Invalid parameter "/1/description": a character string is expected.' ], 'Test proxy.update: invalid "description" (too long)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'description' => str_repeat('a', DB::getFieldLength('proxy', 'description') + 1) ], 'expected_error' => 'Invalid parameter "/1/description": value is too long.' ], // Check "tls_connect". 'Test proxy.update: invalid "tls_connect" (string)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'tls_connect' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/tls_connect": an integer is expected.' ], 'Test proxy.update: invalid "tls_connect" (not in range) for active proxy' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'tls_connect' => self::INVALID_NUMBER ], 'expected_error' => 'Invalid parameter "/1/tls_connect": value must be '.HOST_ENCRYPTION_NONE.'.' ], 'Test proxy.update: invalid "tls_connect" (not in range) for passive proxy' => [ 'proxy' => [ 'proxyid' => 'passive_defaults', 'tls_connect' => self::INVALID_NUMBER ], 'expected_error' => 'Invalid parameter "/1/tls_connect": value must be one of '. implode(', ', [HOST_ENCRYPTION_NONE, HOST_ENCRYPTION_PSK, HOST_ENCRYPTION_CERTIFICATE]).'.' ], // Check "tls_accept". 'Test proxy.update: invalid "tls_accept" (string)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'tls_accept' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/tls_accept": an integer is expected.' ], 'Test proxy.update: invalid "tls_accept" (not in range) for active proxy' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'tls_accept' => self::INVALID_NUMBER ], 'expected_error' => 'Invalid parameter "/1/tls_accept": value must be one of '.HOST_ENCRYPTION_NONE.'-'. (HOST_ENCRYPTION_NONE | HOST_ENCRYPTION_PSK | HOST_ENCRYPTION_CERTIFICATE).'.' ], 'Test proxy.update: invalid "tls_accept" (not in range) for passive proxy' => [ 'proxy' => [ 'proxyid' => 'passive_defaults', 'tls_accept' => self::INVALID_NUMBER ], 'expected_error' => 'Invalid parameter "/1/tls_accept": value must be '.HOST_ENCRYPTION_NONE.'.' ], // Check "tls_psk_identity". 'Test proxy.update: invalid "tls_psk_identity" (boolean)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'tls_psk_identity' => false ], 'expected_error' => 'Invalid parameter "/1/tls_psk_identity": a character string is expected.' ], 'Test proxy.update: invalid "tls_psk_identity" (string) for active proxy #1' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'tls_psk_identity' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/tls_psk_identity": value must be empty.' ], 'Test proxy.update: invalid "tls_psk_identity" (string) for active proxy #2' => [ 'proxy' => [ 'proxyid' => 'active_cert', 'tls_psk_identity' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/tls_psk_identity": value must be empty.' ], 'Test proxy.update: invalid "tls_psk_identity" (empty string) for active proxy #1' => [ 'proxy' => [ 'proxyid' => 'active_psk', 'tls_psk_identity' => '' ], 'expected_error' => 'Invalid parameter "/1/tls_psk_identity": cannot be empty.' ], 'Test proxy.update: invalid "tls_psk_identity" (empty string) for active proxy #2' => [ 'proxy' => [ 'proxyid' => 'active_any', 'tls_psk_identity' => '' ], 'expected_error' => 'Invalid parameter "/1/tls_psk_identity": cannot be empty.' ], 'Test proxy.update: invalid "tls_psk_identity" (too long) for active proxy #1' => [ 'proxy' => [ 'proxyid' => 'active_psk', 'tls_psk_identity' => str_repeat('a', DB::getFieldLength('proxy', 'tls_psk_identity') + 1) ], 'expected_error' => 'Invalid parameter "/1/tls_psk_identity": value is too long.' ], 'Test proxy.update: invalid "tls_psk_identity" (too long) for active proxy #2' => [ 'proxy' => [ 'proxyid' => 'active_any', 'tls_psk_identity' => str_repeat('a', DB::getFieldLength('proxy', 'tls_psk_identity') + 1) ], 'expected_error' => 'Invalid parameter "/1/tls_psk_identity": value is too long.' ], 'Test proxy.update: invalid "tls_psk_identity" (string) for passive proxy #1' => [ 'proxy' => [ 'proxyid' => 'passive_defaults', 'tls_psk_identity' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/tls_psk_identity": value must be empty.' ], 'Test proxy.update: invalid "tls_psk_identity" (string) for passive proxy #2' => [ 'proxy' => [ 'proxyid' => 'passive_cert', 'tls_psk_identity' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/tls_psk_identity": value must be empty.' ], 'Test proxy.update: invalid "tls_psk_identity" (empty string) for passive proxy' => [ 'proxy' => [ 'proxyid' => 'passive_psk', 'tls_psk_identity' => '' ], 'expected_error' => 'Invalid parameter "/1/tls_psk_identity": cannot be empty.' ], 'Test proxy.update: invalid "tls_psk_identity" (too long) for passive proxy' => [ 'proxy' => [ 'proxyid' => 'passive_psk', 'tls_psk_identity' => str_repeat('a', DB::getFieldLength('proxy', 'tls_psk_identity') + 1) ], 'expected_error' => 'Invalid parameter "/1/tls_psk_identity": value is too long.' ], // Check "custom_timeouts". 'Test proxy.update: invalid "custom_timeouts" (null)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => null ], 'expected_error' => 'Invalid parameter "/1/custom_timeouts": an integer is expected.' ], 'Test proxy.update: invalid "custom_timeouts" (boolean)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => false ], 'expected_error' => 'Invalid parameter "/1/custom_timeouts": an integer is expected.' ], 'Test proxy.update: invalid "custom_timeouts" (string)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/custom_timeouts": an integer is expected.' ], 'Test proxy.update: invalid "custom_timeouts" (too small)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => -1 ], 'expected_error' => 'Invalid parameter "/1/custom_timeouts": value must be one of '. implode(', ', [ZBX_PROXY_CUSTOM_TIMEOUTS_DISABLED, ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED]).'.' ], 'Test proxy.update: invalid "custom_timeouts" (too large)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => self::INVALID_NUMBER ], 'expected_error' => 'Invalid parameter "/1/custom_timeouts": value must be one of '. implode(', ', [ZBX_PROXY_CUSTOM_TIMEOUTS_DISABLED, ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED]).'.' ], 'Test proxy.update: invalid "custom_timeouts" (proxy version is outdated)' => [ 'proxy' => [ 'proxyid' => 'version_outdated', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '4s', 'timeout_simple_check' => '4s', 'timeout_snmp_agent' => '4s', 'timeout_external_check' => '4s', 'timeout_db_monitor' => '4s', 'timeout_http_agent' => '4s', 'timeout_ssh_agent' => '4s', 'timeout_telnet_agent' => '4s', 'timeout_script' => '4s', 'timeout_browser' => '61s' ], 'expected_error' => 'Invalid parameter "/1/custom_timeouts": timeouts are disabled because the proxy and server versions do not match.' ], 'Test proxy.update: invalid "custom_timeouts" (proxy version is unsupported)' => [ 'proxy' => [ 'proxyid' => 'version_unsupported', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '4s', 'timeout_simple_check' => '4s', 'timeout_snmp_agent' => '4s', 'timeout_external_check' => '4s', 'timeout_db_monitor' => '4s', 'timeout_http_agent' => '4s', 'timeout_ssh_agent' => '4s', 'timeout_telnet_agent' => '4s', 'timeout_script' => '4s', 'timeout_browser' => '61s' ], 'expected_error' => 'Invalid parameter "/1/custom_timeouts": timeouts are disabled because the proxy and server versions do not match.' ], // Check "timeout_zabbix_agent". 'Test proxy.update: invalid "timeout_zabbix_agent" (null) if custom timeouts are disabled' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'timeout_zabbix_agent' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_zabbix_agent": a character string is expected.' ], 'Test proxy.update: invalid "timeout_zabbix_agent" (boolean) if custom timeouts are disabled' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'timeout_zabbix_agent' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_zabbix_agent": a character string is expected.' ], 'Test proxy.update: invalid "timeout_zabbix_agent" (not empty) if custom timeouts are disabled' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'timeout_zabbix_agent' => '5s' ], 'expected_error' => 'Invalid parameter "/1/timeout_zabbix_agent": value must be empty.' ], 'Test proxy.update: invalid "timeout_zabbix_agent" (null)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_zabbix_agent": a character string is expected.' ], 'Test proxy.update: invalid "timeout_zabbix_agent" (boolean)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_zabbix_agent": a character string is expected.' ], 'Test proxy.update: invalid "timeout_zabbix_agent" (empty string)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '' ], 'expected_error' => 'Invalid parameter "/1/timeout_zabbix_agent": cannot be empty.' ], 'Test proxy.update: invalid "timeout_zabbix_agent" (not a time unit)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/timeout_zabbix_agent": a time unit is expected.' ], 'Test proxy.update: invalid "timeout_zabbix_agent" (too small)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => -1 ], 'expected_error' => 'Invalid parameter "/1/timeout_zabbix_agent": value must be one of 1-600.' ], 'Test proxy.update: invalid "timeout_zabbix_agent" (too large)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => self::INVALID_NUMBER ], 'expected_error' => 'Invalid parameter "/1/timeout_zabbix_agent": value must be one of 1-600.' ], // Check "timeout_simple_check". 'Test proxy.update: invalid "timeout_simple_check" (null) if custom timeouts are disabled' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'timeout_simple_check' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_simple_check": a character string is expected.' ], 'Test proxy.update: invalid "timeout_simple_check" (boolean) if custom timeouts are disabled' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'timeout_simple_check' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_simple_check": a character string is expected.' ], 'Test proxy.update: invalid "timeout_simple_check" (not empty) if custom timeouts are disabled' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'timeout_simple_check' => '5s' ], 'expected_error' => 'Invalid parameter "/1/timeout_simple_check": value must be empty.' ], 'Test proxy.update: invalid "timeout_simple_check" (cannot be empty)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s' ], 'expected_error' => 'Invalid parameter "/1/timeout_simple_check": cannot be empty.' ], 'Test proxy.update: invalid "timeout_simple_check" (null)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_simple_check": a character string is expected.' ], 'Test proxy.update: invalid "timeout_simple_check" (boolean)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_simple_check": a character string is expected.' ], 'Test proxy.update: invalid "timeout_simple_check" (empty string)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '' ], 'expected_error' => 'Invalid parameter "/1/timeout_simple_check": cannot be empty.' ], 'Test proxy.update: invalid "timeout_simple_check" (not a time unit)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/timeout_simple_check": a time unit is expected.' ], 'Test proxy.update: invalid "timeout_simple_check" (too small)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => -1 ], 'expected_error' => 'Invalid parameter "/1/timeout_simple_check": value must be one of 1-600.' ], 'Test proxy.update: invalid "timeout_simple_check" (too large)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => self::INVALID_NUMBER ], 'expected_error' => 'Invalid parameter "/1/timeout_simple_check": value must be one of 1-600.' ], // Check "timeout_snmp_agent". 'Test proxy.update: invalid "timeout_snmp_agent" (null) if custom timeouts are disabled' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'timeout_snmp_agent' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_snmp_agent": a character string is expected.' ], 'Test proxy.update: invalid "timeout_snmp_agent" (boolean) if custom timeouts are disabled' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'timeout_snmp_agent' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_snmp_agent": a character string is expected.' ], 'Test proxy.update: invalid "timeout_snmp_agent" (not empty) if custom timeouts are disabled' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'timeout_snmp_agent' => '5s' ], 'expected_error' => 'Invalid parameter "/1/timeout_snmp_agent": value must be empty.' ], 'Test proxy.update: invalid "timeout_snmp_agent" (null)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_snmp_agent": a character string is expected.' ], 'Test proxy.update: invalid "timeout_snmp_agent" (boolean)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_snmp_agent": a character string is expected.' ], 'Test proxy.update: invalid "timeout_snmp_agent" (empty string)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '' ], 'expected_error' => 'Invalid parameter "/1/timeout_snmp_agent": cannot be empty.' ], 'Test proxy.update: invalid "timeout_snmp_agent" (not a time unit)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/timeout_snmp_agent": a time unit is expected.' ], 'Test proxy.update: invalid "timeout_snmp_agent" (too small)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => -1 ], 'expected_error' => 'Invalid parameter "/1/timeout_snmp_agent": value must be one of 1-600.' ], 'Test proxy.update: invalid "timeout_snmp_agent" (too large)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => self::INVALID_NUMBER ], 'expected_error' => 'Invalid parameter "/1/timeout_snmp_agent": value must be one of 1-600.' ], // Check "timeout_external_check". 'Test proxy.update: invalid "timeout_external_check" (null) if custom timeouts are disabled' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'timeout_external_check' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_external_check": a character string is expected.' ], 'Test proxy.update: invalid "timeout_external_check" (boolean) if custom timeouts are disabled' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'timeout_external_check' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_external_check": a character string is expected.' ], 'Test proxy.update: invalid "timeout_external_check" (not empty) if custom timeouts are disabled' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'timeout_external_check' => '5s' ], 'expected_error' => 'Invalid parameter "/1/timeout_external_check": value must be empty.' ], 'Test proxy.update: invalid "timeout_external_check" (null)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_external_check": a character string is expected.' ], 'Test proxy.update: invalid "timeout_external_check" (boolean)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_external_check": a character string is expected.' ], 'Test proxy.update: invalid "timeout_external_check" (empty string)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '' ], 'expected_error' => 'Invalid parameter "/1/timeout_external_check": cannot be empty.' ], 'Test proxy.update: invalid "timeout_external_check" (not a time unit)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/timeout_external_check": a time unit is expected.' ], 'Test proxy.update: invalid "timeout_external_check" (too small)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => -1 ], 'expected_error' => 'Invalid parameter "/1/timeout_external_check": value must be one of 1-600.' ], 'Test proxy.update: invalid "timeout_external_check" (too large)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => self::INVALID_NUMBER ], 'expected_error' => 'Invalid parameter "/1/timeout_external_check": value must be one of 1-600.' ], // Check "timeout_db_monitor". 'Test proxy.update: invalid "timeout_db_monitor" (null) if custom timeouts are disabled' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'timeout_db_monitor' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_db_monitor": a character string is expected.' ], 'Test proxy.update: invalid "timeout_db_monitor" (boolean) if custom timeouts are disabled' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'timeout_db_monitor' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_db_monitor": a character string is expected.' ], 'Test proxy.update: invalid "timeout_db_monitor" (not empty) if custom timeouts are disabled' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'timeout_db_monitor' => '5s' ], 'expected_error' => 'Invalid parameter "/1/timeout_db_monitor": value must be empty.' ], 'Test proxy.update: invalid "timeout_db_monitor" (null)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_db_monitor": a character string is expected.' ], 'Test proxy.update: invalid "timeout_db_monitor" (boolean)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_db_monitor": a character string is expected.' ], 'Test proxy.update: invalid "timeout_db_monitor" (empty string)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '' ], 'expected_error' => 'Invalid parameter "/1/timeout_db_monitor": cannot be empty.' ], 'Test proxy.update: invalid "timeout_db_monitor" (not a time unit)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/timeout_db_monitor": a time unit is expected.' ], 'Test proxy.update: invalid "timeout_db_monitor" (too small)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => -1 ], 'expected_error' => 'Invalid parameter "/1/timeout_db_monitor": value must be one of 1-600.' ], 'Test proxy.update: invalid "timeout_db_monitor" (too large)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => self::INVALID_NUMBER ], 'expected_error' => 'Invalid parameter "/1/timeout_db_monitor": value must be one of 1-600.' ], // Check "timeout_http_agent". 'Test proxy.update: invalid "timeout_http_agent" (null) if custom timeouts are disabled' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'timeout_http_agent' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_http_agent": a character string is expected.' ], 'Test proxy.update: invalid "timeout_http_agent" (boolean) if custom timeouts are disabled' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'timeout_http_agent' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_http_agent": a character string is expected.' ], 'Test proxy.update: invalid "timeout_http_agent" (not empty) if custom timeouts are disabled' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'timeout_http_agent' => '5s' ], 'expected_error' => 'Invalid parameter "/1/timeout_http_agent": value must be empty.' ], 'Test proxy.update: invalid "timeout_http_agent" (null)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_http_agent": a character string is expected.' ], 'Test proxy.update: invalid "timeout_http_agent" (boolean)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_http_agent": a character string is expected.' ], 'Test proxy.update: invalid "timeout_http_agent" (empty string)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '' ], 'expected_error' => 'Invalid parameter "/1/timeout_http_agent": cannot be empty.' ], 'Test proxy.update: invalid "timeout_http_agent" (not a time unit)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/timeout_http_agent": a time unit is expected.' ], 'Test proxy.update: invalid "timeout_http_agent" (too small)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => -1 ], 'expected_error' => 'Invalid parameter "/1/timeout_http_agent": value must be one of 1-600.' ], 'Test proxy.update: invalid "timeout_http_agent" (too large)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => self::INVALID_NUMBER ], 'expected_error' => 'Invalid parameter "/1/timeout_http_agent": value must be one of 1-600.' ], // Check "timeout_ssh_agent". 'Test proxy.update: invalid "timeout_ssh_agent" (null) if custom timeouts are disabled' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'timeout_ssh_agent' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_ssh_agent": a character string is expected.' ], 'Test proxy.update: invalid "timeout_ssh_agent" (boolean) if custom timeouts are disabled' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'timeout_ssh_agent' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_ssh_agent": a character string is expected.' ], 'Test proxy.update: invalid "timeout_ssh_agent" (not empty) if custom timeouts are disabled' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'timeout_ssh_agent' => '5s' ], 'expected_error' => 'Invalid parameter "/1/timeout_ssh_agent": value must be empty.' ], 'Test proxy.update: invalid "timeout_ssh_agent" (null)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_ssh_agent": a character string is expected.' ], 'Test proxy.update: invalid "timeout_ssh_agent" (boolean)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_ssh_agent": a character string is expected.' ], 'Test proxy.update: invalid "timeout_ssh_agent" (empty string)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '' ], 'expected_error' => 'Invalid parameter "/1/timeout_ssh_agent": cannot be empty.' ], 'Test proxy.update: invalid "timeout_ssh_agent" (not a time unit)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/timeout_ssh_agent": a time unit is expected.' ], 'Test proxy.update: invalid "timeout_ssh_agent" (too small)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => -1 ], 'expected_error' => 'Invalid parameter "/1/timeout_ssh_agent": value must be one of 1-600.' ], 'Test proxy.update: invalid "timeout_ssh_agent" (too large)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => self::INVALID_NUMBER ], 'expected_error' => 'Invalid parameter "/1/timeout_ssh_agent": value must be one of 1-600.' ], // Check "timeout_telnet_agent". 'Test proxy.update: invalid "timeout_telnet_agent" (null) if custom timeouts are disabled' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'timeout_telnet_agent' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_telnet_agent": a character string is expected.' ], 'Test proxy.update: invalid "timeout_telnet_agent" (boolean) if custom timeouts are disabled' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'timeout_telnet_agent' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_telnet_agent": a character string is expected.' ], 'Test proxy.update: invalid "timeout_telnet_agent" (not empty) if custom timeouts are disabled' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'timeout_telnet_agent' => '5s' ], 'expected_error' => 'Invalid parameter "/1/timeout_telnet_agent": value must be empty.' ], 'Test proxy.update: invalid "timeout_telnet_agent" (null)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_telnet_agent": a character string is expected.' ], 'Test proxy.update: invalid "timeout_telnet_agent" (boolean)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_telnet_agent": a character string is expected.' ], 'Test proxy.update: invalid "timeout_telnet_agent" (empty string)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => '' ], 'expected_error' => 'Invalid parameter "/1/timeout_telnet_agent": cannot be empty.' ], 'Test proxy.update: invalid "timeout_telnet_agent" (not a time unit)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/timeout_telnet_agent": a time unit is expected.' ], 'Test proxy.update: invalid "timeout_telnet_agent" (too small)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => -1 ], 'expected_error' => 'Invalid parameter "/1/timeout_telnet_agent": value must be one of 1-600.' ], 'Test proxy.update: invalid "timeout_telnet_agent" (too large)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => self::INVALID_NUMBER ], 'expected_error' => 'Invalid parameter "/1/timeout_telnet_agent": value must be one of 1-600.' ], // Check "timeout_script". 'Test proxy.update: invalid "timeout_script" (null) if custom timeouts are disabled' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'timeout_script' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_script": a character string is expected.' ], 'Test proxy.update: invalid "timeout_script" (boolean) if custom timeouts are disabled' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'timeout_script' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_script": a character string is expected.' ], 'Test proxy.update: invalid "timeout_script" (not empty) if custom timeouts are disabled' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'timeout_script' => '5s' ], 'expected_error' => 'Invalid parameter "/1/timeout_script": value must be empty.' ], 'Test proxy.update: invalid "timeout_script" (null)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => '5s', 'timeout_script' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_script": a character string is expected.' ], 'Test proxy.update: invalid "timeout_script" (boolean)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => '5s', 'timeout_script' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_script": a character string is expected.' ], 'Test proxy.update: invalid "timeout_script" (empty string)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => '5s', 'timeout_script' => '' ], 'expected_error' => 'Invalid parameter "/1/timeout_script": cannot be empty.' ], 'Test proxy.update: invalid "timeout_script" (not a time unit)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => '5s', 'timeout_script' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/timeout_script": a time unit is expected.' ], 'Test proxy.update: invalid "timeout_script" (too small)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => '5s', 'timeout_script' => -1 ], 'expected_error' => 'Invalid parameter "/1/timeout_script": value must be one of 1-600.' ], 'Test proxy.update: invalid "timeout_script" (too large)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => '5s', 'timeout_script' => self::INVALID_NUMBER ], 'expected_error' => 'Invalid parameter "/1/timeout_script": value must be one of 1-600.' ], // Check "timeout_browser". 'Test proxy.update: invalid "timeout_browser" (null) if custom timeouts are disabled' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'timeout_browser' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_browser": a character string is expected.' ], 'Test proxy.update: invalid "timeout_browser" (boolean) if custom timeouts are disabled' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'timeout_browser' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_browser": a character string is expected.' ], 'Test proxy.update: invalid "timeout_browser" (not empty) if custom timeouts are disabled' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'timeout_browser' => '5s' ], 'expected_error' => 'Invalid parameter "/1/timeout_browser": value must be empty.' ], 'Test proxy.update: invalid "timeout_browser" (null)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => '5s', 'timeout_script' => '5s', 'timeout_browser' => null ], 'expected_error' => 'Invalid parameter "/1/timeout_browser": a character string is expected.' ], 'Test proxy.update: invalid "timeout_browser" (boolean)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => '5s', 'timeout_script' => '5s', 'timeout_browser' => false ], 'expected_error' => 'Invalid parameter "/1/timeout_browser": a character string is expected.' ], 'Test proxy.update: invalid "timeout_browser" (empty string)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => '5s', 'timeout_script' => '5s', 'timeout_browser' => '' ], 'expected_error' => 'Invalid parameter "/1/timeout_browser": cannot be empty.' ], 'Test proxy.update: invalid "timeout_browser" (not a time unit)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => '5s', 'timeout_script' => '5s', 'timeout_browser' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/timeout_browser": a time unit is expected.' ], 'Test proxy.update: invalid "timeout_browser" (too small)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => '5s', 'timeout_script' => '5s', 'timeout_browser' => -1 ], 'expected_error' => 'Invalid parameter "/1/timeout_browser": value must be one of 1-600.' ], 'Test proxy.update: invalid "timeout_browser" (too large)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '5s', 'timeout_simple_check' => '5s', 'timeout_snmp_agent' => '5s', 'timeout_external_check' => '5s', 'timeout_db_monitor' => '5s', 'timeout_http_agent' => '5s', 'timeout_ssh_agent' => '5s', 'timeout_telnet_agent' => '5s', 'timeout_script' => '5s', 'timeout_browser' => self::INVALID_NUMBER ], 'expected_error' => 'Invalid parameter "/1/timeout_browser": value must be one of 1-600.' ], // Check "hosts". 'Test proxy.update: invalid "hosts" (string)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'hosts' => 'abc' ], 'expected_error' => 'Invalid parameter "/1/hosts": an array is expected.' ], 'Test proxy.update: invalid "hosts" (array with string)' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'hosts' => ['abc'] ], 'expected_error' => 'Invalid parameter "/1/hosts/1": an array is expected.' ], 'Test proxy.update: missing "hostid" for "hosts"' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'hosts' => [ [] ] ], 'expected_error' => 'Invalid parameter "/1/hosts/1": the parameter "hostid" is missing.' ], 'Test proxy.update: unexpected parameter for "hosts"' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'hosts' => [ ['abc' => ''] ] ], 'expected_error' => 'Invalid parameter "/1/hosts/1": unexpected parameter "abc".' ], 'Test proxy.update: invalid "hostid" (empty string) for "hosts"' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'hosts' => [ ['hostid' => ''] ] ], 'expected_error' => 'Invalid parameter "/1/hosts/1/hostid": a number is expected.' ], 'Test proxy.update: invalid "hostid" (non-existent) for "hosts"' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'hosts' => [ ['hostid' => self::INVALID_NUMBER] ] ], 'expected_error' => 'Invalid parameter "/1/hosts/1/hostid": object does not exist, or you have no permissions to it.' ], 'Test proxy.update: invalid "hostid" (duplicate) for "hosts"' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'hosts' => [ ['hostid' => 0], ['hostid' => 0] ] ], 'expected_error' => 'Invalid parameter "/1/hosts/2": value (hostid)=(0) already exists.' ] ]; } /** * Data provider for proxy.update. Array contains valid proxy parameters. * * @return array */ public static function getProxyUpdateDataValid(): array { return [ 'Test proxy.update: update single proxy without changes' => [ 'proxy' => [ 'proxyid' => 'active_defaults' ], 'expected_error' => null ], 'Test proxy.update: update multiple proxies' => [ 'proxy' => [ [ 'proxyid' => 'active_defaults', 'name' => 'API test proxy.update - active proxy updated', 'description' => 'Active proxy' ], [ 'proxyid' => 'passive_defaults', 'name' => 'API test proxy.update - passive proxy updated', 'description' => 'Passive proxy', 'address' => 'localhost', 'port' => '10051' ] ], 'expected_error' => null ], // Check custom timeouts can be updated. 'Test proxy.update: enable custom timeouts' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED, 'timeout_zabbix_agent' => '10s', 'timeout_simple_check' => '10s', 'timeout_snmp_agent' => '10s', 'timeout_external_check' => '10s', 'timeout_db_monitor' => '10s', 'timeout_http_agent' => '10s', 'timeout_ssh_agent' => '10s', 'timeout_telnet_agent' => '10s', 'timeout_script' => '10s', 'timeout_browser' => '10s' ], 'expected_error' => null ], 'Test proxy.update: disable custom timeouts' => [ 'proxy' => [ 'proxyid' => 'version_current_with_custom_timeouts', 'custom_timeouts' => ZBX_PROXY_CUSTOM_TIMEOUTS_DISABLED ], 'expected_error' => null ], 'Test proxy.update: update single per-item-type timeout if custom timeouts are enabled' => [ 'proxy' => [ 'proxyid' => 'version_current_with_custom_timeouts', 'timeout_external_check' => '30s' ], 'expected_error' => null ], 'Test proxy.update: update multiple per-item-type timeouts if custom timeouts are enabled' => [ 'proxy' => [ 'proxyid' => 'version_current_with_custom_timeouts', 'timeout_snmp_agent' => '30s', 'timeout_ssh_agent' => '5m' ], 'expected_error' => null ], 'Test proxy.update: update multiple per-item-type timeouts with macros values if custom timeouts are enabled' => [ 'proxy' => [ 'proxyid' => 'version_current_with_custom_timeouts', 'timeout_zabbix_agent' => '{$TIMEOUT.ZABBIX.AGENT}', 'timeout_simple_check' => '{$TIMEOUT.SIMPLE.CHECK}', 'timeout_snmp_agent' => '{$TIMEOUT.SNMP.AGENT}', 'timeout_external_check' => '{$TIMEOUT.EXTERNAL.CHECK}', 'timeout_db_monitor' => '{$TIMEOUT.DB.MONITOR}', 'timeout_http_agent' => '{$TIMEOUT.HTTP.AGENT}', 'timeout_ssh_agent' => '{$TIMEOUT.SSH.AGENT}', 'timeout_telnet_agent' => '{$TIMEOUT.TELNET.AGENT}', 'timeout_script' => '{$TIMEOUT.SCRIPT}', 'timeout_browser' => '{$TIMEOUT.BROWSER}' ], 'expected_error' => null ], // Check proxy can be assigned to host. 'Test proxy.update: assign proxy to single host' => [ 'proxy' => [ 'proxyid' => 'active_defaults', 'hosts' => [ ['hostid' => 'monitored_by_server_1'] ] ], 'expected_error' => null ], 'Test proxy.update: assign proxy to multiple hosts' => [ 'proxy' => [ 'proxyid' => 'passive_defaults', 'hosts' => [ ['hostid' => 'monitored_by_server_1'], ['hostid' => 'monitored_by_server_2'] ] ], 'expected_error' => null ] ]; } /** * Test proxy.update method. * * @dataProvider getProxyUpdateDataInvalid * @dataProvider getProxyUpdateDataValid */ public function testProxy_Update(array $proxies, ?string $expected_error): void { // Accept single and multiple proxies just like API method. Work with multidimensional array in result. if (!array_key_exists(0, $proxies)) { $proxies = zbx_toArray($proxies); } // Replace ID placeholders with real IDs. foreach ($proxies as &$proxy) { $proxy = self::resolveIds($proxy); } unset($proxy); $sql_proxies = 'SELECT NULL FROM proxy p'; $old_hash_proxies = CDBHelper::getHash($sql_proxies); if ($expected_error === null) { $proxyids = array_column($proxies, 'proxyid'); $db_proxies = $this->getProxies($proxyids); $this->call('proxy.update', $proxies, $expected_error); $proxies_upd = $this->getProxies($proxyids); $db_defaults = DB::getDefaults('proxy'); $timeout_fields = ['timeout_zabbix_agent', 'timeout_simple_check', 'timeout_snmp_agent', 'timeout_external_check', 'timeout_db_monitor', 'timeout_http_agent', 'timeout_ssh_agent', 'timeout_telnet_agent', 'timeout_script', 'timeout_browser' ]; // Compare records from DB before and after API call. foreach ($proxies as $proxy) { $db_proxy = $db_proxies[$proxy['proxyid']]; $proxy_upd = $proxies_upd[$proxy['proxyid']]; $this->assertNotEmpty($proxy_upd['name']); foreach (['name', 'description', 'allowed_addresses'] as $field) { if (array_key_exists($field, $proxy)) { $this->assertSame($proxy[$field], $proxy_upd[$field]); } else { $this->assertSame($db_proxy[$field], $proxy_upd[$field]); } } if (array_key_exists('proxy_groupid', $proxy)) { $this->assertEquals($proxy['proxy_groupid'], $proxy_upd['proxy_groupid']); } else { $this->assertEquals($db_proxy['proxy_groupid'], $proxy_upd['proxy_groupid']); } if ($proxy_upd['proxy_groupid'] == 0) { foreach (['local_address', 'local_port'] as $field) { if (array_key_exists($field, $proxy)) { $this->assertSame($proxy[$field], $proxy_upd[$field]); } else { $this->assertSame($db_defaults[$field], $proxy_upd[$field]); } } } else { foreach (['local_address', 'local_port'] as $field) { if (array_key_exists($field, $proxy)) { $this->assertSame($proxy[$field], $proxy_upd[$field]); } else { $this->assertSame($db_proxy[$field], $proxy_upd[$field]); } } } if (array_key_exists('operating_mode', $proxy)) { $this->assertEquals($proxy['operating_mode'], $proxy_upd['operating_mode']); } else { $this->assertEquals($db_proxy['operating_mode'], $proxy_upd['operating_mode']); } if ($proxy_upd['operating_mode'] != $db_proxy['operating_mode']) { if ($proxy_upd['operating_mode'] == PROXY_OPERATING_MODE_ACTIVE) { foreach (['address', 'port'] as $field) { if (array_key_exists($field, $proxy)) { $this->assertSame($proxy[$field], $proxy_upd[$field]); } else { $this->assertSame($db_defaults[$field], $proxy_upd[$field]); } } if (array_key_exists('tls_connect', $proxy)) { $this->assertEquals($proxy['tls_connect'], $proxy_upd['tls_connect']); } else { $this->assertEquals($db_defaults['tls_connect'], $proxy_upd['tls_connect']); } } elseif ($proxy_upd['operating_mode'] == PROXY_OPERATING_MODE_PASSIVE) { if (array_key_exists('tls_accept', $proxy)) { $this->assertEquals($proxy['tls_accept'], $proxy_upd['tls_accept']); } else { $this->assertEquals($db_defaults['tls_accept'], $proxy_upd['tls_accept']); } } } else { foreach (['address', 'port'] as $field) { if (array_key_exists($field, $proxy)) { $this->assertSame($proxy[$field], $proxy_upd[$field]); } else { $this->assertSame($db_proxy[$field], $proxy_upd[$field]); } } foreach (['tls_connect', 'tls_accept'] as $field) { if (array_key_exists($field, $proxy)) { $this->assertEquals($proxy[$field], $proxy_upd[$field]); } else { $this->assertEquals($db_proxy[$field], $proxy_upd[$field]); } } } if ($proxy_upd['operating_mode'] == PROXY_OPERATING_MODE_ACTIVE) { if ($proxy_upd['tls_accept'] != $db_proxy['tls_accept']) { foreach (['tls_issuer', 'tls_subject'] as $field) { if ($proxy_upd['tls_accept'] & HOST_ENCRYPTION_CERTIFICATE) { if (array_key_exists($field, $proxy)) { $this->assertSame($proxy[$field], $proxy_upd[$field]); } else { $this->assertEquals($db_proxy[$field], $proxy_upd[$field]); } } else { $this->assertSame($db_defaults[$field], $proxy_upd[$field]); } } foreach (['tls_psk_identity', 'tls_psk'] as $field) { if ($proxy_upd['tls_accept'] & HOST_ENCRYPTION_PSK) { $this->assertNotEmpty($proxy_upd[$field]); if (array_key_exists($field, $proxy)) { $this->assertSame($proxy[$field], $proxy_upd[$field]); } else { $this->assertSame($db_proxy[$field], $proxy_upd[$field]); } } else { $this->assertSame($db_defaults[$field], $proxy_upd[$field]); } } } else { foreach (['tls_issuer', 'tls_subject', 'tls_psk_identity', 'tls_psk'] as $field) { if (array_key_exists($field, $proxy)) { $this->assertSame($proxy[$field], $proxy_upd[$field]); } else { $this->assertSame($db_proxy[$field], $proxy_upd[$field]); } } } } elseif ($proxy_upd['operating_mode'] == PROXY_OPERATING_MODE_PASSIVE) { foreach (['address', 'port'] as $field) { $this->assertNotEmpty($proxy_upd[$field]); } if ($proxy_upd['tls_connect'] != $db_proxy['tls_connect']) { foreach (['tls_issuer', 'tls_subject'] as $field) { if ($proxy_upd['tls_connect'] == HOST_ENCRYPTION_CERTIFICATE) { if (array_key_exists($field, $proxy)) { $this->assertSame($proxy[$field], $proxy_upd[$field]); } else { $this->assertEquals($db_proxy[$field], $proxy_upd[$field]); } } else { $this->assertSame($db_defaults[$field], $proxy_upd[$field]); } } foreach (['tls_psk_identity', 'tls_psk'] as $field) { if ($proxy_upd['tls_connect'] == HOST_ENCRYPTION_PSK) { $this->assertNotEmpty($proxy_upd[$field]); if (array_key_exists($field, $proxy)) { $this->assertSame($proxy[$field], $proxy_upd[$field]); } else { $this->assertSame($db_proxy[$field], $proxy_upd[$field]); } } else { $this->assertSame($db_defaults[$field], $proxy_upd[$field]); } } } else { foreach (['tls_issuer', 'tls_subject', 'tls_psk_identity', 'tls_psk'] as $field) { if (array_key_exists($field, $proxy)) { $this->assertSame($proxy[$field], $proxy_upd[$field]); } else { $this->assertSame($db_proxy[$field], $proxy_upd[$field]); } } } } // Check custom per-item-type timeouts. if (array_key_exists('custom_timeouts', $proxy)) { $this->assertEquals($proxy['custom_timeouts'], $proxy_upd['custom_timeouts']); } else { $this->assertEquals($db_proxy['custom_timeouts'], $proxy_upd['custom_timeouts']); } foreach ($timeout_fields as $field) { if ($proxy_upd['custom_timeouts'] != $db_proxy['custom_timeouts']) { if ($proxy_upd['custom_timeouts'] == ZBX_PROXY_CUSTOM_TIMEOUTS_DISABLED) { if (array_key_exists($field, $proxy)) { $this->assertSame($proxy[$field], $proxy_upd[$field]); } else { $this->assertSame($db_defaults[$field], $proxy_upd[$field]); } } elseif ($proxy_upd['custom_timeouts'] == ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED) { $this->assertNotEmpty($proxy_upd[$field]); $this->assertSame($proxy[$field], $proxy_upd[$field]); } } elseif ($proxy_upd['custom_timeouts'] == ZBX_PROXY_CUSTOM_TIMEOUTS_DISABLED) { if (array_key_exists($field, $proxy)) { $this->assertSame($proxy[$field], $proxy_upd[$field]); } else { $this->assertSame($db_defaults[$field], $proxy_upd[$field]); } } elseif ($proxy_upd['custom_timeouts'] == ZBX_PROXY_CUSTOM_TIMEOUTS_ENABLED) { $this->assertNotEmpty($proxy_upd[$field]); if (array_key_exists($field, $proxy)) { $this->assertSame($proxy[$field], $proxy_upd[$field]); } else { $this->assertSame($db_proxy[$field], $proxy_upd[$field]); } } } // Check hosts. if (array_key_exists('hosts', $proxy)) { if ($proxy['hosts']) { $this->assertNotEmpty($proxy_upd['hosts']); $this->assertEqualsCanonicalizing($proxy['hosts'], $proxy_upd['hosts']); } else { $this->assertEmpty($proxy_upd['hosts']); } } else { $this->assertEqualsCanonicalizing($db_proxy['hosts'], $proxy_upd['hosts']); } } // Restore proxy original data after each test. $this->restoreProxies($db_proxies); } else { // Call method and make sure it really returns the error. $this->call('proxy.update', $proxies, $expected_error); // Make sure nothing has changed as well. $this->assertSame($old_hash_proxies, CDBHelper::getHash($sql_proxies)); } } /** * Data provider for proxy.delete. Array contains invalid proxies that are not possible to delete. * * @return array */ public static function getProxyDeleteDataInvalid(): array { return [ // Check proxy IDs. 'Test proxy.delete: empty ID' => [ 'proxyids' => [''], 'expected_error' => 'Invalid parameter "/1": a number is expected.' ], 'Test proxy.delete: non-existent ID' => [ 'proxyids' => [self::INVALID_NUMBER], 'expected_error' => 'No permissions to referred object or it does not exist!' ], 'Test proxy.delete: with two same IDs' => [ 'proxyids' => [0, 0], 'expected_error' => 'Invalid parameter "/2": value (0) already exists.' ], // Check if deleted proxies used to monitor hosts. 'Test proxy.delete: used in host' => [ 'proxyids' => ['without_proxy_group'], 'expected_error' => 'Host "API test proxy - monitored by proxy without group" is monitored by proxy "API test proxy - without proxy group".' ], // Check if deleted proxies used in actions. 'Test proxy.delete: used in action' => [ 'proxyids' => ['used_in_action'], 'expected_error' => 'Proxy "API test proxy - used in action" is used by action "API test proxy - discovery action".' ], // Check if deleted proxies used in network discovery rules. 'Test proxy.delete: used in discovery rule' => [ 'proxyids' => ['used_in_discovery_rule'], 'expected_error' => 'Proxy "API test proxy - used in discovery rule" is used by discovery rule "API test proxy - discovery rule".' ] ]; } /** * Data provider for proxy.delete. Array contains valid proxies. * * @return array */ public static function getProxyDeleteDataValid(): array { return [ 'Test proxy.delete: delete single' => [ 'proxy' => ['state_unknown'], 'expected_error' => null ], 'Test proxy.delete: delete multiple' => [ 'proxy' => [ 'state_offline', 'state_online' ], 'expected_error' => null ] ]; } /** * Test proxy.delete method. * * @dataProvider getProxyDeleteDataInvalid * @dataProvider getProxyDeleteDataValid */ public function testProxy_Delete(array $proxyids, ?string $expected_error): void { // Replace ID placeholders with real IDs. foreach ($proxyids as &$proxyid) { if (self::isValidIdPlaceholder($proxyid)) { $proxyid = self::$data['proxyids'][$proxyid]; } } unset($proxyid); $sql_proxies = 'SELECT NULL FROM proxy p'; $old_hash_proxies = CDBHelper::getHash($sql_proxies); $this->call('proxy.delete', $proxyids, $expected_error); if ($expected_error === null) { $this->assertNotSame($old_hash_proxies, CDBHelper::getHash($sql_proxies)); $this->assertEquals(0, CDBHelper::getCount( 'SELECT p.proxyid FROM proxy p WHERE '.dbConditionId('p.proxyid', $proxyids) )); foreach ($proxyids as $proxyid) { $key = array_search($proxyid, self::$data['proxyids']); if ($key !== false) { unset(self::$data['proxyids'][$key]); } } } else { $this->assertSame($old_hash_proxies, CDBHelper::getHash($sql_proxies)); } } /** * Get the original proxies before update. * * @param array $proxyids * * @return array */ private function getProxies(array $proxyids): array { $response = $this->call('proxy.get', [ 'output' => ['proxyid', 'name', 'proxy_groupid', 'local_address', 'local_port', 'operating_mode', 'allowed_addresses', 'address', 'port', 'description', 'tls_connect', 'tls_accept', 'tls_issuer', 'tls_subject', 'custom_timeouts', 'timeout_zabbix_agent', 'timeout_simple_check', 'timeout_snmp_agent', 'timeout_external_check', 'timeout_db_monitor', 'timeout_http_agent', 'timeout_ssh_agent', 'timeout_telnet_agent', 'timeout_script', 'timeout_browser', 'lastaccess', 'version', 'compatibility', 'state' ], 'selectHosts' => ['hostid'], 'proxyids' => $proxyids, 'preservekeys' => true, 'nopermissions' => true ]); $options = [ 'output' => ['proxyid', 'tls_psk_identity', 'tls_psk'], 'filter' => ['proxyid' => $proxyids] ]; $db_proxies = DBselect(DB::makeSql('proxy', $options)); while ($db_proxy = DBfetch($db_proxies)) { $response['result'][$db_proxy['proxyid']]['tls_psk_identity'] = $db_proxy['tls_psk_identity']; $response['result'][$db_proxy['proxyid']]['tls_psk'] = $db_proxy['tls_psk']; } return $response['result']; } /** * Restore proxies to their original state. * * @param array $proxies */ private function restoreProxies(array $proxies): void { $rtdata_fields = array_flip(['lastaccess', 'version', 'compatibility', 'state']); $upd_proxy_rtdata = []; foreach ($proxies as &$proxy) { $upd_proxy_rtdata[] = [ 'values' => array_intersect_key($proxy, $rtdata_fields), 'where' => ['proxyid' => $proxy['proxyid']] ]; $proxy = array_diff_key($proxy, $rtdata_fields); } unset($proxy); $this->call('proxy.update', $proxies); DB::update('proxy_rtdata', $upd_proxy_rtdata); } /** * Delete all created data after test. */ public static function clearData(): void { // Delete actions. CDataHelper::call('action.delete', self::$data['actionids']); // Delete discovery rules. CDataHelper::call('drule.delete', self::$data['druleids']); // Delete hosts. CDataHelper::call('host.delete', array_values(self::$data['hostids'])); // Delete host groups. CDataHelper::call('hostgroup.delete', self::$data['groupids']); // Delete proxies. $proxyids = array_values(self::$data['proxyids']); $proxyids = array_merge($proxyids, self::$data['created']); CDataHelper::call('proxy.delete', $proxyids); // Delete proxy groups. CDataHelper::call('proxygroup.delete', array_values(self::$data['proxy_groupids'])); } /** * Helper method to convert placeholders to real IDs. * * @param array $request * * @return array */ private static function resolveIds(array $request): array { foreach (['proxyid', 'proxy_groupid'] as $field) { if (array_key_exists($field, $request) && self::isValidIdPlaceholder($request[$field])) { $request[$field] = self::$data[$field.'s'][$request[$field]]; } } foreach (['proxyids', 'proxy_groupids'] as $field) { if (!array_key_exists($field, $request)) { continue; } if (is_array($request[$field])) { foreach ($request[$field] as &$id) { if (self::isValidIdPlaceholder($id)) { $id = self::$data[$field][$id]; } } unset($id); } elseif (self::isValidIdPlaceholder($request[$field])) { $request[$field] = self::$data[$field][$request[$field]]; } } foreach (['assignedHosts', 'hosts'] as $hosts) { if (array_key_exists($hosts, $request) && is_array($request[$hosts])) { foreach ($request[$hosts] as &$host) { if (is_array($host) && array_key_exists('hostid', $host) && self::isValidIdPlaceholder($host['hostid'])) { $host['hostid'] = self::$data['hostids'][$host['hostid']]; } } unset($host); } } if (array_key_exists('filter', $request) && is_array($request['filter'])) { foreach (['proxyid', 'proxy_groupid'] as $field) { if (!array_key_exists($field, $request['filter'])) { continue; } if (is_array($request['filter'][$field])) { foreach ($request['filter'][$field] as &$id) { if (self::isValidIdPlaceholder($id)) { $id = self::$data[$field.'s'][$id]; } } unset($id); } elseif (self::isValidIdPlaceholder($request['filter'][$field])) { $request['filter'][$field] = self::$data[$field.'s'][$request['filter'][$field]]; } } } return $request; } /** * Helper method to check ID placeholder. * * @param $id * * @return bool */ private static function isValidIdPlaceholder($id): bool { // Do not compare != 0 (it will not work) or !== 0 or !== '0' (avoid type check here). return !is_array($id) && $id != '0' && $id !== '' && $id !== null && $id != self::INVALID_NUMBER; } }