('45559','21','','10584','Get alarms data','aws.ecs.get_alarms','0s;m/1','0','0','0','4','','','','',NULL,NULL,'var AWS = {\r\n	params: {},\r\n	metadata: \'http://169.254.169.254/latest/\',\r\n\r\n	getField: function (data, path) {\r\n		var steps = path.split(\'.\');\r\n		for (var i = 0; i < steps.length; i++) {\r\n			var step = steps[i];\r\n			if (typeof data !== \'object\' || typeof data[step] === \'undefined\') {\r\n				throw \'Required field was not found: \' + path;\r\n			}\r\n\r\n			data = data[step];\r\n		}\r\n\r\n		return data;\r\n	},\r\n\r\n	setParams: function (params) {\r\n		AWS.params[\'proxy\'] = params.proxy;\r\n		switch (AWS.getField(params, \'auth_type\')) {\r\n			case \'role_base\':\r\n				AWS.params[\'auth_type\'] = \'role_base\';\r\n				var request = new HttpRequest();\r\n				if (typeof AWS.params.proxy !== \'undefined\' && AWS.params.proxy !== \'\') {\r\n					request.setProxy(AWS.params.proxy);\r\n				}\r\n				request.addHeader(\'X-aws-ec2-metadata-token-ttl-seconds: 21600\');\r\n				var token = request.put(AWS.metadata + \'api/token\');\r\n\r\n				if (request.getStatus() !== 200 || token === null || token === \'\') {\r\n					throw \'Error getting IMDSv2 session token.\';\r\n				}\r\n				request.addHeader(\'X-aws-ec2-metadata-token: \' + token);\r\n				var IamRoleName = request.get(AWS.metadata + \'meta-data/iam/security-credentials\');\r\n\r\n				if (request.getStatus() !== 200 || IamRoleName === null || IamRoleName === \'\') {\r\n					throw \'Error getting security credentials from instance metadata. Role not found.\';\r\n				}\r\n\r\n				credentials = request.get(AWS.metadata + \'meta-data/iam/security-credentials/\' + encodeURI(IamRoleName));\r\n\r\n				if (request.getStatus() !== 200 || credentials === null || credentials === \'\') {\r\n					throw \'Error getting security credentials from instance metadata.\';\r\n				}\r\n\r\n				try {\r\n					credentials = JSON.parse(credentials);\r\n				}\r\n				catch (error) {\r\n					throw \'Failed to parse response received from instance metadata. Check debug log for more information.\';\r\n				}\r\n\r\n				[\'AccessKeyId\', \'SecretAccessKey\', \'Token\'].forEach(function (field) {\r\n					if (typeof credentials !== \'object\' || typeof credentials[field] === \'undefined\' || credentials[field] === \'\') {\r\n						throw \'Required credentials are not set: "\' + field + \'".\';\r\n					};\r\n					AWS.params[field] = credentials[field];\r\n				});\r\n				break;\r\n			case \'assume_role\':\r\n				AWS.params[\'auth_type\'] = \'assume_role\';\r\n\r\n				[\'AccessKeyId\', \'SecretAccessKey\', \'sts_region\', \'role_arn\'].forEach(function (field) {\r\n					if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n						throw \'Required param is not set: "\' + field + \'".\';\r\n					}\r\n					AWS.params[field] = params[field];\r\n				});\r\n\r\n				role_arn_regex = /role\\/(.+)$/;\r\n\r\n				var payload = {\r\n					\'Action\': \'AssumeRole\',\r\n					\'Version\': \'2011-06-15\',\r\n					\'RoleArn\': AWS.params.role_arn,\r\n					\'RoleSessionName\': AWS.params.role_arn.match(role_arn_regex)[1] + \'Session\',\r\n				};\r\n\r\n				credentials = AWS.getField(AWS.request(\'GET\', AWS.params.sts_region, \'sts\', AWS.prepareParams(payload), \'\'), \'AssumeRoleResponse.AssumeRoleResult.Credentials\');\r\n\r\n				[\'AccessKeyId\', \'SecretAccessKey\', \'SessionToken\'].forEach(function (field) {\r\n					if (typeof credentials !== \'object\' || typeof credentials[field] === \'undefined\' || credentials[field] === \'\') {\r\n						throw \'Required credentials are not set: "\' + field + \'".\';\r\n					};\r\n					AWS.params[field] = credentials[field];\r\n				});\r\n				break;\r\n			default:\r\n				AWS.params[\'auth_type\'] = \'access_key\';\r\n				[\'AccessKeyId\', \'SecretAccessKey\'].forEach(function (field) {\r\n					if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n						throw \'Required param is not set: "\' + field + \'".\';\r\n					}\r\n					AWS.params[field] = params[field];\r\n				});\r\n		}\r\n		[\'region\', \'cluster_name\'].forEach(function (field) {\r\n			if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n				throw \'Required param is not set: "\' + field + \'".\';\r\n			}\r\n			AWS.params[field] = params[field];\r\n		});\r\n	},\r\n\r\n	sign: function (key, message) {\r\n		var hex = hmac(\'sha256\', key, message);\r\n\r\n		if ((hex.length % 2) === 1) {\r\n			throw \'Invalid length of a hex string!\';\r\n		}\r\n\r\n		var result = new Int8Array(hex.length / 2);\r\n		for (var i = 0, b = 0; i < hex.length; i += 2, b++) {\r\n			result[b] = parseInt(hex.substring(i, i + 2), 16);\r\n		}\r\n\r\n		return result;\r\n	},\r\n\r\n	prepareParams: function (params) {\r\n		var result = [];\r\n\r\n		Object.keys(params).sort().forEach(function (key) {\r\n			if (typeof params[key] !== \'object\') {\r\n				result.push(key + \'=\' + encodeURIComponent(params[key]));\r\n			}\r\n			else {\r\n				result.push(prepareObject(key, params[key]));\r\n			}\r\n		});\r\n\r\n		return result.join(\'&\');\r\n	},\r\n\r\n	request: function (method, region, service, params, data) {\r\n		if (typeof data === \'undefined\' || data === null) {\r\n			data = \'\';\r\n		}\r\n\r\n		var amzdate = (new Date()).toISOString().replace(/\\.\\d+Z/, \'Z\').replace(/[-:]/g, \'\'),\r\n			date = amzdate.replace(/T\\d+Z/, \'\'),\r\n			host = service + \'.\' + region + \'.amazonaws.com\',\r\n			canonical_uri = \'/\',\r\n			canonical_headers = \'content-encoding:amz-1.0\\n\' + \'host:\' + host + \'\\n\' + \'x-amz-date:\' + amzdate + \'\\n\',\r\n			signed_headers = \'content-encoding;host;x-amz-date\',\r\n			canonical_request = method + \'\\n\' + canonical_uri + \'\\n\' + params + \'\\n\' + canonical_headers + \'\\n\' + signed_headers + \'\\n\' + sha256(data),\r\n			credential_scope = date + \'/\' + region + \'/\' + service + \'/\' + \'aws4_request\',\r\n			request_string = \'AWS4-HMAC-SHA256\' + \'\\n\' + amzdate + \'\\n\' + credential_scope + \'\\n\' + sha256(canonical_request),\r\n			key = AWS.sign(\'AWS4\' + AWS.params.SecretAccessKey, date),\r\n			key = AWS.sign(key, region),\r\n			key = AWS.sign(key, service),\r\n			key = AWS.sign(key, \'aws4_request\'),\r\n			request = new HttpRequest(),\r\n			url = \'https://\' + host + canonical_uri + \'?\' + params;\r\n\r\n		if (typeof AWS.params.proxy !== \'undefined\' && AWS.params.proxy !== \'\') {\r\n			request.setProxy(AWS.params.proxy);\r\n		}\r\n		request.addHeader(\'x-amz-date: \' + amzdate);\r\n		request.addHeader(\'Accept: application/json\');\r\n		request.addHeader(\'Content-Type: application/json\');\r\n		request.addHeader(\'Content-Encoding: amz-1.0\');\r\n		request.addHeader(\'Authorization: \' + \'AWS4-HMAC-SHA256 Credential=\' + AWS.params.AccessKeyId + \'/\' + credential_scope + \', \' + \'SignedHeaders=\' + signed_headers + \', \' + \'Signature=\' + hmac(\'sha256\', key, request_string));\r\n		if (AWS.params.auth_type === \'role_base\' || (AWS.params.auth_type === \'assume_role\' & !params.includes(\'AssumeRole\'))) {\r\n			request.addHeader(\'X-Amz-Security-Token: \' + (AWS.params.auth_type === \'role_base\' ? AWS.params.Token : AWS.params.SessionToken));\r\n		}\r\n\r\n		Zabbix.log(4, \'[ AWS ECS ] Sending request: \' + url);\r\n		response = request.get(url);\r\n		Zabbix.log(4, \'[ AWS ECS ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n\r\n		if (request.getStatus() !== 200) {\r\n			throw \'Request failed with status code \' + request.getStatus() + \': \' + response;\r\n		}\r\n\r\n		try {\r\n			response = JSON.parse(response);\r\n		}\r\n		catch (error) {\r\n			try {\r\n				response = JSON.parse(XML.toJson(response));\r\n			}\r\n			catch (error) {\r\n				throw \'Failed to parse response received from AWS CloudWatch API. Check debug log for more information.\';\r\n			}\r\n		}\r\n\r\n		return response;\r\n	},\r\n\r\n	getAlarms: function () {\r\n		var payload = {\r\n			\'Action\': \'DescribeAlarms\',\r\n			\'Version\': \'2010-08-01\',\r\n			\'MaxRecords\': 100\r\n		},\r\n			result = [];\r\n\r\n		while (payload.NextToken !== \'\') {\r\n			var alarms = AWS.getField(AWS.request(\'GET\', AWS.params.region, \'monitoring\', AWS.prepareParams(payload)), \'DescribeAlarmsResponse.DescribeAlarmsResult\');\r\n			payload.NextToken = alarms.NextToken || \'\';\r\n			alarms_list = AWS.getField(alarms, \'MetricAlarms\');\r\n\r\n			if (!Array.isArray(alarms_list))\r\n				alarms_list = [alarms_list];\r\n			alarms_list.forEach(function (alarm) {\r\n				var dimensions = alarm.Dimensions;\r\n\r\n				Zabbix.log(4, \'[ AWS ECS ] dimensions: \' + JSON.stringify(dimensions));\r\n				if (Array.isArray(alarm.Metrics)) {\r\n					alarm.Metrics.forEach(function (metric) {\r\n						if (typeof metric.MetricStat === \'object\' && metric.MetricStat !== null\r\n							&& typeof metric.MetricStat.Metric === \'object\' && metric.MetricStat.Metric !== null\r\n							&& Array.isArray(metric.MetricStat.Metric.Dimensions)) {\r\n							dimensions = dimensions.concat(metric.MetricStat.Metric.Dimensions);\r\n						}\r\n					});\r\n				}\r\n				for (var i in dimensions) {\r\n					if (dimensions[i].Name === \'ClusterName\' && dimensions[i].Value === AWS.params.cluster_name) {\r\n						result.push(alarm);\r\n						break;\r\n					}\r\n				}\r\n			});\r\n		}\r\n\r\n		return result;\r\n	}\r\n}\r\n\r\ntry {\r\n	AWS.setParams(JSON.parse(value));\r\n\r\n	return JSON.stringify(AWS.getAlarms());\r\n}\r\ncatch (error) {\r\n	error += (String(error).endsWith(\'.\')) ? \'\' : \'.\';\r\n	Zabbix.log(3, \'[ AWS ECS ] ERROR: \' + error);\r\n\r\n	return JSON.stringify({ \'error\': error });\r\n}','','0','','','','','0',NULL,'Get alarms data.\r\nDescribeAlarms API method: https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_DescribeAlarms.html','0','30d','0','',NULL,'15s','','','','200','1','0','','','0','0','0','0','0','0','0','ee28426c92874a99b998198a5539599d','0','2','0'),
('45560','21','','10584','Get cluster services','aws.ecs.get_cluster_services','5m','0','0','0','4','','','','',NULL,NULL,'var AWS = {\r\n	params: {},\r\n	metadata: \'http://169.254.169.254/latest/\',\r\n\r\n	setParams: function (params) {\r\n		AWS.params[\'proxy\'] = params.proxy;\r\n		switch (AWS.getField(params, \'auth_type\')) {\r\n			case \'role_base\':\r\n				AWS.params[\'auth_type\'] = \'role_base\';\r\n				var request = new HttpRequest();\r\n				if (typeof AWS.params.proxy !== \'undefined\' && AWS.params.proxy !== \'\') {\r\n					request.setProxy(AWS.params.proxy);\r\n				}\r\n				request.addHeader(\'X-aws-ec2-metadata-token-ttl-seconds: 21600\');\r\n				var token = request.put(AWS.metadata + \'api/token\');\r\n\r\n				if (request.getStatus() !== 200 || token === null || token === \'\') {\r\n					throw \'Error getting IMDSv2 session token.\';\r\n				}\r\n				request.addHeader(\'X-aws-ec2-metadata-token: \' + token);\r\n				var IamRoleName = request.get(AWS.metadata + \'meta-data/iam/security-credentials\');\r\n\r\n				if (request.getStatus() !== 200 || IamRoleName === null || IamRoleName === \'\') {\r\n					throw \'Error getting security credentials from instance metadata. Role not found.\';\r\n				}\r\n\r\n				credentials = request.get(AWS.metadata + \'meta-data/iam/security-credentials/\' + encodeURI(IamRoleName));\r\n\r\n				if (request.getStatus() !== 200 || credentials === null || credentials === \'\') {\r\n					throw \'Error getting security credentials from instance metadata.\';\r\n				}\r\n\r\n				try {\r\n					credentials = JSON.parse(credentials);\r\n				}\r\n				catch (error) {\r\n					throw \'Failed to parse response received from instance metadata. Check debug log for more information.\';\r\n				}\r\n\r\n				[\'AccessKeyId\', \'SecretAccessKey\', \'Token\'].forEach(function (field) {\r\n					if (typeof credentials !== \'object\' || typeof credentials[field] === \'undefined\' || credentials[field] === \'\') {\r\n						throw \'Required credentials are not set: "\' + field + \'".\';\r\n					};\r\n					AWS.params[field] = credentials[field];\r\n				});\r\n				break;\r\n			case \'assume_role\':\r\n				AWS.params[\'auth_type\'] = \'assume_role\';\r\n\r\n				[\'AccessKeyId\', \'SecretAccessKey\', \'sts_region\', \'role_arn\'].forEach(function (field) {\r\n					if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n						throw \'Required param is not set: "\' + field + \'".\';\r\n					}\r\n					AWS.params[field] = params[field];\r\n				});\r\n\r\n				role_arn_regex = /role\\/(.+)$/;\r\n\r\n				var payload = {\r\n					\'Action\': \'AssumeRole\',\r\n					\'Version\': \'2011-06-15\',\r\n					\'RoleArn\': AWS.params.role_arn,\r\n					\'RoleSessionName\': AWS.params.role_arn.match(role_arn_regex)[1] + \'Session\',\r\n				};\r\n\r\n				credentials = AWS.getField(AWS.request(\'GET\', AWS.params.sts_region, \'sts\', AWS.prepareParams(payload)), \'AssumeRoleResponse.AssumeRoleResult.Credentials\');\r\n				[\'AccessKeyId\', \'SecretAccessKey\', \'SessionToken\'].forEach(function (field) {\r\n					if (typeof credentials !== \'object\' || typeof credentials[field] === \'undefined\' || credentials[field] === \'\') {\r\n						throw \'Required credentials are not set: "\' + field + \'".\';\r\n					};\r\n					AWS.params[field] = credentials[field];\r\n				});\r\n				break;\r\n			default:\r\n				AWS.params[\'auth_type\'] = \'access_key\';\r\n				[\'AccessKeyId\', \'SecretAccessKey\'].forEach(function (field) {\r\n					if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n						throw \'Required param is not set: "\' + field + \'".\';\r\n					}\r\n					AWS.params[field] = params[field];\r\n				});\r\n		}\r\n		[\'region\', \'cluster_name\'].forEach(function (field) {\r\n			if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n				throw \'Required param is not set: "\' + field + \'".\';\r\n			}\r\n			AWS.params[field] = params[field];\r\n		});\r\n	},\r\n\r\n	getField: function (data, path) {\r\n		var steps = path.split(\'.\');\r\n		for (var i = 0; i < steps.length; i++) {\r\n			var step = steps[i];\r\n			if (typeof data !== \'object\' || typeof data[step] === \'undefined\') {\r\n				throw \'Required field was not found: \' + path;\r\n			}\r\n\r\n			data = data[step];\r\n		}\r\n\r\n		return data;\r\n	},\r\n\r\n	sign: function (key, message) {\r\n		var hex = hmac(\'sha256\', key, message);\r\n\r\n		if ((hex.length % 2) === 1) {\r\n			throw \'Invalid length of a hex string!\';\r\n		}\r\n\r\n		var result = new Int8Array(hex.length / 2);\r\n		for (var i = 0, b = 0; i < hex.length; i += 2, b++) {\r\n			result[b] = parseInt(hex.substring(i, i + 2), 16);\r\n		}\r\n\r\n		return result;\r\n	},\r\n\r\n	prepareParams: function (params) {\r\n		var result = [];\r\n\r\n		Object.keys(params).sort().forEach(function (key) {\r\n			if (typeof params[key] !== \'object\') {\r\n				result.push(key + \'=\' + encodeURIComponent(params[key]));\r\n			}\r\n			else {\r\n				result.push(prepareObject(key, params[key]));\r\n			}\r\n		});\r\n\r\n		return result.join(\'&\');\r\n	},\r\n\r\n	request: function (method, region, service, params, data) {\r\n		if (typeof data === \'undefined\' || data === null) {\r\n			data = \'\';\r\n		}\r\n\r\n		var amzdate = (new Date()).toISOString().replace(/\\.\\d+Z/, \'Z\').replace(/[-:]/g, \'\'),\r\n			date = amzdate.replace(/T\\d+Z/, \'\'),\r\n			canonical_uri = \'/\',\r\n			host = service + \'.\' + region + \'.amazonaws.com\',\r\n			canonical_headers = \'content-encoding:amz-1.0\\n\' + \'host:\' + host + \'\\n\' + \'x-amz-date:\' + amzdate + \'\\n\',\r\n			signed_headers = \'content-encoding;host;x-amz-date\',\r\n			canonical_request = method + \'\\n\' + canonical_uri + \'\\n\' + params + \'\\n\' + canonical_headers + \'\\n\' + signed_headers + \'\\n\' + sha256(data),\r\n			credential_scope = date + \'/\' + region + \'/\' + service + \'/\' + \'aws4_request\',\r\n			request_string = \'AWS4-HMAC-SHA256\' + \'\\n\' + amzdate + \'\\n\' + credential_scope + \'\\n\' + sha256(canonical_request),\r\n			key = AWS.sign(\'AWS4\' + AWS.params.SecretAccessKey, date),\r\n			key = AWS.sign(key, region),\r\n			key = AWS.sign(key, service),\r\n			key = AWS.sign(key, \'aws4_request\'),\r\n			request = new HttpRequest(),\r\n			url = \'https://\' + host + canonical_uri + \'?\' + params;\r\n\r\n		if (typeof AWS.params.proxy !== \'undefined\' && AWS.params.proxy !== \'\') {\r\n			request.setProxy(AWS.params.proxy);\r\n		}\r\n		request.addHeader(\'x-amz-date: \' + amzdate);\r\n		request.addHeader(\'x-amz-content-sha256:\' + sha256(data));\r\n		request.addHeader(\'Accept: application/json\');\r\n		request.addHeader(\'Content-Type: application/x-www-form-urlencoded\');\r\n		request.addHeader(\'Content-Encoding: amz-1.0\');\r\n		request.addHeader(\'Authorization: \' + \'AWS4-HMAC-SHA256 Credential=\' + AWS.params.AccessKeyId + \'/\' + credential_scope + \', \' + \'SignedHeaders=\' + signed_headers + \', \' + \'Signature=\' + hmac(\'sha256\', key, request_string));\r\n		if (AWS.params.auth_type === \'role_base\' || (AWS.params.auth_type === \'assume_role\' & !params.includes(\'AssumeRole\'))) {\r\n			request.addHeader(\'X-Amz-Security-Token: \' + (AWS.params.auth_type === \'role_base\' ? AWS.params.Token : AWS.params.SessionToken));\r\n		}\r\n\r\n		Zabbix.log(4, \'[ AWS ECS ] Sending request: \' + url);\r\n		response = request.get(url);\r\n		Zabbix.log(4, \'[ AWS ECS ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n\r\n		if (request.getStatus() !== 200) {\r\n			throw \'Request failed with status code \' + request.getStatus() + \': \' + response;\r\n		}\r\n\r\n		try {\r\n			response = JSON.parse(response);\r\n		}\r\n		catch (error) {\r\n			try {\r\n				response = JSON.parse(XML.toJson(response));\r\n			}\r\n			catch (error) {\r\n				throw \'Failed to parse response received from AWS CloudWatch API. Check debug log for more information.\';\r\n			}\r\n		}\r\n\r\n		return response;\r\n	},\r\n\r\n	listServices: function () {\r\n		var payload = {\r\n			\'Action\': \'ListServices\',\r\n			\'Version\': \'2014-11-13\',\r\n			\'cluster\': AWS.params.cluster_name\r\n		},\r\n			services = [];\r\n\r\n		ECSClusters_Services = AWS.getField(AWS.request(\'GET\', AWS.params.region, \'ecs\', AWS.prepareParams(payload)), \'ListServicesResponse.ListServicesResult.serviceArns\');\r\n\r\n		for (k in ECSClusters_Services) {\r\n			id = ECSClusters_Services[k];\r\n\r\n			json = {};\r\n			input = id.split(AWS.params.cluster_name + \'/\');\r\n			for (var i = 1; i < input.length; i += 2) {\r\n				json[input[i]] = input[i + 1];\r\n			}\r\n			services.push({\r\n				\'service_name\': input[1],\r\n			});\r\n		}\r\n\r\n		if (Array.isArray(services))\r\n			return services;\r\n		else\r\n			return [services];\r\n	}\r\n};\r\n\r\ntry {\r\n	AWS.setParams(JSON.parse(value));\r\n	return JSON.stringify(AWS.listServices());\r\n}\r\ncatch (error) {\r\n	error += (String(error).endsWith(\'.\')) ? \'\' : \'.\';\r\n	Zabbix.log(3, \'[ AWS ECS ] ERROR: \' + error);\r\n	return JSON.stringify({ \'error\': error });\r\n}','','0','','','','','0',NULL,'Get cluster services.\r\nFull metrics list related to ECS: https://docs.aws.amazon.com/AmazonECS/latest/userguide/metrics-dimensions.html','0','30d','0','',NULL,'15s','','','','200','1','0','','','0','0','0','0','0','0','0','9818272bc51e4848bba7b2863dda9424','0','2','0'),
('45561','21','','10584','Get cluster metrics','aws.ecs.get_metrics','0s;m/1','0','0','0','4','','','','',NULL,NULL,'var AWS = {\r\n	params: {},\r\n	request_period: 600,\r\n	metadata: \'http://169.254.169.254/latest/\',\r\n\r\n	setParams: function (params) {\r\n		AWS.params[\'proxy\'] = params.proxy;\r\n		switch (AWS.getField(params, \'auth_type\')) {\r\n			case \'role_base\':\r\n				AWS.params[\'auth_type\'] = \'role_base\';\r\n				var request = new HttpRequest();\r\n				if (typeof AWS.params.proxy !== \'undefined\' && AWS.params.proxy !== \'\') {\r\n					request.setProxy(AWS.params.proxy);\r\n				}\r\n				request.addHeader(\'X-aws-ec2-metadata-token-ttl-seconds: 21600\');\r\n				var token = request.put(AWS.metadata + \'api/token\');\r\n\r\n				if (request.getStatus() !== 200 || token === null || token === \'\') {\r\n					throw \'Error getting IMDSv2 session token.\';\r\n				}\r\n				request.addHeader(\'X-aws-ec2-metadata-token: \' + token);\r\n				var IamRoleName = request.get(AWS.metadata + \'meta-data/iam/security-credentials\');\r\n\r\n				if (request.getStatus() !== 200 || IamRoleName === null || IamRoleName === \'\') {\r\n					throw \'Error getting security credentials from instance metadata. Role not found.\';\r\n				}\r\n\r\n				credentials = request.get(AWS.metadata + \'meta-data/iam/security-credentials/\' + encodeURI(IamRoleName));\r\n\r\n				if (request.getStatus() !== 200 || credentials === null || credentials === \'\') {\r\n					throw \'Error getting security credentials from instance metadata.\';\r\n				}\r\n\r\n				try {\r\n					credentials = JSON.parse(credentials);\r\n				}\r\n				catch (error) {\r\n					throw \'Failed to parse response received from instance metadata. Check debug log for more information.\';\r\n				}\r\n\r\n				[\'AccessKeyId\', \'SecretAccessKey\', \'Token\'].forEach(function (field) {\r\n					if (typeof credentials !== \'object\' || typeof credentials[field] === \'undefined\' || credentials[field] === \'\') {\r\n						throw \'Required credentials are not set: "\' + field + \'".\';\r\n					};\r\n					AWS.params[field] = credentials[field];\r\n				});\r\n				break;\r\n			case \'assume_role\':\r\n				AWS.params[\'auth_type\'] = \'assume_role\';\r\n\r\n				[\'AccessKeyId\', \'SecretAccessKey\', \'sts_region\', \'role_arn\'].forEach(function (field) {\r\n					if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n						throw \'Required param is not set: "\' + field + \'".\';\r\n					}\r\n					AWS.params[field] = params[field];\r\n				});\r\n\r\n				role_arn_regex = /role\\/(.+)$/;\r\n\r\n				var payload = {\r\n					\'Action\': \'AssumeRole\',\r\n					\'Version\': \'2011-06-15\',\r\n					\'RoleArn\': AWS.params.role_arn,\r\n					\'RoleSessionName\': AWS.params.role_arn.match(role_arn_regex)[1] + \'Session\',\r\n				};\r\n\r\n				credentials = AWS.getField(AWS.request(\'GET\', AWS.params.sts_region, \'sts\', AWS.prepareParams(payload), \'\'), \'AssumeRoleResponse.AssumeRoleResult.Credentials\');\r\n\r\n				[\'AccessKeyId\', \'SecretAccessKey\', \'SessionToken\'].forEach(function (field) {\r\n					if (typeof credentials !== \'object\' || typeof credentials[field] === \'undefined\' || credentials[field] === \'\') {\r\n						throw \'Required credentials are not set: "\' + field + \'".\';\r\n					};\r\n					AWS.params[field] = credentials[field];\r\n				});\r\n				break;\r\n			default:\r\n				AWS.params[\'auth_type\'] = \'access_key\';\r\n				[\'AccessKeyId\', \'SecretAccessKey\'].forEach(function (field) {\r\n					if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n						throw \'Required param is not set: "\' + field + \'".\';\r\n					}\r\n					AWS.params[field] = params[field];\r\n				});\r\n		}\r\n		[\'region\', \'cluster_name\'].forEach(function (field) {\r\n			if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n				throw \'Required param is not set: "\' + field + \'".\';\r\n			}\r\n			AWS.params[field] = params[field];\r\n		});\r\n	},\r\n\r\n	getField: function (data, path) {\r\n		var steps = path.split(\'.\');\r\n		for (var i = 0; i < steps.length; i++) {\r\n			var step = steps[i];\r\n			if (typeof data !== \'object\' || typeof data[step] === \'undefined\') {\r\n				throw \'Required field was not found: \' + path;\r\n			}\r\n\r\n			data = data[step];\r\n		}\r\n\r\n		return data;\r\n	},\r\n\r\n	sign: function (key, message) {\r\n		var hex = hmac(\'sha256\', key, message);\r\n\r\n		if ((hex.length % 2) === 1) {\r\n			throw \'Invalid length of a hex string!\';\r\n		}\r\n\r\n		var result = new Int8Array(hex.length / 2);\r\n		for (var i = 0, b = 0; i < hex.length; i += 2, b++) {\r\n			result[b] = parseInt(hex.substring(i, i + 2), 16);\r\n		}\r\n\r\n		return result;\r\n	},\r\n\r\n	prepareRecursive: function (prefix, param) {\r\n		var result = {};\r\n\r\n		if (typeof param === \'object\') {\r\n			if (Array.isArray(param)) {\r\n				param.forEach(function (value, index) {\r\n					var nested = AWS.prepareRecursive(prefix + \'.member.\' + (index + 1), value);\r\n					Object.keys(nested).forEach(function (key) {\r\n						result[key] = nested[key];\r\n					});\r\n				});\r\n			}\r\n			else {\r\n				Object.keys(param).forEach(function (k) {\r\n					var nested = AWS.prepareRecursive(prefix + \'.\' + k, param[k]);\r\n					Object.keys(nested).forEach(function (key) {\r\n						result[key] = nested[key];\r\n					});\r\n				});\r\n			}\r\n		}\r\n		else {\r\n			result[prefix] = param;\r\n		}\r\n\r\n		return result;\r\n	},\r\n\r\n	renderPayload: function (period, cluster_name) {\r\n		var metrics_list = [\r\n			\'ContainerInstanceCount:Count\',\r\n			\'ServiceCount:Count\',\r\n			\'CpuReserved:None\',\r\n			\'CpuUtilized:None\',\r\n			\'MemoryReserved:Megabytes\',\r\n			\'MemoryUtilized:Megabytes\',\r\n			\'NetworkRxBytes:Bytes/Second\',\r\n			\'NetworkTxBytes:Bytes/Second\',\r\n			\'StorageReadBytes:Bytes\',\r\n			\'StorageWriteBytes:Bytes\',\r\n			\'TaskCount:Count\',\r\n			\'EphemeralStorageReserved:Gigabytes\',\r\n			\'EphemeralStorageUtilized:Gigabytes\'\r\n		];\r\n\r\n		var metric_payload = [];\r\n		metrics_list.forEach(function (metric) {\r\n			var parts = metric.split(\':\', 2);\r\n			var name = parts[0].replace(/[^a-zA-Z0-9]/g, \'\');\r\n			metric_payload.push({\r\n				\'Id\': name.charAt(0).toLowerCase() + name.slice(1),\r\n				\'MetricStat\': {\r\n					\'Metric\': {\r\n						\'MetricName\': parts[0],\r\n						\'Namespace\': \'ECS/ContainerInsights\',\r\n						\'Dimensions\': [\r\n							{\r\n								\'Name\': \'ClusterName\',\r\n								\'Value\': cluster_name\r\n							}\r\n						]\r\n					},\r\n					\'Period\': period,\r\n					\'Stat\': \'Average\',\r\n					\'Unit\': parts[1]\r\n				}\r\n			});\r\n		});\r\n\r\n		return metric_payload;\r\n	},\r\n\r\n	prepareParams: function (params) {\r\n		var result = [];\r\n\r\n		Object.keys(params).sort().forEach(function (key) {\r\n			if (typeof params[key] !== \'object\') {\r\n				result.push(key + \'=\' + encodeURIComponent(params[key]));\r\n			}\r\n			else {\r\n				result.push(prepareObject(key, params[key]));\r\n			}\r\n		});\r\n\r\n		return result.join(\'&\');\r\n	},\r\n\r\n	request: function (method, region, service, params, data) {\r\n		if (typeof data === \'undefined\' || data === null) {\r\n			data = \'\';\r\n		}\r\n\r\n		var amzdate = (new Date()).toISOString().replace(/\\.\\d+Z/, \'Z\').replace(/[-:]/g, \'\'),\r\n			date = amzdate.replace(/T\\d+Z/, \'\'),\r\n			host = service + \'.\' + region + \'.amazonaws.com\',\r\n			canonical_uri = \'/\',\r\n			canonical_headers = \'content-encoding:amz-1.0\\n\' + \'host:\' + host + \'\\n\' + \'x-amz-date:\' + amzdate + \'\\n\',\r\n			signed_headers = \'content-encoding;host;x-amz-date\',\r\n			canonical_request = method + \'\\n\' + canonical_uri + \'\\n\' + params + \'\\n\' + canonical_headers + \'\\n\' + signed_headers + \'\\n\' + sha256(data),\r\n			credential_scope = date + \'/\' + region + \'/\' + service + \'/\' + \'aws4_request\',\r\n			request_string = \'AWS4-HMAC-SHA256\' + \'\\n\' + amzdate + \'\\n\' + credential_scope + \'\\n\' + sha256(canonical_request),\r\n			key = AWS.sign(\'AWS4\' + AWS.params.SecretAccessKey, date),\r\n			key = AWS.sign(key, region),\r\n			key = AWS.sign(key, service),\r\n			key = AWS.sign(key, \'aws4_request\'),\r\n			request = new HttpRequest(),\r\n			url = \'https://\' + host + canonical_uri + \'?\' + params;\r\n\r\n		if (typeof AWS.params.proxy !== \'undefined\' && AWS.params.proxy !== \'\') {\r\n			request.setProxy(AWS.params.proxy);\r\n		}\r\n		request.addHeader(\'x-amz-date: \' + amzdate);\r\n		request.addHeader(\'Accept: application/json\');\r\n		request.addHeader(\'Content-Type: application/json\');\r\n		request.addHeader(\'Content-Encoding: amz-1.0\');\r\n		request.addHeader(\'Authorization: \' + \'AWS4-HMAC-SHA256 Credential=\' + AWS.params.AccessKeyId + \'/\' + credential_scope + \', \' + \'SignedHeaders=\' + signed_headers + \', \' + \'Signature=\' + hmac(\'sha256\', key, request_string));\r\n		if (AWS.params.auth_type === \'role_base\' || (AWS.params.auth_type === \'assume_role\' & !params.includes(\'AssumeRole\'))) {\r\n			request.addHeader(\'X-Amz-Security-Token: \' + (AWS.params.auth_type === \'role_base\' ? AWS.params.Token : AWS.params.SessionToken));\r\n		}\r\n\r\n		Zabbix.log(4, \'[ AWS ECS  ] Sending request: \' + url);\r\n		response = request.get(url);\r\n		Zabbix.log(4, \'[ AWS ECS ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n\r\n		if (request.getStatus() !== 200) {\r\n			throw \'Request failed with status code \' + request.getStatus() + \': \' + response;\r\n		}\r\n\r\n		try {\r\n			response = JSON.parse(response);\r\n		}\r\n		catch (error) {\r\n			try {\r\n				response = JSON.parse(XML.toJson(response));\r\n			}\r\n			catch (error) {\r\n				throw \'Failed to parse response received from AWS CloudWatch API. Check debug log for more information.\';\r\n			}\r\n		}\r\n\r\n		return response;\r\n	},\r\n\r\n	getMetricsData: function () {\r\n		var timestamp = new Date().getTime(),\r\n			MetricData = [],\r\n			CPUUtilization,\r\n			MemoryUtilization,\r\n			DiskUtilization,\r\n			obj = {},\r\n			metrics = [\'CpuReserved\', \'CpuUtilized\', \'MemoryReserved\', \'MemoryUtilized\', \'EphemeralStorageReserved\', \'EphemeralStorageUtilized\'],\r\n			end_time = new Date(timestamp).toISOString().replace(/\\.\\d+Z/, \'Z\'),\r\n			start_time = new Date(timestamp - AWS.request_period * 1000).toISOString().replace(/\\.\\d+Z/, \'Z\'),\r\n			payload = AWS.prepareRecursive(\'MetricDataQueries\', AWS.renderPayload(AWS.request_period, AWS.params.cluster_name));\r\n\r\n		payload[\'Action\'] = \'GetMetricData\';\r\n		payload[\'Version\'] = \'2010-08-01\';\r\n		payload[\'StartTime\'] = start_time;\r\n		payload[\'EndTime\'] = end_time;\r\n		payload[\'ScanBy\'] = \'TimestampDescending\';\r\n\r\n		result = AWS.request(\'GET\', AWS.params.region, \'monitoring\', AWS.prepareParams(payload));\r\n		MetricData = AWS.getField(result, \'GetMetricDataResponse.GetMetricDataResult.MetricDataResults\')\r\n\r\n		MetricData.forEach(function (id) {\r\n			for (i in metrics) {\r\n				if (AWS.getField(id, \'Label\') === metrics[i]) {\r\n					obj[metrics[i]] = AWS.getField(id, \'Values\');\r\n				}\r\n			}\r\n		});\r\n		CPUUtilization = Math.abs(obj.CpuUtilized * 100 / obj.CpuReserved);\r\n		MemoryUtilization = Math.abs(obj.MemoryUtilized * 100 / obj.MemoryReserved);\r\n		DiskUtilization = Math.abs(obj.EphemeralStorageUtilized * 100 / obj.EphemeralStorageReserved);\r\n		return ({ MetricData, MemoryUtilization, CPUUtilization, DiskUtilization });\r\n	}\r\n};\r\n\r\ntry {\r\n	AWS.setParams(JSON.parse(value));\r\n\r\n	return JSON.stringify(AWS.getMetricsData());\r\n}\r\ncatch (error) {\r\n	error += (String(error).endsWith(\'.\')) ? \'\' : \'.\';\r\n	Zabbix.log(3, \'[ AWS ECS ] ERROR: \' + error);\r\n\r\n	return JSON.stringify({ \'error\': error });\r\n}','','0','','','','','0',NULL,'Get cluster metrics.\r\nFull metrics list related to ECS: https://docs.aws.amazon.com/AmazonECS/latest/userguide/metrics-dimensions.html','0','30d','0','',NULL,'15s','','','','200','1','0','','','0','0','0','0','0','0','0','01f1a371b56e4945b604cd8b396c85f5','0','2','0'),
('45576','21','','10584','[{#AWS.ECS.SERVICE.NAME}]: Get metrics','aws.ecs.services.get_metrics["{#AWS.ECS.SERVICE.NAME}"]','0s;m/5','0','0','0','4','','','','',NULL,NULL,'var AWS = {\r\n	params: {},\r\n	request_period: 600,\r\n	metadata: \'http://169.254.169.254/latest/\',\r\n\r\n	setParams: function (params) {\r\n		AWS.params[\'proxy\'] = params.proxy;\r\n		switch (AWS.getField(params, \'auth_type\')) {\r\n			case \'role_base\':\r\n				AWS.params[\'auth_type\'] = \'role_base\';\r\n				var request = new HttpRequest();\r\n				if (typeof AWS.params.proxy !== \'undefined\' && AWS.params.proxy !== \'\') {\r\n					request.setProxy(AWS.params.proxy);\r\n				}\r\n				request.addHeader(\'X-aws-ec2-metadata-token-ttl-seconds: 21600\');\r\n				var token = request.put(AWS.metadata + \'api/token\');\r\n\r\n				if (request.getStatus() !== 200 || token === null || token === \'\') {\r\n					throw \'Error getting IMDSv2 session token.\';\r\n				}\r\n				request.addHeader(\'X-aws-ec2-metadata-token: \' + token);\r\n				var IamRoleName = request.get(AWS.metadata + \'meta-data/iam/security-credentials\');\r\n\r\n				if (request.getStatus() !== 200 || IamRoleName === null || IamRoleName === \'\') {\r\n					throw \'Error getting security credentials from instance metadata. Role not found.\';\r\n				}\r\n\r\n				credentials = request.get(AWS.metadata + \'meta-data/iam/security-credentials/\' + encodeURI(IamRoleName));\r\n\r\n				if (request.getStatus() !== 200 || credentials === null || credentials === \'\') {\r\n					throw \'Error getting security credentials from instance metadata.\';\r\n				}\r\n\r\n				try {\r\n					credentials = JSON.parse(credentials);\r\n				}\r\n				catch (error) {\r\n					throw \'Failed to parse response received from instance metadata. Check debug log for more information.\';\r\n				}\r\n\r\n				[\'AccessKeyId\', \'SecretAccessKey\', \'Token\'].forEach(function (field) {\r\n					if (typeof credentials !== \'object\' || typeof credentials[field] === \'undefined\' || credentials[field] === \'\') {\r\n						throw \'Required credentials are not set: "\' + field + \'".\';\r\n					};\r\n					AWS.params[field] = credentials[field];\r\n				});\r\n				break;\r\n			case \'assume_role\':\r\n				AWS.params[\'auth_type\'] = \'assume_role\';\r\n\r\n				[\'AccessKeyId\', \'SecretAccessKey\', \'sts_region\', \'role_arn\'].forEach(function (field) {\r\n					if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n						throw \'Required param is not set: "\' + field + \'".\';\r\n					}\r\n					AWS.params[field] = params[field];\r\n				});\r\n\r\n				role_arn_regex = /role\\/(.+)$/;\r\n\r\n				var payload = {\r\n					\'Action\': \'AssumeRole\',\r\n					\'Version\': \'2011-06-15\',\r\n					\'RoleArn\': AWS.params.role_arn,\r\n					\'RoleSessionName\': AWS.params.role_arn.match(role_arn_regex)[1] + \'Session\',\r\n				};\r\n\r\n				credentials = AWS.getField(AWS.request(\'GET\', AWS.params.sts_region, \'sts\', AWS.prepareParams(payload), \'\'), \'AssumeRoleResponse.AssumeRoleResult.Credentials\');\r\n\r\n				[\'AccessKeyId\', \'SecretAccessKey\', \'SessionToken\'].forEach(function (field) {\r\n					if (typeof credentials !== \'object\' || typeof credentials[field] === \'undefined\' || credentials[field] === \'\') {\r\n						throw \'Required credentials are not set: "\' + field + \'".\';\r\n					};\r\n					AWS.params[field] = credentials[field];\r\n				});\r\n				break;\r\n			default:\r\n				AWS.params[\'auth_type\'] = \'access_key\';\r\n				[\'AccessKeyId\', \'SecretAccessKey\'].forEach(function (field) {\r\n					if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n						throw \'Required param is not set: "\' + field + \'".\';\r\n					}\r\n					AWS.params[field] = params[field];\r\n				});\r\n		}\r\n		[\'region\', \'cluster_name\', \'service_name\'].forEach(function (field) {\r\n			if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n				throw \'Required param is not set: "\' + field + \'".\';\r\n			}\r\n			AWS.params[field] = params[field];\r\n		});\r\n	},\r\n\r\n	getField: function (data, path) {\r\n		var steps = path.split(\'.\');\r\n		for (var i = 0; i < steps.length; i++) {\r\n			var step = steps[i];\r\n			if (typeof data !== \'object\' || typeof data[step] === \'undefined\') {\r\n				throw \'Required field was not found: \' + path;\r\n			}\r\n\r\n			data = data[step];\r\n		}\r\n\r\n		return data;\r\n	},\r\n\r\n	sign: function (key, message) {\r\n		var hex = hmac(\'sha256\', key, message);\r\n\r\n		if ((hex.length % 2) === 1) {\r\n			throw \'Invalid length of a hex string!\';\r\n		}\r\n\r\n		var result = new Int8Array(hex.length / 2);\r\n		for (var i = 0, b = 0; i < hex.length; i += 2, b++) {\r\n			result[b] = parseInt(hex.substring(i, i + 2), 16);\r\n		}\r\n\r\n		return result;\r\n	},\r\n\r\n	prepareRecursive: function (prefix, param) {\r\n		var result = {};\r\n\r\n		if (typeof param === \'object\') {\r\n			if (Array.isArray(param)) {\r\n				param.forEach(function (value, index) {\r\n					var nested = AWS.prepareRecursive(prefix + \'.member.\' + (index + 1), value);\r\n					Object.keys(nested).forEach(function (key) {\r\n						result[key] = nested[key];\r\n					});\r\n				});\r\n			}\r\n			else {\r\n				Object.keys(param).forEach(function (k) {\r\n					var nested = AWS.prepareRecursive(prefix + \'.\' + k, param[k]);\r\n					Object.keys(nested).forEach(function (key) {\r\n						result[key] = nested[key];\r\n					});\r\n				});\r\n			}\r\n		}\r\n		else {\r\n			result[prefix] = param;\r\n		}\r\n\r\n		return result;\r\n	},\r\n\r\n	renderPayload: function (period, cluster_name, service_name) {\r\n		var metrics_list = [\r\n			\'CpuReserved:None:ECS/ContainerInsights\',\r\n			\'CpuUtilized:None:ECS/ContainerInsights\',\r\n			\'CPUUtilization:Percent:AWS/ECS\',\r\n			\'MemoryUtilization:Percent:AWS/ECS\',\r\n			\'MemoryReserved:Megabytes:ECS/ContainerInsights\',\r\n			\'MemoryUtilized:Megabytes:ECS/ContainerInsights\',\r\n			\'NetworkRxBytes:Bytes/Second:ECS/ContainerInsights\',\r\n			\'NetworkTxBytes:Bytes/Second:ECS/ContainerInsights\',\r\n			\'StorageReadBytes:Bytes:ECS/ContainerInsights\',\r\n			\'StorageWriteBytes:Bytes:ECS/ContainerInsights\',\r\n			\'DeploymentCount:Count:ECS/ContainerInsights\',\r\n			\'TaskSetCount:Count:ECS/ContainerInsights\',\r\n			\'DesiredTaskCount:Count:ECS/ContainerInsights\',\r\n			\'PendingTaskCount:Count:ECS/ContainerInsights\',\r\n			\'RunningTaskCount:Count:ECS/ContainerInsights\',\r\n			\'EphemeralStorageReserved:Gigabytes:ECS/ContainerInsights\',\r\n			\'EphemeralStorageUtilized:Gigabytes:ECS/ContainerInsights\'\r\n		];\r\n\r\n		var metric_payload = [];\r\n		metrics_list.forEach(function (metric) {\r\n			var parts = metric.split(\':\', 3);\r\n			var name = parts[0].replace(/[^a-zA-Z0-9]/g, \'\');\r\n			metric_payload.push({\r\n				\'Id\': name.charAt(0).toLowerCase() + name.slice(1),\r\n				\'MetricStat\': {\r\n					\'Metric\': {\r\n						\'MetricName\': parts[0],\r\n						\'Namespace\': parts[2],\r\n						\'Dimensions\': [\r\n							{\r\n								\'Name\': \'ClusterName\',\r\n								\'Value\': cluster_name\r\n							}\r\n							,\r\n							{\r\n								\'Name\': \'ServiceName\',\r\n								\'Value\': service_name\r\n							}\r\n						]\r\n					},\r\n					\'Period\': period,\r\n					\'Stat\': \'Average\',\r\n					\'Unit\': parts[1]\r\n				}\r\n			});\r\n		});\r\n\r\n		return metric_payload;\r\n	},\r\n\r\n	prepareParams: function (params) {\r\n		var result = [];\r\n\r\n		Object.keys(params).sort().forEach(function (key) {\r\n			if (typeof params[key] !== \'object\') {\r\n				result.push(key + \'=\' + encodeURIComponent(params[key]));\r\n			}\r\n			else {\r\n				result.push(prepareObject(key, params[key]));\r\n			}\r\n		});\r\n\r\n		return result.join(\'&\');\r\n	},\r\n\r\n	request: function (method, region, service, params, data) {\r\n		if (typeof data === \'undefined\' || data === null) {\r\n			data = \'\';\r\n		}\r\n\r\n		var amzdate = (new Date()).toISOString().replace(/\\.\\d+Z/, \'Z\').replace(/[-:]/g, \'\'),\r\n			date = amzdate.replace(/T\\d+Z/, \'\'),\r\n			host = service + \'.\' + region + \'.amazonaws.com\',\r\n			canonical_uri = \'/\',\r\n			canonical_headers = \'content-encoding:amz-1.0\\n\' + \'host:\' + host + \'\\n\' + \'x-amz-date:\' + amzdate + \'\\n\',\r\n			signed_headers = \'content-encoding;host;x-amz-date\',\r\n			canonical_request = method + \'\\n\' + canonical_uri + \'\\n\' + params + \'\\n\' + canonical_headers + \'\\n\' + signed_headers + \'\\n\' + sha256(data),\r\n			credential_scope = date + \'/\' + region + \'/\' + service + \'/\' + \'aws4_request\',\r\n			request_string = \'AWS4-HMAC-SHA256\' + \'\\n\' + amzdate + \'\\n\' + credential_scope + \'\\n\' + sha256(canonical_request),\r\n			key = AWS.sign(\'AWS4\' + AWS.params.SecretAccessKey, date),\r\n			key = AWS.sign(key, region),\r\n			key = AWS.sign(key, service),\r\n			key = AWS.sign(key, \'aws4_request\'),\r\n			request = new HttpRequest(),\r\n			url = \'https://\' + host + canonical_uri + \'?\' + params;\r\n\r\n		if (typeof AWS.params.proxy !== \'undefined\' && AWS.params.proxy !== \'\') {\r\n			request.setProxy(AWS.params.proxy);\r\n		}\r\n		request.addHeader(\'x-amz-date: \' + amzdate);\r\n		request.addHeader(\'Accept: application/json\');\r\n		request.addHeader(\'Content-Type: application/json\');\r\n		request.addHeader(\'Content-Encoding: amz-1.0\');\r\n		request.addHeader(\'Authorization: \' + \'AWS4-HMAC-SHA256 Credential=\' + AWS.params.AccessKeyId + \'/\' + credential_scope + \', \' + \'SignedHeaders=\' + signed_headers + \', \' + \'Signature=\' + hmac(\'sha256\', key, request_string));\r\n		if (AWS.params.auth_type === \'role_base\' || (AWS.params.auth_type === \'assume_role\' & !params.includes(\'AssumeRole\'))) {\r\n			request.addHeader(\'X-Amz-Security-Token: \' + (AWS.params.auth_type === \'role_base\' ? AWS.params.Token : AWS.params.SessionToken));\r\n		}\r\n\r\n		Zabbix.log(4, \'[ AWS ECS  ] Sending request: \' + url);\r\n		response = request.get(url);\r\n		Zabbix.log(4, \'[ AWS ECS ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n\r\n		if (request.getStatus() !== 200) {\r\n			throw \'Request failed with status code \' + request.getStatus() + \': \' + response;\r\n		}\r\n\r\n		try {\r\n			response = JSON.parse(response);\r\n		}\r\n		catch (error) {\r\n			try {\r\n				response = JSON.parse(XML.toJson(response));\r\n			}\r\n			catch (error) {\r\n				throw \'Failed to parse response received from AWS CloudWatch API. Check debug log for more information.\';\r\n			}\r\n		}\r\n\r\n		return response;\r\n	},\r\n\r\n	getMetricsData: function () {\r\n		var timestamp = new Date().getTime(),\r\n			end_time = new Date(timestamp).toISOString().replace(/\\.\\d+Z/, \'Z\'),\r\n			start_time = new Date(timestamp - AWS.request_period * 1000).toISOString().replace(/\\.\\d+Z/, \'Z\'),\r\n			payload = AWS.prepareRecursive(\'MetricDataQueries\', AWS.renderPayload(AWS.request_period, AWS.params.cluster_name, AWS.params.service_name));\r\n\r\n		payload[\'Action\'] = \'GetMetricData\';\r\n		payload[\'Version\'] = \'2010-08-01\';\r\n		payload[\'StartTime\'] = start_time;\r\n		payload[\'EndTime\'] = end_time;\r\n		payload[\'ScanBy\'] = \'TimestampDescending\';\r\n\r\n		result = AWS.request(\'GET\', AWS.params.region, \'monitoring\', AWS.prepareParams(payload));\r\n		MetricData = AWS.getField(result, \'GetMetricDataResponse.GetMetricDataResult.MetricDataResults\')\r\n\r\n		return MetricData;\r\n	}\r\n};\r\n\r\ntry {\r\n	AWS.setParams(JSON.parse(value));\r\n\r\n	return JSON.stringify(AWS.getMetricsData());\r\n}\r\ncatch (error) {\r\n	error += (String(error).endsWith(\'.\')) ? \'\' : \'.\';\r\n	Zabbix.log(3, \'[ AWS ECS ] ERROR: \' + error);\r\n\r\n	return JSON.stringify({ \'error\': error });\r\n}','','0','','','','','2',NULL,'Get metrics of ESC services.\r\nFull metrics list related to ECS : https://docs.aws.amazon.com/ecs/index.html','0','30d','0','',NULL,'15s','','','','200','1','0','','','0','0','0','0','0','0','0','0f80f5477ed04dbfbcb241c06854a6ff','0','2','0'),
('45595','21','','10535','ECS clusters discovery','aws.ecs.discovery','12h','90d','365d','0','4','','','','',NULL,NULL,'var AWS = {\r\n	params: {},\r\n	metadata: \'http://169.254.169.254/latest/\',\r\n\r\n	setParams: function (params) {\r\n		AWS.params[\'proxy\'] = params.proxy;\r\n		switch (AWS.getField(params, \'auth_type\')) {\r\n			case \'role_base\':\r\n				AWS.params[\'auth_type\'] = \'role_base\';\r\n				var request = new HttpRequest();\r\n				if (typeof AWS.params.proxy !== \'undefined\' && AWS.params.proxy !== \'\') {\r\n					request.setProxy(AWS.params.proxy);\r\n				}\r\n				request.addHeader(\'X-aws-ec2-metadata-token-ttl-seconds: 21600\');\r\n				var token = request.put(AWS.metadata + \'api/token\');\r\n\r\n				if (request.getStatus() !== 200 || token === null || token === \'\') {\r\n					throw \'Error getting IMDSv2 session token.\';\r\n				}\r\n				request.addHeader(\'X-aws-ec2-metadata-token: \' + token);\r\n				var IamRoleName = request.get(AWS.metadata + \'meta-data/iam/security-credentials\');\r\n\r\n				if (request.getStatus() !== 200 || IamRoleName === null || IamRoleName === \'\') {\r\n					throw \'Error getting security credentials from instance metadata. Role not found.\';\r\n				}\r\n\r\n				credentials = request.get(AWS.metadata + \'meta-data/iam/security-credentials/\' + encodeURI(IamRoleName));\r\n\r\n				if (request.getStatus() !== 200 || credentials === null || credentials === \'\') {\r\n					throw \'Error getting security credentials from instance metadata.\';\r\n				}\r\n\r\n				try {\r\n					credentials = JSON.parse(credentials);\r\n				}\r\n				catch (error) {\r\n					throw \'Failed to parse response received from instance metadata. Check debug log for more information.\';\r\n				}\r\n\r\n				[\'AccessKeyId\', \'SecretAccessKey\', \'Token\'].forEach(function (field) {\r\n					if (typeof credentials !== \'object\' || typeof credentials[field] === \'undefined\' || credentials[field] === \'\') {\r\n						throw \'Required credentials are not set: "\' + field + \'".\';\r\n					};\r\n					AWS.params[field] = credentials[field];\r\n				});\r\n				break;\r\n			case \'assume_role\':\r\n				AWS.params[\'auth_type\'] = \'assume_role\';\r\n\r\n				[\'AccessKeyId\', \'SecretAccessKey\', \'sts_region\', \'role_arn\'].forEach(function (field) {\r\n					if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n						throw \'Required param is not set: "\' + field + \'".\';\r\n					}\r\n					AWS.params[field] = params[field];\r\n				});\r\n\r\n				role_arn_regex = /role\\/(.+)$/;\r\n\r\n				var payload = {\r\n					\'Action\': \'AssumeRole\',\r\n					\'Version\': \'2011-06-15\',\r\n					\'RoleArn\': AWS.params.role_arn,\r\n					\'RoleSessionName\': AWS.params.role_arn.match(role_arn_regex)[1] + \'Session\',\r\n				};\r\n\r\n				credentials = AWS.getField(AWS.request(\'GET\', AWS.params.sts_region, \'sts\', AWS.prepareParams(payload)), \'AssumeRoleResponse.AssumeRoleResult.Credentials\');\r\n\r\n				[\'AccessKeyId\', \'SecretAccessKey\', \'SessionToken\'].forEach(function (field) {\r\n					if (typeof credentials !== \'object\' || typeof credentials[field] === \'undefined\' || credentials[field] === \'\') {\r\n						throw \'Required credentials are not set: "\' + field + \'".\';\r\n					};\r\n					AWS.params[field] = credentials[field];\r\n				});\r\n				break;\r\n			default:\r\n				AWS.params[\'auth_type\'] = \'access_key\';\r\n				[\'AccessKeyId\', \'SecretAccessKey\'].forEach(function (field) {\r\n					if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n						throw \'Required param is not set: "\' + field + \'".\';\r\n					}\r\n					AWS.params[field] = params[field];\r\n				});\r\n		}\r\n		[\'describe_region\', \'region_match\', \'region_not_match\'].forEach(function (field) {\r\n			if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n				throw \'Required param is not set: "\' + field + \'".\';\r\n			}\r\n			AWS.params[field] = params[field];\r\n		});\r\n	},\r\n\r\n	getField: function (data, path) {\r\n		var steps = path.split(\'.\');\r\n		for (var i = 0; i < steps.length; i++) {\r\n			var step = steps[i];\r\n			if (typeof data !== \'object\' || typeof data[step] === \'undefined\') {\r\n				throw \'Required field was not found: \' + path;\r\n			}\r\n			data = data[step];\r\n		}\r\n\r\n		return data;\r\n\r\n	},\r\n\r\n	sign: function (key, message) {\r\n		var hex = hmac(\'sha256\', key, message);\r\n		if ((hex.length % 2) === 1) {\r\n			throw \'Invalid length of a hex string!\';\r\n		}\r\n		var result = new Int8Array(hex.length / 2);\r\n		for (var i = 0, b = 0; i < hex.length; i += 2, b++) {\r\n			result[b] = parseInt(hex.substring(i, i + 2), 16);\r\n		}\r\n\r\n		return result;\r\n\r\n	},\r\n\r\n	prepareParams: function (params) {\r\n		var result = [];\r\n		Object.keys(params).sort().forEach(function (key) {\r\n			if (typeof params[key] !== \'object\') {\r\n				result.push(key + \'=\' + encodeURIComponent(params[key]));\r\n			}\r\n			else {\r\n				result.push(prepareObject(key, params[key]));\r\n			}\r\n		});\r\n\r\n		return result.join(\'&\');\r\n\r\n	},\r\n\r\n	request: function (method, region, service, params, data) {\r\n		if (typeof data === \'undefined\' || data === null) {\r\n			data = \'\';\r\n		}\r\n		var amzdate = (new Date()).toISOString().replace(/\\.\\d+Z/, \'Z\').replace(/[-:]/g, \'\'),\r\n			date = amzdate.replace(/T\\d+Z/, \'\'),\r\n			canonical_uri = \'/\',\r\n			host = service + \'.\' + region + \'.amazonaws.com\',\r\n			canonical_headers = \'content-encoding:amz-1.0\\n\' + \'host:\' + host + \'\\n\' + \'x-amz-date:\' + amzdate + \'\\n\',\r\n			signed_headers = \'content-encoding;host;x-amz-date\',\r\n			canonical_request = method + \'\\n\' + canonical_uri + \'\\n\' + params + \'\\n\' + canonical_headers + \'\\n\' + signed_headers + \'\\n\' + sha256(data),\r\n			credential_scope = date + \'/\' + region + \'/\' + service + \'/\' + \'aws4_request\',\r\n			request_string = \'AWS4-HMAC-SHA256\' + \'\\n\' + amzdate + \'\\n\' + credential_scope + \'\\n\' + sha256(canonical_request),\r\n			key = AWS.sign(\'AWS4\' + AWS.params.SecretAccessKey, date),\r\n			key = AWS.sign(key, region),\r\n			key = AWS.sign(key, service),\r\n			key = AWS.sign(key, \'aws4_request\'),\r\n			request = new HttpRequest(),\r\n			url = \'https://\' + host + canonical_uri + \'?\' + params;\r\n\r\n		if (typeof AWS.params.proxy !== \'undefined\' && AWS.params.proxy !== \'\') {\r\n			request.setProxy(AWS.params.proxy);\r\n		}\r\n		request.addHeader(\'x-amz-date: \' + amzdate);\r\n		request.addHeader(\'x-amz-content-sha256:\' + sha256(data));\r\n		request.addHeader(\'Accept: application/json\');\r\n		request.addHeader(\'Content-Type: application/x-www-form-urlencoded\');\r\n		request.addHeader(\'Content-Encoding: amz-1.0\');\r\n		request.addHeader(\'Authorization: \' + \'AWS4-HMAC-SHA256 Credential=\' + AWS.params.AccessKeyId + \'/\' + credential_scope + \', \' + \'SignedHeaders=\' + signed_headers + \', \' + \'Signature=\' + hmac(\'sha256\', key, request_string));\r\n		if (AWS.params.auth_type === \'role_base\' || (AWS.params.auth_type === \'assume_role\' & !params.includes(\'AssumeRole\'))) {\r\n			request.addHeader(\'X-Amz-Security-Token: \' + (AWS.params.auth_type === \'role_base\' ? AWS.params.Token : AWS.params.SessionToken));\r\n		}\r\n\r\n		Zabbix.log(4, \'[ AWS ECS ] Sending request: \' + url);\r\n		response = request.get(url);\r\n		Zabbix.log(4, \'[ AWS ECS ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n\r\n		if (request.getStatus() !== 200) {\r\n			throw \'Request failed with status code \' + request.getStatus() + \': \' + response;\r\n		}\r\n		try {\r\n			response = JSON.parse(response);\r\n		}\r\n		catch (error) {\r\n			try {\r\n				response = JSON.parse(XML.toJson(response));\r\n			}\r\n			catch (error) {\r\n				throw \'Failed to parse response received from AWS API. Check debug log for more information.\';\r\n			}\r\n		}\r\n\r\n		return response;\r\n\r\n	},\r\n\r\n	listRegions: function () {\r\n		var payload = {\r\n			\'Action\': \'DescribeRegions\',\r\n			\'Version\': \'2016-11-15\'\r\n		};\r\n\r\n		regions = AWS.getField(AWS.request(\'GET\', AWS.params.describe_region, \'ec2\', AWS.prepareParams(payload)), \'DescribeRegionsResponse.regionInfo.item\');\r\n\r\n		if (!Array.isArray(regions))\r\n			regions = [regions]\r\n\r\n		return regions\r\n	},\r\n\r\n	listClusters: function () {\r\n		var data = [],\r\n			regions = AWS.listRegions(),\r\n			result,\r\n			ECSClusters,\r\n			payload = {\r\n				\'Action\': \'ListClusters\',\r\n				\'Version\': \'2014-11-13\'\r\n			};\r\n\r\n		regions.forEach(function (region) {\r\n			var region_name = AWS.getField(region, \'regionName\');\r\n			if (region_name.match(AWS.params.region_match) === null ||\r\n				region_name.match(AWS.params.region_not_match) !== null)\r\n				return;\r\n\r\n			result = AWS.request(\'GET\', region_name, \'ecs\', AWS.prepareParams(payload));\r\n			ECSClusters = AWS.getField(result, \'ListClustersResponse.ListClustersResult.clusterArns\')\r\n			for (k in ECSClusters) {\r\n				clusters = ECSClusters[k];\r\n				json = {};\r\n				input = clusters.split(\'/\');\r\n				for (var i = 1; i < input.length; i += 2) {\r\n					json[input[i]] = input[i + 1];\r\n				}\r\n				data.push({\r\n					\'clusters_name\': input[1],\r\n					\'region\': region_name\r\n				});\r\n			}\r\n		});\r\n\r\n		return data;\r\n	},\r\n\r\n	decribeClusters: function (cluster_name, region_name) {\r\n		var payload = {\r\n			\'Action\': \'DescribeClusters\',\r\n			\'Version\': \'2014-11-13\',\r\n			\'clusters.clusterName\': cluster_name,\r\n			\'include.statistics\': \'STATISTICS\'\r\n		};\r\n		result = AWS.request(\'GET\', region_name, \'ecs\', AWS.prepareParams(payload));\r\n\r\n		return result;\r\n\r\n	}\r\n\r\n};\r\n\r\ntry {\r\n	AWS.setParams(JSON.parse(value));\r\n	var clusters = AWS.listClusters(),\r\n		infrastructure = [],\r\n		metrics = [\'runningEC2TasksCount\', \'pendingEC2TasksCount\', \'activeEC2ServiceCount\', \'drainingEC2ServiceCount\'],\r\n		ECSClusters = [],\r\n		DescribeClusters = [];\r\n	DescribeClusters = clusters.map(function (cluster) {\r\n		ECSClusters = AWS.getField(AWS.decribeClusters(cluster.clusters_name, cluster.region), \'DescribeClustersResponse.DescribeClustersResult.clusters\')\r\n		for (k in ECSClusters) {\r\n			var ECS2 = 0;\r\n			statistic = AWS.getField(ECSClusters[k], \'statistics\');\r\n			statistic.forEach(function (id) {\r\n				for (i in metrics) {\r\n					if (AWS.getField(id, \'name\') === metrics[i]) {\r\n						ECS2 += Number(AWS.getField(id, \'value\'));\r\n					}\r\n				}\r\n			})\r\n			infrastructure = (ECS2 > 0) ? \'use_ecs2\' : \'serverless\';\r\n\r\n			return {\r\n				\'clusterName\': ECSClusters[k].clusterName,\r\n				\'status\': ECSClusters[k].status,\r\n				\'infrastructure\': infrastructure,\r\n				\'region\': cluster.region\r\n			}\r\n\r\n		}\r\n	})\r\n\r\n	return JSON.stringify(DescribeClusters);\r\n\r\n}\r\ncatch (error) {\r\n	error += (String(error).endsWith(\'.\')) ? \'\' : \'.\';\r\n	Zabbix.log(3, \'[ AWS ECS ] ERROR: \' + error);\r\n	return JSON.stringify({ \'error\': error });\r\n}','','0','','','','','1',NULL,'Get ECS clusters.','0','7d','1','',NULL,'{$AWS.DATA.TIMEOUT}','','','','200','1','0','','','0','0','0','0','0','0','0','44b68894d68c45ec9a5ea787c975ae16','0','2','0'),
('45596','21','','10586','Get access token and service catalog','openstack.identity.auth','{$OPENSTACK.AUTH.INTERVAL}','0','0','0','4','','','','',NULL,NULL,'\r\nconst request_path = \'/v3/auth/tokens\';\r\n\r\nfunction checkParams(params) {\r\n	[\'api_url\', \'app_cred_id\', \'app_cred_secret\'].forEach(function (field) {\r\n		if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n			throw \'Required param is not set: \' + field + \'.\';\r\n		}\r\n	});\r\n	return params;\r\n}\r\n\r\nfunction getHttpData(url, params, app_cred_id, app_cred_secret) {\r\n	const request = new HttpRequest();\r\n\r\n	request.addHeader(\'Content-Type: application/json\');\r\n\r\n	const request_body = {\r\n		"auth": {\r\n			"identity": {\r\n				"methods": [\r\n					"application_credential"\r\n				],\r\n				"application_credential": {\r\n					"id": app_cred_id,\r\n					"secret": app_cred_secret\r\n				}\r\n			}\r\n		}\r\n	};\r\n\r\n	if (params[\'http_proxy\']) {\r\n		request.setProxy(params[\'http_proxy\'])\r\n		Zabbix.log(4, \'[ Openstack Nova API ] Using http proxy: \' + params[\'http_proxy\']);\r\n	}\r\n\r\n	const response = request.post(url, JSON.stringify(request_body));\r\n	Zabbix.log(4, \'[ Openstack Identity API ] [ \' + url + \' ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n\r\n	if (request.getStatus() !== 201) {\r\n		if (typeof (response.error && response.error.message) !== \'undefined\') {\r\n			throw response.error.message;\r\n		} else {\r\n			throw \'Failed to receive data: invalid response status code. Check debug log for more information.\';\r\n		}\r\n	}\r\n\r\n	return {\'request\': request, \'response\': response};\r\n}\r\n\r\nfunction parseHttpData(http_data) {\r\n	var token;\r\n	const headers = http_data[\'request\'].getHeaders(true);\r\n	if (typeof headers === "object") {\r\n		if (headers !== null) {\r\n			try {\r\n				token = headers["X-Subject-Token"][0];\r\n			} catch (error) {\r\n				throw \'Failed to parse response received from OpenStack Identity API. Check debug log for more information.\';\r\n			}\r\n		} else {\r\n			throw \'Response object is empty. Check debug log for more information.\';\r\n		}\r\n	} else {\r\n		throw \'Cannot process response data: received data is not an object. Check debug log for more information.\';\r\n	}\r\n\r\n	const supported_services = [\'nova\'];\r\n\r\n	var ret = [];\r\n	const data = JSON.parse(http_data[\'response\']);\r\n	if (data[\'token\'][\'catalog\']) {\r\n		const service_catalog = data[\'token\'][\'catalog\'];\r\n	} else {\r\n		throw \'Cannot find service catalog in HTTP response.\'\r\n	}\r\n\r\n	service_catalog.forEach(function (service) {\r\n		if (supported_services.indexOf(service.name) > -1) {\r\n			service.endpoints.forEach(function (endpoint) {\r\n				if (endpoint.interface === \'public\') {\r\n					ret.push({\r\n						\'service_name\': service.name[0].toUpperCase() + service.name.slice(1),\r\n						\'service_url\': endpoint.url,\r\n						\'token\': token\r\n					});\r\n				}\r\n			})\r\n		}\r\n	});\r\n\r\n	return JSON.stringify(ret);\r\n}\r\n\r\nconst params = checkParams(JSON.parse(value)),\r\n	url = params.api_url,\r\n	auth_cred_id = params.app_cred_id,\r\n	auth_cred_secret = params.app_cred_secret;\r\n\r\nconst httpData = getHttpData(url + request_path, params, auth_cred_id, auth_cred_secret);\r\nreturn parseHttpData(httpData);','','0','','','','','0',NULL,'Authorizes user on the OpenStack Identity service and gets the service catalog.','0','30d','0','',NULL,'10s','','','','200','1','0','','','0','0','0','0','0','0','0','0518d08edbf2480abf15f4ef0e7a251a','0','2','0'),
('45597','19','','10587','Get availability zones','openstack.nova.availability_zone.get','{$OPENSTACK.NOVA.INTERVAL.AVAILABILITY_ZONE}','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Gets a list of availability zones and its data.','0','30d','0','',NULL,'10s','{$OPENSTACK.NOVA.SERVICE.URL}/os-availability-zone/detail','','','200','1','0','{$OPENSTACK.HTTP.PROXY}','X-Auth-Token: {$OPENSTACK.TOKEN}','0','0','0','0','0','0','0','87d263a6f797439c8c7699d96f4305fb','0','2','0'),
('45598','19','','10587','Get hypervisors','openstack.nova.hypervisors.get','{$OPENSTACK.NOVA.INTERVAL.HYPERVISOR}','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Gets a list of hypervisors and its data.','0','30d','0','',NULL,'10s','{$OPENSTACK.NOVA.SERVICE.URL}/os-hypervisors/detail','','','200','1','0','{$OPENSTACK.HTTP.PROXY}','X-Auth-Token: {$OPENSTACK.TOKEN}','0','0','0','0','0','0','0','c4297b412ad54bae85a1219e2d988bcb','0','2','0'),
('45599','19','','10587','Get absolute limits','openstack.nova.limits.get','{$OPENSTACK.NOVA.INTERVAL.LIMITS}','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Gets absolute limits for the project.','0','30d','0','',NULL,'10s','{$OPENSTACK.NOVA.SERVICE.URL}/limits','','','200','1','0','{$OPENSTACK.HTTP.PROXY}','X-Auth-Token: {$OPENSTACK.TOKEN}','0','0','0','0','0','0','0','02698d2fcd2949868013dedb311b8db3','0','2','0'),
('45600','15','','10587','Instances count, free','openstack.nova.limits.instances.free','{$OPENSTACK.NOVA.INTERVAL.LIMITS}','31d','365d','0','3','','','','',NULL,NULL,'last(//openstack.nova.limits.instances.max)-last(//openstack.nova.limits.instances.current)','','0','','','','','0',NULL,'Number of available servers for each tenant.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','29898c0cb13d4ccebc3da95c082da29b','0','2','0'),
('45601','15','','10587','RAM usage, free','openstack.nova.limits.ram.free','{$OPENSTACK.NOVA.INTERVAL.LIMITS}','31d','365d','0','3','','b','','',NULL,NULL,'last(//openstack.nova.limits.ram.max)-last(//openstack.nova.limits.ram.current)','','0','','','','','0',NULL,'Amount of available server RAM.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','bdc1492bbb5c4bcd844eaa6f6e76c1ff','0','2','0'),
('45602','15','','10587','vCPUs usage, free','openstack.nova.limits.vcpu.free','{$OPENSTACK.NOVA.INTERVAL.LIMITS}','31d','365d','0','3','','','','',NULL,NULL,'last(//openstack.nova.limits.vcpu.max)-last(//openstack.nova.limits.vcpu.current)','','0','','','','','0',NULL,'Number of available server cores for each tenant.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','97d3b897722d4910aea8e4c3c5f6c9a9','0','2','0'),
('45603','19','','10587','Get servers','openstack.nova.servers.get','{$OPENSTACK.NOVA.INTERVAL.SERVERS}','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Gets a list of servers.','0','30d','0','',NULL,'10s','{$OPENSTACK.NOVA.SERVICE.URL}/servers','','','200','1','0','{$OPENSTACK.HTTP.PROXY}','X-Auth-Token: {$OPENSTACK.TOKEN}','0','0','0','0','0','0','0','85d746d8b6cf404f95eeb7903c2e66e0','0','2','0'),
('45604','19','','10587','Get compute services','openstack.nova.services.get','{$OPENSTACK.NOVA.INTERVAL.SERVICES}','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Gets a list of compute services and its data.','0','30d','0','',NULL,'10s','{$OPENSTACK.NOVA.SERVICE.URL}/os-services','','','200','1','0','{$OPENSTACK.HTTP.PROXY}','X-Auth-Token: {$OPENSTACK.TOKEN}','0','0','0','0','0','0','0','3db93b6116ad416eb10da851cce385a1','0','2','0'),
('45605','21','','10587','Get tenants','openstack.nova.tenant.get','{$OPENSTACK.NOVA.INTERVAL.TENANTS}','0','0','0','4','','','','',NULL,NULL,'\r\nconst request_path = \'/os-simple-tenant-usage\';\r\n\r\nfunction checkParams(params) {\r\n	[\'api_url\', \'api_token\', \'period\'].forEach(function (field) {\r\n		if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n			throw \'Required param is not set: \' + field + \'.\';\r\n		}\r\n		if (field === \'period\') {\r\n			const supported_values = [\'y\', \'m\', \'w\', \'d\']\r\n			if (supported_values.indexOf(params[field]) === -1) {\r\n				throw \'Tenant period not correctly set. Expected one of "y", "m", "w", "d"; received: \' + field + \'.\';\r\n			}\r\n		}\r\n	});\r\n	return params;\r\n}\r\n\r\nfunction buildUrl(url, period) {\r\n	const current_date = new Date();\r\n	var datetime_formatted = \'\'\r\n	switch (period) {\r\n		case \'y\':\r\n			datetime_formatted =\r\n				current_date.getFullYear() + \'-\' +\r\n				\'1-\' +\r\n				\'1T\' +\r\n				\'00:00:00\'\r\n			break;\r\n		case \'m\':\r\n			datetime_formatted =\r\n			current_date.getFullYear() + \'-\' +\r\n				(current_date.getMonth() + 1) + \'-\' +\r\n			\'1T\' +\r\n			\'00:00:00\'\r\n			break;\r\n		case \'w\':\r\n			const first_date_of_week = current_date.getDate() - current_date.getDay() + 1\r\n			datetime_formatted =\r\n				current_date.getFullYear() + \'-\' +\r\n				(current_date.getMonth() + 1) + \'-\' +\r\n				first_date_of_week + \'T\' +\r\n				\'00:00:00\'\r\n			break;\r\n		case \'d\':\r\n			datetime_formatted =\r\n				current_date.getFullYear() + \'-\' +\r\n				(current_date.getMonth() + 1) + \'-\' +\r\n				current_date.getDate() + \'T\' +\r\n				\'00:00:00\'\r\n			break;\r\n	}\r\n\r\n	return url + request_path + \'?\' +\r\n		\'start=\' + encodeURIComponent(datetime_formatted)\r\n}\r\n\r\nfunction getHttpData(url, params, api_token) {\r\n	const request = new HttpRequest();\r\n\r\n	request.addHeader(\'Content-Type: application/json\');\r\n	request.addHeader(\'X-Auth-Token: \' + api_token);\r\n	if (params[\'http_proxy\']) {\r\n		request.setProxy(params[\'http_proxy\'])\r\n		Zabbix.log(4, \'[ Openstack Nova API ] Using http proxy: \' + params[\'http_proxy\']);\r\n	}\r\n\r\n	const response = request.get(url, JSON.stringify(params));\r\n	Zabbix.log(4, \'[ Openstack Nova API ] [ \' + url + \' ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n\r\n	if (request.getStatus() !== 200) {\r\n		if (typeof (response.error && response.error.message) !== \'undefined\') {\r\n			throw response.error.message;\r\n		} else {\r\n			throw \'Failed to receive data: invalid response status code ( \' + request.getStatus() + \' ). Check debug log for more information.\';\r\n		}\r\n	}\r\n\r\n	return response;\r\n}\r\n\r\nconst params = checkParams(JSON.parse(value)),\r\n	url = params.api_url,\r\n	token = params.api_token,\r\n	period = params.period;\r\n\r\nreturn getHttpData(buildUrl(url, period), params, token);','','0','','','','','0',NULL,'Gets a list of tenants and its data.','0','30d','0','',NULL,'10s','','','','200','1','0','','','0','0','0','0','0','0','0','c258e567922c4f71a4dee9c0d6b88b1e','0','2','0'),
('45618','19','','10587','Server [{#SERVER_ID}]:[{#SERVER_NAME}]: Status','openstack.nova.server.status.get[{#SERVER_ID}]','{$OPENSTACK.NOVA.INTERVAL.SERVERS}','31d','365d','0','3','','','','',NULL,'1106','','','0','','','','','2',NULL,'Server status.','0','30d','0','',NULL,'10s','{$OPENSTACK.NOVA.SERVICE.URL}/servers/{#SERVER_ID}','','','200','1','0','{$OPENSTACK.HTTP.PROXY}','X-Auth-Token: {$OPENSTACK.TOKEN}','0','0','0','0','0','0','0','84fd4be0c5f84744ac6bd93d4d4e8f0e','0','2','0'),
('45635','11','','10589','Get archive','db.odbc.select[pgsql.archive,,"Database={$PG.DATABASE};{$PG.CONNSTRING.ODBC}"]','1m','0','0','0','4','','','','',NULL,NULL,'WITH values AS (\r\n  SELECT\r\n    4096/(ceil(pg_settings.setting::numeric/1024/1024))::int AS segment_parts_count,\r\n    setting::bigint AS segment_size,\r\n    (\'x\' || substring(pg_stat_archiver.last_archived_wal from 9 for 8))::bit(32)::int AS last_wal_div,\r\n    (\'x\' || substring(pg_stat_archiver.last_archived_wal from 17 for 8))::bit(32)::int AS last_wal_mod,\r\n    CASE WHEN pg_is_in_recovery() THEN NULL \r\n      ELSE (\'x\' || substring(pg_walfile_name(pg_current_wal_lsn()) from 9 for 8))::bit(32)::int END AS current_wal_div,\r\n    CASE WHEN pg_is_in_recovery() THEN NULL \r\n      ELSE (\'x\' || substring(pg_walfile_name(pg_current_wal_lsn()) from 17 for 8))::bit(32)::int END AS current_wal_mod\r\n  FROM pg_settings, pg_stat_archiver\r\n  WHERE pg_settings.name = \'wal_segment_size\')\r\nSELECT json_build_object(\r\n  \'archived_count\', (SELECT archived_count FROM pg_stat_archiver),\r\n  \'failed_count\', (SELECT failed_count FROM pg_stat_archiver),\r\n  \'count_files\', (SELECT greatest(coalesce((segment_parts_count - last_wal_mod) + ((current_wal_div - last_wal_div - 1) * segment_parts_count) + current_wal_mod - 1, 0), 0) FROM values),\r\n  \'size_files\', (SELECT greatest(coalesce(((segment_parts_count - last_wal_mod) + ((current_wal_div - last_wal_div - 1) * segment_parts_count) + current_wal_mod - 1) * segment_size, 0), 0) FROM values)\r\n) AS result','','0','{$PG.USER}','{$PG.PASSWORD}','','','0',NULL,'Collect archive status metrics.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','9440208c49134347809eff39109c644f','0','2','0'),
('45636','11','','10589','Replication: Lag in bytes','db.odbc.select[pgsql.replication.lag.b,,"Database={$PG.DATABASE};{$PG.CONNSTRING.ODBC}"]','1m','31d','365d','0','3','','B','','',NULL,NULL,'SELECT\r\n  CASE\r\n    WHEN NOT pg_is_in_recovery() OR pg_last_wal_receive_lsn() = pg_last_wal_replay_lsn() THEN 0\r\n      ELSE COALESCE(EXTRACT(EPOCH FROM now() - pg_last_xact_replay_timestamp())::integer, 0)\r\n    END AS lag','','0','{$PG.USER}','{$PG.PASSWORD}','','','0',NULL,'Replication lag with master, in bytes.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','669d87ebf9324d6eaa26c3cb44efc850','0','2','0'),
('45637','11','','10589','Count of autovacuum workers','db.odbc.select[pgsql.autovacuum.count,,"Database={$PG.DATABASE};{$PG.CONNSTRING.ODBC}"]','1m','31d','365d','0','0','','','','',NULL,NULL,'SELECT count(*)\r\n  FROM pg_catalog.pg_stat_activity\r\n    WHERE backend_type = \'autovacuum worker\'\r\n      AND state <> \'idle\'\r\n      AND pid <> pg_catalog.pg_backend_pid()','','0','{$PG.USER}','{$PG.PASSWORD}','','','0',NULL,'Number of autovacuum workers.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','dd79edeb2d65420fb58d587e411c440f','0','2','0'),
('45638','15','','10589','Cache hit ratio, %','pgsql.cache.hit','1m','31d','365d','0','0','','%','','',NULL,NULL,'last(//pgsql.dbstat.sum.blks_hit.rate) * 100 / (last(//pgsql.dbstat.sum.blks_hit.rate) + last(//pgsql.dbstat.sum.blks_read.rate))','','0','','','','','0',NULL,'Cache hit ratio.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','6444043a810b4b2f89740c1c794a47c0','0','2','0'),
('45639','11','','10589','Get WAL','db.odbc.select[pgsql.wal.stat,,"Database={$PG.DATABASE};{$PG.CONNSTRING.ODBC}"]','5m','0','0','0','4','','','','',NULL,NULL,'SELECT row_to_json(T)\r\n  FROM (\r\n    SELECT\r\n      CASE\r\n        WHEN pg_is_in_recovery() THEN 0\r\n        ELSE pg_wal_lsn_diff(pg_current_wal_lsn(),\'0/00000000\')\r\n      END AS WRITE,\r\n      CASE \r\n        WHEN NOT pg_is_in_recovery() THEN 0\r\n        ELSE pg_wal_lsn_diff(pg_last_wal_receive_lsn(),\'0/00000000\')\r\n      END AS RECEIVE,\r\n      count(*)\r\n      FROM pg_ls_waldir() AS COUNT\r\n  ) T','','0','{$PG.USER}','{$PG.PASSWORD}','','','0',NULL,'Collect write-ahead log (WAL) metrics.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','8af13c6154744e9596a0f96dfbf09d8b','0','2','0'),
('45640','11','','10589','Uptime','db.odbc.select[pgsql.uptime,,"Database={$PG.DATABASE};{$PG.CONNSTRING.ODBC}"]','1m','31d','365d','0','0','','s','','',NULL,NULL,'SELECT date_part(\'epoch\', now() - pg_postmaster_start_time())','','0','{$PG.USER}','{$PG.PASSWORD}','','','0',NULL,'Time since the server started.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','817c494132044fff88ea4c9fcaacb60a','0','2','0'),
('45641','11','','10589','Replication: Status','db.odbc.select[pgsql.replication.status,,"Database={$PG.DATABASE};{$PG.CONNSTRING.ODBC}"]','1m','31d','365d','0','3','','','','',NULL,'1109','SELECT\r\n  CASE\r\n    WHEN NOT pg_is_in_recovery() THEN 2\r\n    ELSE (SELECT count(*) FROM pg_stat_wal_receiver)\r\n  END AS repl_status','','0','{$PG.USER}','{$PG.PASSWORD}','','','0',NULL,'Replication status: 0 — streaming is down, 1 — streaming is up, 2 — master mode.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','6cc8c748f6174d3dba9aa9b39570b006','0','2','0'),
('45642','11','','10589','Replication: Recovery role','db.odbc.select[pgsql.replication.recovery_role,,"Database={$PG.DATABASE};{$PG.CONNSTRING.ODBC}"]','1m','31d','365d','0','3','','','','',NULL,'1108','SELECT pg_is_in_recovery()::int','','0','{$PG.USER}','{$PG.PASSWORD}','','','0',NULL,'Replication role: 1 — recovery is still in progress (standby mode), 0 — master mode.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','f8205cdd902a4a688b5bcb7f65d8e41d','0','2','0'),
('45643','11','','10589','Replication: Lag in seconds','db.odbc.select[pgsql.replication.lag.sec,,"Database={$PG.DATABASE};{$PG.CONNSTRING.ODBC}"]','1m','31d','365d','0','3','','s','','',NULL,NULL,'SELECT\r\n  CASE\r\n    WHEN NOT pg_is_in_recovery() OR pg_last_wal_receive_lsn() = pg_last_wal_replay_lsn() THEN 0\r\n      ELSE COALESCE(EXTRACT(EPOCH FROM now() - pg_last_xact_replay_timestamp())::integer, 0)\r\n    END AS lag','','0','{$PG.USER}','{$PG.PASSWORD}','','','0',NULL,'Replication lag with master, in seconds.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','bb87b83d35784d3ea5be2263fa3722b0','0','2','0'),
('45644','11','','10589','Get replication','db.odbc.select[pgsql.replication.process,,"Database={$PG.DATABASE};{$PG.CONNSTRING.ODBC}"]','1m','0','0','0','4','','','','',NULL,NULL,'SELECT json_object_agg(application_name, row_to_json(T))\r\n  FROM (\r\n    SELECT\r\n      application_name,\r\n      EXTRACT(epoch FROM COALESCE(flush_lag,\'0\'::interval)) AS flush_lag,\r\n      EXTRACT(epoch FROM COALESCE(replay_lag,\'0\'::interval)) AS replay_lag,\r\n      EXTRACT(epoch FROM COALESCE(write_lag, \'0\'::interval)) AS write_lag\r\n    FROM pg_stat_replication\r\n  ) T','','0','{$PG.USER}','{$PG.PASSWORD}','','','0',NULL,'Collect metrics from the pg_stat_replication, which contains information about the WAL sender process, showing statistics about replication to that sender\'s connected standby server.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','3f2b5c02a6be40d4837205f68aaacabb','0','2','0'),
('45645','11','','10589','Replication: Standby count','db.odbc.select[pgsql.replication.count,,"Database={$PG.DATABASE};{$PG.CONNSTRING.ODBC}"]','1m','31d','365d','0','3','','','','',NULL,NULL,'SELECT count(*) FROM pg_stat_replication','','0','{$PG.USER}','{$PG.PASSWORD}','','','0',NULL,'Number of standby servers.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','d156db3cb35049a88179060583961156','0','2','0'),
('45646','11','','10589','Ping','db.odbc.select[pgsql.ping,,"Database={$PG.DATABASE};{$PG.CONNSTRING.ODBC}"]','1m','31d','365d','0','3','','','','',NULL,'1110','SELECT 1','','0','{$PG.USER}','{$PG.PASSWORD}','','','0',NULL,'Used to test a connection to see if it is alive. It is set to 0 if the query is unsuccessful.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','3c16a3c2db7641c2b6958649d7b4809e','0','2','0'),
('45647','11','','10589','Age of oldest xid','db.odbc.select[pgsql.oldest.xid,,"Database={$PG.DATABASE};{$PG.CONNSTRING.ODBC}"]','1m','31d','365d','0','0','','','','',NULL,NULL,'SELECT greatest(max(age(backend_xmin)), max(age(backend_xid)))\r\n  FROM pg_catalog.pg_stat_activity','','0','{$PG.USER}','{$PG.PASSWORD}','','','0',NULL,'Age of oldest xid.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','266a9b5c1e604d97ac5a74ccdb598c97','0','2','0'),
('45648','11','','10589','Get locks','db.odbc.select[pgsql.locks,,"Database={$PG.DATABASE};{$PG.CONNSTRING.ODBC}"]','1m','0','0','0','4','','','','',NULL,NULL,'WITH T AS\r\n  (SELECT db.datname dbname,\r\n      lower(replace(Q.mode, \'Lock\', \'\')) AS MODE,\r\n      coalesce(T.qty, 0) val\r\n  FROM pg_database db\r\n  JOIN (\r\n      VALUES (\'AccessShareLock\') ,(\'RowShareLock\') ,(\'RowExclusiveLock\') ,(\'ShareUpdateExclusiveLock\') ,(\'ShareLock\') ,(\'ShareRowExclusiveLock\') ,(\'ExclusiveLock\') ,(\'AccessExclusiveLock\')) Q(MODE) ON TRUE NATURAL\r\n  LEFT JOIN\r\n    (SELECT datname,\r\n      MODE,\r\n      count(MODE) qty\r\n    FROM pg_locks lc\r\n    RIGHT JOIN pg_database db ON db.oid = lc.database\r\n    GROUP BY 1, 2) T\r\n  WHERE NOT db.datistemplate\r\n  ORDER BY 1, 2)\r\nSELECT json_object_agg(dbname, row_to_json(T2))\r\nFROM\r\n  (SELECT dbname,\r\n      sum(val) AS total,\r\n      sum(CASE\r\n          WHEN MODE = \'accessexclusive\' THEN val\r\n        END) AS accessexclusive,\r\n      sum(CASE\r\n          WHEN MODE = \'accessshare\' THEN val\r\n        END) AS accessshare,\r\n      sum(CASE\r\n          WHEN MODE = \'exclusive\' THEN val\r\n        END) AS EXCLUSIVE,\r\n      sum(CASE\r\n          WHEN MODE = \'rowexclusive\' THEN val\r\n        END) AS rowexclusive,\r\n      sum(CASE\r\n          WHEN MODE = \'rowshare\' THEN val\r\n        END) AS rowshare,\r\n      sum(CASE\r\n          WHEN MODE = \'share\' THEN val\r\n        END) AS SHARE,\r\n      sum(CASE\r\n          WHEN MODE = \'sharerowexclusive\' THEN val\r\n        END) AS sharerowexclusive,\r\n      sum(CASE\r\n          WHEN MODE = \'shareupdateexclusive\' THEN val\r\n        END) AS shareupdateexclusive\r\n  FROM T\r\n  GROUP BY dbname) T2','','0','{$PG.USER}','{$PG.PASSWORD}','','','0',NULL,'Collect all metrics from pg_locks per database:\r\nhttps://www.postgresql.org/docs/current/explicit-locking.html#LOCKING-TABLES','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','efa015e294684fdeb711a0fde1256cf9','0','2','0'),
('45649','11','','10589','Get dbstat sum','db.odbc.select[pgsql.dbstat.sum,,"Database={$PG.DATABASE};{$PG.CONNSTRING.ODBC}"]','1m','0','0','0','4','','','','',NULL,NULL,'SELECT row_to_json(T) FROM (\r\n  SELECT sum(numbackends) AS numbackends,\r\n    sum(xact_commit) AS xact_commit,\r\n    sum(xact_rollback) AS xact_rollback,\r\n    sum(blks_read) AS blks_read,\r\n    sum(blks_hit) AS blks_hit,\r\n    sum(tup_returned) AS tup_returned,\r\n    sum(tup_fetched) AS tup_fetched,\r\n    sum(tup_inserted) AS tup_inserted,\r\n    sum(tup_updated) AS tup_updated,\r\n    sum(tup_deleted) AS tup_deleted,\r\n    sum(conflicts) AS conflicts,\r\n    sum(temp_files) AS temp_files,\r\n    sum(temp_bytes) AS temp_bytes,\r\n    sum(deadlocks) AS deadlocks,\r\n    sum(blk_read_time) AS blk_read_time,\r\n    sum(blk_write_time) AS blk_write_time\r\n  FROM pg_stat_database) T','','0','{$PG.USER}','{$PG.PASSWORD}','','','0',NULL,'Collect all metrics from pg_stat_database as sums for all databases:\r\nhttps://www.postgresql.org/docs/current/monitoring-stats.html#PG-STAT-DATABASE-VIEW','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','6ea1a17fad8b4ef3aba8b49a0922a77d','0','2','0'),
('45650','11','','10589','Get dbstat','db.odbc.select[pgsql.dbstat,,"Database={$PG.DATABASE};{$PG.CONNSTRING.ODBC}"]','1m','0','0','0','4','','','','',NULL,NULL,'SELECT json_object_agg(coalesce (datname,\'null\'), row_to_json(T)) FROM (\r\n  SELECT datname,\r\n    numbackends AS numbackends,\r\n    xact_commit AS xact_commit,\r\n    xact_rollback AS xact_rollback,\r\n    blks_read AS blks_read,\r\n    blks_hit AS blks_hit,\r\n    tup_returned AS tup_returned,\r\n    tup_fetched AS tup_fetched,\r\n    tup_inserted AS tup_inserted,\r\n    tup_updated AS tup_updated,\r\n    tup_deleted AS tup_deleted,\r\n    conflicts AS conflicts,\r\n    temp_files AS temp_files,\r\n    temp_bytes AS temp_bytes,\r\n    deadlocks AS deadlocks,\r\n    blk_read_time AS blk_read_time,\r\n    blk_write_time AS blk_write_time\r\n  FROM pg_catalog.pg_stat_database WHERE datname IS NOT NULL) T;','','0','{$PG.USER}','{$PG.PASSWORD}','','','0',NULL,'Collect all metrics from pg_stat_database per database:\r\nhttps://www.postgresql.org/docs/current/monitoring-stats.html#PG-STAT-DATABASE-VIEW','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','0f93764d56574a288467ad16dce11a17','0','2','0'),
('45651','11','','10589','Get queries','db.odbc.select[pgsql.queries,,"Database={$PG.DATABASE};{$PG.CONNSTRING.ODBC}"]','1m','0','0','0','4','','','','',NULL,NULL,'WITH T AS\r\n  (SELECT db.datname,\r\n    coalesce(T.query_time_max, 0) query_time_max,\r\n    coalesce(T.tx_time_max, 0) tx_time_max,\r\n    coalesce(T.mro_time_max, 0) mro_time_max,\r\n    coalesce(T.query_time_sum, 0) query_time_sum,\r\n    coalesce(T.tx_time_sum, 0) tx_time_sum,\r\n    coalesce(T.mro_time_sum, 0) mro_time_sum,\r\n    coalesce(T.query_slow_count, 0) query_slow_count,\r\n    coalesce(T.tx_slow_count, 0) tx_slow_count,\r\n    coalesce(T.mro_slow_count, 0) mro_slow_count\r\n  FROM pg_database db NATURAL\r\n  LEFT JOIN (\r\n    SELECT datname,\r\n      extract(epoch FROM now())::integer ts,\r\n      coalesce(max(extract(\'epoch\' FROM (clock_timestamp() - query_start))::integer * (state NOT IN (\'idle\', \'idle in transaction\', \'idle in transaction (aborted)\') AND query !~* E\'^(\\\\s*(--[^\\\\n]*\\\\n|/\\\\*.*\\\\*/|\\\\n))*(autovacuum|VACUUM|ANALYZE|REINDEX|CLUSTER|CREATE|ALTER|TRUNCATE|DROP)\')::integer), 0) query_time_max,\r\n      coalesce(max(extract(\'epoch\' FROM (clock_timestamp() - query_start))::integer * (state NOT IN (\'idle\') AND query !~* E\'^(\\\\s*(--[^\\\\n]*\\\\n|/\\\\*.*\\\\*/|\\\\n))*(autovacuum|VACUUM|ANALYZE|REINDEX|CLUSTER|CREATE|ALTER|TRUNCATE|DROP)\')::integer), 0) tx_time_max,\r\n      coalesce(max(extract(\'epoch\' FROM (clock_timestamp() - query_start))::integer * (state NOT IN (\'idle\') AND query ~* E\'^(\\\\s*(--[^\\\\n]*\\\\n|/\\\\*.*\\\\*/|\\\\n))*(autovacuum|VACUUM|ANALYZE|REINDEX|CLUSTER|CREATE|ALTER|TRUNCATE|DROP)\')::integer), 0) mro_time_max,\r\n      coalesce(sum(extract(\'epoch\' FROM (clock_timestamp() - query_start))::integer * (state NOT IN (\'idle\', \'idle in transaction\', \'idle in transaction (aborted)\') AND query !~* E\'^(\\\\s*(--[^\\\\n]*\\\\n|/\\\\*.*\\\\*/|\\\\n))*(autovacuum|VACUUM|ANALYZE|REINDEX|CLUSTER|CREATE|ALTER|TRUNCATE|DROP)\')::integer), 0) query_time_sum,\r\n      coalesce(sum(extract(\'epoch\' FROM (clock_timestamp() - query_start))::integer * (state NOT IN (\'idle\') AND query !~* E\'^(\\\\s*(--[^\\\\n]*\\\\n|/\\\\*.*\\\\*/|\\\\n))*(autovacuum|VACUUM|ANALYZE|REINDEX|CLUSTER|CREATE|ALTER|TRUNCATE|DROP)\')::integer), 0) tx_time_sum,\r\n      coalesce(sum(extract(\'epoch\' FROM (clock_timestamp() - query_start))::integer * (state NOT IN (\'idle\') AND query ~* E\'^(\\\\s*(--[^\\\\n]*\\\\n|/\\\\*.*\\\\*/|\\\\n))*(autovacuum|VACUUM|ANALYZE|REINDEX|CLUSTER|CREATE|ALTER|TRUNCATE|DROP)\')::integer), 0) mro_time_sum,\r\n\r\n      coalesce(sum((extract(\'epoch\' FROM (clock_timestamp() - query_start)) > {$PG.QUERY_ETIME.MAX.WARN})::integer * (state NOT IN (\'idle\', \'idle in transaction\', \'idle in transaction (aborted)\') AND query !~* E\'^(\\\\s*(--[^\\\\n]*\\\\n|/\\\\*.*\\\\*/|\\\\n))*(autovacuum|VACUUM|ANALYZE|REINDEX|CLUSTER|CREATE|ALTER|TRUNCATE|DROP)\')::integer), 0) query_slow_count,\r\n      coalesce(sum((extract(\'epoch\' FROM (clock_timestamp() - query_start)) > {$PG.QUERY_ETIME.MAX.WARN})::integer * (state NOT IN (\'idle\') AND query !~* E\'^(\\\\s*(--[^\\\\n]*\\\\n|/\\\\*.*\\\\*/|\\\\n))*(autovacuum|VACUUM|ANALYZE|REINDEX|CLUSTER|CREATE|ALTER|TRUNCATE|DROP)\')::integer), 0) tx_slow_count,\r\n      coalesce(sum((extract(\'epoch\' FROM (clock_timestamp() - query_start)) > {$PG.QUERY_ETIME.MAX.WARN})::integer * (state NOT IN (\'idle\') AND query ~* E\'^(\\\\s*(--[^\\\\n]*\\\\n|/\\\\*.*\\\\*/|\\\\n))*(autovacuum|VACUUM|ANALYZE|REINDEX|CLUSTER|CREATE|ALTER|TRUNCATE|DROP)\')::integer), 0) mro_slow_count\r\n    FROM pg_stat_activity\r\n    WHERE pid <> pg_backend_pid()\r\n    GROUP BY 1) T\r\n  WHERE NOT db.datistemplate )\r\nSELECT json_object_agg(datname, row_to_json(T))\r\nFROM T','','0','{$PG.USER}','{$PG.PASSWORD}','','','0',NULL,'Collect all metrics by query execution time.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','ee6b3f64e07d4acd875dbd83dccd51d0','0','2','0'),
('45652','11','','10589','Get bgwriter','db.odbc.select[pgsql.bgwriter,,"Database={$PG.DATABASE};{$PG.CONNSTRING.ODBC}"]','1m','0','0','0','4','','','','',NULL,NULL,'SELECT row_to_json(T) FROM (\r\n  SELECT checkpoints_timed,\r\n    checkpoints_req,\r\n    checkpoint_write_time,\r\n    checkpoint_sync_time,\r\n    current_setting(\'block_size\')::int*buffers_checkpoint AS buffers_checkpoint,\r\n    current_setting(\'block_size\')::int*buffers_clean AS buffers_clean,\r\n    maxwritten_clean,\r\n    current_setting(\'block_size\')::int*buffers_backend AS buffers_backend,\r\n    buffers_backend_fsync,\r\n    current_setting(\'block_size\')::int*buffers_alloc AS buffers_alloc\r\n  FROM pg_stat_bgwriter) T','','0','{$PG.USER}','{$PG.PASSWORD}','','','0',NULL,'Collect all metrics from pg_stat_bgwriter:\r\nhttps://www.postgresql.org/docs/current/monitoring-stats.html#PG-STAT-BGWRITER-VIEW','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','ec6e574448804ed5bb71fa6dafa3b3f8','0','2','0'),
('45653','11','','10589','Get connections sum','db.odbc.select[pgsql.connections.sum,,"Database={$PG.DATABASE};{$PG.CONNSTRING.ODBC}"]','1m','0','0','0','4','','','','',NULL,NULL,'SELECT row_to_json(T)\r\n  FROM (\r\n    SELECT\r\n      sum(CASE WHEN state = \'active\' THEN 1 ELSE 0 END) AS active,\r\n      sum(CASE WHEN state = \'idle\' THEN 1 ELSE 0 END) AS idle,\r\n      sum(CASE WHEN state = \'idle in transaction\' THEN 1 ELSE 0 END) AS idle_in_transaction,\r\n      sum(CASE WHEN state = \'idle in transaction (aborted)\' THEN 1 ELSE 0 END) AS idle_in_transaction_aborted,\r\n      sum(CASE WHEN state = \'fastpath function call\' THEN 1 ELSE 0 END) AS fastpath_function_call,\r\n      sum(CASE WHEN state = \'disabled\' THEN 1 ELSE 0 END) AS disabled,\r\n      count(*) AS total,\r\n      count(*)*100/(SELECT current_setting(\'max_connections\')::int) AS total_pct,\r\n      sum(CASE WHEN wait_event IS NOT NULL THEN 1 ELSE 0 END) AS waiting,\r\n      (SELECT count(*) FROM pg_prepared_xacts) AS prepared\r\n    FROM pg_stat_activity WHERE datid IS NOT NULL AND state IS NOT NULL) T','','0','{$PG.USER}','{$PG.PASSWORD}','','','0',NULL,'Collect all metrics from pg_stat_activity:\r\nhttps://www.postgresql.org/docs/current/monitoring-stats.html#PG-STAT-ACTIVITY-VIEW','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','1d267b6aed064d03b4f464b27c1e897e','0','2','0'),
('45697','11','','10589','Database discovery','db.odbc.select[pgsql.db.discovery,,"Database={$PG.DATABASE};{$PG.CONNSTRING.ODBC}"]','1h','90d','365d','0','4','','','','',NULL,NULL,'WITH T AS (\r\n  SELECT\r\n    datname AS "{#DBNAME}"\r\n  FROM pg_database\r\n  WHERE\r\n    NOT datistemplate\r\n    AND datallowconn\r\n    AND datname != \'postgres\'\r\n)\r\nSELECT \'{"data":\'|| regexp_replace(coalesce(json_agg(T), \'[]\'::json)::text, E\'[\\\\n\\\\r\\\\s]+\', \'\', \'g\') || \'}\'\r\nFROM T','','0','{$PG.USER}','{$PG.PASSWORD}','','','1',NULL,'Discovers databases (DB) in the database management system (DBMS), except:\r\n- templates;\r\n- default "postgres" DB;\r\n- DBs that do not allow connections.','0','7d','1','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','1c51decca55847a8adba4260f53e0acf','0','2','0'),
('45698','11','','10589','Replication discovery','db.odbc.select[pgsql.replication.process.discovery,,"Database={$PG.DATABASE};{$PG.CONNSTRING.ODBC}"]','15m','90d','365d','0','4','','','','',NULL,NULL,'SELECT json_build_object(\'data\',COALESCE(json_agg(json_build_object(\'{#APPLICATION_NAME}\',application_name)), \'[]\'))		\r\nFROM pg_stat_replication','','0','{$PG.USER}','{$PG.PASSWORD}','','','1',NULL,'Discovers replication lag metrics.','0','7d','1','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','46a6f3cdfff244a28cb712c4186afc7f','0','2','0'),
('45699','11','','10589','DB [{#DBNAME}]: Database age','db.odbc.select[pgsql.db.age,,"Database={#DBNAME};{$PG.CONNSTRING.ODBC}"]','10m','31d','365d','0','3','','','','',NULL,NULL,'SELECT age(datfrozenxid)\r\n  FROM pg_catalog.pg_database\r\n  WHERE datname = \'{#DBNAME}\'','','0','{$PG.USER}','{$PG.PASSWORD}','','','2',NULL,'Database age.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','98b74e578a3e48f3990bc16eb0217a17','0','2','0'),
('45700','11','','10589','DB [{#DBNAME}]: Bloating tables','db.odbc.select[pgsql.db.bloating_tables,,"Database={#DBNAME};{$PG.CONNSTRING.ODBC}"]','1m','31d','365d','0','3','','','','',NULL,NULL,'SELECT count(*)\r\nFROM pg_catalog.pg_stat_all_tables\r\nWHERE (n_dead_tup/(n_live_tup+n_dead_tup)::float8) > 0.2\r\n  AND (n_live_tup+n_dead_tup) > 50','','0','{$PG.USER}','{$PG.PASSWORD}','','','2',NULL,'Number of bloating tables.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','cb7067b756bc4b3eb5be2ee2361df6f8','0','2','0'),
('45701','11','','10589','DB [{#DBNAME}]: Database size','db.odbc.select[pgsql.db.size,,"Database={#DBNAME};{$PG.CONNSTRING.ODBC}"]','5m','31d','365d','0','3','','B','','',NULL,NULL,'SELECT pg_database_size(current_database())','','0','{$PG.USER}','{$PG.PASSWORD}','','','2',NULL,'Database size.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','f6bc4dd7f66a4a399a16230b6a7a8f2d','0','2','0'),
('45743','21','','10590','Authentication','sd_wan.authentication','{$SDWAN.AUTH.FREQUENCY}','0','0','0','4','','','','',NULL,NULL,'var params = JSON.parse(value),\r\n	request = new HttpRequest(),\r\n	cookies = [],\r\n	token = "",\r\n	error_msg = "";\r\n\r\nfunction authenticate(url) {\r\n	var payload = \'j_username=\' + encodeURIComponent(params.username)\r\n		+ \'&j_password=\' + encodeURIComponent(params.password);\r\n	request.addHeader(\'Content-Type\', \'application/x-www-form-urlencoded\');\r\n	response = request.post(url, payload);\r\n	Zabbix.log(4, \'[ SD-WAN API ] [ \' + url + \' ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n\r\n	if (request.getStatus() !== 200) {\r\n		throw \'Failed to receive data: invalid response status code.\';\r\n	}\r\n\r\n	if (response !== null && response != "") {\r\n		throw \'Authentication failed.\';\r\n	}\r\n\r\n	var headers = request.getHeaders();\r\n	for (key in headers) {\r\n		if (key.toLowerCase() == \'set-cookie\') {\r\n			var entries = headers[key].split(\',\');\r\n			for (idx in entries) {\r\n				var value = entries[idx].split(\';\')[0];\r\n				cookies.push(value);\r\n			}\r\n		}\r\n	}\r\n};\r\n\r\nfunction getToken(url) {\r\n	response = request.get(url);\r\n	Zabbix.log(4, \'[ SD-WAN API ] [ \' + url + \' ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n\r\n	if (request.getStatus() !== 200) {\r\n		throw \'Failed to receive data: invalid response status code.\';\r\n	}\r\n\r\n	var headers = request.getHeaders();\r\n	for (key in headers) {\r\n		if (key.toLowerCase() == \'content-type\' && headers[key] != \'application/json\') {\r\n			throw \'Something went wrong while getting the authentication token. Check debug log for more information.\';\r\n		}\r\n	}\r\n\r\n	return response;\r\n};\r\n\r\ntry {\r\n\r\n	[\'username\', \'password\', \'url\'].forEach(function (field) {\r\n		var macro = \'{$SDWAN.API.\' + field.toUpperCase() + \'}\';\r\n		if (params[field] === macro || params[field] === \'\') {\r\n			throw \'Please change \' + macro + \' macro to the proper value.\';\r\n		}\r\n		if (typeof params[field] === \'undefined\') {\r\n			throw \'Please set \\\'\' + field + \'\\\' script input parameter to \' + macro + \' macro value.\';\r\n		}\r\n	});\r\n\r\n	if (params.url.indexOf(\'http://\') === -1 && params.url.indexOf(\'https://\') === -1) {\r\n		params.url = \'https://\' + params.url;\r\n	}\r\n\r\n	if (!params.url.endsWith(\'/\')) {\r\n		params.url += \'/\';\r\n	}\r\n\r\n	if (typeof params.http_proxy !== \'undefined\' && params.http_proxy !== \'{\' + \'$SDWAN.HTTP_PROXY}\' && params.http_proxy !== \'\') {\r\n		request.setProxy(params.http_proxy);\r\n	}\r\n\r\n	authenticate(params.url + \'j_security_check\');\r\n	token = getToken(params.url + \'dataservice/client/token\');\r\n\r\n} catch (err) {\r\n	error_msg = err;\r\n};\r\n\r\nreturn JSON.stringify({\r\n	\'cookie\': cookies.join(\'; \'),\r\n	\'token\': token,\r\n	\'error\': error_msg.toString()\r\n});','','0','','','','','0',NULL,'Cisco SD-WAN authentication with service account parameters and temporary-generated token usage.\r\nReturns an authentication token and session id; it is required only once and is used for all dependent script items.\r\nA session will expire after 30 minutes of inactivity or after 24 hours, which is the total lifespan of a session.\r\nCheck the template documentation for the details.','0','30d','0','',NULL,'{$SDWAN.DATA.TIMEOUT}','','','','200','1','0','','','0','0','0','0','0','0','0','5aa5a643a3cf42148454507da22aeb17','0','2','0'),
('45744','15','','10591','Memory utilization','sd_wan.device.memory.util','1m','31d','365d','0','0','','%','','',NULL,NULL,'last(//sd_wan.device.memory.used)/last(//sd_wan.device.memory.total)*100','','0','','','','','0',NULL,'Calculated percentage of the memory used, in %.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','8b8551ab8a8c4586b2a1bc02bcc7ca60','0','2','0'),
('45745','21','','10591','Get routes data','sd_wan.get.routes','{$SDWAN.ROUTES.FREQUENCY}','0','0','0','4','','','','',NULL,NULL,'var params = JSON.parse(value),\r\n	request = new HttpRequest(),\r\n	result = { "data": [], "error": "" },\r\n	error_msg = "";\r\n\r\nfunction getHttpData(url, data, token, cookie) {\r\n	request.addHeader(\'Cookie: \' + cookie);\r\n	request.addHeader(\'Content-Type: application/json\');\r\n	request.addHeader(\'X-XSRF-TOKEN: \' + token);\r\n\r\n	if (typeof data !== \'undefined\') {\r\n		data = JSON.stringify(data);\r\n	}\r\n\r\n	response = request.post(url, data);\r\n	Zabbix.log(4, \'[ Cisco SD-WAN ] [ \' + url + \' ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n\r\n	if (request.getStatus() !== 200) {\r\n		throw \'Failed to receive data: invalid response status code.\';\r\n	}\r\n\r\n	if (response !== null) {\r\n		try {\r\n			response = JSON.parse(response);\r\n		}\r\n		catch (error) {\r\n			throw \'Failed to parse response received from Cisco SD-WAN API. Check debug log for more information.\';\r\n		}\r\n	}\r\n\r\n	if (typeof (response) !== \'object\' || response === null) {\r\n		throw \'Cannot process response data: received data is not an object.\';\r\n	}\r\n\r\n	return response;\r\n};\r\n\r\ntry {\r\n	[\'auth.token\', \'auth.cookie\', \'api.url\', \'device_id\'].forEach(function (field) {\r\n		var macro = \'{$SDWAN.\' + field.toUpperCase() + \'}\';\r\n		var key = field.split(\'.\').slice(-1);\r\n		if (params[key] === macro || params[key] === \'\') {\r\n			throw \'Please change \' + macro + \' macro to the proper value.\';\r\n		}\r\n		if (typeof params[key] === \'undefined\') {\r\n			throw \'Please set \\\'\' + key + \'\\\' script input parameter to \' + macro + \' macro value.\';\r\n		}\r\n	});\r\n\r\n	if (params.url.indexOf(\'http://\') === -1 && params.url.indexOf(\'https://\') === -1) {\r\n		params.url = \'https://\' + params.url;\r\n	}\r\n\r\n	if (!params.url.endsWith(\'/\')) {\r\n		params.url += \'/\';\r\n	}\r\n\r\n	if (typeof params.http_proxy !== \'undefined\' && params.http_proxy !== \'{\' + \'$SDWAN.HTTP_PROXY}\' && params.http_proxy !== \'\') {\r\n		request.setProxy(params.http_proxy);\r\n	}\r\n\r\n	if (!params.interval.endsWith(\'h\')) {\r\n		throw \'The value of {\' + \'$SDWAN.ROUTES.INTERVAL} must be expressed in hours.\';\r\n	}\r\n	else {\r\n		try {\r\n			params.interval = Number(params.interval.replace(\'h\', \'\'));\r\n		}\r\n		catch (error) {\r\n			throw \'Please change {\' + \'$SDWAN.ROUTES.INTERVAL} macro to the proper value.\';\r\n		}\r\n	}\r\n\r\n	var req_data = {\r\n		"query": {\r\n			"condition": "AND",\r\n			"rules": [\r\n				{\r\n					"value": [\r\n						String(params.interval)\r\n					],\r\n					"field": "entry_time",\r\n					"type": "date",\r\n					"operator": "last_n_hours"\r\n				},\r\n				{\r\n					"value": [\r\n						params.device_id\r\n					],\r\n					"field": "vdevice_name",\r\n					"type": "string",\r\n					"operator": "in"\r\n				}\r\n			]\r\n		},\r\n		"aggregation": {\r\n			"field": [\r\n				{\r\n					"property": "local_color",\r\n					"order": "asc",\r\n					"sequence": 1\r\n				},\r\n				{\r\n					"property": "remote_color",\r\n					"order": "asc",\r\n					"sequence": 1\r\n				}\r\n			],\r\n			"metrics": [\r\n				{\r\n					"property": "loss_percentage",\r\n					"type": "avg"\r\n				},\r\n				{\r\n					"property": "latency",\r\n					"type": "avg"\r\n				},\r\n				{\r\n					"property": "jitter",\r\n					"type": "avg"\r\n				}\r\n			]\r\n		}\r\n	};\r\n\r\n	var routes = getHttpData(\r\n		params.url + \'dataservice/statistics/approute/aggregation\',\r\n		req_data,\r\n		params.token,\r\n		params.cookie\r\n	);\r\n\r\n	if (Array.isArray(routes.data)) {\r\n		result["data"] = routes.data;\r\n	}\r\n	else {\r\n		throw \'Failed to parse response received from Cisco SD-WAN API. Check debug log for more information.\';\r\n	}\r\n} catch (error) {\r\n	error_msg = error.toString();\r\n	error_msg += (error_msg.endsWith(\'.\')) ? \'\' : \'.\';\r\n	Zabbix.log(3, \'[ Cisco SD-WAN ] ERROR: \' + error_msg);\r\n};\r\n\r\nresult.error = error_msg;\r\n\r\nreturn JSON.stringify(result);','','0','','','','','0',NULL,'Item for gathering device routes from Cisco SD-WAN API.','0','30d','0','',NULL,'{$SDWAN.DATA.TIMEOUT}','','','','200','1','0','','','0','0','0','0','0','0','0','d9ae4a103ae74932a57ad495f2829b62','0','2','0'),
('45746','21','','10591','Get interfaces data','sd_wan.get.interfaces','1m','0','0','0','4','','','','',NULL,NULL,'var params = JSON.parse(value),\r\n	request = new HttpRequest(),\r\n	result = { "data": [], "error": "" },\r\n	error_msg = "";\r\n\r\nfunction getHttpData(url, token, cookie) {\r\n	request.addHeader(\'Cookie: \' + cookie);\r\n	request.addHeader(\'X-XSRF-TOKEN: \' + token);\r\n	response = request.get(url);\r\n	Zabbix.log(4, \'[ Cisco SD-WAN ] [ \' + url + \' ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n\r\n	if (request.getStatus() !== 200) {\r\n		throw \'Failed to receive data: invalid response status code.\';\r\n	}\r\n\r\n	if (response !== null) {\r\n		try {\r\n			response = JSON.parse(response);\r\n		}\r\n		catch (error) {\r\n			throw \'Failed to parse response received from Cisco SD-WAN API. Check debug log for more information.\';\r\n		}\r\n	}\r\n\r\n	if (typeof (response) !== \'object\' || response === null) {\r\n		throw \'Cannot process response data: received data is not an object.\';\r\n	}\r\n\r\n	return response;\r\n};\r\n\r\ntry {\r\n	[\'auth.token\', \'auth.cookie\', \'api.url\', \'device_id\'].forEach(function (field) {\r\n		var macro = \'{$SDWAN.\' + field.toUpperCase() + \'}\';\r\n		var key = field.split(\'.\').slice(-1);\r\n		if (params[key] === macro || params[key] === \'\') {\r\n			throw \'Please change \' + macro + \' macro to the proper value.\';\r\n		}\r\n		if (typeof params[key] === \'undefined\') {\r\n			throw \'Please set \\\'\' + key + \'\\\' script input parameter to \' + macro + \' macro value.\';\r\n		}\r\n	});\r\n\r\n	if (params.url.indexOf(\'http://\') === -1 && params.url.indexOf(\'https://\') === -1) {\r\n		params.url = \'https://\' + params.url;\r\n	}\r\n\r\n	if (!params.url.endsWith(\'/\')) {\r\n		params.url += \'/\';\r\n	}\r\n\r\n	if (typeof params.http_proxy !== \'undefined\' && params.http_proxy !== \'{\' + \'$SDWAN.HTTP_PROXY}\' && params.http_proxy !== \'\') {\r\n		request.setProxy(params.http_proxy);\r\n	}\r\n\r\n	var interface_list = getHttpData(\r\n		params.url + \'dataservice/device/interface?deviceId=\' + encodeURIComponent(params.device_id),\r\n		params.token,\r\n		params.cookie\r\n	);\r\n\r\n	if (Array.isArray(interface_list.data) && interface_list.data.length > 0) {\r\n		var interfaces = {};\r\n		interface_list.data.forEach(function (if_item) {\r\n			var if_key = if_item[\'vdevice-name\'] + \'_\' + if_item.ifname + \'_\' + if_item.ifindex;\r\n			interfaces[if_key] = (typeof interfaces[if_key] !== \'undefined\') ? interfaces[if_key] : {};\r\n			if (typeof if_item[\'af-type\'] !== \'undefined\') {\r\n				if (if_item[\'af-type\'].includes(\'ipv6\')) {\r\n					Object.keys(if_item).sort().forEach(function (key) {\r\n						if (key.match(/([tr]x-)/g)) {\r\n							interfaces[if_key][\'ipv6-\' + key] = if_item[key];\r\n						}\r\n					});\r\n				}\r\n				else {\r\n					interfaces[if_key] = if_item;\r\n				}\r\n			}\r\n			else {\r\n				interfaces[if_key] = if_item;\r\n			}\r\n		});\r\n		Object.keys(interfaces).forEach(function (key) {\r\n			result.data.push(interfaces[key]);\r\n		});\r\n	}\r\n	else {\r\n		throw \'Failed to parse response received from Cisco SD-WAN API. Check debug log for more information.\';\r\n	}\r\n} catch (error) {\r\n	error_msg = error.toString();\r\n	error_msg += (error_msg.endsWith(\'.\')) ? \'\' : \'.\';\r\n	Zabbix.log(3, \'[ Cisco SD-WAN ] ERROR: \' + error_msg);\r\n};\r\n\r\nresult.error = error_msg;\r\n\r\nreturn JSON.stringify(result);','','0','','','','','0',NULL,'Item for gathering device interfaces from Cisco SD-WAN API.','0','30d','0','',NULL,'{$SDWAN.DATA.TIMEOUT}','','','','200','1','0','','','0','0','0','0','0','0','0','694fb02640314fcab6cb2352fe4378ea','0','2','0'),
('45747','21','','10591','Get device data','sd_wan.get.device','1m','0','0','0','4','','','','',NULL,NULL,'var params = JSON.parse(value),\r\n	request = new HttpRequest(),\r\n	device_info = {},\r\n	error_msg = "";\r\n\r\nfunction getHttpData(url, token, cookie) {\r\n	request.addHeader(\'Cookie: \' + cookie);\r\n	request.addHeader(\'X-XSRF-TOKEN: \' + token);\r\n	response = request.get(url);\r\n	Zabbix.log(4, \'[ Cisco SD-WAN ] [ \' + url + \' ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n\r\n	if (request.getStatus() !== 200) {\r\n		throw \'Failed to receive data: invalid response status code.\';\r\n	}\r\n\r\n	if (response !== null) {\r\n		try {\r\n			response = JSON.parse(response);\r\n		}\r\n		catch (error) {\r\n			throw \'Failed to parse response received from Cisco SD-WAN API. Check debug log for more information.\';\r\n		}\r\n	}\r\n\r\n	if (typeof (response) !== \'object\' || response === null) {\r\n		throw \'Cannot process response data: received data is not an object.\';\r\n	}\r\n\r\n	return response;\r\n};\r\n\r\ntry {\r\n	[\'auth.token\', \'auth.cookie\', \'api.url\', \'device_id\'].forEach(function (field) {\r\n		var macro = \'{$SDWAN.\' + field.toUpperCase() + \'}\';\r\n		var key = field.split(\'.\').slice(-1);\r\n		if (params[key] === macro || params[key] === \'\') {\r\n			throw \'Please change \' + macro + \' macro to the proper value.\';\r\n		}\r\n		if (typeof params[key] === \'undefined\') {\r\n			throw \'Please set \\\'\' + key + \'\\\' script input parameter to \' + macro + \' macro value.\';\r\n		}\r\n	});\r\n\r\n	if (params.url.indexOf(\'http://\') === -1 && params.url.indexOf(\'https://\') === -1) {\r\n		params.url = \'https://\' + params.url;\r\n	}\r\n\r\n	if (!params.url.endsWith(\'/\')) {\r\n		params.url += \'/\';\r\n	}\r\n\r\n	if (typeof params.http_proxy !== \'undefined\' && params.http_proxy !== \'{\' + \'$SDWAN.HTTP_PROXY}\' && params.http_proxy !== \'\') {\r\n		request.setProxy(params.http_proxy);\r\n	}\r\n\r\n	device_info = getHttpData(\r\n		params.url + \'dataservice/device?deviceId=\' + encodeURIComponent(params.device_id),\r\n		params.token,\r\n		params.cookie\r\n	);\r\n\r\n	if (Array.isArray(device_info.data) && device_info.data.length > 0) {\r\n		device_info = device_info.data[0];\r\n	}\r\n	else {\r\n		throw \'Failed to parse response received from Cisco SD-WAN API. Check debug log for more information.\';\r\n	}\r\n\r\n	var system_info = getHttpData(\r\n		params.url + \'dataservice/device/system/status?deviceId=\' + params.device_id,\r\n		params.token,\r\n		params.cookie\r\n	);\r\n\r\n	if (Array.isArray(system_info.data) && system_info.data.length > 0) {\r\n		device_info = Object.assign(device_info, system_info.data[0]);\r\n	}\r\n	else {\r\n		throw \'Failed to parse response received from Cisco SD-WAN API. Check debug log for more information.\';\r\n	}\r\n} catch (error) {\r\n	error_msg = error.toString();\r\n	error_msg += (error_msg.endsWith(\'.\')) ? \'\' : \'.\';\r\n	Zabbix.log(3, \'[ Cisco SD-WAN ] ERROR: \' + error_msg);\r\n};\r\n\r\ndevice_info.error = error_msg;\r\n\r\nreturn JSON.stringify(device_info);','','0','','','','','0',NULL,'Item for gathering device data from Cisco SD-WAN API.','0','30d','0','',NULL,'{$SDWAN.DATA.TIMEOUT}','','','','200','1','0','','','0','0','0','0','0','0','0','7a4cc11f131e4f7f9511ac19dbfb82f4','0','2','0'),
('45818','19','','10593','Get projects','mantisbt.get.projects','1h','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Get projects from Mantis BT.','0','30d','0','',NULL,'30s','{$MANTIS.URL}/api/rest/projects/','','','200','1','0','{$MANTIS.HTTP.PROXY}','Authorization: {$MANTIS.TOKEN}','0','0','0','0','0','0','0','bf1b74b98d5b4311afeb721059c01da9','0','2','0'),
('45820','19','','10593','Project [{#NAME}]: Get issues','mantisbt.get.issues[{#NAME}]','20m','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','2',NULL,'Getting project issues.','0','30d','0','',NULL,'30s','{$MANTIS.URL}/api/rest/issues?project_id={#ID}&page_size=0','','','200','1','0','{$MANTIS.HTTP.PROXY}','Authorization: {$MANTIS.TOKEN}','0','0','0','0','0','0','0','f0064281917741aaa9b8e808509077e1','0','2','0'),
('45852','19','','10594','Nomad clients get','nomad.client.nodes.get','1h','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Nomad clients data in raw format.','0','30d','0','',NULL,'{$NOMAD.DATA.TIMEOUT}','{$NOMAD.ENDPOINT.API.URL}/v1/nodes','[{"os":"true"}]','','','1','0','{$NOMAD.HTTP.PROXY}','X-Nomad-Token: {$NOMAD.TOKEN}','2','0','1','0','0','0','0','99d8cd0768094bef93995e4baa475186','0','2','0'),
('45853','21','','10594','Nomad servers get','nomad.server.nodes.get','1h','0','0','0','4','','','','',NULL,NULL,'var Nomad = {\r\n	setParams: function (params) {\r\n		[\'api_endpoint\'].forEach(function (field) {\r\n			if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n				throw \'Required param is not set: "\' + field + \'".\';\r\n			}\r\n		});\r\n\r\n		Nomad.params = params;\r\n		if (typeof Nomad.params.api_endpoint === \'string\' && !Nomad.params.api_endpoint.endsWith(\'/\')) {\r\n			Nomad.params.api_endpoint += \'/\';\r\n		}\r\n	},\r\n\r\n	request: function (query) {\r\n		var response,\r\n			request = new HttpRequest(),\r\n			url = Nomad.params.api_endpoint + query;\r\n\r\n		request.addHeader(\'Content-Type: application/json\');\r\n		request.addHeader(\'X-Nomad-Token: \' + Nomad.params.token);\r\n		if (Nomad.params.http_proxy) {\r\n			request.setProxy(Nomad.params.http_proxy)\r\n			Zabbix.log(4, \'[ Nomad ] Using http proxy: \' + Nomad.params.http_proxy);\r\n		}\r\n\r\n		Zabbix.log(4, \'[ Nomad ] Sending request: \' + url);\r\n		response = request.get(url);\r\n\r\n		Zabbix.log(4, \'[ Nomad ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n\r\n		if (response !== null) {\r\n			try {\r\n				response = JSON.parse(response);\r\n			}\r\n			catch (error) {\r\n				throw \'Failed to parse response received from Nomad agent API.\';\r\n			}\r\n		}\r\n\r\n		return {\r\n			status: request.getStatus(),\r\n			response: response\r\n		};\r\n	},\r\n\r\n	getField: function (data, path) {\r\n		var steps = path.split(\'.\');\r\n		for (var i = 0; i < steps.length; i++) {\r\n			var step = steps[i];\r\n			if (typeof data !== \'object\' || typeof data[step] === \'undefined\') {\r\n				throw \'Required field was not found: \' + path;\r\n			}\r\n\r\n			data = data[step];\r\n		}\r\n\r\n		return data;\r\n	},\r\n\r\n	getIds: function () {\r\n		var result = this.request(\'v1/operator/raft/configuration\');\r\n\r\n		if (typeof result.response !== \'object\' || result.status != 200) {\r\n			throw \'Cannot get servers list from Nomad agent API.\';\r\n		}\r\n\r\n		return this.getField(result, \'response.Servers\')\r\n			.map(function (srv) {\r\n				return srv[\'ID\'];\r\n			});\r\n	},\r\n\r\n	getServers: function () {\r\n		var ids = this.getIds();\r\n		result = Nomad.request(\'v1/agent/members\');\r\n\r\n		if (typeof result.response !== \'object\' || result.status != 200) {\r\n			throw \'Cannot get servers list from Nomad agent API.\';\r\n		}\r\n\r\n		return this.getField(result,\'response.Members\').filter(function (s) {\r\n			return ids.indexOf(s.Tags.id) >= 0;\r\n		});\r\n\r\n	},\r\n};\r\n\r\ntry {\r\n	Nomad.setParams(JSON.parse(value));\r\n\r\n	var servers = Nomad.getServers();\r\n\r\n	return JSON.stringify(servers);\r\n\r\n}\r\ncatch (error) {\r\n	error += ((String(error).endsWith(\'.\')) ? \'\' : \'.\');\r\n	Zabbix.log(3, \'[ Nomad ] ERROR: \' + error);\r\n\r\n	return JSON.stringify({ error: error + \' Check debug log for more information.\' });\r\n}','','0','','','','','0',NULL,'Nomad servers data in raw format.','0','30d','0','',NULL,'{$NOMAD.DATA.TIMEOUT}','','','','200','1','0','','','0','0','0','0','0','0','0','254354aa21764751bf7e1961e37de7ae','0','2','0'),
('45854','3','','10595','Service [rpc] state','net.tcp.service[tcp,,{$NOMAD.CLIENT.RPC.PORT}]','1m','31d','365d','0','3','','','','',NULL,'1120','','','0','','','','','0',NULL,'Current [rpc] service state.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','f98bd789c9f7409aac2e1902776ddc21','0','2','0'),
('45855','3','','10595','Service [serf] state','net.tcp.service[tcp,,{$NOMAD.CLIENT.SERF.PORT}]','1m','31d','365d','0','3','','','','',NULL,'1120','','','0','','','','','0',NULL,'Current [serf] service state.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','00b39edd70cc42daa565879494f15f38','0','2','0'),
('45856','19','','10595','Node info get','nomad.client.node.info.get','1h','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Node info data in raw format.','0','30d','0','',NULL,'{$NOMAD.DATA.TIMEOUT}','{$NOMAD.CLIENT.API.SCHEME}://{HOST.IP}:{$NOMAD.CLIENT.API.PORT}/v1/nodes','[{"filter":"ID == \\"{HOST.HOST}\\""}]','','','1','0','{$NOMAD.HTTP.PROXY}','X-Nomad-Token: {$NOMAD.TOKEN}','2','0','1','0','0','0','0','36eb68c80b194a4591208cf210fb6d6e','0','2','0'),
('45857','19','','10595','Allocated jobs get','nomad.client.job.allocs.get','1h','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Allocated jobs data in raw format.','0','30d','0','',NULL,'{$NOMAD.DATA.TIMEOUT}','{$NOMAD.CLIENT.API.SCHEME}://{HOST.IP}:{$NOMAD.CLIENT.API.PORT}/v1/allocations','[{"reverse":"true"},{"task_states":"false"},{"filter":"NodeID == \\"{HOST.HOST}\\" and DesiredStatus == \\"run\\" and ClientStatus == \\"running\\""}]','','','1','0','{$NOMAD.HTTP.PROXY}','X-Nomad-Token: {$NOMAD.TOKEN}','2','0','1','0','0','0','0','9948608c5b3a4dad9d1b433483296427','0','2','0'),
('45858','19','','10595','Telemetry get','nomad.client.data.get','1m','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Telemetry data in raw format.','0','30d','0','',NULL,'{$NOMAD.DATA.TIMEOUT}','{$NOMAD.CLIENT.API.SCHEME}://{HOST.IP}:{$NOMAD.CLIENT.API.PORT}/v1/metrics','[{"format":"prometheus"}]','','','1','0','{$NOMAD.HTTP.PROXY}','X-Nomad-Token: {$NOMAD.TOKEN}','2','0','1','0','0','0','0','fe07fd88f3e14273b3f0b135aab26236','0','2','0'),
('45859','3','','10596','Service [rpc] state','net.tcp.service[tcp,,{$NOMAD.SERVER.RPC.PORT}]','1m','31d','365d','0','3','','','','',NULL,'1123','','','0','','','','','0',NULL,'Current [rpc] service state.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','c5903e91262b4877be8c7e8f304b2862','0','2','0'),
('45860','19','','10596','Telemetry get','nomad.server.data.get','1m','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Telemetry data in raw format.','0','30d','0','',NULL,'{$NOMAD.DATA.TIMEOUT}','{$NOMAD.SERVER.API.SCHEME}://{HOST.IP}:{$NOMAD.SERVER.API.PORT}/v1/metrics','[{"format":"prometheus"}]','','','1','0','{$NOMAD.HTTP.PROXY}','X-Nomad-Token: {$NOMAD.TOKEN}','2','0','1','0','0','0','0','b7ba2f4a56b04de298fde77cbf5afb6a','0','2','0'),
('45861','3','','10596','Service [serf] state','net.tcp.service[tcp,,{$NOMAD.SERVER.SERF.PORT}]','1m','31d','365d','0','3','','','','',NULL,'1123','','','0','','','','','0',NULL,'Current [serf] service state.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','9eecc3ee79f04448991c83ac93459597','0','2','0'),
('45862','19','','10596','Internal stats get','nomad.server.stats.get','1h','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Internal stats data in raw format.','0','30d','0','',NULL,'{$NOMAD.DATA.TIMEOUT}','{$NOMAD.SERVER.API.SCHEME}://{HOST.IP}:{$NOMAD.SERVER.API.PORT}/v1/agent/self','[{"filter":"ID == \\"{HOST.HOST}\\""}]','','','1','0','{$NOMAD.HTTP.PROXY}','X-Nomad-Token: {$NOMAD.TOKEN}','2','0','1','0','0','0','0','f8d3a680e6f94250ab0a1ef8169889e3','0','2','0'),
('46045','5','','10048','Utilization of snmp poller data collector processes, in %','zabbix[process,snmp poller,avg,busy]','1m','31d','365d','0','0','','%','','',NULL,NULL,'','','0','','','','','0',NULL,'The average percentage of the time during which the snmp poller processes have been busy for the last minute.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','96b04e9605e04b26a280bc62da92879b','0','2','0'),
('46047','5','','10047','Utilization of snmp poller data collector processes, in %','zabbix[process,snmp poller,avg,busy]','1m','31d','365d','0','0','','%','','',NULL,NULL,'','','0','','','','','0',NULL,'The average percentage of the time during which the snmp poller processes have been busy for the last minute.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','aa5db45e74834355a80566316017d6d4','0','2','0'),
('46050','19','','10599','Get access token','acronis.cpc.account_manager.get_token','{$ACRONIS.CPC.AUTH.INTERVAL}','0','0','0','4','','','','',NULL,NULL,'','','1','{$ACRONIS.CPC.AUTH.CLIENT.ID}','{$ACRONIS.CPC.AUTH.SECRET}','','','0',NULL,'Authorizes API user and receives access token.','0','30d','0','',NULL,'15s','{$ACRONIS.CPC.DATACENTER.URL}{$ACRONIS.CPC.PATH.ACCOUNT.MANAGEMENT}/idp/token','','grant_type=client_credentials','','1','0','{$ACRONIS.CPC.HTTP.PROXY}','Content-Type: application/x-www-form-urlencoded\r\nX-Application-Secret: 5619386d-de56-49ec-8508-f5c399d3b9bd','0','1','0','0','0','0','0','bce642c2c6e743ccb618c96f6ca533da','0','2','0'),
('46051','19','','10600','Get customers','acronis.cpc.customers.get','5m','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Fetches all customers.','0','30d','0','',NULL,'15s','{$ACRONIS.CPC.DATACENTER.URL}{$ACRONIS.CPC.PATH.ACCOUNT.MANAGEMENT}/tenants','[{"subtree_root_id":"{$ACRONIS.CPC.MSP.TENANT.UUID}"}]','','','1','0','{$ACRONIS.CPC.HTTP.PROXY}','Accept: application/json\r\nAuthorization: Bearer {$ACRONIS.CPC.ACCESS_TOKEN}\r\nX-Application-Secret: 5619386d-de56-49ec-8508-f5c399d3b9bd','0','0','0','0','0','0','0','77f25dbbd477458a88f1850701dccc69','0','2','0'),
('46052','19','','10600','Get alerts','acronis.cpc.alerts.get','5m','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Fetches all alerts.','0','30d','0','',NULL,'15s','{$ACRONIS.CPC.DATACENTER.URL}{$ACRONIS.CPC.PATH.ALERTS}/alerts','','','','1','0','{$ACRONIS.CPC.HTTP.PROXY}','Accept: application/json\r\nAuthorization: Bearer {$ACRONIS.CPC.ACCESS_TOKEN}\r\nX-Application-Secret: 5619386d-de56-49ec-8508-f5c399d3b9bd','0','0','0','0','0','0','0','dba9a02767be47819f7012f316723fff','0','2','0'),
('46053','19','','10600','Get devices','acronis.cpc.devices.get','1m','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Fetches all devices.','0','30d','0','',NULL,'15s','{$ACRONIS.CPC.DATACENTER.URL}{$ACRONIS.CPC.PATH.RESOURCE.MANAGEMENT}/resources','[{"type":"{$ACRONIS.CPC.DEVICE.RESOURCE.TYPE}"}]','','','1','0','{$ACRONIS.CPC.HTTP.PROXY}','Accept: application/json\r\nAuthorization: Bearer {$ACRONIS.CPC.ACCESS_TOKEN}\r\nX-Application-Secret: 5619386d-de56-49ec-8508-f5c399d3b9bd','0','0','0','0','0','0','0','81b3d23d30964b88aeb3a0911ba0e487','0','2','0'),
('46054','21','','10600','Register integration','acronis.cpc.register.integration','24h','0','0','0','3','','','','',NULL,NULL,'\r\nconst request_path = \'/api/integration_management/v2/status\';\r\nconst app_id = \'5619386d-de56-49ec-8508-f5c399d3b9bd\';\r\n\r\nfunction checkParams(params) {\r\n	[\'api_url\', \'api_token\', \'tenant_uuid\'].forEach(function (field) {\r\n		if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n			throw \'Required param is not set: \' + field + \'.\';\r\n		}\r\n	});\r\n	return params;\r\n}\r\n\r\nfunction getHttpData(url, register, params, api_token, tenant_uuid) {\r\n	const request = new HttpRequest();\r\n\r\n	request.addHeader(\'Content-Type: application/json\');\r\n	request.addHeader(\'Authorization: Bearer \' + api_token);\r\n	request.addHeader(\'X-Application-Secret: \' + app_id);\r\n\r\n	if (params[\'http_proxy\']) {\r\n		request.setProxy(params[\'http_proxy\']);\r\n		Zabbix.log(4, \'[ ACRONIS CYBER PROTECT CLOUD API ] Using http proxy: \' + params[\'http_proxy\']);\r\n	}\r\n\r\n	if (!register) {\r\n		const response = request.get(url + \'?tenantID=\' + encodeURIComponent(tenant_uuid));\r\n		Zabbix.log(4, \'[ ACRONIS CYBER PROTECT CLOUD API ] [ \' + url + \' ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n\r\n		if (request.getStatus() !== 200) {\r\n			if (typeof (response.error && response.error.message) !== \'undefined\') {\r\n				throw response.error.message;\r\n			} else {\r\n				throw \'Failed to receive data: invalid response status code. Check debug log for more information.\';\r\n			}\r\n		}\r\n\r\n		return response;\r\n\r\n	} else {\r\n\r\n		const request_body = {\r\n			"application_id": app_id,\r\n			"module": {\r\n				"name": "Zabbix integration with Acronis Cyber Protect Cloud",\r\n				"version": "1.0.0"\r\n			},\r\n			"vendor_system": {\r\n				"name": "Product integrated with Acronis",\r\n				"version": "23.07"\r\n			},\r\n			"events": [\r\n				{\r\n					"category": "activation",\r\n					"action": "activated integration",\r\n					"activation_event": true\r\n				}\r\n			]\r\n		};\r\n\r\n		const response = request.post(url + \'?tenantID=\' + encodeURIComponent(tenant_uuid), JSON.stringify(request_body));\r\n		Zabbix.log(4, \'[ ACRONIS CYBER PROTECT CLOUD API ] [ \' + url + \' ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n\r\n		if (request.getStatus() !== 204) {\r\n			if (typeof (response.error && response.error.message) !== \'undefined\') {\r\n				throw response.error.message;\r\n			} else {\r\n				throw \'Failed to receive data: invalid response status code. Check debug log for more information.\';\r\n			}\r\n		}\r\n\r\n		return 1;\r\n	}\r\n}\r\n\r\nfunction parseGetStatusData(http_response) {\r\n	const data = JSON.parse(http_response);\r\n	if (data[\'items\']) {\r\n		data[\'items\'].forEach(function (app) {\r\n			if (app[\'application_id\'] && app[\'application_id\'] === app_id) {\r\n				return app[\'active\'];\r\n			}\r\n		});\r\n		return false;\r\n	} else {\r\n		throw \'Unexpected data structure in HTTP response.\';\r\n	}\r\n}\r\n\r\nconst params = checkParams(JSON.parse(value)),\r\n	url = params.api_url,\r\n	api_token = params.api_token,\r\n	tenant_uuid = params.tenant_uuid;\r\n\r\nconst current_activation_status = parseGetStatusData(getHttpData(url + request_path, false, params, api_token, tenant_uuid));\r\n\r\nif (!current_activation_status) {\r\n	return getHttpData(url + request_path, true, params, api_token, tenant_uuid);\r\n} else {\r\n	return 0;\r\n}','','0','','','','','0',NULL,'Registers integration on Acronis services.','0','30d','0','',NULL,'30s','','','','200','1','0','','','0','0','0','0','0','0','0','3697d34ebbb74b90aa7318321ecc27e5','0','2','0'),
('46064','19','','10600','Device [{#NAME}]:[{#ID}]: Raw data resources status','acronis.cpc.device.res.status.raw[{#NAME}]','1m','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','2',NULL,'Gets statuses for device resources.','0','30d','0','',NULL,'15s','{$ACRONIS.CPC.DATACENTER.URL}{$ACRONIS.CPC.PATH.RESOURCE.MANAGEMENT}/resource_statuses','[{"resource_id":"{#ID}"},{"include_attributes":"true"}]','','','1','0','{$ACRONIS.CPC.HTTP.PROXY}','Accept: application/json\r\nAuthorization: Bearer {$ACRONIS.CPC.ACCESS_TOKEN}\r\nX-Application-Secret: 5619386d-de56-49ec-8508-f5c399d3b9bd','0','0','0','0','0','0','0','20d93972ca2f47af96aed7ee9aa642af','0','2','0'),
('46085','19','','10602','Get server information','nextcloud.serverinfo.get_data','1m','0','0','0','4','','','','',NULL,NULL,'','','1','{$NEXTCLOUD.USER.NAME}','{$NEXTCLOUD.USER.PASSWORD}','','','0',NULL,'This item provides useful server information, such as CPU load, RAM usage, disk usage, number of users, etc.\r\nhttps://github.com/nextcloud/serverinfo','0','30d','0','',NULL,'10s','{$NEXTCLOUD.SCHEMA}://{$NEXTCLOUD.ADDRESS}/ocs/v2.php/apps/serverinfo/api/v1/info','','','200,401','1','0','{$NEXTCLOUD.PROXY}','OCS-APIRequest: true','0','0','0','0','0','0','0','8a7fb4062f484de4a8579ebb83b297a2','0','2','0'),
('46116','19','','10602','Nextcloud: User discovery','nextcloud.user.discovery','1h','90d','365d','0','4','','','','',NULL,NULL,'','','1','{$NEXTCLOUD.USER.NAME}','{$NEXTCLOUD.USER.PASSWORD}','','','1',NULL,'User discovery.','0','1d','1','',NULL,'10s','{$NEXTCLOUD.SCHEMA}://{$NEXTCLOUD.ADDRESS}/ocs/v1.php/cloud/users?format=json','','','200','1','0','{$NEXTCLOUD.PROXY}','OCS-APIRequest: true','0','0','0','0','0','0','0','477477630aa14dd8b3940f7b95697893','0','2','0'),
('46117','19','','10602','User "{#NEXTCLOUD.USER}": Get data','nextcloud.user.get_data[{#NEXTCLOUD.USER}]','1m','0','0','0','4','','','','',NULL,NULL,'','','1','{$NEXTCLOUD.USER.NAME}','{$NEXTCLOUD.USER.PASSWORD}','','','2',NULL,'Get common information about user','0','30d','0','',NULL,'10s','{$NEXTCLOUD.SCHEMA}://{$NEXTCLOUD.ADDRESS}/ocs/v1.php/cloud/users/{#NEXTCLOUD.USER}','','','200,401','1','0','{$NEXTCLOUD.PROXY}','OCS-APIRequest: true','0','0','0','0','0','0','0','78b3e2a8e7844b0ea5929dbecd8a2ed7','0','2','0'),
('46129','17','','10518','SNMP traps (fallback)','snmptrap.fallback','0','31d','0','0','2','','','','hh:mm:sszyyyy/MM/dd',NULL,NULL,'','','0','','','','','0',NULL,'The item is used to collect all SNMP traps unmatched by other snmptrap items.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','a33215bcdb5b42cd809f258c4118e07a','0','2','0'),
('46130','0','','10329','Version','pgsql.version["{$PG.CONNSTRING.AGENT2}","{$PG.USER}","{$PG.PASSWORD}","{$PG.DATABASE}"]','15m','31d','0','0','1','','','','',NULL,NULL,'','','0','','','','','0',NULL,'PostgreSQL version.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','523528aad175455fbd1daba161365651','0','2','0'),
('46131','11','','10589','Version','db.odbc.select[pgsql.version,,"Database={$PG.DATABASE};{$PG.CONNSTRING.ODBC}"]','15m','31d','0','0','1','','','','',NULL,NULL,'SELECT version()','','0','{$PG.USER}','{$PG.PASSWORD}','','','0',NULL,'PostgreSQL version.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','4bfb0c1697f043d9acf640b84cc8d945','0','2','0'),
('46132','3','','10603','Check port availability','net.tcp.service["{$FGATE.SCHEME}","{$FGATE.API.FQDN}","{$FGATE.API.PORT}"]','1m','31d','365d','0','3','','','','',NULL,'1136','','','0','','','','','0',NULL,'','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','27d30f93ff7c49d89537c43bad5f9453','0','2','0'),
('46133','19','','10603','Get firmware info','fgate.firmware.get_data','1m','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Item for gathering device firmware info from FortiGate API.','0','30d','0','',NULL,'{$FGATE.DATA.TIMEOUT}','{$FGATE.SCHEME}://{$FGATE.API.FQDN}:{$FGATE.API.PORT}/api/v2/monitor/system/firmware','[{"access_token":"{$FGATE.API.TOKEN}"}]','','200','1','0','{$FGATE.HTTP.PROXY}','','0','0','0','0','0','0','0','bc2ac899ea284703a6a8753ac5abc7c6','0','2','0'),
('46134','19','','10603','Get system info','fgate.system.get_data','1m','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Item for gathering device system info from FortiGate API.','0','30d','0','',NULL,'{$FGATE.DATA.TIMEOUT}','{$FGATE.SCHEME}://{$FGATE.API.FQDN}:{$FGATE.API.PORT}/api/v2/monitor/web-ui/state','[{"access_token":"{$FGATE.API.TOKEN}"}]','','200','1','0','{$FGATE.HTTP.PROXY}','','0','0','0','0','0','0','0','a6b831300e7048fbad4502973d0318e7','0','2','0'),
('46135','21','','10603','Get service licenses','fgate.service.get_data','1m','0','0','0','4','','','','',NULL,NULL,'var params = JSON.parse(value),\r\n	request = new HttpRequest(),\r\n	result = {"data": {}, "lld": [], "error": ""},\r\n	api_url = "",\r\n	error_msg = "";\r\n\r\nfunction getHttpData(url) {\r\n	response = request.get(url);\r\n	Zabbix.log(4, \'[ FortiGate ] [ \' + url + \' ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n\r\n	if (request.getStatus() !== 200) {\r\n		throw \'Failed to receive data: invalid response status code. Check debug log for more information.\';\r\n	}\r\n\r\n	if (response !== null) {\r\n		try {\r\n			response = JSON.parse(response);\r\n		}\r\n		catch (error) {\r\n			throw \'Failed to parse response received from FortiGate API. Check debug log for more information.\';\r\n		}\r\n	}\r\n\r\n	if (typeof response !== \'object\' || response === null) {\r\n		throw \'Cannot process response data: received data is not an object.\';\r\n	}\r\n\r\n	if ((typeof response.status !== \'undefined\' && response.status != \'success\') || typeof response.results === \'undefined\') {\r\n		var uri = \'/\' + response.path + \'/\' + response.name + ((typeof response.action !== \'undefined\') ? \'?action=\' + response.action : "");\r\n		throw \'Failed to parse response received from \' + uri + \'. Check debug log for more information.\';\r\n	}\r\n\r\n	return response;\r\n};\r\n\r\nfunction capitalize(word, idx) {\r\n	return upAcronymCase(word.charAt(idx).toUpperCase() + word.slice(idx+1));\r\n}\r\n\r\nfunction upAcronymCase(word) {\r\n	if (word.length < 4) {\r\n		return word.toUpperCase()\r\n	}\r\n	return word;\r\n}\r\n\r\nfunction prepareServiceName(key) {\r\n	var result = [];\r\n	key.split(\'_\').forEach(function (w) {\r\n		var forti_idx = w.indexOf(\'forti\');\r\n		w = upAcronymCase(w);\r\n		if (forti_idx !== -1)\r\n			w = \'Forti\' + capitalize(w, forti_idx + 5);\r\n		else\r\n			w = capitalize(w, 0)\r\n		result.push(w);\r\n	});\r\n\r\n	return result.join(\' \');\r\n};\r\n\r\ntry {\r\n	[\'scheme\', \'api.token\', \'api.fqdn\', \'api.port\'].forEach(function (field) {\r\n		var macro = \'{$FGATE.\' + field.toUpperCase() + \'}\';\r\n		var key = field.split(\'.\').pop();\r\n		if (params[key] === macro || params[key] === \'\') {\r\n			throw \'Please change \' + macro + \' macro to the proper value.\';\r\n		}\r\n		if (typeof params[key] === \'undefined\') {\r\n			throw \'Please set "\' + key + \'" script input parameter to \' + macro + \' macro value.\';\r\n		}\r\n	});\r\n\r\n	api_url = params.scheme + \'://\' + params.fqdn + \':\' + params.port;\r\n\r\n	if (typeof params.http_proxy !== \'undefined\' && params.http_proxy !== \'{\' + \'$FGATE.HTTP.PROXY}\' && params.http_proxy !== \'\') {\r\n		request.setProxy(params.http_proxy);\r\n	}\r\n\r\n	var licence_list = getHttpData(\r\n		api_url + \'/api/v2/monitor/license/status?access_token=\' + encodeURIComponent(params.token)\r\n	);\r\n\r\n	result.data = licence_list.results;\r\n	Object.keys(licence_list.results).forEach(function (key) {\r\n		var resource = licence_list.results[key];\r\n		if (typeof resource.status !== \'undefined\' && typeof resource.type !== \'undefined\') {\r\n			result.lld.push({\r\n				"key": key,\r\n				"name": prepareServiceName(key),\r\n				"status": resource.status,\r\n				"type": resource.type,\r\n			});\r\n		}\r\n	});\r\n} catch (error) {\r\n	error_msg = error.toString();\r\n	error_msg += error_msg.endsWith(\'.\') ? \'\' : \'.\';\r\n	Zabbix.log(3, \'[ FortiGate ] ERROR: \' + error_msg);\r\n};\r\n\r\nresult.error = error_msg;\r\n\r\nreturn JSON.stringify(result);','','0','','','','','0',NULL,'Item for gathering information about service licenses from FortiGate API.','0','30d','0','',NULL,'{$FGATE.DATA.TIMEOUT}','','','','200','1','0','','','0','0','0','0','0','0','0','90a78cff28d54a1b9b955e9dc94d48c7','0','2','0'),
('46136','21','','10603','Get SD-WAN data','fgate.sdwan.get_data','1m','0','0','0','4','','','','',NULL,NULL,'var params = JSON.parse(value),\r\n	request = new HttpRequest(),\r\n	result = {"data": {}, "error": ""},\r\n	api_url = "",\r\n	health_members = [],\r\n	health_checks = [],\r\n	members = {},\r\n	error_msg = "";\r\n\r\nfunction getHttpData(url) {\r\n	response = request.get(url);\r\n	Zabbix.log(4, \'[ FortiGate ] [ \' + url + \' ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n\r\n	if (request.getStatus() !== 200) {\r\n		throw \'Failed to receive data: invalid response status code. Check debug log for more information.\';\r\n	}\r\n\r\n	if (response !== null) {\r\n		try {\r\n			response = JSON.parse(response);\r\n		}\r\n		catch (error) {\r\n			throw \'Failed to parse response received from FortiGate API. Check debug log for more information.\';\r\n		}\r\n	}\r\n\r\n	if (typeof response !== \'object\' || response === null) {\r\n		throw \'Cannot process response data: received data is not an object.\';\r\n	}\r\n\r\n	if ((typeof response.status !== \'undefined\' && response.status != \'success\') || typeof response.results === \'undefined\') {\r\n		var uri = \'/\' + response.path + \'/\' + response.name + ((typeof response.action !== \'undefined\') ? \'?action=\' + response.action : "");\r\n		throw \'Failed to parse response received from \' + uri + \'. Check debug log for more information.\';\r\n	}\r\n\r\n	return response;\r\n};\r\n\r\ntry {\r\n	[\'scheme\', \'api.token\', \'api.fqdn\', \'api.port\'].forEach(function (field) {\r\n		var macro = \'{$FGATE.\' + field.toUpperCase() + \'}\';\r\n		var key = field.split(\'.\').pop();\r\n		if (params[key] === macro || params[key] === \'\') {\r\n			throw \'Please change \' + macro + \' macro to the proper value.\';\r\n		}\r\n		if (typeof params[key] === \'undefined\') {\r\n			throw \'Please set "\' + key + \'" script input parameter to \' + macro + \' macro value.\';\r\n		}\r\n	});\r\n\r\n	if (typeof params.http_proxy !== \'undefined\' && params.http_proxy !== \'{\' + \'$FGATE.HTTP.PROXY}\' && params.http_proxy !== \'\') {\r\n		request.setProxy(params.http_proxy);\r\n	}\r\n\r\n	api_url = params.scheme + \'://\' + params.fqdn + \':\' + params.port;\r\n\r\n	var sdwan_member_data = getHttpData(\r\n		api_url + \'/api/v2/monitor/virtual-wan/members?access_token=\' + encodeURIComponent(params.token)\r\n	);\r\n\r\n	var sdwan_health_data = getHttpData(\r\n		api_url + \'/api/v2/monitor/virtual-wan/health-check?access_token=\' + encodeURIComponent(params.token)\r\n	);\r\n\r\n	var sdwan_list = getHttpData(\r\n		api_url + \'/api/v2/cmdb/system/sdwan?access_token=\' + encodeURIComponent(params.token)\r\n	);\r\n\r\n	sdwan_list.results[\'health-check\'].forEach(function (item) {\r\n		health_checks[item.q_origin_key] = item.members.length;\r\n		item.members.forEach(function (m) {\r\n			health_members.push({\r\n				\'member_id\': m.q_origin_key,\r\n				\'health_id\': item.q_origin_key,\r\n				\'health_name\': item.name,\r\n			});\r\n		});\r\n	});\r\n\r\n	sdwan_list.results.members.forEach(function (item) {\r\n		members[item.q_origin_key] = item;\r\n	});\r\n\r\n	result.data = {\r\n		\'member_lld\': sdwan_list.results.members.filter(function (v) {\r\n			if (v.interface.length > 0) {\r\n				return v;\r\n			}\r\n		}).map(function (v) {\r\n			if (typeof v.interface !== \'undefined\' && typeof sdwan_member_data.results[v.interface] !== \'undefined\') {\r\n				Object.assign(v, sdwan_member_data.results[v.interface]);\r\n			}\r\n			return v;\r\n		}),\r\n		\'health_lld\': health_members.map(function (m) {\r\n			var item = {};\r\n			if (typeof members[String(m.member_id)] !== \'undefined\') {\r\n				[\'interface\', \'status\'].forEach(function (k) {\r\n					item[k] = members[String(m.member_id)][k];\r\n				});\r\n				Object.assign(item, m);\r\n			};\r\n			return item;\r\n		}).filter(function (v) {\r\n			if (v.interface.length > 0) {\r\n				return v;\r\n			}\r\n		}),\r\n		\'health_data\': sdwan_list.results[\'health-check\'].filter(function (v) {\r\n			if (typeof health_checks[String(v.q_origin_key)] !== \'undefined\' && health_checks[String(v.q_origin_key)] > 0) {\r\n				return v;\r\n			}\r\n		}).map(function (v) {\r\n			delete v.members;\r\n			if (typeof v.name !== \'undefined\' && typeof sdwan_health_data.results[v.name] !== \'undefined\') {\r\n				Object.assign(v, sdwan_health_data.results[v.name]);\r\n			}\r\n			return v;\r\n		})\r\n	}\r\n} catch (error) {\r\n	error_msg = error.toString();\r\n	error_msg += error_msg.endsWith(\'.\') ? \'\' : \'.\';\r\n	Zabbix.log(3, \'[ FortiGate ] ERROR: \' + error_msg);\r\n};\r\n\r\nresult.error = error_msg;\r\n\r\nreturn JSON.stringify(result);','','0','','','','','0',NULL,'Item for gathering SD-WAN information from FortiGate API.','0','30d','0','',NULL,'{$FGATE.DATA.TIMEOUT}','','','','200','1','0','','','0','0','0','0','0','0','0','01814568a3bc4774a37957ff3d8c5e09','0','2','0'),
('46137','21','','10603','Get resources data','fgate.resources.get_data','1m','0','0','0','4','','','','',NULL,NULL,'var params = JSON.parse(value),\r\n	request = new HttpRequest(),\r\n	result = {"data": {}, "error": ""},\r\n	api_url = "",\r\n	error_msg = "";\r\n\r\nfunction getHttpData(url) {\r\n	response = request.get(url);\r\n	Zabbix.log(4, \'[ FortiGate ] [ \' + url + \' ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n\r\n	if (request.getStatus() !== 200) {\r\n		throw \'Failed to receive data: invalid response status code. Check debug log for more information.\';\r\n	}\r\n\r\n	if (response !== null) {\r\n		try {\r\n			response = JSON.parse(response);\r\n		}\r\n		catch (error) {\r\n			throw \'Failed to parse response received from FortiGate API. Check debug log for more information.\';\r\n		}\r\n	}\r\n\r\n	if (typeof response !== \'object\' || response === null) {\r\n		throw \'Cannot process response data: received data is not an object.\';\r\n	}\r\n\r\n	if ((typeof response.status !== \'undefined\' && response.status != \'success\') || typeof response.results === \'undefined\') {\r\n		var uri = \'/\' + response.path + \'/\' + response.name + ((typeof response.action !== \'undefined\') ? \'?action=\' + response.action : "");\r\n		throw \'Failed to parse response received from \' + uri + \'. Check debug log for more information.\';\r\n	}\r\n\r\n	return response;\r\n};\r\n\r\ntry {\r\n	[\'scheme\', \'api.token\', \'api.fqdn\', \'api.port\'].forEach(function (field) {\r\n		var macro = \'{$FGATE.\' + field.toUpperCase() + \'}\';\r\n		var key = field.split(\'.\').pop();\r\n		if (params[key] === macro || params[key] === \'\') {\r\n			throw \'Please change \' + macro + \' macro to the proper value.\';\r\n		}\r\n		if (typeof params[key] === \'undefined\') {\r\n			throw \'Please set "\' + key + \'" script input parameter to \' + macro + \' macro value.\';\r\n		}\r\n	});\r\n\r\n	if (typeof params.http_proxy !== \'undefined\' && params.http_proxy !== \'{\' + \'$FGATE.HTTP.PROXY}\' && params.http_proxy !== \'\') {\r\n		request.setProxy(params.http_proxy);\r\n	}\r\n\r\n	api_url = params.scheme + \'://\' + params.fqdn + \':\' + params.port;\r\n\r\n	var resource_list = getHttpData(\r\n		api_url + \'/api/v2/monitor/system/resource/usage?access_token=\' + encodeURIComponent(params.token) + \'&interval=1-min\'\r\n	);\r\n\r\n	var disk_info = getHttpData(\r\n		api_url + \'/api/v2/monitor/log/current-disk-usage?access_token=\' + encodeURIComponent(params.token)\r\n	);\r\n\r\n	if (typeof resource_list.results !== \'undefined\' && typeof resource_list.results === \'object\') {\r\n		Object.keys(resource_list.results).forEach(function (key) {\r\n			var resource = resource_list.results[key];\r\n			if (resource.length > 0) {\r\n				result.data[key] = resource[0].current;\r\n			}\r\n		});\r\n	}\r\n	else {\r\n		throw \'Failed to parse response received from FortiGate API. Check debug log for more information.\';\r\n	}\r\n\r\n	Object.keys(disk_info.results).forEach(function (key) {\r\n		result.data[\'disk_\' + key.split(\'_\')[0]] = disk_info.results[key];\r\n	});\r\n} catch (error) {\r\n	error_msg = error.toString();\r\n	error_msg += error_msg.endsWith(\'.\') ? \'\' : \'.\';\r\n	Zabbix.log(3, \'[ FortiGate ] ERROR: \' + error_msg);\r\n};\r\n\r\nresult.error = error_msg;\r\n\r\nreturn JSON.stringify(result);','','0','','','','','0',NULL,'Item for gathering device resource data from FortiGate API.','0','30d','0','',NULL,'{$FGATE.DATA.TIMEOUT}','','','','200','1','0','','','0','0','0','0','0','0','0','06199d6a96f2414b976d357cd2c95cb6','0','2','0'),
('46138','21','','10603','Get interfaces data','fgate.netif.get_data','1m','0','0','0','4','','','','',NULL,NULL,'var params = JSON.parse(value),\r\n	request = new HttpRequest(),\r\n	result = {"data": {}, "error": ""},\r\n	api_url = "",\r\n	interfaces = {},\r\n	error_msg = "";\r\n\r\nfunction getHttpData(url) {\r\n	response = request.get(url);\r\n	Zabbix.log(4, \'[ FortiGate ] [ \' + url + \' ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n\r\n	if (request.getStatus() !== 200) {\r\n		throw \'Failed to receive data: invalid response status code. Check debug log for more information.\';\r\n	}\r\n\r\n	if (response !== null) {\r\n		try {\r\n			response = JSON.parse(response);\r\n		}\r\n		catch (error) {\r\n			throw \'Failed to parse response received from FortiGate API. Check debug log for more information.\';\r\n		}\r\n	}\r\n\r\n	if (typeof response !== \'object\' || response === null) {\r\n		throw \'Cannot process response data: received data is not an object.\';\r\n	}\r\n\r\n	if ((typeof response.status !== \'undefined\' && response.status != \'success\') || typeof response.results === \'undefined\') {\r\n		var uri = \'/\' + response.path + \'/\' + response.name + ((typeof response.action !== \'undefined\') ? \'?action=\' + response.action : "");\r\n		throw \'Failed to parse response received from \' + uri + \'. Check debug log for more information.\';\r\n	}\r\n\r\n	return response;\r\n};\r\n\r\ntry {\r\n	[\'scheme\', \'api.token\', \'api.fqdn\', \'api.port\'].forEach(function (field) {\r\n		var macro = \'{$FGATE.\' + field.toUpperCase() + \'}\';\r\n		var key = field.split(\'.\').pop();\r\n		if (params[key] === macro || params[key] === \'\') {\r\n			throw \'Please change \' + macro + \' macro to the proper value.\';\r\n		}\r\n		if (typeof params[key] === \'undefined\') {\r\n			throw \'Please set "\' + key + \'" script input parameter to \' + macro + \' macro value.\';\r\n		}\r\n	});\r\n\r\n	if (typeof params.http_proxy !== \'undefined\' && params.http_proxy !== \'{\' + \'$FGATE.HTTP.PROXY}\' && params.http_proxy !== \'\') {\r\n		request.setProxy(params.http_proxy);\r\n	}\r\n\r\n	api_url = params.scheme + \'://\' + params.fqdn + \':\' + params.port;\r\n\r\n	var netif_data = getHttpData(\r\n		api_url + \'/api/v2/monitor/system/interface?access_token=\' + encodeURIComponent(params.token)\r\n	);\r\n\r\n	var netif_list = getHttpData(\r\n		api_url + \'/api/v2/cmdb/system/interface?access_token=\' + encodeURIComponent(params.token)\r\n	);\r\n\r\n	result.data = netif_list.results.map(function (v) {\r\n		var item = {};\r\n		[\'q_origin_key\', \'name\', \'mode\', \'type\', \'description\'].forEach(function (k) {\r\n			item[k] = v[k];\r\n		});\r\n		if (typeof item.q_origin_key !== \'undefined\' && typeof netif_data.results[String(item.q_origin_key)] !== \'undefined\') {\r\n			Object.assign(item, netif_data.results[String(item.q_origin_key)]);\r\n		}\r\n		if (typeof item.alias !== \'undefined\') {\r\n			item.alias = item.alias.slice(1,-1);\r\n		}\r\n		else {\r\n			item.alias = \'\';\r\n		}\r\n		if (typeof item.link === \'undefined\') {\r\n			item.link = false;\r\n		}\r\n		if (typeof item.id === \'undefined\') {\r\n			item.id = item.q_origin_key;\r\n		}\r\n		return item;\r\n	});\r\n} catch (error) {\r\n	error_msg = error.toString();\r\n	error_msg += error_msg.endsWith(\'.\') ? \'\' : \'.\';\r\n	Zabbix.log(3, \'[ FortiGate ] ERROR: \' + error_msg);\r\n};\r\n\r\nresult.error = error_msg;\r\n\r\nreturn JSON.stringify(result);','','0','','','','','0',NULL,'Item for gathering network interfaces info from FortiGate API.','0','30d','0','',NULL,'{$FGATE.DATA.TIMEOUT}','','','','200','1','0','','','0','0','0','0','0','0','0','3bf84b70672d4fbca282ce1bf970581d','0','2','0'),
('46139','21','','10603','Get firewall data','fgate.fwp.get_data','1m','0','0','0','4','','','','',NULL,NULL,'var params = JSON.parse(value),\r\n	request = new HttpRequest(),\r\n	result = {"data": {}, "error": ""},\r\n	api_url = "",\r\n	policies = {},\r\n	error_msg = "";\r\n\r\nfunction getHttpData(url) {\r\n	response = request.get(url);\r\n	Zabbix.log(4, \'[ FortiGate ] [ \' + url + \' ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n\r\n	if (request.getStatus() !== 200) {\r\n		throw \'Failed to receive data: invalid response status code. Check debug log for more information.\';\r\n	}\r\n\r\n	if (response !== null) {\r\n		try {\r\n			response = JSON.parse(response);\r\n		}\r\n		catch (error) {\r\n			throw \'Failed to parse response received from FortiGate API. Check debug log for more information.\';\r\n		}\r\n	}\r\n\r\n	if (typeof response !== \'object\' || response === null) {\r\n		throw \'Cannot process response data: received data is not an object.\';\r\n	}\r\n\r\n	if ((typeof response.status !== \'undefined\' && response.status != \'success\') || typeof response.results === \'undefined\') {\r\n		var uri = \'/\' + response.path + \'/\' + response.name + ((typeof response.action !== \'undefined\') ? \'?action=\' + response.action : "");\r\n		throw \'Failed to parse response received from \' + uri + \'. Check debug log for more information.\';\r\n	}\r\n\r\n	return response;\r\n};\r\n\r\ntry {\r\n	[\'scheme\', \'api.token\', \'api.fqdn\', \'api.port\'].forEach(function (field) {\r\n		var macro = \'{$FGATE.\' + field.toUpperCase() + \'}\';\r\n		var key = field.split(\'.\').pop();\r\n		if (params[key] === macro || params[key] === \'\') {\r\n			throw \'Please change \' + macro + \' macro to the proper value.\';\r\n		}\r\n		if (typeof params[key] === \'undefined\') {\r\n			throw \'Please set "\' + key + \'" script input parameter to \' + macro + \' macro value.\';\r\n		}\r\n	});\r\n\r\n	if (typeof params.http_proxy !== \'undefined\' && params.http_proxy !== \'{\' + \'$FGATE.HTTP.PROXY}\' && params.http_proxy !== \'\') {\r\n		request.setProxy(params.http_proxy);\r\n	}\r\n\r\n	api_url = params.scheme + \'://\' + params.fqdn + \':\' + params.port;\r\n\r\n	var firewall_data = getHttpData(\r\n		api_url + \'/api/v2/monitor/firewall/policy?access_token=\' + encodeURIComponent(params.token)\r\n	);\r\n\r\n	var firewall_list = getHttpData(\r\n		api_url + \'/api/v2/cmdb/firewall/policy?access_token=\' + encodeURIComponent(params.token)\r\n	);\r\n\r\n	firewall_list.results.forEach(function (v) {\r\n		var item = {};\r\n		[\'q_origin_key\', \'status\', \'name\', \'uuid\', \'action\', \'ip-version-type\', \'label\'].forEach(function (k) {\r\n			item[k] = v[k];\r\n		});\r\n		policies[v.policyid] = item;\r\n	});\r\n\r\n	result.data = firewall_data.results.map(function (v) {\r\n		if (typeof v.policyid !== \'undefined\' && typeof policies[String(v.policyid)] !== \'undefined\') {\r\n			Object.assign(v, policies[String(v.policyid)]);\r\n		}\r\n		return v;\r\n	}).filter(function (v) {\r\n		if (typeof v.name !== \'undefined\') {\r\n			return v;\r\n		}\r\n	});\r\n} catch (error) {\r\n	error_msg = error.toString();\r\n	error_msg += error_msg.endsWith(\'.\') ? \'\' : \'.\';\r\n	Zabbix.log(3, \'[ FortiGate ] ERROR: \' + error_msg);\r\n};\r\n\r\nresult.error = error_msg;\r\n\r\nreturn JSON.stringify(result);','','0','','','','','0',NULL,'Item for gathering firewall policies info from FortiGate API.','0','30d','0','',NULL,'{$FGATE.DATA.TIMEOUT}','','','','200','1','0','','','0','0','0','0','0','0','0','a7f8a7da176040ab8a43618e14944e42','0','2','0'),
('46212','3','','10604','ICMP ping','icmpping','1m','31d','365d','0','3','','','','',NULL,'1140','','','0','','','','','0',NULL,'Host accessibility by ICMP.\r\n0 - ICMP ping failed.\r\n1 - ICMP ping successful.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','5686859d4317437c9c23160b987a3468','0','2','0'),
('46213','20','1.3.6.1.2.1.1.5.0','10604','System name','system.name','15m','31d','0','0','1','','','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: SNMPv2-MIB\r\nAn administratively-assigned name for the node (the node\'s fully-qualified domain name). If not provided, the value is a zero-length string.','3','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','07256dfb73794eaea91c9c622e617200','0','2','0'),
('46214','20','1.3.6.1.4.1.12356.101.4.1.4.0','10604','Memory utilization','vm.memory.util[memoryUsedPercentage.0]','1m','31d','365d','0','0','','%','','',NULL,NULL,'','','0','','','','','0',NULL,'Current memory utilization (percentage).','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','29a7ec8007ef44b0b473f1c16be11059','0','2','0'),
('46215','15','','10604','Used memory','vm.memory.used[fgSysMemUsage.0]','1m','31d','365d','0','0','','B','','',NULL,NULL,'(last(//vm.memory.total[fgSysMemCapacity.0])*last(//vm.memory.util[memoryUsedPercentage.0]))/100','','0','','','','','0',NULL,'MIB: FORTINET-FORTIGATE-MIB\r\nPhysical memory (RAM) used calculated based on memory utilization percentage.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','15fb0d4185f04b4fb8e2efc6d0ef514c','0','2','0'),
('46216','20','1.3.6.1.4.1.12356.101.4.1.5.0','10604','Total memory','vm.memory.total[fgSysMemCapacity.0]','1m','31d','365d','0','3','','B','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: FORTINET-FORTIGATE-MIB\r\nTotal physical memory (RAM) installed.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','5ccef71de6944c91bf7d1e330782b542','0','2','0'),
('46217','15','','10604','Available memory','vm.memory.available[fgSysMemFree.0]','1m','31d','365d','0','3','','B','','',NULL,NULL,'last(//vm.memory.total[fgSysMemCapacity.0])-last(//vm.memory.used[fgSysMemUsage.0])','','0','','','','','0',NULL,'Total memory available for utilization.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','bbc42709b2d2467e8fd7963309c6090a','0','2','0'),
('46218','20','1.3.6.1.4.1.12356.101.4.1.6.0','10604','Used disk space','vfs.fs.used[fgSysDiskUsage.0]','1m','31d','365d','0','3','','B','','',NULL,NULL,'','','0','','','','','0',NULL,'Current hard disk usage.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','3a96f25d233e49039eb03b78fc8fd509','0','2','0'),
('46219','20','1.3.6.1.4.1.12356.101.4.1.7.0','10604','Total disk space','vfs.fs.total[fgSysDiskCapacity.0]','1m','31d','365d','0','3','','B','','',NULL,NULL,'','','0','','','','','0',NULL,'Total hard disk capacity.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','84318818c417403bbfadff759f87e4f4','0','2','0'),
('46220','15','','10604','Free disk percentage','vfs.fs.pfree','1m','31d','365d','0','0','','%','','',NULL,NULL,'100-(last(//vfs.fs.used[fgSysDiskUsage.0])/last(//vfs.fs.total[fgSysDiskCapacity.0])*100)','','0','','','','','0',NULL,'Free disk space, expressed in %.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','b7001a7fd88040fe8a11512df1d9ec07','0','2','0'),
('46221','15','','10604','Free disk space','vfs.fs.free','1m','31d','365d','0','3','','B','','',NULL,NULL,'last(//vfs.fs.total[fgSysDiskCapacity.0])-last(//vfs.fs.used[fgSysDiskUsage.0])','','0','','','','','0',NULL,'Free hard disk capacity.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','c702bedf91d74cd8b2346ea0abca37c5','0','2','0'),
('46222','20','1.3.6.1.4.1.12356.101.4.1.20.0','10604','System uptime','system.uptime[fgSysUpTime.0]','1m','31d','365d','0','3','','uptime','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: FORTINET-FORTIGATE-MIB\r\nTime since the network management portion of the system was last re-initialized.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','6b85f5f1738b46acb17157d8fbf60ecf','0','2','0'),
('46223','20','1.3.6.1.2.1.1.2.0','10604','System object ID','system.objectid[sysObjectID.0]','15m','31d','0','0','1','','','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: SNMPv2-MIB\r\nThe vendor\'s authoritative identification of the entity as part of the vendor\'s SMI enterprises subtree with the prefix 1.3.6.1.4.1 (e.g., a vendor with the identifier 1.3.6.1.4.1.4242 might assign a system object with the OID 1.3.6.1.4.1.4242.1.1).','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','53aee5ecb43b4fe29a2e172f48577fa5','0','2','0'),
('46224','20','1.3.6.1.2.1.1.6.0','10604','System location','system.location[sysLocation.0]','15m','31d','0','0','1','','','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: SNMPv2-MIB\r\nPhysical location of the node (e.g., `equipment room`, `3rd floor`). If not provided, the value is a zero-length string.','24','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','8adf6927a2ba4c26b31a1a527cfd33f7','0','2','0'),
('46225','3','','10604','ICMP loss','icmppingloss','1m','31d','365d','0','0','','%','','',NULL,NULL,'','','0','','','','','0',NULL,'Percentage of lost packets.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','60ba9ecc198840a3a92ef3221e21a97e','0','2','0'),
('46226','20','1.3.6.1.2.1.47.1.1.1.1.11.1','10604','Hardware serial number','system.hw.serialnumber','1h','31d','0','0','1','','','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: ENTITY-MIB\r\nSerial number of the device.','8','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','4ad23a8963e64a7da8b064463631a2f9','0','2','0'),
('46227','20','1.3.6.1.2.1.47.1.2.1.1.2.1','10604','Hardware model name','system.hw.model','1h','31d','0','0','1','','','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: ENTITY-MIB\r\nModel of the device.','29','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','d1cde0e8780a455db0f7aec7b6b3bc7a','0','2','0'),
('46228','20','1.3.6.1.4.1.12356.101.4.1.1.0','10604','Firmware version','system.hw.firmware','1h','31d','0','0','1','','','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: FORTINET-FORTIGATE-MIB\r\nFirmware version of the device.','16','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','277fdc82a6d04e53a0da7bb29d087de7','0','2','0'),
('46229','20','1.3.6.1.2.1.1.1.0','10604','System description','system.descr[sysDescr.0]','15m','31d','0','0','1','','','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: SNMPv2-MIB\r\nA textual description of the entity. This value should include the full name and version identification of the system\'s hardware type, software operating system, and networking software.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','c2a2247eaddf4908b731ef0c42627d47','0','2','0'),
('46230','20','1.3.6.1.4.1.12356.101.4.1.3.0','10604','CPU utilization','system.cpu.util[fgSysCpuUsage.0]','1m','31d','365d','0','0','','%','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: FORTINET-FORTIGATE-MIB\r\nCPU utilization in %.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','e6c36e1b4fac4242a3c3ddd4a5483dde','0','2','0'),
('46231','20','1.3.6.1.4.1.12356.101.4.4.1.0','10604','Number of CPUs','system.cpu.num','1m','31d','365d','0','3','','','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: FORTINET-FORTIGATE-MIB\r\nNumber of processors.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','c728a8f64cff450ebc445d9abc03486d','0','2','0'),
('46232','20','1.3.6.1.2.1.1.4.0','10604','System contact details','system.contact[sysContact.0]','15m','31d','0','0','1','','','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: SNMPv2-MIB\r\nName and contact information of the contact person for the node. If not provided, the value is a zero-length string.','23','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','cc57314e0cd143c79654e53d16f341ca','0','2','0'),
('46233','17','','10604','SNMP traps (fallback)','snmptrap.fallback','0','31d','0','0','2','','','','hh:mm:sszyyyy/MM/dd',NULL,NULL,'','','0','','','','','0',NULL,'Used for collecting all SNMP traps unmatched by other `snmptrap` items.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','b00ecb6f04a04f579ce0a8e6a1c0984e','0','2','0'),
('46234','20','walk[1.3.6.1.2.1.2.2.1.8,1.3.6.1.2.1.2.2.1.7,1.3.6.1.2.1.31.1.1.1.18,1.3.6.1.2.1.31.1.1.1.1,1.3.6.1.2.1.2.2.1.2,1.3.6.1.2.1.2.2.1.3,1.3.6.1.2.1.31.1.1.1.6,1.3.6.1.2.1.31.1.1.1.10,1.3.6.1.2.1.2.2.1.14,1.3.6.1.2.1.2.2.1.20,1.3.6.1.2.1.2.2.1.19,1.3.6.1.2.1.2.2.1.13,1.3.6.1.2.1.31.1.1.1.15]','10604','SNMP walk network interfaces','net.if.walk','1m','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Used for discovering interfaces from IF-MIB.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','abd3f407b66946dab2b05f7ec8a2daf2','0','2','0'),
('46235','3','','10604','ICMP response time','icmppingsec','1m','31d','365d','0','0','','s','','',NULL,NULL,'','','0','','','','','0',NULL,'ICMP ping response time (in seconds).','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','c5c3cde736544304a76c5fe1774c1fc7','0','2','0'),
('46236','5','','10604','SNMP agent availability','zabbix[host,snmp,available]','1m','31d','365d','0','3','','','','',NULL,'1141','','','0','','','','','0',NULL,'Availability of SNMP checks on the host. The value of this item corresponds to availability icons in the host list.\r\nPossible values:\r\n0 - not available\r\n1 - available\r\n2 - unknown','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','3e37679441344327bf86ae38cd62f580','0','2','0'),
('46247','19','','10548','Get SAML SSO','meraki.get.saml','12h','31d','365d','0','3','','','','',NULL,'1142','','','0','','','','','0',NULL,'Return the enabled SAML SSO settings for the organization.','0','30d','0','',NULL,'{$MERAKI.DATA.TIMEOUT}','https://{$MERAKI.API.URL}/organizations/{$ID}/saml','','','200','1','0','{$MERAKI.HTTP_PROXY}','X-Cisco-Meraki-API-Key: {$MERAKI.TOKEN}\r\nUser-Agent: ZabbixServer/1.1 Zabbix','0','0','0','0','0','0','0','b33608b4c24d4c7bbf1f76f639890715','0','2','0'),
('46248','19','','10548','Get admin\'s account','meraki.get.admins','12h','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Get list of the dashboard administrators in this organization.','0','30d','0','',NULL,'{$MERAKI.DATA.TIMEOUT}','https://{$MERAKI.API.URL}/organizations/{$ID}/admins','','','200','1','0','{$MERAKI.HTTP_PROXY}','X-Cisco-Meraki-API-Key: {$MERAKI.TOKEN}\r\nUser-Agent: ZabbixServer/1.1 Zabbix','0','0','0','0','0','0','0','75c09cebedc7436cb4304acc3652955c','0','2','0'),
('46249','21','','10548','Get list licenses','meraki.get.list.licenses','12h','0','0','0','4','','','','',NULL,NULL,'var params = JSON.parse(value);\r\n\r\nvar request = new HttpRequest();\r\n\r\nrequest.addHeader(\'X-Cisco-Meraki-API-Key:\' + params.token);\r\nrequest.addHeader(\'User-Agent: ZabbixServer/1.1 Zabbix\');\r\n\r\nvar response,\r\n	error_msg = \'\',\r\n	organization_devices = [],\r\n	licenses = [];\r\n\r\nfunction getField(data, path) {\r\n	var steps = path.split(\'.\');\r\n	for (var i = 0; i < steps.length; i++) {\r\n		var step = steps[i];\r\n		if (typeof data !== \'object\' || typeof data[step] === \'undefined\') {\r\n			throw \'Required field was not found: \' + path;\r\n		}\r\n		data = data[step];\r\n	}\r\n\r\n	return data;\r\n\r\n};\r\n\r\nfunction getHttpData(url) {\r\n	response = request.get(url);\r\n	Zabbix.log(4, \'[ Meraki API ] [ \' + url + \' ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n\r\n	if (response !== null) {\r\n		try {\r\n			response = JSON.parse(response);\r\n		}\r\n		catch (error) {\r\n			throw \'Failed to parse response received from Meraki API. Check debug log for more information.\';\r\n		}\r\n	}\r\n\r\n	if (request.getStatus() !== 200) {\r\n		if (response.errors) {\r\n			throw response.errors.join(\', \');\r\n		} else {\r\n			throw \'Failed to receive data: invalid response status code.\';\r\n		}\r\n	}\r\n\r\n	if (typeof (response) !== \'object\' || response === null) {\r\n		throw \'Cannot process response data: received data is not an object.\';\r\n	}\r\n\r\n	return response;\r\n};\r\n\r\ntry {\r\n\r\n	if (params.token === \'{\' + \'$MERAKI.TOKEN}\') {\r\n		throw \'Please change {\' + \'$MERAKI.TOKEN} macro to the proper value.\';\r\n	}\r\n\r\n	if (params.url.indexOf(\'http://\') === -1 && params.url.indexOf(\'https://\') === -1) {\r\n		params.url = \'https://\' + params.url;\r\n	}\r\n\r\n	if (!params.url.endsWith(\'/\')) {\r\n		params.url += \'/\';\r\n	}\r\n\r\n	if (typeof params.httpproxy !== \'undefined\' && params.httpproxy !== \'\') {\r\n		request.setProxy(params.httpproxy);\r\n	}\r\n\r\n	licenses = getHttpData(params.url + \'organizations/\' + encodeURIComponent(params.organizationId) + \'/licenses\');\r\n\r\n	organization_devices = getHttpData(params.url + \'organizations/\' + encodeURIComponent(params.organizationId) + \'/devices/statuses\');\r\n\r\n	licenses.forEach(function (license) {\r\n\r\n		license.deviceName = getField(license, \'deviceSerial\');\r\n\r\n		for (i in organization_devices) {\r\n\r\n			if (getField(license, \'deviceSerial\') === getField(organization_devices[i], \'serial\')) {\r\n\r\n				device_name = getField(organization_devices[i], \'name\');\r\n\r\n				if (!device_name) {\r\n					device_name = getField(organization_devices[i], \'serial\');\r\n				}\r\n				license.deviceName = device_name;\r\n			}\r\n		}\r\n	});\r\n\r\n\r\n} catch (error) {\r\n	error_msg = error;\r\n};\r\n\r\nreturn JSON.stringify({\r\n	\'licenses\': licenses,\r\n	\'error\': error_msg.toString()\r\n});','','0','','','','','0',NULL,'Return list of the licenses for the organization.','0','30d','0','',NULL,'{$MERAKI.DATA.TIMEOUT}','','','','200','1','0','','','0','0','0','0','0','0','0','8ea56a7338f040fcbb9016da892dec90','0','2','0'),
('46250','19','','10548','Get login security','meraki.get.login.security','12h','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Return the login security settings for the organization.','0','30d','0','',NULL,'{$MERAKI.DATA.TIMEOUT}','https://{$MERAKI.API.URL}/organizations/{$ID}/loginSecurity','','','200','1','0','{$MERAKI.HTTP_PROXY}','X-Cisco-Meraki-API-Key: {$MERAKI.TOKEN}\r\nUser-Agent: ZabbixServer/1.1 Zabbix','0','0','0','0','0','0','0','ac5da80c1e9b46a2ac31809e16fe1bfc','0','2','0'),
('46251','19','','10548','Get SAML roles','meraki.get.saml.roles','12h','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Get list of the SAML roles for this organization.','0','30d','0','',NULL,'{$MERAKI.DATA.TIMEOUT}','https://{$MERAKI.API.URL}/organizations/{$ID}/samlRoles','','','200','1','0','{$MERAKI.HTTP_PROXY}','X-Cisco-Meraki-API-Key: {$MERAKI.TOKEN}\r\nUser-Agent: ZabbixServer/1.1 Zabbix','0','0','0','0','0','0','0','055cc5b5b49b4f398e06832091f66544','0','2','0'),
('46308','5','','10048','Proxy memory buffer, % used','zabbix[proxy_buffer,buffer,pused]','1m','31d','365d','0','0','','%','','',NULL,NULL,'','','0','','','','','0',NULL,'Statistics and availability of Zabbix proxy memory buffer usage statistics. Percentage of used proxy memory buffer.\r\nProxy memory buffer is used to store the new historical data and upload from it without accessing database.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','e60cdba498a94c19955696f40d5e1b32','0','2','0'),
('46309','5','','10048','Proxy buffer, state changes','zabbix[proxy_buffer,state,changes]','1m','31d','365d','0','3','','','','',NULL,NULL,'','','0','','','','','0',NULL,'The number of state changes between disk/memory buffer modes since proxy start.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','1f5fbc277a574ce7a418439695f124ca','0','2','0'),
('46310','5','','10048','Proxy buffer, state','zabbix[proxy_buffer,state,current]','1m','31d','365d','0','3','','','','',NULL,'1145','','','0','','','','','0',NULL,'The current working state of proxy buffer where the new data is being stored. Possible values:\r\n\r\n  0 - disk (also returned when memory buffer is disabled);\r\n  1 - memory.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','c970e56eda504a4d89b051439dda9787','0','2','0'),
('46314','5','','10047','Number of values synchronized with the database per second','zabbix[vps,written]','1m','31d','365d','0','0','','!vps','','',NULL,NULL,'','','0','','','','','0',NULL,'Average quantity of values written to the database, recalculated once per minute.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','0f61de4dcc1b469a94dd024e1b932936','0','2','0'),
('46319','21','','10605','Get data','hpe.ilo.get_data','{$ILO.INTERVAL}','0','0','0','4','','','','',NULL,NULL,'var ilo = {\r\n	params: {},\r\n	session_token: "",\r\n	session_url: "",\r\n\r\n	setParams: function (params) {\r\n		[\'ilo_url\', \'user\', \'password\'].forEach(function (field) {\r\n			if (typeof params !== \'object\' || typeof params[field] === \'undefined\'\r\n				|| params[field] === \'\') {\r\n				throw \'Required parameter is not set: "\' + field + \'".\';\r\n			}\r\n		});\r\n\r\n		ilo.params = params;\r\n\r\n		if (typeof ilo.params.ilo_url === \'string\' && !ilo.params.ilo_url.endsWith(\'/\')) {\r\n			ilo.params.ilo_url += \'/\';\r\n		}\r\n	},\r\n\r\n	apiAuth: function () {\r\n		var request = new HttpRequest(),\r\n			response,\r\n			headers,\r\n			url = encodeURI(ilo.params.ilo_url + \'redfish/v1/SessionService/Sessions/\'),\r\n			auth_data = {\r\n				UserName: ilo.params.user,\r\n				Password: ilo.params.password\r\n			};\r\n\r\n		request.addHeader(\'Content-Type: application/json\');\r\n		request.addHeader(\'Authorization: Basic \' + btoa(ilo.params.user + \':\' + ilo.params.password));\r\n\r\n		if (typeof ilo.params.http_proxy !== \'undefined\' && ilo.params.http_proxy !== \'\') {\r\n			request.setProxy(ilo.params.http_proxy);\r\n			Zabbix.log(4, \'[ HPE iLO ] Using HTTP proxy: \' + ilo.params.http_proxy);\r\n		}\r\n\r\n		Zabbix.log(4, \'[ HPE iLO ] Sending request: \' + url);\r\n\r\n		response = request.post(url, JSON.stringify(auth_data));\r\n\r\n		Zabbix.log(4, \'[ HPE iLO ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n\r\n		if (request.getStatus() != 201) {\r\n			throw \'Authentication failed with status code \' + request.getStatus() + \': \' + response;\r\n		}\r\n\r\n		try {\r\n			response = JSON.parse(response);\r\n		}\r\n		catch (error) {\r\n			throw \'Failed to parse auth response received from API. Check debug log for more information.\';\r\n		}\r\n\r\n		try {\r\n			headers = request.getHeaders();\r\n		}\r\n		catch (error) {\r\n			throw \'Failed to parse auth headers received from API. Check debug log for more information.\';\r\n		}\r\n\r\n		try {\r\n			ilo.session_token = headers[\'X-Auth-Token\'];\r\n			ilo.session_url = headers[\'Location\'];\r\n		}\r\n		catch (error) {\r\n			throw \'Failed to retrieve auth token or session URL from API. Check debug log for more information.\';\r\n		}\r\n\r\n		delete request;\r\n	},\r\n\r\n	apiLogout: function () {\r\n		var request = new HttpRequest(),\r\n			response,\r\n			url = encodeURI(ilo.session_url);\r\n\r\n		request.addHeader(\'X-Auth-Token: \' + ilo.session_token);\r\n\r\n		if (typeof ilo.params.http_proxy !== \'undefined\' && ilo.params.http_proxy !== \'\') {\r\n			request.setProxy(ilo.params.http_proxy);\r\n			Zabbix.log(4, \'[ HPE iLO ] Using HTTP proxy: \' + ilo.params.http_proxy);\r\n		}\r\n\r\n		Zabbix.log(4, \'[ HPE iLO ] Sending request: \' + url);\r\n\r\n		response = request.delete(url);\r\n\r\n		Zabbix.log(4, \'[ HPE iLO ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n\r\n		if (request.getStatus() != 200) {\r\n			throw \'Deleting of session failed with status code \' + request.getStatus() + \': \' + response;\r\n		}\r\n\r\n		delete request;\r\n	},\r\n\r\n	apiRequest: function (query) {\r\n		var request = new HttpRequest(),\r\n			response,\r\n			url = encodeURI(ilo.params.ilo_url + query);\r\n\r\n		if (typeof ilo.params.http_proxy !== \'undefined\' && ilo.params.http_proxy !== \'\') {\r\n			request.setProxy(ilo.params.http_proxy);\r\n			Zabbix.log(4, \'[ HPE iLO ] Using HTTP proxy: \' + ilo.params.http_proxy);\r\n		}\r\n\r\n		request.addHeader(\'X-Auth-Token: \' + ilo.session_token);\r\n\r\n		Zabbix.log(4, \'[ HPE iLO ] Sending request: \' + url);\r\n\r\n		response = request.get(url);\r\n\r\n		Zabbix.log(4, \'[ HPE iLO ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n\r\n		if (request.getStatus() < 200 || request.getStatus() >= 300) {\r\n			throw \'Request failed with status code \' + request.getStatus() + \': \' + response;\r\n		}\r\n\r\n		try {\r\n			response = JSON.parse(response);\r\n		}\r\n		catch (error) {\r\n			throw \'Failed to parse response received from API. Check debug log for more information.\';\r\n		}\r\n\r\n		delete request;\r\n\r\n		return response;\r\n	},\r\n\r\n	checkArray: function (array) {\r\n		return typeof array !== \'undefined\' && Array.isArray(array) && array.length > 0 ? true : false;\r\n	}\r\n};\r\n\r\ntry {\r\n	ilo.setParams(JSON.parse(value));\r\n	ilo.apiAuth();\r\n	var systems = [],\r\n		storages = [],\r\n		controllers = [],\r\n		drives = [],\r\n		volumes = [],\r\n		chassis = [],\r\n		fans = [],\r\n		sensors = [],\r\n		psu = [],\r\n		managers = [];\r\n\r\n	var get_systems = ilo.apiRequest(\'redfish/v1/Systems?$expand=.\');\r\n\r\n	if (ilo.checkArray(get_systems.Members)) {\r\n		for (i in get_systems.Members) {\r\n			if (\'Id\' in get_systems.Members[i]) {\r\n				if (get_systems.Members[i].HostName === null) {\r\n					get_systems.Members[i].HostName = get_systems.Members[i].Id;\r\n				}\r\n\r\n				systems.push(get_systems.Members[i]);\r\n\r\n				var system_storages = ilo.apiRequest(\'redfish/v1/Systems/\' + get_systems.Members[i].Id + \'/Storage?$expand=.\');\r\n\r\n				if (ilo.checkArray(system_storages.Members)) {\r\n					for (j in system_storages.Members) {\r\n						system_storages.Members[j].systemHostname = get_systems.Members[i].HostName;\r\n						system_storages.Members[j].systemType = get_systems.Members[i].SystemType;\r\n						system_storages.Members[j].systemId = get_systems.Members[i].Id;\r\n\r\n						storages.push(system_storages.Members[j]);\r\n\r\n						if (\'Id\' in system_storages.Members[j]) {\r\n							var storage_controllers = ilo.apiRequest(\'redfish/v1/Systems/\' + get_systems.Members[i].Id + \'/Storage/\' + system_storages.Members[j].Id + \'/Controllers?$expand=.\');\r\n\r\n							if (ilo.checkArray(storage_controllers.Members)) {\r\n								for (k in storage_controllers.Members) {\r\n									storage_controllers.Members[k].systemHostname = get_systems.Members[i].HostName;\r\n									storage_controllers.Members[k].systemType = get_systems.Members[i].SystemType;\r\n									storage_controllers.Members[k].systemId = get_systems.Members[i].Id;\r\n									storage_controllers.Members[k].storageId = system_storages.Members[j].Id;\r\n\r\n									controllers.push(storage_controllers.Members[k]);\r\n								}\r\n							}\r\n\r\n							var storage_drives = ilo.apiRequest(\'redfish/v1/Systems/\' + get_systems.Members[i].Id + \'/Storage/\' + system_storages.Members[j].Id + \'?$expand=.\');\r\n\r\n							if (ilo.checkArray(storage_drives.Drives)) {\r\n								for (k in storage_drives.Drives) {\r\n									storage_drives.Drives[k].systemHostname = get_systems.Members[i].HostName;\r\n									storage_drives.Drives[k].systemType = get_systems.Members[i].SystemType;\r\n									storage_drives.Drives[k].systemId = get_systems.Members[i].Id;\r\n									storage_drives.Drives[k].storageId = system_storages.Members[j].Id;\r\n\r\n									drives.push(storage_drives.Drives[k]);\r\n								}\r\n							}\r\n\r\n							if (\'Volumes\' in system_storages.Members[j]) {\r\n								var storage_volumes = ilo.apiRequest(\'redfish/v1/Systems/\' + get_systems.Members[i].Id + \'/Storage/\' + system_storages.Members[j].Id + \'/Volumes?$expand=.\');\r\n\r\n								if (ilo.checkArray(storage_volumes.Members)) {\r\n									for (k in storage_volumes.Members) {\r\n										storage_volumes.Members[k].systemHostname = get_systems.Members[i].HostName;\r\n										storage_volumes.Members[k].systemType = get_systems.Members[i].SystemType;\r\n										storage_volumes.Members[k].systemId = get_systems.Members[i].Id;\r\n										storage_volumes.Members[k].storageId = system_storages.Members[j].Id;\r\n\r\n										volumes.push(storage_volumes.Members[k]);\r\n									}\r\n								}\r\n							}\r\n						}\r\n					}\r\n				}\r\n			}\r\n		}\r\n	}\r\n\r\n	var get_chassis = ilo.apiRequest(\'redfish/v1/Chassis?$expand=.\');\r\n\r\n	if (ilo.checkArray(get_chassis.Members)) {\r\n		for (i in get_chassis.Members) {\r\n			if (\'Id\' in get_chassis.Members[i]) {\r\n				chassis.push(get_chassis.Members[i]);\r\n\r\n				chassis_thermal = ilo.apiRequest(\'redfish/v1/Chassis/\' + get_chassis.Members[i].Id + \'/Thermal/\');\r\n\r\n				if (ilo.checkArray(chassis_thermal.Fans)) {\r\n					for (j in chassis_thermal.Fans) {\r\n						chassis_thermal.Fans[j].chassisId = get_chassis.Members[i].Id;\r\n\r\n						fans.push(chassis_thermal.Fans[j]);\r\n					}\r\n				}\r\n\r\n				if (ilo.checkArray(chassis_thermal.Temperatures)) {\r\n					for (j in chassis_thermal.Temperatures) {\r\n						chassis_thermal.Temperatures[j].chassisId = get_chassis.Members[i].Id;\r\n\r\n						sensors.push(chassis_thermal.Temperatures[j]);\r\n					}\r\n				}\r\n\r\n				chassis_power = ilo.apiRequest(\'redfish/v1/Chassis/\' + get_chassis.Members[i].Id + \'/Power/\');\r\n\r\n				if (ilo.checkArray(chassis_power.PowerSupplies)) {\r\n					for (j in chassis_power.PowerSupplies) {\r\n						chassis_power.PowerSupplies[j].chassisId = get_chassis.Members[i].Id;\r\n\r\n						psu.push(chassis_power.PowerSupplies[j]);\r\n					}\r\n				}\r\n			}\r\n		}\r\n	}\r\n\r\n	var get_managers = ilo.apiRequest(\'redfish/v1/Managers?$expand=.\');\r\n\r\n	if (ilo.checkArray(get_managers.Members)) {\r\n		for (i in get_managers.Members) {\r\n			if (\'Id\' in get_managers.Members[i]) {\r\n				managers.push(get_managers.Members[i]);\r\n			}\r\n		}\r\n	}\r\n\r\n	ilo.apiLogout();\r\n\r\n	return JSON.stringify({\r\n		\'systems\': systems,\r\n		\'storages\': storages,\r\n		\'controllers\': controllers,\r\n		\'drives\': drives,\r\n		\'volumes\': volumes,\r\n		\'chassis\': chassis,\r\n		\'fans\': fans,\r\n		\'sensors\': sensors,\r\n		\'psu\': psu,\r\n		\'managers\': managers\r\n	});\r\n}\r\ncatch (error) {\r\n	error += (String(error).endsWith(\'.\')) ? \'\' : \'.\';\r\n	Zabbix.log(3, \'[ HPE iLO ] ERROR: \' + error);\r\n	return JSON.stringify({ error: error });\r\n}','','0','','','','','0',NULL,'The JSON with the result of API requests.','0','30d','0','',NULL,'{$ILO.TIMEOUT}','','','','200','1','0','','','0','0','0','0','0','0','0','3c2d368291294faa98c01a27f36ad805','0','2','0'),
('46374','21','','10530','Filter [{#AWS.S3.FILTER.ID.NAME}]: Get request metrics','aws.s3.get_metrics["{#AWS.S3.FILTER.ID.NAME}"]','{$AWS.S3.UPDATE.INTERVAL}','0','0','0','4','','','','',NULL,NULL,'var AWS = {\r\n	params: {},\r\n	metadata: \'http://169.254.169.254/latest/\',\r\n\r\n	getField: function (data, path) {\r\n		var steps = path.split(\'.\');\r\n		for (var i = 0; i < steps.length; i++) {\r\n			var step = steps[i];\r\n			if (typeof data !== \'object\' || typeof data[step] === \'undefined\') {\r\n				throw \'Required field was not found: \' + path;\r\n			}\r\n\r\n			data = data[step];\r\n		}\r\n\r\n		return data;\r\n	},\r\n\r\n	isFloat: function (n) {\r\n		n = parseFloat(n);\r\n		return Number(n) === n && n % 1 !== 0;\r\n	},\r\n\r\n	checkNumber: function checkNumber(string) {\r\n		if (typeof string !== "string" || isNaN(string) || AWS.isFloat(string)) {\r\n			throw \'Incorrect "timespan" parameter given: \' + string + \' Must be an unsigned number\';\r\n		}\r\n		return string;\r\n	},\r\n\r\n	setParams: function (params) {\r\n		AWS.params[\'proxy\'] = params.proxy;\r\n		switch (AWS.getField(params, \'auth_type\')) {\r\n			case \'role_base\':\r\n				AWS.params[\'auth_type\'] = \'role_base\';\r\n				var request = new HttpRequest();\r\n				if (typeof AWS.params.proxy !== \'undefined\' && AWS.params.proxy !== \'\') {\r\n					request.setProxy(AWS.params.proxy);\r\n				}\r\n				request.addHeader(\'X-aws-ec2-metadata-token-ttl-seconds: 21600\');\r\n				var token = request.put(AWS.metadata + \'api/token\');\r\n\r\n				if (request.getStatus() !== 200 || token === null || token === \'\') {\r\n					throw \'Error getting IMDSv2 session token.\';\r\n				}\r\n				request.addHeader(\'X-aws-ec2-metadata-token: \' + token);\r\n				var IamRoleName = request.get(AWS.metadata + \'meta-data/iam/security-credentials\');\r\n\r\n				if (request.getStatus() !== 200 || IamRoleName === null || IamRoleName === \'\') {\r\n					throw \'Error getting security credentials from instance metadata. Role not found.\';\r\n				}\r\n\r\n				credentials = request.get(AWS.metadata + \'meta-data/iam/security-credentials/\' + encodeURI(IamRoleName));\r\n\r\n				if (request.getStatus() !== 200 || credentials === null || credentials === \'\') {\r\n					throw \'Error getting security credentials from instance metadata.\';\r\n				}\r\n\r\n				try {\r\n					credentials = JSON.parse(credentials);\r\n				}\r\n				catch (error) {\r\n					throw \'Failed to parse response received from instance metadata. Check debug log for more information.\';\r\n				}\r\n\r\n				[\'AccessKeyId\', \'SecretAccessKey\', \'Token\'].forEach(function (field) {\r\n					if (typeof credentials !== \'object\' || typeof credentials[field] === \'undefined\' || credentials[field] === \'\') {\r\n						throw \'Required credentials are not set: "\' + field + \'".\';\r\n					};\r\n					AWS.params[field] = credentials[field];\r\n				});\r\n				break;\r\n			case \'assume_role\':\r\n				AWS.params[\'auth_type\'] = \'assume_role\';\r\n\r\n				[\'AccessKeyId\', \'SecretAccessKey\', \'sts_region\', \'role_arn\'].forEach(function (field) {\r\n					if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n						throw \'Required param is not set: "\' + field + \'".\';\r\n					}\r\n					AWS.params[field] = params[field];\r\n				});\r\n\r\n				role_arn_regex = /role\\/(.+)$/;\r\n\r\n				var payload = {\r\n					\'Action\': \'AssumeRole\',\r\n					\'Version\': \'2011-06-15\',\r\n					\'RoleArn\': AWS.params.role_arn,\r\n					\'RoleSessionName\': AWS.params.role_arn.match(role_arn_regex)[1] + \'Session\',\r\n				};\r\n\r\n				credentials = AWS.getField(AWS.request(\'POST\', AWS.params.sts_region, \'sts\', AWS.prepareParams(payload), \'\'), \'AssumeRoleResponse.AssumeRoleResult.Credentials\');\r\n\r\n				[\'AccessKeyId\', \'SecretAccessKey\', \'SessionToken\'].forEach(function (field) {\r\n					if (typeof credentials !== \'object\' || typeof credentials[field] === \'undefined\' || credentials[field] === \'\') {\r\n						throw \'Required credentials are not set: "\' + field + \'".\';\r\n					};\r\n					AWS.params[field] = credentials[field];\r\n				});\r\n				break;\r\n			default:\r\n				AWS.params[\'auth_type\'] = \'access_key\';\r\n				[\'AccessKeyId\', \'SecretAccessKey\'].forEach(function (field) {\r\n					if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n						throw \'Required param is not set: "\' + field + \'".\';\r\n					}\r\n					AWS.params[field] = params[field];\r\n				});\r\n		}\r\n		[\'region\', \'bucket_name\', \'filter_id\'].forEach(function (field) {\r\n			if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n				throw \'Required param is not set: "\' + field + \'".\';\r\n			}\r\n			AWS.params[field] = params[field];\r\n		});\r\n\r\n		updateInterval = AWS.checkNumber(\'{$AWS.S3.UPDATE.INTERVAL}\');\r\n\r\n		if (updateInterval > 86400 || updateInterval < 1) {\r\n			throw \'Incorrect "update interval" parameter given: \' + updateInterval + \' Must be between 1 and 86400 seconds.\';\r\n		}\r\n	},\r\n\r\n	sign: function (key, message) {\r\n		var hex = hmac(\'sha256\', key, message);\r\n\r\n		if ((hex.length % 2) === 1) {\r\n			throw \'Invalid length of a hex string!\';\r\n		}\r\n\r\n		var result = new Int8Array(hex.length / 2);\r\n		for (var i = 0, b = 0; i < hex.length; i += 2, b++) {\r\n			result[b] = parseInt(hex.substring(i, i + 2), 16);\r\n		}\r\n\r\n		return result;\r\n	},\r\n\r\n	renderMetricQuery: function (period, bucket_name, filter_id) {\r\n		var metrics_list = [\r\n			\'AllRequests:Count:Sum\',\r\n			\'GetRequests:Count:Sum\',\r\n			\'PutRequests:Count:Sum\',\r\n			\'DeleteRequests:Count:Sum\',\r\n			\'HeadRequests:Count:Sum\',\r\n			\'PostRequests:Count:Sum\',\r\n			\'SelectRequests:Count:Sum\',\r\n			\'SelectBytesScanned:Bytes:Average\',\r\n			\'SelectBytesReturned:Bytes:Average\',\r\n			\'ListRequests:Count:Sum\',\r\n			\'BytesDownloaded:Bytes:Average\',\r\n			\'BytesUploaded:Bytes:Average\',\r\n			\'4xxErrors:Count:Average\',\r\n			\'5xxErrors:Count:Average\',\r\n			\'TotalRequestLatency:Milliseconds:p90\',\r\n			\'FirstByteLatency:Milliseconds:p90\',\r\n			\'ReplicationLatency:Seconds:Average\',\r\n			\'BytesPendingReplication:Bytes:Average\',\r\n			\'OperationsPendingReplication:Count:Average\',\r\n\r\n		];\r\n\r\n		var metric_payload = [];\r\n		metrics_list.forEach(function (metric, index) {\r\n			var parts = metric.split(\':\', 3);\r\n			metric_payload.push({\r\n				\'Id\': \'m\' + index,\r\n				\'MetricStat\': {\r\n					\'Metric\': {\r\n						\'MetricName\': parts[0],\r\n						\'Namespace\': \'AWS/S3\',\r\n						\'Dimensions\': [\r\n							{\r\n								\'Name\': \'BucketName\',\r\n								\'Value\': bucket_name\r\n							},\r\n							{\r\n								\'Name\': \'FilterId\',\r\n								\'Value\': filter_id\r\n							}\r\n						]\r\n					},\r\n					\'Period\': period,\r\n					\'Stat\': parts[2],\r\n					\'Unit\': parts[1]\r\n				}\r\n			});\r\n		});\r\n\r\n		return metric_payload;\r\n\r\n	},\r\n	prepareParams: function (params) {\r\n		var result = [];\r\n\r\n		Object.keys(params).sort().forEach(function (key) {\r\n			if (typeof params[key] !== \'object\') {\r\n				result.push(key + \'=\' + encodeURIComponent(params[key]));\r\n			}\r\n			else {\r\n				result.push(prepareObject(key, params[key]));\r\n			}\r\n		});\r\n\r\n		return result.join(\'&\');\r\n	},\r\n\r\n	request: function (method, region, service, params, data) {\r\n		if (typeof data === \'undefined\' || data === null) {\r\n			data = \'\';\r\n		}\r\n		else {\r\n			data = JSON.stringify(data)\r\n		}\r\n\r\n		var amzdate = (new Date()).toISOString().replace(/\\.\\d+Z/, \'Z\').replace(/[-:]/g, \'\'),\r\n			date = amzdate.replace(/T\\d+Z/, \'\'),\r\n			host = service + \'.\' + region + \'.amazonaws.com\',\r\n			canonical_uri = \'/\';\r\n\r\n		if (AWS.params.auth_type === \'role_base\' || (AWS.params.auth_type === \'assume_role\' & !params.includes(\'AssumeRole\'))) {\r\n			token = AWS.params.auth_type === \'role_base\' ? AWS.params.Token : AWS.params.SessionToken;\r\n			var canonical_headers = \'content-encoding:amz-1.0\\n\' + \'host:\' + host + \'\\n\' + \'x-amz-date:\' + amzdate + \'\\n\' + \'x-amz-security-token:\' + token + \'\\n\',\r\n				signed_headers = \'content-encoding;host;x-amz-date;x-amz-security-token\';\r\n		}\r\n		else {\r\n			var canonical_headers = \'content-encoding:amz-1.0\\n\' + \'host:\' + host + \'\\n\' + \'x-amz-date:\' + amzdate + \'\\n\',\r\n				signed_headers = \'content-encoding;host;x-amz-date\';\r\n		}\r\n\r\n		var canonical_request = method + \'\\n\' + canonical_uri + \'\\n\' + params + \'\\n\' + canonical_headers + \'\\n\' + signed_headers + \'\\n\' + sha256(data),\r\n			credential_scope = date + \'/\' + region + \'/\' + service + \'/\' + \'aws4_request\',\r\n			request_string = \'AWS4-HMAC-SHA256\' + \'\\n\' + amzdate + \'\\n\' + credential_scope + \'\\n\' + sha256(canonical_request),\r\n			key = AWS.sign(\'AWS4\' + AWS.params.SecretAccessKey, date),\r\n			key = AWS.sign(key, region),\r\n			key = AWS.sign(key, service),\r\n			key = AWS.sign(key, \'aws4_request\'),\r\n			request = new HttpRequest(),\r\n			url = \'https://\' + host + canonical_uri + \'?\' + params;\r\n\r\n		if (typeof AWS.params.proxy !== \'undefined\' && AWS.params.proxy !== \'\') {\r\n			request.setProxy(AWS.params.proxy);\r\n		}\r\n		request.addHeader(\'x-amz-date: \' + amzdate);\r\n		request.addHeader(\'X-Amz-Target: GraniteServiceVersion20100801.GetMetricData\')\r\n		request.addHeader(\'Accept: application/json\');\r\n		request.addHeader(\'Content-Type: application/json\');\r\n		request.addHeader(\'Content-Encoding: amz-1.0\');\r\n		request.addHeader(\'Authorization: \' + \'AWS4-HMAC-SHA256 Credential=\' + AWS.params.AccessKeyId + \'/\' + credential_scope + \', \' + \'SignedHeaders=\' + signed_headers + \', \' + \'Signature=\' + hmac(\'sha256\', key, request_string));\r\n		if (AWS.params.auth_type === \'role_base\' || (AWS.params.auth_type === \'assume_role\' & !params.includes(\'AssumeRole\'))) {\r\n			request.addHeader(\'X-Amz-Security-Token: \' + token);\r\n		}\r\n\r\n		Zabbix.log(4, \'[ AWS S3 ] Sending request: \' + url);\r\n		response = request.post(url, data);\r\n		Zabbix.log(4, \'[ AWS S3 ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n\r\n		if (request.getStatus() !== 200) {\r\n			throw \'Request failed with status code \' + request.getStatus() + \': \' + response;\r\n		}\r\n\r\n		try {\r\n			response = JSON.parse(response);\r\n		}\r\n		catch (error) {\r\n			try {\r\n				response = JSON.parse(XML.toJson(response));\r\n			}\r\n			catch (error) {\r\n				throw \'Failed to parse response received from AWS CloudWatch API. Check debug log for more information.\';\r\n			}\r\n		}\r\n\r\n		return response;\r\n	},\r\n\r\n	getMetricsData: function () {\r\n		var payload = {},\r\n			end_time = Math.floor((new Date().getTime()) / 1000),\r\n			start_time = end_time - updateInterval;\r\n\r\n		payload[\'StartTime\'] = start_time;\r\n		payload[\'EndTime\'] = end_time;\r\n		payload[\'ScanBy\'] = \'TimestampDescending\';\r\n		payload[\'MetricDataQueries\'] = AWS.renderMetricQuery(60, AWS.params.bucket_name, AWS.params.filter_id);\r\n		result = AWS.request(\'POST\', AWS.params.region, \'monitoring\', \'\', payload);\r\n		if (typeof result !== \'object\' || typeof result.MetricDataResults !== \'object\') {\r\n			throw \'Cannot get metrics data from AWS CloudWatch API. Check debug log for more information.\';\r\n		}\r\n\r\n		return result.MetricDataResults;\r\n	}\r\n};\r\n\r\ntry {\r\n	AWS.setParams(JSON.parse(value));\r\n\r\n	return JSON.stringify(AWS.getMetricsData());\r\n}\r\ncatch (error) {\r\n	error += (String(error).endsWith(\'.\')) ? \'\' : \'.\';\r\n	Zabbix.log(3, \'[ AWS S3 ] ERROR: \' + error);\r\n\r\n	return JSON.stringify({ \'error\': error });\r\n}','','0','','','','','2',NULL,'Get bucket request metrics filter: \'{#AWS.S3.FILTER.ID.NAME}\'.\r\nFull metrics list related to S3: https://docs.aws.amazon.com/AmazonS3/latest/userguide/metrics-dimensions.html','0','30d','0','',NULL,'15s','','','','200','1','0','','','0','0','0','0','0','0','0','eabbd51547cb4a0484182d42601728c3','0','2','0'),
('46396','21','','10606','Get daily costs','azure.get.daily.costs','0s;h/5m/30','0','0','0','4','','','','',NULL,NULL,'var AzureCost = {\r\n	params: {},\r\n	token: null,\r\n\r\n	setParams: function (params) {\r\n		[\'app_id\', \'password\', \'tenant_id\', \'subscription_id\'].forEach(function (field) {\r\n			if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n				throw \'Required param is not set: \' + field + \'.\';\r\n			}\r\n		});\r\n		AzureCost.params = params;\r\n	},\r\n\r\n	login: function () {\r\n		var response,\r\n			login = new HttpRequest();\r\n\r\n		if (typeof AzureCost.params.proxy !== \'undefined\' && AzureCost.params.proxy !== \'\') {\r\n			login.setProxy(AzureCost.params.proxy);\r\n		}\r\n\r\n		login.addHeader(\'Content-Type: application/x-www-form-urlencoded\');\r\n		response = login.post(\r\n			\'https://login.microsoftonline.com/\' + encodeURIComponent(AzureCost.params.tenant_id) + \'/oauth2/token\',\r\n			\'grant_type=client_credentials&resource=\' + encodeURIComponent(\'https://management.azure.com/\') + \'&client_id=\' + encodeURIComponent(AzureCost.params.app_id) + \'&client_secret=\' + encodeURIComponent(AzureCost.params.password)\r\n		);\r\n\r\n		if (login.getStatus() !== 200) {\r\n			throw \'Login failed with status code \' + login.getStatus() + \': \' + response;\r\n		}\r\n		try {\r\n			response = JSON.parse(response);\r\n		}\r\n		catch (error) {\r\n			throw \'Failed to parse login session response.\';\r\n		}\r\n		if (!response.hasOwnProperty(\'access_token\')) {\r\n			throw \'Authentication response does not contain access token.\';\r\n		}\r\n\r\n		AzureCost.token = response[\'access_token\'];\r\n	},\r\n\r\n	request: function (url, body) {\r\n		if (typeof body === \'undefined\' || body === null) {\r\n			body = \'\';\r\n		}\r\n		var response,\r\n			headers,\r\n			regex = /-retry-after":"(\\d+)"/,\r\n			ratelimit,\r\n			request = new HttpRequest();\r\n\r\n		if (typeof AzureCost.params.proxy !== \'undefined\' && AzureCost.params.proxy !== \'\') {\r\n			request.setProxy(AzureCost.params.proxy);\r\n		}\r\n		if (!AzureCost.token) {\r\n			throw \'Request does not contain access token.\';\r\n		}\r\n		request.addHeader(\'Accept: application/json\');\r\n		request.addHeader(\'Content-Type: application/json\');\r\n		request.addHeader(\'Authorization: Bearer \' + AzureCost.token);\r\n\r\n		Zabbix.log(4, \'[ AzureCost ] request url: \' + url);\r\n\r\n		response = request.post(url, body);\r\n		headers = JSON.stringify(request.getHeaders());\r\n\r\n		if (headers.match(regex) !== null && request.getStatus() === 429) {\r\n			ratelimit = headers.match(regex)[1];\r\n			Zabbix.log(4, \'[ AzureCost ] Microsoft Cost Management have rate limit requests per 1 minute, retrying after \' + ratelimit + \' seconds\');\r\n			Zabbix.sleep(ratelimit * 1010);\r\n			response = request.post(url, body);\r\n		}\r\n		if (request.getStatus() !== 200) {\r\n			throw \'Request failed with status code \' + request.getStatus() + \': \' + response;\r\n		}\r\n\r\n		try {\r\n			return JSON.parse(response);\r\n		}\r\n		catch (error) {\r\n			throw \'Failed to parse response received from API.\';\r\n		}\r\n	},\r\n\r\n	getField: function (data, path) {\r\n		var steps = path.split(\'.\');\r\n		for (var i = 0; i < steps.length; i++) {\r\n			var step = steps[i];\r\n			if (typeof data !== \'object\' || typeof data[step] === \'undefined\') {\r\n				throw \'Required field was not found: \' + path;\r\n			}\r\n			data = data[step];\r\n		}\r\n\r\n		return data;\r\n	},\r\n\r\n	getCost: function () {\r\n		var metricData = {},\r\n			today = new Date(),\r\n			start_date = new Date(today);\r\n		start_date.setDate(today.getDate() - 1);\r\n\r\n		bodyRawCost = {\r\n			type: \'Usage\',\r\n			\'timeframe\': \'Custom\',\r\n			\'timePeriod\': {\r\n				\'from\': start_date,\r\n				\'to\': start_date\r\n			},\r\n			dataset: {\r\n				granularity: \'Daily\',\r\n				aggregation: {\r\n					totalCost: {\r\n						name: \'PreTaxCost\',\r\n						function: \'Sum\'\r\n					}\r\n				},\r\n				grouping: [\r\n					{\r\n						type: \'Dimension\',\r\n						name: \'Meter\',\r\n					},\r\n					{\r\n						type: \'Dimension\',\r\n						name: \'MeterSubcategory\',\r\n					},\r\n					{\r\n						type: \'Dimension\',\r\n						name: \'ResourceGroup\',\r\n					},\r\n					{\r\n						type: \'Dimension\',\r\n						name: \'ServiceName\',\r\n					},\r\n					{\r\n						type: \'Dimension\',\r\n						name: \'ResourceLocation\',\r\n					}\r\n				]\r\n			}\r\n		};\r\n		metricData = AzureCost.request(\'https://management.azure.com/subscriptions/\' + AzureCost.params.subscription_id + \'/providers/Microsoft.CostManagement/query?api-version=2023-11-01\', JSON.stringify(bodyRawCost));\r\n\r\n		var columns = AzureCost.getField(metricData, \'properties.columns\');\r\n\r\n		return transformedData = {\r\n			data: AzureCost.getField(metricData, \'properties.rows\').map(function (row) {\r\n				rowData = {};\r\n				columns.forEach(function (column, i) {\r\n					columnName = columns[i].name;\r\n					columnType = columns[i].type;\r\n					cellValue = row[i];\r\n					rowData[columnName] = column.type === "Number" ? cellValue.toString() : cellValue;\r\n				});\r\n				rowData.UsageDate = rowData.UsageDate.replace(/(\\d{4})(\\d{2})(\\d{2})/, "$1-$2-$3");\r\n\r\n				return rowData;\r\n			})\r\n		};\r\n	}\r\n};\r\n\r\ntry {\r\n	AzureCost.setParams(JSON.parse(value));\r\n	AzureCost.login();\r\n\r\n	return JSON.stringify(AzureCost.getCost());\r\n}\r\ncatch (error) {\r\n	error += (String(error).endsWith(\'.\')) ? \'\' : \'.\';\r\n	Zabbix.log(3, \'[ AzureCost ] ERROR: \' + error);\r\n\r\n	return JSON.stringify({ \'error\': error });\r\n}','','0','','','','','0',NULL,'The result of API requests is expressed in the JSON.','0','30d','0','',NULL,'{$AZURE.DATA.TIMEOUT}','','','','200','1','0','','','0','0','0','0','0','0','0','f50c96da86654a25b937756cc7f7010e','0','2','0'),
('46397','21','','10606','Get monthly costs','azure.get.monthly.costs','0s;h/12','0','0','0','4','','','','',NULL,NULL,'var AzureCost = {\r\n	params: {},\r\n	token: null,\r\n\r\n	setParams: function (params) {\r\n		[\'app_id\', \'password\', \'tenant_id\', \'subscription_id\', \'month\'].forEach(function (field) {\r\n			if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n				throw \'Required param is not set: \' + field + \'.\';\r\n			}\r\n		});\r\n		AzureCost.params = params;\r\n\r\n		today = new Date();\r\n		AzureCost.params.end_date = today.toISOString();\r\n		month = today.getMonth();\r\n		today.setMonth(month - params.month);\r\n		AzureCost.params.start_time = new Date(today.getFullYear(), today.getMonth()).toISOString();\r\n	},\r\n\r\n	login: function () {\r\n		var response,\r\n			login = new HttpRequest();\r\n\r\n		if (typeof AzureCost.params.proxy !== \'undefined\' && AzureCost.params.proxy !== \'\') {\r\n			login.setProxy(AzureCost.params.proxy);\r\n		}\r\n\r\n		login.addHeader(\'Content-Type: application/x-www-form-urlencoded\');\r\n		response = login.post(\r\n			\'https://login.microsoftonline.com/\' + encodeURIComponent(AzureCost.params.tenant_id) + \'/oauth2/token\',\r\n			\'grant_type=client_credentials&resource=\' + encodeURIComponent(\'https://management.azure.com/\') + \'&client_id=\' + encodeURIComponent(AzureCost.params.app_id) + \'&client_secret=\' + encodeURIComponent(AzureCost.params.password)\r\n		);\r\n\r\n		if (login.getStatus() !== 200) {\r\n			throw \'Login failed with status code \' + login.getStatus() + \': \' + response;\r\n		}\r\n		try {\r\n			response = JSON.parse(response);\r\n		}\r\n		catch (error) {\r\n			throw \'Failed to parse login session response.\';\r\n		}\r\n		if (!response.hasOwnProperty(\'access_token\')) {\r\n			throw \'Authentication response does not contain access token.\';\r\n		}\r\n\r\n		AzureCost.token = response[\'access_token\'];\r\n	},\r\n\r\n	request: function (url, body) {\r\n		if (typeof body === \'undefined\' || body === null) {\r\n			body = \'\';\r\n		}\r\n		var response,\r\n			headers,\r\n			regex = /-retry-after":"(\\d+)"/,\r\n			ratelimit,\r\n			request = new HttpRequest();\r\n\r\n		if (typeof AzureCost.params.proxy !== \'undefined\' && AzureCost.params.proxy !== \'\') {\r\n			request.setProxy(AzureCost.params.proxy);\r\n		}\r\n		if (!AzureCost.token) {\r\n			throw \'Request does not contain access token.\';\r\n		}\r\n		request.addHeader(\'Accept: application/json\');\r\n		request.addHeader(\'Content-Type: application/json\');\r\n		request.addHeader(\'Authorization: Bearer \' + AzureCost.token);\r\n\r\n		Zabbix.log(4, \'[ AzureCost ] request url: \' + url);\r\n\r\n		response = request.post(url, body);\r\n		headers = JSON.stringify(request.getHeaders());\r\n\r\n		if (headers.match(regex) !== null && request.getStatus() === 429) {\r\n			ratelimit = headers.match(regex)[1];\r\n			Zabbix.log(4, \'[ AzureCost ] Microsoft Cost Management have rate limit requests per 1 minute, retrying after \' + ratelimit + \' seconds\');\r\n			Zabbix.sleep(ratelimit * 1010);\r\n			response = request.post(url, body);\r\n		}\r\n		if (request.getStatus() !== 200) {\r\n			throw \'Request failed with status code \' + request.getStatus() + \': \' + response;\r\n		}\r\n\r\n		try {\r\n			return JSON.parse(response);\r\n		}\r\n		catch (error) {\r\n			throw \'Failed to parse response received from API.\';\r\n		}\r\n	},\r\n\r\n	getField: function (data, path) {\r\n		var steps = path.split(\'.\');\r\n		for (var i = 0; i < steps.length; i++) {\r\n			var step = steps[i];\r\n			if (typeof data !== \'object\' || typeof data[step] === \'undefined\') {\r\n				throw \'Required field was not found: \' + path;\r\n			}\r\n			data = data[step];\r\n		}\r\n\r\n		return data;\r\n	},\r\n\r\n	getCost: function (grouping) {\r\n		var metricData = {},\r\n			bodyRawCost = {\r\n				type: \'Usage\',\r\n				timeframe: \'Custom\',\r\n				timePeriod: {\r\n					from: AzureCost.params.start_time,\r\n					to: AzureCost.params.end_date\r\n				},\r\n				dataset: {\r\n					aggregation: {\r\n						totalCost: {\r\n							name: \'PreTaxCost\',\r\n							function: \'Sum\'\r\n						}\r\n					},\r\n					grouping: [\r\n						{\r\n							type: \'Dimension\',\r\n							name: \'BillingMonth\'\r\n						},\r\n						{\r\n							type: \'Dimension\',\r\n							name: grouping\r\n						},\r\n					]\r\n				}\r\n			};\r\n\r\n		metricData = AzureCost.request(\'https://management.azure.com/subscriptions/\' + AzureCost.params.subscription_id + \'/providers/Microsoft.CostManagement/query?api-version=2023-11-01\', JSON.stringify(bodyRawCost));\r\n\r\n		var columns = AzureCost.getField(metricData, \'properties.columns\');\r\n\r\n		return transformedData = {\r\n			data: AzureCost.getField(metricData, \'properties.rows\').map(function (row) {\r\n				rowData = {};\r\n				columns.forEach(function (column, i) {\r\n					columnName = columns[i].name;\r\n					cellValue = row[i];\r\n					rowData[columnName] = column.type === "Number" ? cellValue.toString() : cellValue;\r\n				});\r\n				rowData.BillingMonth = rowData.BillingMonth.slice(0, 7);\r\n\r\n				return rowData;\r\n			})\r\n		};\r\n	}\r\n};\r\n\r\ntry {\r\n	AzureCost.setParams(JSON.parse(value));\r\n	AzureCost.login();\r\n\r\n	serviceCost = AzureCost.getCost(\'ServiceName\');\r\n	resourceGroupCost = AzureCost.getCost(\'ResourceGroup\');\r\n	resourceLocationCost = AzureCost.getCost(\'ResourceLocation\');\r\n	monthCost = AzureCost.getCost(\'SubscriptionId\');\r\n\r\n	return JSON.stringify({ resourceGroupCost, resourceLocationCost, serviceCost, monthCost });\r\n}\r\ncatch (error) {\r\n	error += (String(error).endsWith(\'.\')) ? \'\' : \'.\';\r\n	Zabbix.log(3, \'[ AzureCost ] ERROR: \' + error);\r\n\r\n	return JSON.stringify({ \'error\': error });\r\n}','','0','','','','','0',NULL,'The result of API requests is expressed in the JSON.','0','30d','0','',NULL,'{$AZURE.DATA.TIMEOUT}','','','','200','1','0','','','0','0','0','0','0','0','0','bbf6a0b136464d76a535ca016dcb8ae1','0','2','0'),
('46408','11','','10327','Get availability groups','db.odbc.get[get_availability_group,"{$MSSQL.DSN}"]','1m','0','0','0','4','','','','',NULL,NULL,'SELECT\r\n  ag.name as group_name,\r\n  ISNULL(ags.primary_recovery_health, 2) as primary_recovery_health,\r\n  ISNULL(ags.primary_replica, \'Unknown\') as primary_replica,\r\n  ISNULL(\r\n    ags.secondary_recovery_health, 2\r\n  ) as secondary_recovery_health,\r\n  ags.synchronization_health as synchronization_health\r\nFROM\r\n  sys.dm_hadr_availability_group_states ags\r\nJOIN sys.availability_groups ag ON ag.group_id = ags.group_id','','0','{$MSSQL.USER}','{$MSSQL.PASSWORD}','','','0',NULL,'The item gets availability group states - name, primary and secondary health, synchronization health.','0','30d','0','',NULL,'30s','','','','200','1','0','','','0','0','0','0','0','0','0','f495898e37c94bfda4ce387f7129b996','0','2','0'),
('46409','11','','10327','Get database','db.odbc.get[get_database,"{$MSSQL.DSN}"]','1h','0','0','0','4','','','','',NULL,NULL,'SELECT name as dbname, recovery_model\r\nFROM sys.databases','','0','{$MSSQL.USER}','{$MSSQL.PASSWORD}','','','0',NULL,'Getting databases - database name and recovery model.','0','30d','0','',NULL,'30s','','','','200','1','0','','','0','0','0','0','0','0','0','9c902b33ed254e1892e44218a67876d3','0','2','0'),
('46410','11','','10327','Get DB mirroring','db.odbc.get[get_db_mirroring,"{$MSSQL.DSN}"]','1m','0','0','0','4','','','','',NULL,NULL,'SELECT\r\n  ISNULL(m.mirroring_role, 0) as mirroring_role,\r\n  ISNULL(m.mirroring_role_sequence, 0) as mirroring_role_sequence,\r\n  ISNULL(m.mirroring_state, 7) as mirroring_state,\r\n  ISNULL(m.mirroring_witness_state, 3) as mirroring_witness_state,\r\n  ISNULL(m.mirroring_safety_level, 3) as mirroring_safety_level,\r\n  db_name(m.database_id) as dbname\r\nFROM\r\n  sys.database_mirroring as m\r\nWHERE\r\n  m.mirroring_state_desc IS NOT NULL','','0','{$MSSQL.USER}','{$MSSQL.PASSWORD}','','','0',NULL,'Getting DB mirroring.','0','30d','0','',NULL,'30s','','','','200','1','0','','','0','0','0','0','0','0','0','9948ac27a2f84ba5a74ee0860d934f4e','0','2','0'),
('46411','11','','10327','Get local DB','db.odbc.get[get_local_db,"{$MSSQL.DSN}"]','1m','0','0','0','4','','','','',NULL,NULL,'SELECT ag.name AS group_name, \r\n  drs.database_state as database_state, \r\n  drs.is_suspended as is_suspended, \r\n  drs.synchronization_health as synchronization_health, \r\n  arcs.replica_server_name AS replica_name,\r\n  db_name(drs.database_id) AS dbname, \r\n  drs.is_local\r\nFROM sys.dm_hadr_database_replica_states drs \r\nJOIN sys.dm_hadr_availability_replica_cluster_states arcs\r\n  ON arcs.replica_id = drs.replica_id\r\nJOIN sys.availability_groups ag \r\n  ON ag.group_id = arcs.group_id\r\nJOIN sys.dm_hadr_availability_replica_states ars \r\n  ON ars.replica_id = arcs.replica_id\r\nWHERE drs.is_local = 1','','0','{$MSSQL.USER}','{$MSSQL.PASSWORD}','','','0',NULL,'Getting the states of the local availability database.','0','30d','0','',NULL,'30s','','','','200','1','0','','','0','0','0','0','0','0','0','3960ea4dc0054ee099d5bca005535e6b','0','2','0'),
('46412','11','','10327','Get non-local DB','db.odbc.get[get_non_local_db,"{$MSSQL.DSN}"]','1m','0','0','0','4','','','','',NULL,NULL,'SELECT ag.name AS group_name, \r\n  ISNULL(drs.log_send_queue_size, 0) as log_send_queue_size, \r\n  ISNULL(drs.redo_queue_size, 0) as redo_queue_size, \r\n  arcs.replica_server_name AS replica_name,\r\n  db_name(drs.database_id) AS dbname, \r\n  drs.is_local\r\nFROM sys.dm_hadr_database_replica_states drs \r\nJOIN sys.dm_hadr_availability_replica_cluster_states arcs\r\n  ON arcs.replica_id = drs.replica_id\r\nJOIN sys.availability_groups ag \r\n  ON ag.group_id = arcs.group_id\r\nJOIN sys.dm_hadr_availability_replica_states ars \r\n  ON ars.replica_id = arcs.replica_id\r\nWHERE drs.is_local = 0','','0','{$MSSQL.USER}','{$MSSQL.PASSWORD}','','','0',NULL,'Getting the non-local availability database.','0','30d','0','',NULL,'30s','','','','200','1','0','','','0','0','0','0','0','0','0','e4480bba876d472294920020734eadf5','0','2','0'),
('46413','11','','10327','Get quorum','db.odbc.get[get_quorum,"{$MSSQL.DSN}"]','1m','0','0','0','4','','','','',NULL,NULL,'SELECT quorum_type, quorum_state, cluster_name\r\nFROM sys.dm_hadr_cluster','','0','{$MSSQL.USER}','{$MSSQL.PASSWORD}','','','0',NULL,'Getting quorum - cluster name, type, and state.','0','30d','0','',NULL,'10s','','','','200','1','0','','','0','0','0','0','0','0','0','3fcb3b84bdee42428bedc39fcc582c9e','0','2','0'),
('46414','11','','10327','Get quorum member','db.odbc.get[get_quorum_member,"{$MSSQL.DSN}"]','1m','0','0','0','4','','','','',NULL,NULL,'SELECT a.member_name, a.member_type, a.member_state, a.number_of_quorum_votes, b.cluster_name\r\nFROM sys.dm_hadr_cluster_members a\r\nCROSS JOIN sys.dm_hadr_cluster b','','0','{$MSSQL.USER}','{$MSSQL.PASSWORD}','','','0',NULL,'Getting quorum members - member name, type, state, and number of quorum votes.','0','30d','0','',NULL,'10s','','','','200','1','0','','','0','0','0','0','0','0','0','69a31cdfbf9b4099bf89adb26e8b9f06','0','2','0'),
('46415','11','','10327','Get replica','db.odbc.get[get_replica,"{$MSSQL.DSN}"]','1m','0','0','0','4','','','','',NULL,NULL,'SELECT \r\n  ars.connected_state as connected_state, \r\n  ars.is_local as is_local, \r\n  arcs.join_state as join_state, \r\n  ISNULL(ars.operational_state, 6) as operational_state, \r\n  ISNULL(ars.recovery_health, 2) as recovery_health, \r\n  ars.role as role, \r\n  ars.synchronization_health as synchronization_health, \r\n  ag.name as group_name, \r\n  arcs.replica_server_name as replica_name \r\nFROM \r\n  sys.dm_hadr_availability_replica_cluster_states as arcs \r\nJOIN sys.availability_groups ag ON ag.group_id = arcs.group_id \r\nJOIN sys.dm_hadr_availability_replica_states ars ON ars.replica_id = arcs.replica_id','','0','{$MSSQL.USER}','{$MSSQL.PASSWORD}','','','0',NULL,'Getting the database replica.','0','30d','0','',NULL,'30s','','','','200','1','0','','','0','0','0','0','0','0','0','7a82483c605d4e8eb67c2576069cf8a9','0','2','0'),
('46450','19','','10547','Get status','meraki.device.get.status','{$MERAKI.GET.STATUS.INTERVAL}','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Item for gathering device status from Meraki API.','0','30d','0','',NULL,'{$MERAKI.DATA.TIMEOUT}','https://{$MERAKI.API.URL}/organizations/{$ORGANIZATION_ID}/devices/statuses?serials[]={$SERIAL}','','','200','1','0','{$MERAKI.HTTP_PROXY}','X-Cisco-Meraki-API-Key: {$MERAKI.TOKEN}\r\nUser-Agent: ZabbixServer/1.1 Zabbix','0','0','0','0','0','0','0','0c97a8fcad764133b4e7c35d0134665c','0','2','0'),
('46451','21','','10607','Get ELB ALB alarms data','aws.elb.alb.get_alarms','0s;m/1','0','0','0','4','','','','',NULL,NULL,'var AWS = {\r\n	params: {},\r\n	metadata: \'http://169.254.169.254/latest/\',\r\n\r\n	getField: function (data, path) {\r\n		var steps = path.split(\'.\');\r\n		for (var i = 0; i < steps.length; i++) {\r\n			var step = steps[i];\r\n			if (typeof data !== \'object\' || typeof data[step] === \'undefined\') {\r\n				throw \'Required field was not found: \' + path;\r\n			}\r\n\r\n			data = data[step];\r\n		}\r\n\r\n		return data;\r\n	},\r\n\r\n	setParams: function (params) {\r\n		AWS.params[\'proxy\'] = params.proxy;\r\n		switch (AWS.getField(params, \'auth_type\')) {\r\n			case \'role_base\':\r\n				AWS.params[\'auth_type\'] = \'role_base\';\r\n				var request = new HttpRequest();\r\n				if (typeof AWS.params.proxy !== \'undefined\' && AWS.params.proxy !== \'\') {\r\n					request.setProxy(AWS.params.proxy);\r\n				}\r\n				request.addHeader(\'X-aws-ec2-metadata-token-ttl-seconds: 21600\');\r\n				var token = request.put(AWS.metadata + \'api/token\');\r\n\r\n				if (request.getStatus() !== 200 || token === null || token === \'\') {\r\n					throw \'Error getting IMDSv2 session token.\';\r\n				}\r\n				request.addHeader(\'X-aws-ec2-metadata-token: \' + token);\r\n				var IamRoleName = request.get(AWS.metadata + \'meta-data/iam/security-credentials\');\r\n\r\n				if (request.getStatus() !== 200 || IamRoleName === null || IamRoleName === \'\') {\r\n					throw \'Error getting security credentials from instance metadata. Role not found.\';\r\n				}\r\n\r\n				credentials = request.get(AWS.metadata + \'meta-data/iam/security-credentials/\' + encodeURI(IamRoleName));\r\n\r\n				if (request.getStatus() !== 200 || credentials === null || credentials === \'\') {\r\n					throw \'Error getting security credentials from instance metadata.\';\r\n				}\r\n\r\n				try {\r\n					credentials = JSON.parse(credentials);\r\n				}\r\n				catch (error) {\r\n					throw \'Failed to parse response received from instance metadata. Check debug log for more information.\';\r\n				}\r\n\r\n				[\'AccessKeyId\', \'SecretAccessKey\', \'Token\'].forEach(function (field) {\r\n					if (typeof credentials !== \'object\' || typeof credentials[field] === \'undefined\' || credentials[field] === \'\') {\r\n						throw \'Required credentials are not set: "\' + field + \'".\';\r\n					};\r\n					AWS.params[field] = credentials[field];\r\n				});\r\n				break;\r\n			case \'assume_role\':\r\n				AWS.params[\'auth_type\'] = \'assume_role\';\r\n\r\n				[\'AccessKeyId\', \'SecretAccessKey\', \'sts_region\', \'role_arn\'].forEach(function (field) {\r\n					if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n						throw \'Required param is not set: "\' + field + \'".\';\r\n					}\r\n					AWS.params[field] = params[field];\r\n				});\r\n\r\n				role_arn_regex = /role\\/(.+)$/;\r\n\r\n				var payload = {\r\n					\'Action\': \'AssumeRole\',\r\n					\'Version\': \'2011-06-15\',\r\n					\'RoleArn\': AWS.params.role_arn,\r\n					\'RoleSessionName\': AWS.params.role_arn.match(role_arn_regex)[1] + \'Session\',\r\n				};\r\n\r\n				credentials = AWS.getField(AWS.request(\'GET\', AWS.params.sts_region, \'sts\', AWS.prepareParams(payload), \'\'), \'AssumeRoleResponse.AssumeRoleResult.Credentials\');\r\n\r\n				[\'AccessKeyId\', \'SecretAccessKey\', \'SessionToken\'].forEach(function (field) {\r\n					if (typeof credentials !== \'object\' || typeof credentials[field] === \'undefined\' || credentials[field] === \'\') {\r\n						throw \'Required credentials are not set: "\' + field + \'".\';\r\n					};\r\n					AWS.params[field] = credentials[field];\r\n				});\r\n				break;\r\n			default:\r\n				AWS.params[\'auth_type\'] = \'access_key\';\r\n				[\'AccessKeyId\', \'SecretAccessKey\'].forEach(function (field) {\r\n					if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n						throw \'Required param is not set: "\' + field + \'".\';\r\n					}\r\n					AWS.params[field] = params[field];\r\n				});\r\n		}\r\n		[\'region\', \'arn\', \'loadbalancer_name\'].forEach(function (field) {\r\n			if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n				throw \'Required param is not set: "\' + field + \'".\';\r\n			}\r\n			AWS.params[field] = params[field];\r\n		});\r\n	},\r\n\r\n	sign: function (key, message) {\r\n		var hex = hmac(\'sha256\', key, message);\r\n\r\n		if ((hex.length % 2) === 1) {\r\n			throw \'Invalid length of a hex string!\';\r\n		}\r\n\r\n		var result = new Int8Array(hex.length / 2);\r\n		for (var i = 0, b = 0; i < hex.length; i += 2, b++) {\r\n			result[b] = parseInt(hex.substring(i, i + 2), 16);\r\n		}\r\n\r\n		return result;\r\n	},\r\n\r\n	prepareParams: function (params) {\r\n		var result = [];\r\n\r\n		Object.keys(params).sort().forEach(function (key) {\r\n			if (typeof params[key] !== \'object\') {\r\n				result.push(key + \'=\' + encodeURIComponent(params[key]));\r\n			}\r\n			else {\r\n				result.push(prepareObject(key, params[key]));\r\n			}\r\n		});\r\n\r\n		return result.join(\'&\');\r\n	},\r\n\r\n	request: function (method, region, service, params, data) {\r\n		if (typeof data === \'undefined\' || data === null) {\r\n			data = \'\';\r\n		}\r\n\r\n		var amzdate = (new Date()).toISOString().replace(/\\.\\d+Z/, \'Z\').replace(/[-:]/g, \'\'),\r\n			date = amzdate.replace(/T\\d+Z/, \'\'),\r\n			host = service + \'.\' + region + \'.amazonaws.com\',\r\n			canonical_uri = \'/\',\r\n			canonical_headers = \'content-encoding:amz-1.0\\n\' + \'host:\' + host + \'\\n\' + \'x-amz-date:\' + amzdate + \'\\n\',\r\n			signed_headers = \'content-encoding;host;x-amz-date\',\r\n			canonical_request = method + \'\\n\' + canonical_uri + \'\\n\' + params + \'\\n\' + canonical_headers + \'\\n\' + signed_headers + \'\\n\' + sha256(data),\r\n			credential_scope = date + \'/\' + region + \'/\' + service + \'/\' + \'aws4_request\',\r\n			request_string = \'AWS4-HMAC-SHA256\' + \'\\n\' + amzdate + \'\\n\' + credential_scope + \'\\n\' + sha256(canonical_request),\r\n			key = AWS.sign(\'AWS4\' + AWS.params.SecretAccessKey, date),\r\n			key = AWS.sign(key, region),\r\n			key = AWS.sign(key, service),\r\n			key = AWS.sign(key, \'aws4_request\'),\r\n			request = new HttpRequest(),\r\n			url = \'https://\' + host + canonical_uri + \'?\' + params;\r\n\r\n		if (typeof AWS.params.proxy !== \'undefined\' && AWS.params.proxy !== \'\') {\r\n			request.setProxy(AWS.params.proxy);\r\n		}\r\n		request.addHeader(\'x-amz-date: \' + amzdate);\r\n		request.addHeader(\'Accept: application/json\');\r\n		request.addHeader(\'Content-Type: application/json\');\r\n		request.addHeader(\'Content-Encoding: amz-1.0\');\r\n		request.addHeader(\'Authorization: \' + \'AWS4-HMAC-SHA256 Credential=\' + AWS.params.AccessKeyId + \'/\' + credential_scope + \', \' + \'SignedHeaders=\' + signed_headers + \', \' + \'Signature=\' + hmac(\'sha256\', key, request_string));\r\n		if (AWS.params.auth_type === \'role_base\' || (AWS.params.auth_type === \'assume_role\' & !params.includes(\'AssumeRole\'))) {\r\n			request.addHeader(\'X-Amz-Security-Token: \' + (AWS.params.auth_type === \'role_base\' ? AWS.params.Token : AWS.params.SessionToken));\r\n		}\r\n\r\n		Zabbix.log(4, \'[ AWS ELB ] Sending request: \' + url);\r\n		response = request.get(url);\r\n		Zabbix.log(4, \'[ AWS ELB ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n\r\n		if (request.getStatus() !== 200) {\r\n			throw \'Request failed with status code \' + request.getStatus() + \': \' + response;\r\n		}\r\n\r\n		try {\r\n			response = JSON.parse(response);\r\n		}\r\n		catch (error) {\r\n			try {\r\n				response = JSON.parse(XML.toJson(response));\r\n			}\r\n			catch (error) {\r\n				throw \'Failed to parse response received from AWS CloudWatch API. Check debug log for more information.\';\r\n			}\r\n		}\r\n\r\n		return response;\r\n	},\r\n\r\n	getAlarms: function () {\r\n		var payload = {\r\n			\'Action\': \'DescribeAlarms\',\r\n			\'Version\': \'2010-08-01\',\r\n			\'MaxRecords\': 100\r\n		},\r\n			result = [];\r\n\r\n		while (payload.NextToken !== \'\') {\r\n			var alarms = AWS.getField(AWS.request(\'GET\', AWS.params.region, \'monitoring\', AWS.prepareParams(payload)), \'DescribeAlarmsResponse.DescribeAlarmsResult\');\r\n			payload.NextToken = alarms.NextToken || \'\';\r\n			alarms_list = AWS.getField(alarms, \'MetricAlarms\');\r\n			regex = /loadbalancer\\/(.+)$/;\r\n\r\n			if (!Array.isArray(alarms_list))\r\n				alarms_list = [alarms_list];\r\n			alarms_list.forEach(function (alarm) {\r\n				var dimensions = alarm.Dimensions;\r\n\r\n				if (Array.isArray(alarm.Metrics)) {\r\n					alarm.Metrics.forEach(function (metric) {\r\n						if (typeof metric.MetricStat === \'object\' && metric.MetricStat !== null\r\n							&& typeof metric.MetricStat.Metric === \'object\' && metric.MetricStat.Metric !== null\r\n							&& Array.isArray(metric.MetricStat.Metric.Dimensions)) {\r\n							dimensions = dimensions.concat(metric.MetricStat.Metric.Dimensions);\r\n						}\r\n					});\r\n				}\r\n				for (var i in dimensions) {\r\n					if ((dimensions[i].Name === \'LoadBalancer\' && dimensions[i].Value === AWS.params.arn.match(regex)[1])\r\n						|| (dimensions[i].Name === \'LoadBalancerName\' && dimensions[i].Value === AWS.params.loadbalancer_name)) {\r\n						result.push(alarm);\r\n						break;\r\n					}\r\n				}\r\n			});\r\n		}\r\n\r\n		return result;\r\n	}\r\n};\r\n\r\ntry {\r\n	AWS.setParams(JSON.parse(value));\r\n\r\n	return JSON.stringify(AWS.getAlarms());\r\n}\r\ncatch (error) {\r\n	error += (String(error).endsWith(\'.\')) ? \'\' : \'.\';\r\n	Zabbix.log(3, \'[ AWS ELB Alarms ] ERROR: \' + error);\r\n\r\n	return JSON.stringify({ \'error\': error });\r\n}','','0','','','','','0',NULL,'`DescribeAlarms` API method: https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_DescribeAlarms.html','0','30d','0','',NULL,'{$AWS.DATA.TIMEOUT}','','','','200','1','0','','','0','0','0','0','0','0','0','059b7697baba46b2a7f138a1011a0e0c','0','2','0'),
('46452','21','','10607','Get metrics data','aws.elb.alb.get_metrics','0s;m/1','0','0','0','4','','','','',NULL,NULL,'var AWS = {\r\n	params: {},\r\n	metadata: \'http://169.254.169.254/latest/\',\r\n	request_period: 60,\r\n\r\n	getField: function (data, path) {\r\n		var steps = path.split(\'.\');\r\n		for (var i = 0; i < steps.length; i++) {\r\n			var step = steps[i];\r\n			if (typeof data !== \'object\' || typeof data[step] === \'undefined\') {\r\n				throw \'Required field was not found: \' + path;\r\n			}\r\n\r\n			data = data[step];\r\n		}\r\n\r\n		return data;\r\n	},\r\n\r\n	setParams: function (params) {\r\n		AWS.params[\'proxy\'] = params.proxy;\r\n		switch (AWS.getField(params, \'auth_type\')) {\r\n			case \'role_base\':\r\n				AWS.params[\'auth_type\'] = \'role_base\';\r\n				var request = new HttpRequest();\r\n				if (typeof AWS.params.proxy !== \'undefined\' && AWS.params.proxy !== \'\') {\r\n					request.setProxy(AWS.params.proxy);\r\n				}\r\n				request.addHeader(\'X-aws-ec2-metadata-token-ttl-seconds: 21600\');\r\n				var token = request.put(AWS.metadata + \'api/token\');\r\n\r\n				if (request.getStatus() !== 200 || token === null || token === \'\') {\r\n					throw \'Error getting IMDSv2 session token.\';\r\n				}\r\n				request.addHeader(\'X-aws-ec2-metadata-token: \' + token);\r\n				var IamRoleName = request.get(AWS.metadata + \'meta-data/iam/security-credentials\');\r\n\r\n				if (request.getStatus() !== 200 || IamRoleName === null || IamRoleName === \'\') {\r\n					throw \'Error getting security credentials from instance metadata. Role not found.\';\r\n				}\r\n\r\n				credentials = request.get(AWS.metadata + \'meta-data/iam/security-credentials/\' + encodeURI(IamRoleName));\r\n\r\n				if (request.getStatus() !== 200 || credentials === null || credentials === \'\') {\r\n					throw \'Error getting security credentials from instance metadata.\';\r\n				}\r\n\r\n				try {\r\n					credentials = JSON.parse(credentials);\r\n				}\r\n				catch (error) {\r\n					throw \'Failed to parse response received from instance metadata. Check debug log for more information.\';\r\n				}\r\n\r\n				[\'AccessKeyId\', \'SecretAccessKey\', \'Token\'].forEach(function (field) {\r\n					if (typeof credentials !== \'object\' || typeof credentials[field] === \'undefined\' || credentials[field] === \'\') {\r\n						throw \'Required credentials are not set: "\' + field + \'".\';\r\n					};\r\n					AWS.params[field] = credentials[field];\r\n				});\r\n				break;\r\n			case \'assume_role\':\r\n				AWS.params[\'auth_type\'] = \'assume_role\';\r\n\r\n				[\'AccessKeyId\', \'SecretAccessKey\', \'sts_region\', \'role_arn\'].forEach(function (field) {\r\n					if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n						throw \'Required param is not set: "\' + field + \'".\';\r\n					}\r\n					AWS.params[field] = params[field];\r\n				});\r\n\r\n				role_arn_regex = /role\\/(.+)$/;\r\n\r\n				var payload = {\r\n					\'Action\': \'AssumeRole\',\r\n					\'Version\': \'2011-06-15\',\r\n					\'RoleArn\': AWS.params.role_arn,\r\n					\'RoleSessionName\': AWS.params.role_arn.match(role_arn_regex)[1] + \'Session\',\r\n				};\r\n\r\n				credentials = AWS.getField(AWS.request(\'POST\', AWS.params.sts_region, \'sts\', AWS.prepareParams(payload), \'\'), \'AssumeRoleResponse.AssumeRoleResult.Credentials\');\r\n\r\n				[\'AccessKeyId\', \'SecretAccessKey\', \'SessionToken\'].forEach(function (field) {\r\n					if (typeof credentials !== \'object\' || typeof credentials[field] === \'undefined\' || credentials[field] === \'\') {\r\n						throw \'Required credentials are not set: "\' + field + \'".\';\r\n					};\r\n					AWS.params[field] = credentials[field];\r\n				});\r\n				break;\r\n			default:\r\n				AWS.params[\'auth_type\'] = \'access_key\';\r\n				[\'AccessKeyId\', \'SecretAccessKey\'].forEach(function (field) {\r\n					if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n						throw \'Required param is not set: "\' + field + \'".\';\r\n					}\r\n					AWS.params[field] = params[field];\r\n				});\r\n		}\r\n		[\'region\', \'arn\'].forEach(function (field) {\r\n			if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n				throw \'Required param is not set: "\' + field + \'".\';\r\n			}\r\n			AWS.params[field] = params[field];\r\n		});\r\n	},\r\n\r\n	sign: function (key, message) {\r\n		var hex = hmac(\'sha256\', key, message);\r\n\r\n		if ((hex.length % 2) === 1) {\r\n			throw \'Invalid length of a hex string!\';\r\n		}\r\n\r\n		var result = new Int8Array(hex.length / 2);\r\n		for (var i = 0, b = 0; i < hex.length; i += 2, b++) {\r\n			result[b] = parseInt(hex.substring(i, i + 2), 16);\r\n		}\r\n\r\n		return result;\r\n	},\r\n\r\n	prepareParams: function (params) {\r\n		var result = [];\r\n\r\n		Object.keys(params).sort().forEach(function (key) {\r\n			if (typeof params[key] !== \'object\') {\r\n				result.push(key + \'=\' + encodeURIComponent(params[key]));\r\n			}\r\n			else {\r\n				result.push(prepareObject(key, params[key]));\r\n			}\r\n		});\r\n\r\n		return result.join(\'&\');\r\n	},\r\n\r\n	renderMetricQuery: function (period, arn) {\r\n		var metrics_list = [\r\n			\'ActiveConnectionCount:Sum\',\r\n			\'ClientTLSNegotiationErrorCount:Sum\',\r\n			\'ConsumedLCUs:Sum\',\r\n			\'DesyncMitigationMode_NonCompliant_Request_Count:Sum\',\r\n			\'HTTP_Fixed_Response_Count:Sum\',\r\n			\'HTTP_Redirect_Count:Sum\',\r\n			\'HTTP_Redirect_Url_Limit_Exceeded_Count:Sum\',\r\n			\'HTTPCode_ELB_3XX_Count:Sum\',\r\n			\'HTTPCode_ELB_4XX_Count:Sum\',\r\n			\'HTTPCode_ELB_5XX_Count:Sum\',\r\n			\'HTTPCode_ELB_500_Count:Sum\',\r\n			\'HTTPCode_ELB_502_Count:Sum\',\r\n			\'HTTPCode_ELB_503_Count:Sum\',\r\n			\'HTTPCode_ELB_504_Count:Sum\',\r\n			\'NewConnectionCount:Sum\',\r\n			\'ProcessedBytes:Sum\',\r\n			\'RejectedConnectionCount:Sum\',\r\n			\'RequestCount:Sum\',\r\n			\'RuleEvaluations:Sum\',\r\n			\'TargetResponseTime:Average\',\r\n			\'TargetTLSNegotiationErrorCount:Sum\',\r\n			\'TargetConnectionErrorCount:Sum\',\r\n			\'ELBAuthError:Sum\',\r\n			\'ELBAuthFailure:Sum\',\r\n			\'ELBAuthLatency:Sum\',\r\n			\'ELBAuthSuccess:Sum\',\r\n			\'ELBAuthUserClaimsSizeExceeded:Sum\',\r\n		],\r\n			regex = /loadbalancer\\/(.+)$/;\r\n\r\n		var metric_payload = [];\r\n		metrics_list.forEach(function (metric, index) {\r\n			var parts = metric.split(\':\', 2);\r\n			metric_payload.push({\r\n				\'Id\': \'m\' + index,\r\n				\'MetricStat\': {\r\n					\'Metric\': {\r\n						\'MetricName\': parts[0],\r\n						\'Namespace\': \'AWS/ApplicationELB\',\r\n						\'Dimensions\': [\r\n							{\r\n								\'Name\': \'LoadBalancer\',\r\n								\'Value\': arn.match(regex)[1],\r\n							}\r\n						]\r\n					},\r\n					\'Period\': period,\r\n					\'Stat\': parts[1],\r\n				}\r\n			});\r\n		});\r\n\r\n		return metric_payload;\r\n	},\r\n\r\n	request: function (method, region, service, params, data) {\r\n		if (typeof data === \'undefined\' || data === null) {\r\n			data = JSON.stringify([]);\r\n		}\r\n		else {\r\n			data = JSON.stringify(data)\r\n		}\r\n		var amzdate = (new Date()).toISOString().replace(/\\.\\d+Z/, \'Z\').replace(/[-:]/g, \'\'),\r\n			date = amzdate.replace(/T\\d+Z/, \'\'),\r\n			canonical_uri = \'/\',\r\n			host = service + \'.\' + region + \'.amazonaws.com\',\r\n			canonical_headers = \'content-encoding:amz-1.0\\n\' + \'host:\' + host + \'\\n\' + \'x-amz-date:\' + amzdate + \'\\n\',\r\n			signed_headers = \'content-encoding;host;x-amz-date\',\r\n			canonical_request = method + \'\\n\' + canonical_uri + \'\\n\' + params + \'\\n\' + canonical_headers + \'\\n\' + signed_headers + \'\\n\' + sha256(data),\r\n			credential_scope = date + \'/\' + region + \'/\' + service + \'/\' + \'aws4_request\',\r\n			request_string = \'AWS4-HMAC-SHA256\' + \'\\n\' + amzdate + \'\\n\' + credential_scope + \'\\n\' + sha256(canonical_request),\r\n			key = AWS.sign(\'AWS4\' + AWS.params.SecretAccessKey, date),\r\n			key = AWS.sign(key, region),\r\n			key = AWS.sign(key, service),\r\n			key = AWS.sign(key, \'aws4_request\'),\r\n			request = new HttpRequest(),\r\n			url = \'https://\' + host + canonical_uri + \'?\' + params;\r\n\r\n		if (typeof AWS.params.proxy !== \'undefined\' && AWS.params.proxy !== \'\') {\r\n			request.setProxy(AWS.params.proxy);\r\n		}\r\n		request.addHeader(\'x-amz-date: \' + amzdate);\r\n		request.addHeader(\'x-amz-content-sha256:\' + sha256(data));\r\n		request.addHeader(\'X-Amz-Target: GraniteServiceVersion20100801.GetMetricData\')\r\n		request.addHeader(\'Accept: application/json\');\r\n		request.addHeader(\'Content-Type: application/json\');\r\n		request.addHeader(\'Content-Encoding: amz-1.0\');\r\n		request.addHeader(\'Authorization: \' + \'AWS4-HMAC-SHA256 Credential=\' + AWS.params.AccessKeyId + \'/\' + credential_scope + \', \' + \'SignedHeaders=\' + signed_headers + \', \' + \'Signature=\' + hmac(\'sha256\', key, request_string));\r\n		if (AWS.params.auth_type === \'role_base\' || (AWS.params.auth_type === \'assume_role\' & !params.includes(\'AssumeRole\'))) {\r\n			request.addHeader(\'X-Amz-Security-Token: \' + (AWS.params.auth_type === \'role_base\' ? AWS.params.Token : AWS.params.SessionToken));\r\n		}\r\n\r\n		Zabbix.log(4, \'[ AWS ELB ] Sending request: \' + url);\r\n		response = request.post(url, data);\r\n		Zabbix.log(4, \'[ AWS ELB ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n		if (request.getStatus() !== 200) {\r\n			throw \'Request failed with status code \' + request.getStatus() + \': \' + response;\r\n		}\r\n\r\n		return JSON.parse(response);\r\n	},\r\n\r\n	getMetricsData: function () {\r\n		var end_time = Math.floor((new Date().getTime()) / 1000),\r\n			start_time = end_time - AWS.request_period * 60;\r\n		payload = {\r\n			\'StartTime\': start_time,\r\n			\'EndTime\': end_time,\r\n			\'ScanBy\': \'TimestampDescending\',\r\n			\'MetricDataQueries\': AWS.renderMetricQuery(AWS.request_period, AWS.params.arn)\r\n		};\r\n\r\n		return AWS.getField(AWS.request(\'POST\', AWS.params.region, \'monitoring\', \'\', payload), \'MetricDataResults\');\r\n	}\r\n};\r\n\r\ntry {\r\n	AWS.setParams(JSON.parse(value));\r\n	return JSON.stringify(AWS.getMetricsData());\r\n}\r\ncatch (error) {\r\n	error += (String(error).endsWith(\'.\')) ? \'\' : \'.\';\r\n	Zabbix.log(3, \'[ AWS ELB Get metrics] ERROR: \' + error);\r\n\r\n	return JSON.stringify({ \'error\': error });\r\n}','','0','','','','','0',NULL,'Get ELB Application Load Balancer metrics.\r\nFull metrics list related to Application Load Balancer: https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-cloudwatch-metrics.html','0','30d','0','',NULL,'{$AWS.DATA.TIMEOUT}','','','','200','1','0','','','0','0','0','0','0','0','0','c7b4e867ff8246058d931ca76d18d4e7','0','2','0'),
('46453','21','','10607','Get target groups','aws.elb.alb.get_target_groups','0s;m/30','0','0','0','4','','','','',NULL,NULL,'var AWS = {\r\n	params: {},\r\n	metadata: \'http://169.254.169.254/latest/\',\r\n\r\n	getField: function (data, path) {\r\n		var steps = path.split(\'.\');\r\n		for (var i = 0; i < steps.length; i++) {\r\n			var step = steps[i];\r\n			if (typeof data !== \'object\' || typeof data[step] === \'undefined\') {\r\n				throw \'Required field was not found: \' + path;\r\n			}\r\n\r\n			data = data[step];\r\n		}\r\n\r\n		return data;\r\n	},\r\n\r\n	setParams: function (params) {\r\n		AWS.params[\'proxy\'] = params.proxy;\r\n		switch (AWS.getField(params, \'auth_type\')) {\r\n			case \'role_base\':\r\n				AWS.params[\'auth_type\'] = \'role_base\';\r\n				var request = new HttpRequest();\r\n				if (typeof AWS.params.proxy !== \'undefined\' && AWS.params.proxy !== \'\') {\r\n					request.setProxy(AWS.params.proxy);\r\n				}\r\n				request.addHeader(\'X-aws-ec2-metadata-token-ttl-seconds: 21600\');\r\n				var token = request.put(AWS.metadata + \'api/token\');\r\n\r\n				if (request.getStatus() !== 200 || token === null || token === \'\') {\r\n					throw \'Error getting IMDSv2 session token.\';\r\n				}\r\n				request.addHeader(\'X-aws-ec2-metadata-token: \' + token);\r\n				var IamRoleName = request.get(AWS.metadata + \'meta-data/iam/security-credentials\');\r\n\r\n				if (request.getStatus() !== 200 || IamRoleName === null || IamRoleName === \'\') {\r\n					throw \'Error getting security credentials from instance metadata. Role not found.\';\r\n				}\r\n\r\n				credentials = request.get(AWS.metadata + \'meta-data/iam/security-credentials/\' + encodeURI(IamRoleName));\r\n\r\n				if (request.getStatus() !== 200 || credentials === null || credentials === \'\') {\r\n					throw \'Error getting security credentials from instance metadata.\';\r\n				}\r\n\r\n				try {\r\n					credentials = JSON.parse(credentials);\r\n				}\r\n				catch (error) {\r\n					throw \'Failed to parse response received from instance metadata. Check debug log for more information.\';\r\n				}\r\n\r\n				[\'AccessKeyId\', \'SecretAccessKey\', \'Token\'].forEach(function (field) {\r\n					if (typeof credentials !== \'object\' || typeof credentials[field] === \'undefined\' || credentials[field] === \'\') {\r\n						throw \'Required credentials are not set: "\' + field + \'".\';\r\n					};\r\n					AWS.params[field] = credentials[field];\r\n				});\r\n				break;\r\n			case \'assume_role\':\r\n				AWS.params[\'auth_type\'] = \'assume_role\';\r\n\r\n				[\'AccessKeyId\', \'SecretAccessKey\', \'sts_region\', \'role_arn\'].forEach(function (field) {\r\n					if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n						throw \'Required param is not set: "\' + field + \'".\';\r\n					}\r\n					AWS.params[field] = params[field];\r\n				});\r\n\r\n				role_arn_regex = /role\\/(.+)$/;\r\n\r\n				var payload = {\r\n					\'Action\': \'AssumeRole\',\r\n					\'Version\': \'2011-06-15\',\r\n					\'RoleArn\': AWS.params.role_arn,\r\n					\'RoleSessionName\': AWS.params.role_arn.match(role_arn_regex)[1] + \'Session\',\r\n				};\r\n\r\n				credentials = AWS.getField(AWS.request(\'GET\', AWS.params.sts_region, \'sts\', AWS.prepareParams(payload), \'\'), \'AssumeRoleResponse.AssumeRoleResult.Credentials\');\r\n\r\n				[\'AccessKeyId\', \'SecretAccessKey\', \'SessionToken\'].forEach(function (field) {\r\n					if (typeof credentials !== \'object\' || typeof credentials[field] === \'undefined\' || credentials[field] === \'\') {\r\n						throw \'Required credentials are not set: "\' + field + \'".\';\r\n					};\r\n					AWS.params[field] = credentials[field];\r\n				});\r\n				break;\r\n			default:\r\n				AWS.params[\'auth_type\'] = \'access_key\';\r\n				[\'AccessKeyId\', \'SecretAccessKey\'].forEach(function (field) {\r\n					if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n						throw \'Required param is not set: "\' + field + \'".\';\r\n					}\r\n					AWS.params[field] = params[field];\r\n				});\r\n		}\r\n		[\'region\', \'arn\'].forEach(function (field) {\r\n			if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n				throw \'Required param is not set: "\' + field + \'".\';\r\n			}\r\n			AWS.params[field] = params[field];\r\n		});\r\n	},\r\n\r\n	sign: function (key, message) {\r\n		var hex = hmac(\'sha256\', key, message);\r\n\r\n		if ((hex.length % 2) === 1) {\r\n			throw \'Invalid length of a hex string!\';\r\n		}\r\n\r\n		var result = new Int8Array(hex.length / 2);\r\n		for (var i = 0, b = 0; i < hex.length; i += 2, b++) {\r\n			result[b] = parseInt(hex.substring(i, i + 2), 16);\r\n		}\r\n\r\n		return result;\r\n	},\r\n\r\n	prepareParams: function (params) {\r\n		var result = [];\r\n\r\n		Object.keys(params).sort().forEach(function (key) {\r\n			if (typeof params[key] !== \'object\') {\r\n				result.push(key + \'=\' + encodeURIComponent(params[key]));\r\n			}\r\n			else {\r\n				result.push(prepareObject(key, params[key]));\r\n			}\r\n		});\r\n\r\n		return result.join(\'&\');\r\n	},\r\n\r\n	request: function (method, region, service, params, data) {\r\n		if (typeof data === \'undefined\' || data === null) {\r\n			data = JSON.stringify([]);\r\n		}\r\n		var amzdate = (new Date()).toISOString().replace(/\\.\\d+Z/, \'Z\').replace(/[-:]/g, \'\'),\r\n			date = amzdate.replace(/T\\d+Z/, \'\'),\r\n			canonical_uri = \'/\',\r\n			host = service + \'.\' + region + \'.amazonaws.com\',\r\n			canonical_headers = \'content-encoding:amz-1.0\\n\' + \'host:\' + host + \'\\n\' + \'x-amz-date:\' + amzdate + \'\\n\',\r\n			signed_headers = \'content-encoding;host;x-amz-date\',\r\n			canonical_request = method + \'\\n\' + canonical_uri + \'\\n\' + params + \'\\n\' + canonical_headers + \'\\n\' + signed_headers + \'\\n\' + sha256(data),\r\n			credential_scope = date + \'/\' + region + \'/\' + service + \'/\' + \'aws4_request\',\r\n			request_string = \'AWS4-HMAC-SHA256\' + \'\\n\' + amzdate + \'\\n\' + credential_scope + \'\\n\' + sha256(canonical_request),\r\n			key = AWS.sign(\'AWS4\' + AWS.params.SecretAccessKey, date),\r\n			key = AWS.sign(key, region),\r\n			key = AWS.sign(key, service),\r\n			key = AWS.sign(key, \'aws4_request\'),\r\n			request = new HttpRequest(),\r\n			url = \'https://\' + host + canonical_uri + \'?\' + params;\r\n\r\n		if (typeof AWS.params.proxy !== \'undefined\' && AWS.params.proxy !== \'\') {\r\n			request.setProxy(AWS.params.proxy);\r\n		}\r\n		request.addHeader(\'x-amz-date: \' + amzdate);\r\n		request.addHeader(\'x-amz-content-sha256:\' + sha256(data));\r\n		request.addHeader(\'Accept: application/json\');\r\n		request.addHeader(\'Content-Type: application/json\');\r\n		request.addHeader(\'Content-Encoding: amz-1.0\');\r\n		request.addHeader(\'Authorization: \' + \'AWS4-HMAC-SHA256 Credential=\' + AWS.params.AccessKeyId + \'/\' + credential_scope + \', \' + \'SignedHeaders=\' + signed_headers + \', \' + \'Signature=\' + hmac(\'sha256\', key, request_string));\r\n		if (AWS.params.auth_type === \'role_base\' || (AWS.params.auth_type === \'assume_role\' & !params.includes(\'AssumeRole\'))) {\r\n			request.addHeader(\'X-Amz-Security-Token: \' + (AWS.params.auth_type === \'role_base\' ? AWS.params.Token : AWS.params.SessionToken));\r\n		}\r\n\r\n		Zabbix.log(4, \'[ AWS ELB ] Sending request: \' + url);\r\n		response = request.get(url);\r\n		Zabbix.log(4, \'[ AWS ELB ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n		if (request.getStatus() !== 200) {\r\n			throw \'Request failed with status code \' + request.getStatus() + \': \' + response;\r\n		}\r\n\r\n		return JSON.parse(response);\r\n	},\r\n\r\n	listTargetGroups: function () {\r\n		var lld_array = [],\r\n			regex = /targetgroup\\/(.+)$/,\r\n			payload = {\r\n				\'Action\': \'DescribeTargetGroups\',\r\n				\'LoadBalancerArn\': AWS.params.arn,\r\n				\'Version\': \'2015-12-01\'\r\n			};\r\n		targets = AWS.getField(AWS.request(\'GET\', AWS.params.region, \'elasticloadbalancing\', AWS.prepareParams(payload), \'\'), \'DescribeTargetGroupsResponse.DescribeTargetGroupsResult.TargetGroups\');\r\n\r\n		if (!Array.isArray(targets))\r\n			targets = [targets]\r\n\r\n		targets.forEach(function (targets) {\r\n			lld_array.push(\r\n				{\r\n					target_name: AWS.getField(targets, \'TargetGroupName\'),\r\n					target_arn: AWS.getField(targets, \'TargetGroupArn\').match(regex)[0],\r\n					type: AWS.getField(targets, \'TargetType\'),\r\n					protocol: AWS.getField(targets, \'Protocol\')\r\n				}\r\n			)\r\n		});\r\n\r\n		return lld_array;\r\n	}\r\n};\r\n\r\ntry {\r\n	AWS.setParams(JSON.parse(value));\r\n	return JSON.stringify(AWS.listTargetGroups());\r\n}\r\ncatch (error) {\r\n	error += (String(error).endsWith(\'.\')) ? \'\' : \'.\';\r\n	Zabbix.log(3, \'[ AWS ELB Target groups ] ERROR: \' + error);\r\n\r\n	return JSON.stringify({ \'error\': error });\r\n}','','0','','','','','0',NULL,'Get ELB target group.\r\n`DescribeTargetGroups` API method: https://docs.aws.amazon.com/elasticloadbalancing/latest/APIReference/API_DescribeTargetGroups.html','0','30d','0','',NULL,'{$AWS.DATA.TIMEOUT}','','','','200','1','0','','','0','0','0','0','0','0','0','9b118d348b934146bab54e2df582e2b0','0','2','0'),
('46485','21','','10607','[{#AWS.ELB.TARGET.GROUP.NAME}]: Get metrics','aws.elb.alb.target_groups.get_metrics["{#AWS.ELB.TARGET.GROUP.NAME}"]','0s;m/5','0','0','0','4','','','','',NULL,NULL,'var AWS = {\r\n	params: {},\r\n	metadata: \'http://169.254.169.254/latest/\',\r\n	request_period: 60,\r\n\r\n	getField: function (data, path) {\r\n		var steps = path.split(\'.\');\r\n		for (var i = 0; i < steps.length; i++) {\r\n			var step = steps[i];\r\n			if (typeof data !== \'object\' || typeof data[step] === \'undefined\') {\r\n				throw \'Required field was not found: \' + path;\r\n			}\r\n\r\n			data = data[step];\r\n		}\r\n\r\n		return data;\r\n	},\r\n\r\n	setParams: function (params) {\r\n		AWS.params[\'proxy\'] = params.proxy;\r\n		switch (AWS.getField(params, \'auth_type\')) {\r\n			case \'role_base\':\r\n				AWS.params[\'auth_type\'] = \'role_base\';\r\n				var request = new HttpRequest();\r\n				if (typeof AWS.params.proxy !== \'undefined\' && AWS.params.proxy !== \'\') {\r\n					request.setProxy(AWS.params.proxy);\r\n				}\r\n				request.addHeader(\'X-aws-ec2-metadata-token-ttl-seconds: 21600\');\r\n				var token = request.put(AWS.metadata + \'api/token\');\r\n\r\n				if (request.getStatus() !== 200 || token === null || token === \'\') {\r\n					throw \'Error getting IMDSv2 session token.\';\r\n				}\r\n				request.addHeader(\'X-aws-ec2-metadata-token: \' + token);\r\n				var IamRoleName = request.get(AWS.metadata + \'meta-data/iam/security-credentials\');\r\n\r\n				if (request.getStatus() !== 200 || IamRoleName === null || IamRoleName === \'\') {\r\n					throw \'Error getting security credentials from instance metadata. Role not found.\';\r\n				}\r\n\r\n				credentials = request.get(AWS.metadata + \'meta-data/iam/security-credentials/\' + encodeURI(IamRoleName));\r\n\r\n				if (request.getStatus() !== 200 || credentials === null || credentials === \'\') {\r\n					throw \'Error getting security credentials from instance metadata.\';\r\n				}\r\n\r\n				try {\r\n					credentials = JSON.parse(credentials);\r\n				}\r\n				catch (error) {\r\n					throw \'Failed to parse response received from instance metadata. Check debug log for more information.\';\r\n				}\r\n\r\n				[\'AccessKeyId\', \'SecretAccessKey\', \'Token\'].forEach(function (field) {\r\n					if (typeof credentials !== \'object\' || typeof credentials[field] === \'undefined\' || credentials[field] === \'\') {\r\n						throw \'Required credentials are not set: "\' + field + \'".\';\r\n					};\r\n					AWS.params[field] = credentials[field];\r\n				});\r\n				break;\r\n			case \'assume_role\':\r\n				AWS.params[\'auth_type\'] = \'assume_role\';\r\n\r\n				[\'AccessKeyId\', \'SecretAccessKey\', \'sts_region\', \'role_arn\'].forEach(function (field) {\r\n					if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n						throw \'Required param is not set: "\' + field + \'".\';\r\n					}\r\n					AWS.params[field] = params[field];\r\n				});\r\n\r\n				role_arn_regex = /role\\/(.+)$/;\r\n\r\n				var payload = {\r\n					\'Action\': \'AssumeRole\',\r\n					\'Version\': \'2011-06-15\',\r\n					\'RoleArn\': AWS.params.role_arn,\r\n					\'RoleSessionName\': AWS.params.role_arn.match(role_arn_regex)[1] + \'Session\',\r\n				};\r\n\r\n				credentials = AWS.getField(AWS.request(\'POST\', AWS.params.sts_region, \'sts\', AWS.prepareParams(payload), \'\'), \'AssumeRoleResponse.AssumeRoleResult.Credentials\');\r\n\r\n				[\'AccessKeyId\', \'SecretAccessKey\', \'SessionToken\'].forEach(function (field) {\r\n					if (typeof credentials !== \'object\' || typeof credentials[field] === \'undefined\' || credentials[field] === \'\') {\r\n						throw \'Required credentials are not set: "\' + field + \'".\';\r\n					};\r\n					AWS.params[field] = credentials[field];\r\n				});\r\n				break;\r\n			default:\r\n				AWS.params[\'auth_type\'] = \'access_key\';\r\n				[\'AccessKeyId\', \'SecretAccessKey\'].forEach(function (field) {\r\n					if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n						throw \'Required param is not set: "\' + field + \'".\';\r\n					}\r\n					AWS.params[field] = params[field];\r\n				});\r\n		}\r\n		[\'region\', \'arn\', \'target_arn\'].forEach(function (field) {\r\n			if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n				throw \'Required param is not set: "\' + field + \'".\';\r\n			}\r\n			AWS.params[field] = params[field];\r\n		});\r\n	},\r\n\r\n	sign: function (key, message) {\r\n		var hex = hmac(\'sha256\', key, message);\r\n\r\n		if ((hex.length % 2) === 1) {\r\n			throw \'Invalid length of a hex string!\';\r\n		}\r\n\r\n		var result = new Int8Array(hex.length / 2);\r\n		for (var i = 0, b = 0; i < hex.length; i += 2, b++) {\r\n			result[b] = parseInt(hex.substring(i, i + 2), 16);\r\n		}\r\n\r\n		return result;\r\n	},\r\n\r\n	prepareParams: function (params) {\r\n		var result = [];\r\n\r\n		Object.keys(params).sort().forEach(function (key) {\r\n			if (typeof params[key] !== \'object\') {\r\n				result.push(key + \'=\' + encodeURIComponent(params[key]));\r\n			}\r\n			else {\r\n				result.push(prepareObject(key, params[key]));\r\n			}\r\n		});\r\n\r\n		return result.join(\'&\');\r\n	},\r\n\r\n	renderMetricQuery: function (period, arn, target_arn) {\r\n		var metrics_list = [\r\n			\'HTTPCode_Target_2XX_Count:Sum\',\r\n			\'HTTPCode_Target_3XX_Count:Sum\',\r\n			\'HTTPCode_Target_4XX_Count:Sum\',\r\n			\'HTTPCode_Target_5XX_Count:Sum\',\r\n			\'HealthyHostCount:Average\',\r\n			\'UnHealthyHostCount:Average\',\r\n			\'HealthyStateRouting:Sum\',\r\n			\'UnhealthyStateRouting:Sum\',\r\n			\'UnhealthyRoutingRequestCount:Sum\',\r\n			\'HealthyStateDNS:Sum\',\r\n			\'UnhealthyStateDNS:Sum\',\r\n			\'RequestCountPerTarget:Sum\',\r\n			\'MitigatedHostCount:Average\',\r\n			\'AnomalousHostCount:Average\',\r\n		],\r\n			regex = /loadbalancer\\/(.+)$/;\r\n\r\n		var metric_payload = [];\r\n		metrics_list.forEach(function (metric, index) {\r\n			var parts = metric.split(\':\', 2);\r\n			metric_payload.push({\r\n				\'Id\': \'m\' + index,\r\n				\'MetricStat\': {\r\n					\'Metric\': {\r\n						\'MetricName\': parts[0],\r\n						\'Namespace\': \'AWS/ApplicationELB\',\r\n						\'Dimensions\': [\r\n							{\r\n								\'Name\': \'LoadBalancer\',\r\n								\'Value\': arn.match(regex)[1],\r\n							},\r\n							{\r\n								\'Name\': \'TargetGroup\',\r\n								\'Value\': target_arn\r\n							}\r\n						]\r\n					},\r\n					\'Period\': period,\r\n					\'Stat\': parts[1],\r\n				}\r\n			});\r\n		});\r\n\r\n		return metric_payload;\r\n	},\r\n\r\n	request: function (method, region, service, params, data) {\r\n		if (typeof data === \'undefined\' || data === null) {\r\n			data = JSON.stringify([]);\r\n		}\r\n		else {\r\n			data = JSON.stringify(data)\r\n		}\r\n		var amzdate = (new Date()).toISOString().replace(/\\.\\d+Z/, \'Z\').replace(/[-:]/g, \'\'),\r\n			date = amzdate.replace(/T\\d+Z/, \'\'),\r\n			canonical_uri = \'/\',\r\n			host = service + \'.\' + region + \'.amazonaws.com\',\r\n			canonical_headers = \'content-encoding:amz-1.0\\n\' + \'host:\' + host + \'\\n\' + \'x-amz-date:\' + amzdate + \'\\n\',\r\n			signed_headers = \'content-encoding;host;x-amz-date\',\r\n			canonical_request = method + \'\\n\' + canonical_uri + \'\\n\' + params + \'\\n\' + canonical_headers + \'\\n\' + signed_headers + \'\\n\' + sha256(data),\r\n			credential_scope = date + \'/\' + region + \'/\' + service + \'/\' + \'aws4_request\',\r\n			request_string = \'AWS4-HMAC-SHA256\' + \'\\n\' + amzdate + \'\\n\' + credential_scope + \'\\n\' + sha256(canonical_request),\r\n			key = AWS.sign(\'AWS4\' + AWS.params.SecretAccessKey, date),\r\n			key = AWS.sign(key, region),\r\n			key = AWS.sign(key, service),\r\n			key = AWS.sign(key, \'aws4_request\'),\r\n			request = new HttpRequest(),\r\n			url = \'https://\' + host + canonical_uri + \'?\' + params;\r\n\r\n		if (typeof AWS.params.proxy !== \'undefined\' && AWS.params.proxy !== \'\') {\r\n			request.setProxy(AWS.params.proxy);\r\n		}\r\n		request.addHeader(\'x-amz-date: \' + amzdate);\r\n		request.addHeader(\'x-amz-content-sha256:\' + sha256(data));\r\n		request.addHeader(\'X-Amz-Target: GraniteServiceVersion20100801.GetMetricData\')\r\n		request.addHeader(\'Accept: application/json\');\r\n		request.addHeader(\'Content-Type: application/json\');\r\n		request.addHeader(\'Content-Encoding: amz-1.0\');\r\n		request.addHeader(\'Authorization: \' + \'AWS4-HMAC-SHA256 Credential=\' + AWS.params.AccessKeyId + \'/\' + credential_scope + \', \' + \'SignedHeaders=\' + signed_headers + \', \' + \'Signature=\' + hmac(\'sha256\', key, request_string));\r\n		if (AWS.params.auth_type === \'role_base\' || (AWS.params.auth_type === \'assume_role\' & !params.includes(\'AssumeRole\'))) {\r\n			request.addHeader(\'X-Amz-Security-Token: \' + (AWS.params.auth_type === \'role_base\' ? AWS.params.Token : AWS.params.SessionToken));\r\n		}\r\n\r\n		Zabbix.log(4, \'[ AWS ELB ] Sending request: \' + url);\r\n		response = request.post(url, data);\r\n		Zabbix.log(4, \'[ AWS ELB ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n		if (request.getStatus() !== 200) {\r\n			throw \'Request failed with status code \' + request.getStatus() + \': \' + response;\r\n		}\r\n\r\n		return JSON.parse(response);\r\n	},\r\n\r\n	getMetricsData: function () {\r\n		var end_time = Math.floor((new Date().getTime()) / 1000),\r\n			start_time = end_time - AWS.request_period * 60;\r\n		payload = {\r\n			\'StartTime\': start_time,\r\n			\'EndTime\': end_time,\r\n			\'ScanBy\': \'TimestampDescending\',\r\n			\'MetricDataQueries\': AWS.renderMetricQuery(AWS.request_period, AWS.params.arn, AWS.params.target_arn)\r\n		};\r\n\r\n		return AWS.getField(AWS.request(\'POST\', AWS.params.region, \'monitoring\', \'\', payload), \'MetricDataResults\');\r\n	}\r\n};\r\n\r\ntry {\r\n	AWS.setParams(JSON.parse(value));\r\n	return JSON.stringify(AWS.getMetricsData());\r\n}\r\ncatch (error) {\r\n	error += (String(error).endsWith(\'.\')) ? \'\' : \'.\';\r\n	Zabbix.log(3, \'[ AWS ELB Get targets group metrics] ERROR: \' + error);\r\n\r\n	return JSON.stringify({ \'error\': error });\r\n}','','0','','','','','2',NULL,'Get the metrics of the ELB target group `{#AWS.ELB.TARGET.GROUP.NAME}`.\r\nFull list of metrics related to AWS ELB here: https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-cloudwatch-metrics.html#user-authentication-metric-table','0','30d','0','',NULL,'{$AWS.DATA.TIMEOUT}','','','','200','1','0','','','0','0','0','0','0','0','0','306971d2e8fb441d8ae4a658b26304c3','0','2','0'),
('46503','21','','10535','ELB load balancers discovery','aws.elb.discovery','12h','31d','365d','0','4','','','','',NULL,NULL,'var AWS = {\r\n	params: {},\r\n	metadata: \'http://169.254.169.254/latest/\',\r\n\r\n	getField: function (data, path) {\r\n		var steps = path.split(\'.\');\r\n		for (var i = 0; i < steps.length; i++) {\r\n			var step = steps[i];\r\n			if (typeof data !== \'object\' || typeof data[step] === \'undefined\') {\r\n				throw \'Required field was not found: \' + path;\r\n			}\r\n\r\n			data = data[step];\r\n		}\r\n\r\n		return data;\r\n	},\r\n\r\n	setParams: function (params) {\r\n		AWS.params[\'proxy\'] = params.proxy;\r\n		switch (AWS.getField(params, \'auth_type\')) {\r\n			case \'role_base\':\r\n				AWS.params[\'auth_type\'] = \'role_base\';\r\n				var request = new HttpRequest();\r\n				if (typeof AWS.params.proxy !== \'undefined\' && AWS.params.proxy !== \'\') {\r\n					request.setProxy(AWS.params.proxy);\r\n				}\r\n				request.addHeader(\'X-aws-ec2-metadata-token-ttl-seconds: 21600\');\r\n				var token = request.put(AWS.metadata + \'api/token\');\r\n\r\n				if (request.getStatus() !== 200 || token === null || token === \'\') {\r\n					throw \'Error getting IMDSv2 session token.\';\r\n				}\r\n				request.addHeader(\'X-aws-ec2-metadata-token: \' + token);\r\n				var IamRoleName = request.get(AWS.metadata + \'meta-data/iam/security-credentials\');\r\n\r\n				if (request.getStatus() !== 200 || IamRoleName === null || IamRoleName === \'\') {\r\n					throw \'Error getting security credentials from instance metadata. Role not found.\';\r\n				}\r\n\r\n				credentials = request.get(AWS.metadata + \'meta-data/iam/security-credentials/\' + encodeURI(IamRoleName));\r\n\r\n				if (request.getStatus() !== 200 || credentials === null || credentials === \'\') {\r\n					throw \'Error getting security credentials from instance metadata.\';\r\n				}\r\n\r\n				try {\r\n					credentials = JSON.parse(credentials);\r\n				}\r\n				catch (error) {\r\n					throw \'Failed to parse response received from instance metadata. Check debug log for more information.\';\r\n				}\r\n\r\n				[\'AccessKeyId\', \'SecretAccessKey\', \'Token\'].forEach(function (field) {\r\n					if (typeof credentials !== \'object\' || typeof credentials[field] === \'undefined\' || credentials[field] === \'\') {\r\n						throw \'Required credentials are not set: "\' + field + \'".\';\r\n					};\r\n					AWS.params[field] = credentials[field];\r\n				});\r\n				break;\r\n			case \'assume_role\':\r\n				AWS.params[\'auth_type\'] = \'assume_role\';\r\n\r\n				[\'AccessKeyId\', \'SecretAccessKey\', \'sts_region\', \'role_arn\'].forEach(function (field) {\r\n					if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n						throw \'Required param is not set: "\' + field + \'".\';\r\n					}\r\n					AWS.params[field] = params[field];\r\n				});\r\n\r\n				role_arn_regex = /role\\/(.+)$/;\r\n\r\n				var payload = {\r\n					\'Action\': \'AssumeRole\',\r\n					\'Version\': \'2011-06-15\',\r\n					\'RoleArn\': AWS.params.role_arn,\r\n					\'RoleSessionName\': AWS.params.role_arn.match(role_arn_regex)[1] + \'Session\',\r\n				};\r\n\r\n				credentials = AWS.getField(AWS.request(\'GET\', AWS.params.sts_region, \'sts\', AWS.prepareParams(payload)), \'AssumeRoleResponse.AssumeRoleResult.Credentials\');\r\n\r\n				[\'AccessKeyId\', \'SecretAccessKey\', \'SessionToken\'].forEach(function (field) {\r\n					if (typeof credentials !== \'object\' || typeof credentials[field] === \'undefined\' || credentials[field] === \'\') {\r\n						throw \'Required credentials are not set: "\' + field + \'".\';\r\n					};\r\n					AWS.params[field] = credentials[field];\r\n				});\r\n				break;\r\n			default:\r\n				AWS.params[\'auth_type\'] = \'access_key\';\r\n				[\'AccessKeyId\', \'SecretAccessKey\'].forEach(function (field) {\r\n					if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n						throw \'Required param is not set: "\' + field + \'".\';\r\n					}\r\n					AWS.params[field] = params[field];\r\n				});\r\n		}\r\n		[\'describe_region\', \'region_match\', \'region_not_match\'].forEach(function (field) {\r\n			if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n				throw \'Required param is not set: "\' + field + \'".\';\r\n			}\r\n			AWS.params[field] = params[field];\r\n		});\r\n	},\r\n\r\n	sign: function (key, message) {\r\n		var hex = hmac(\'sha256\', key, message);\r\n\r\n		if ((hex.length % 2) === 1) {\r\n			throw \'Invalid length of a hex string!\';\r\n		}\r\n\r\n		var result = new Int8Array(hex.length / 2);\r\n		for (var i = 0, b = 0; i < hex.length; i += 2, b++) {\r\n			result[b] = parseInt(hex.substring(i, i + 2), 16);\r\n		}\r\n\r\n		return result;\r\n	},\r\n\r\n	prepareParams: function (params) {\r\n		var result = [];\r\n\r\n		Object.keys(params).sort().forEach(function (key) {\r\n			if (typeof params[key] !== \'object\') {\r\n				result.push(key + \'=\' + encodeURIComponent(params[key]));\r\n			}\r\n			else {\r\n				result.push(prepareObject(key, params[key]));\r\n			}\r\n		});\r\n\r\n		return result.join(\'&\');\r\n	},\r\n\r\n	request: function (method, region, service, params, data) {\r\n		if (typeof data === \'undefined\' || data === null) {\r\n			data = \'\';\r\n		}\r\n\r\n		var amzdate = (new Date()).toISOString().replace(/\\.\\d+Z/, \'Z\').replace(/[-:]/g, \'\'),\r\n			date = amzdate.replace(/T\\d+Z/, \'\'),\r\n			canonical_uri = \'/\',\r\n			host = service + \'.\' + region + \'.amazonaws.com\',\r\n			canonical_headers = \'content-encoding:amz-1.0\\n\' + \'host:\' + host + \'\\n\' + \'x-amz-date:\' + amzdate + \'\\n\',\r\n			signed_headers = \'content-encoding;host;x-amz-date\',\r\n			canonical_request = method + \'\\n\' + canonical_uri + \'\\n\' + params + \'\\n\' + canonical_headers + \'\\n\' + signed_headers + \'\\n\' + sha256(data),\r\n			credential_scope = date + \'/\' + region + \'/\' + service + \'/\' + \'aws4_request\',\r\n			request_string = \'AWS4-HMAC-SHA256\' + \'\\n\' + amzdate + \'\\n\' + credential_scope + \'\\n\' + sha256(canonical_request),\r\n			key = AWS.sign(\'AWS4\' + AWS.params.SecretAccessKey, date),\r\n			key = AWS.sign(key, region),\r\n			key = AWS.sign(key, service),\r\n			key = AWS.sign(key, \'aws4_request\'),\r\n			request = new HttpRequest(),\r\n			url = \'https://\' + host + canonical_uri + \'?\' + params;\r\n\r\n		if (typeof AWS.params.proxy !== \'undefined\' && AWS.params.proxy !== \'\') {\r\n			request.setProxy(AWS.params.proxy);\r\n		}\r\n		request.addHeader(\'x-amz-date: \' + amzdate);\r\n		request.addHeader(\'x-amz-content-sha256:\' + sha256(data));\r\n		request.addHeader(\'Accept: application/json\');\r\n		request.addHeader(\'Content-Type: application/json\');\r\n		request.addHeader(\'Content-Encoding: amz-1.0\');\r\n		request.addHeader(\'Authorization: \' + \'AWS4-HMAC-SHA256 Credential=\' + AWS.params.AccessKeyId + \'/\' + credential_scope + \', \' + \'SignedHeaders=\' + signed_headers + \', \' + \'Signature=\' + hmac(\'sha256\', key, request_string));\r\n		if (AWS.params.auth_type === \'role_base\' || (AWS.params.auth_type === \'assume_role\' & !params.includes(\'AssumeRole\'))) {\r\n			request.addHeader(\'X-Amz-Security-Token: \' + (AWS.params.auth_type === \'role_base\' ? AWS.params.Token : AWS.params.SessionToken));\r\n		}\r\n\r\n		Zabbix.log(4, \'[ AWS ELB ] Sending request: \' + url);\r\n		response = request.get(url);\r\n		Zabbix.log(4, \'[ AWS ELB ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n\r\n		if (request.getStatus() !== 200) {\r\n			throw \'Request failed with status code \' + request.getStatus() + \': \' + response;\r\n		}\r\n\r\n		try {\r\n			response = JSON.parse(response);\r\n		}\r\n		catch (error) {\r\n			try {\r\n				response = JSON.parse(XML.toJson(response));\r\n			}\r\n			catch (error) {\r\n				throw \'Failed to parse response received from AWS API. Check debug log for more information.\';\r\n			}\r\n		}\r\n\r\n		return response;\r\n	},\r\n\r\n	listRegions: function () {\r\n		var payload = {\r\n			\'Action\': \'DescribeRegions\',\r\n			\'Version\': \'2016-11-15\'\r\n		};\r\n\r\n		regions = AWS.getField(AWS.request(\'GET\', AWS.params.describe_region, \'ec2\', AWS.prepareParams(payload)), \'DescribeRegionsResponse.regionInfo.item\');\r\n\r\n		if (!Array.isArray(regions))\r\n			regions = [regions]\r\n		return regions\r\n	},\r\n\r\n	listLoadBalancers: function () {\r\n		var lld_array = [],\r\n			regions = AWS.listRegions(),\r\n			payload = {\r\n				\'Action\': \'DescribeLoadBalancers\',\r\n				\'Version\': \'2015-12-01\'\r\n			};\r\n\r\n		regions.forEach(function (region) {\r\n			var region_name = AWS.getField(region, \'regionName\');\r\n			if (region_name.match(AWS.params.region_match) === null ||\r\n				region_name.match(AWS.params.region_not_match) !== null)\r\n				return;\r\n			elb = AWS.getField(AWS.request(\'GET\', region_name, \'elasticloadbalancing\', AWS.prepareParams(payload)), \'DescribeLoadBalancersResponse.DescribeLoadBalancersResult.LoadBalancers\');\r\n			if (!Array.isArray(elb))\r\n				elb = [elb]\r\n\r\n			elb.forEach(function (elb) {\r\n				lld_array.push(\r\n					{\r\n						name: AWS.getField(elb, \'LoadBalancerName\'),\r\n						arn: AWS.getField(elb, \'LoadBalancerArn\'),\r\n						type: AWS.getField(elb, \'Type\'),\r\n						state: AWS.getField(elb, \'State.Code\'),\r\n						dns_name: AWS.getField(elb, \'DNSName\'),\r\n						region: region_name\r\n					}\r\n				)\r\n			});\r\n		});\r\n\r\n		return lld_array;\r\n	}\r\n};\r\n\r\ntry {\r\n	AWS.setParams(JSON.parse(value));\r\n\r\n	return JSON.stringify(AWS.listLoadBalancers());\r\n}\r\ncatch (error) {\r\n	error += (String(error).endsWith(\'.\')) ? \'\' : \'.\';\r\n	Zabbix.log(3, \'[ AWS ELB ] ERROR: \' + error);\r\n	return JSON.stringify({ \'error\': error });\r\n}','','0','','','','','1',NULL,'Get ELB load balancers.','0','7d','1','',NULL,'{$AWS.DATA.TIMEOUT}','','','','200','1','0','','','0','0','0','0','0','0','0','e7ac860c53bf403f9aee8cdd4b099c05','0','2','0'),
('46504','0','','10609','Get availability groups','mssql.availability.group.get["{$MSSQL.URI}","{$MSSQL.USER}","{$MSSQL.PASSWORD}"]','1m','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'The item gets availability group states - name, primary and secondary health, synchronization health.','0','30d','0','',NULL,'30s','','','','200','1','0','','','0','0','0','0','0','0','0','71ade3c11bcd4f4691c5fa1c3fa6ded1','0','2','0'),
('46505','15','','10609','Average latch wait time','mssql.average_latch_wait_time','0;m0-59s3','31d','365d','0','0','','ms','','',NULL,NULL,'(last(//mssql.average_latch_wait_time_raw) - last(//mssql.average_latch_wait_time_raw,#2)) /\r\n(last(//mssql.average_latch_wait_time_base) - last(//mssql.average_latch_wait_time_base,#2) +\r\n(last(//mssql.average_latch_wait_time_base) - last(//mssql.average_latch_wait_time_base,#2)=0))','','0','','','','','0',NULL,'Average latch wait time (in milliseconds) for latch requests that had to wait.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','8c5e2250dcc4405d95cc33167be33bb2','0','2','0'),
('46506','15','','10609','Total average wait time','mssql.average_wait_time','0;m0-59s3','31d','365d','0','0','','ms','','',NULL,NULL,'(last(//mssql.average_wait_time_raw) - last(//mssql.average_wait_time_raw,#2)) /\r\n(last(//mssql.average_wait_time_base) - last(//mssql.average_wait_time_base,#2) +\r\n(last(//mssql.average_wait_time_base) - last(//mssql.average_wait_time_base,#2)=0))','','0','','','','','0',NULL,'The average wait time, in milliseconds, for each lock request that had to wait.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','3ba031d33d9147f786ee6fb6fddafaed','0','2','0'),
('46507','0','','10609','Get database','mssql.db.get["{$MSSQL.URI}","{$MSSQL.USER}","{$MSSQL.PASSWORD}"]','1h','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Getting databases - database name and recovery model.','0','30d','0','',NULL,'30s','','','','200','1','0','','','0','0','0','0','0','0','0','6c942840048b463e9439f327adceb767','0','2','0'),
('46508','0','','10609','Get job status','mssql.job.status.get["{$MSSQL.URI}","{$MSSQL.USER}","{$MSSQL.PASSWORD}"]','10m','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'The item gets the SQL agent job status.','0','30d','0','',NULL,'30s','','','','200','1','0','','','0','0','0','0','0','0','0','e36f8695b4f74178a19bb88afad586b8','0','2','0'),
('46509','0','','10609','Get last backup','mssql.last.backup.get["{$MSSQL.URI}","{$MSSQL.USER}","{$MSSQL.PASSWORD}"]','10m','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'The item gets information about backup processes.','0','30d','0','',NULL,'30s','','','','200','1','0','','','0','0','0','0','0','0','0','a394835aeddd46a18327f25747e3564d','0','2','0'),
('46510','0','','10609','Get local DB','mssql.local.db.get["{$MSSQL.URI}","{$MSSQL.USER}","{$MSSQL.PASSWORD}"]','1m','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Getting the states of the local availability database.','0','30d','0','',NULL,'30s','','','','200','1','0','','','0','0','0','0','0','0','0','f049c16678ad4daa83e55ab6c3a99fbc','0','2','0'),
('46511','0','','10609','Get DB mirroring','mssql.mirroring.get["{$MSSQL.URI}","{$MSSQL.USER}","{$MSSQL.PASSWORD}"]','1m','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Getting DB mirroring.','0','30d','0','',NULL,'30s','','','','200','1','0','','','0','0','0','0','0','0','0','fb51801472fc4ca7beed49c2586ba1cb','0','2','0'),
('46512','0','','10609','Get non-local DB','mssql.nonlocal.db.get["{$MSSQL.URI}","{$MSSQL.USER}","{$MSSQL.PASSWORD}"]','1m','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Getting the non-local availability database.','0','30d','0','',NULL,'30s','','','','200','1','0','','','0','0','0','0','0','0','0','8730198507594f4aa38d45bf00e65a38','0','2','0'),
('46513','15','','10609','Percent of ad hoc queries running','mssql.percent_of_adhoc_queries','0;m0-59s3','31d','365d','0','0','','%','','',NULL,NULL,'last(//mssql.sql_compilations_sec.rate) * 100 /\r\n(last(//mssql.batch_requests_sec.rate) + (last(//mssql.batch_requests_sec.rate)=0))','','0','','','','','0',NULL,'The ratio of SQL compilations per second to batch requests per second, in percent.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','2064cd9f8e7646fa8fb329ca287fedd2','0','2','0'),
('46514','15','','10609','Percent of Recompiled Transact-SQL Objects','mssql.percent_recompilations_to_compilations','0;m0-59s3','31d','365d','0','0','','%','','',NULL,NULL,'last(//mssql.sql_recompilations_sec.rate) * 100 /\r\n(last(//mssql.sql_compilations_sec.rate) + (last(//mssql.sql_compilations_sec.rate)=0))','','0','','','','','0',NULL,'The ratio of SQL re-compilations per second to SQL compilations per second, in percent.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','98b0754f231c4160bcd2daafeef64fe0','0','2','0'),
('46515','0','','10609','Get performance counters','mssql.perfcounter.get["{$MSSQL.URI}","{$MSSQL.USER}","{$MSSQL.PASSWORD}"]','0;m0-59','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'The item gets server global status information.','0','30d','0','',NULL,'30s','','','','200','1','0','','','0','0','0','0','0','0','0','2128f1e7d0fa46e2bdb8b06f5c07c436','0','2','0'),
('46516','0','','10609','Get quorum','mssql.quorum.get["{$MSSQL.URI}","{$MSSQL.USER}","{$MSSQL.PASSWORD}"]','1m','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Getting quorum - cluster name, type, and state.','0','30d','0','',NULL,'10s','','','','200','1','0','','','0','0','0','0','0','0','0','432178b4071e46758c421f6d9b75f4cd','0','2','0'),
('46517','0','','10609','Get quorum member','mssql.quorum.member.get["{$MSSQL.URI}","{$MSSQL.USER}","{$MSSQL.PASSWORD}"]','1m','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Getting quorum members - member name, type, state, and number of quorum votes.','0','30d','0','',NULL,'10s','','','','200','1','0','','','0','0','0','0','0','0','0','7343a6e34956475db3e79f7cfa905baa','0','2','0'),
('46518','0','','10609','Get replica','mssql.replica.get["{$MSSQL.URI}","{$MSSQL.USER}","{$MSSQL.PASSWORD}"]','1m','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Getting the database replica.','0','30d','0','',NULL,'30s','','','','200','1','0','','','0','0','0','0','0','0','0','77deceae02df4e2280f42ae7b7b16f76','0','2','0'),
('46519','15','','10609','Full scans to Index searches ratio','mssql.scan_to_search','0;m0-59s3','31d','365d','0','0','','','','',NULL,NULL,'last(//mssql.full_scans_sec.rate) / (last(//mssql.index_searches_sec.rate) + (last(//mssql.index_searches_sec.rate)=0))','','0','','','','','0',NULL,'The ratio of full scans per second to index searches per second. The threshold recommendation is strictly for OLTP workloads.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','5dda9c1a17fa43ada4a6857e62148f1a','0','2','0'),
('46520','0','','10609','Version','mssql.version["{$MSSQL.URI}","{$MSSQL.USER}","{$MSSQL.PASSWORD}"]','1m','31d','0','0','1','','','','',NULL,NULL,'','','0','','','','','0',NULL,'MSSQL Server version.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','624ea81f4a7c43659f291a2fc7913778','0','2','0'),
('46521','3','','10609','Service\'s TCP port state','net.tcp.service[tcp,{$MSSQL.HOST},{$MSSQL.PORT}]','30s','31d','365d','0','3','','','','',NULL,'1177','','','0','','','','','0',NULL,'Test the availability of MSSQL Server on a TCP port.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','7fc4f1f9c3df45269972e617ce81f4b2','0','2','0'),
('46659','21','','10610','Get cluster','yugabytedb.clusters.get','1h','0','0','0','4','','','','',NULL,NULL,'var YugabyteDB = {\r\n	params: {},\r\n	clusters: [],\r\n	error_msg: \'\',\r\n\r\n	setParams: function (params) {\r\n		[\'account_id\', \'project_id\', \'token\'].forEach(function (field) {\r\n			if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n				throw \'Required param is not set: \' + field + \'.\';\r\n			}\r\n		});\r\n\r\n		YugabyteDB.params = params;\r\n	},\r\n\r\n\r\n	request: function (url, data) {\r\n		if (typeof data === \'undefined\' || data === null) {\r\n			data = \'\';\r\n		}\r\n\r\n		var response, request = new HttpRequest();\r\n		if (typeof YugabyteDB.params.proxy !== \'undefined\' && YugabyteDB.params.proxy !== \'\') {\r\n			request.setProxy(YugabyteDB.params.proxy);\r\n		}\r\n		if (YugabyteDB.params.token) {\r\n			request.addHeader(\'Accept: application/json\');\r\n			request.addHeader(\'Authorization: Bearer \' + YugabyteDB.params.token);\r\n		}\r\n\r\n		Zabbix.log(4, \'[ YugabyteDB ] Sending request: \' + url);\r\n\r\n		response = request.get(url);\r\n\r\n		Zabbix.log(4, \'[ YugabyteDB ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n\r\n		if (request.getStatus() !== 200 || response === null) {\r\n			throw \'Request failed with status code \' + request.getStatus() + \': \' + response;\r\n		}\r\n\r\n		try {\r\n			return JSON.parse(response);\r\n		}\r\n		catch (error) {\r\n			throw \'Failed to parse response received from API:\' + error;\r\n		}\r\n	}\r\n\r\n};\r\n\r\ntry {\r\n	YugabyteDB.setParams(JSON.parse(value));\r\n\r\n	clusters = YugabyteDB.request(\r\n		\'https://cloud.yugabyte.com/api/public/v1/accounts/\' + YugabyteDB.params.account_id + \'/projects/\' + YugabyteDB.params.project_id + \'/clusters\'\r\n	)\r\n\r\n	YugabyteDB.clusters = clusters.data;\r\n}\r\ncatch (error) {\r\n	Zabbix.log(3, \'[ YugabyteDB ] ERROR: \' + error);\r\n	YugabyteDB.error_msg = \'Failed to get data from API:\' + error;\r\n}\r\n\r\nreturn JSON.stringify({\'clusters\': YugabyteDB.clusters, \'error\': YugabyteDB.error_msg});','','0','','','','','0',NULL,'Get raw data about clusters.','0','30d','0','',NULL,'10s','','','','200','1','0','','','0','0','0','0','0','0','0','25196b29de6c45c18485f2aefe306818','0','2','0'),
('46660','15','','10611','YSQL connections utilization','yugabytedb.cluster.connection.utilization','1m','31d','365d','0','0','','%','','',NULL,NULL,'(last(//yugabytedb.cluster.connection.count)/last(//yugabytedb.cluster.connection.limit))*100','','0','','','','','0',NULL,'Cumulative number of connections to the YSQL backend for all nodes, expressed in percent.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','a7c388d2e66b48469e47a55cbb6ec614','0','2','0'),
('46661','15','','10611','Disk space utilization','yugabytedb.cluster.disk.utilization','1m','31d','365d','0','0','','%','','',NULL,NULL,'(last(//yugabytedb.cluster.disk.usage)/last(//yugabytedb.cluster.disk.provisioned))*100','','0','','','','','0',NULL,'Shows the percentage of disk space used by the cluster.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','b2de999838914ca2bfc2c4fdfd22db74','0','2','0'),
('46662','21','','10611','Get cluster','yugabytedb.cluster.get','10m','0','0','0','4','','','','',NULL,NULL,'var YugabyteDB = {\r\n	params: {},\r\n	clusters: [],\r\n	error_msg: \'\',\r\n\r\n	setParams: function (params) {\r\n		[\'account_id\', \'project_id\', \'token\', \'cluster_id\'].forEach(function (field) {\r\n			if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n				throw \'Required param is not set: \' + field + \'.\';\r\n			}\r\n		});\r\n\r\n		YugabyteDB.params = params;\r\n	},\r\n\r\n\r\n	request: function (url, data) {\r\n		if (typeof data === \'undefined\' || data === null) {\r\n			data = \'\';\r\n		}\r\n\r\n		var response, request = new HttpRequest();\r\n		if (typeof YugabyteDB.params.proxy !== \'undefined\' && YugabyteDB.params.proxy !== \'\') {\r\n			request.setProxy(YugabyteDB.params.proxy);\r\n		}\r\n		if (YugabyteDB.params.token) {\r\n			request.addHeader(\'Accept: application/json\');\r\n			request.addHeader(\'Authorization: Bearer \' + YugabyteDB.params.token);\r\n		}\r\n\r\n		Zabbix.log(4, \'[ YugabyteDB ] Sending request: \' + url);\r\n\r\n		response = request.get(url);\r\n\r\n		Zabbix.log(4, \'[ YugabyteDB ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n\r\n		if (request.getStatus() !== 200 || response === null) {\r\n			throw \'Request failed with status code \' + request.getStatus() + \': \' + response;\r\n		}\r\n\r\n		try {\r\n			return JSON.parse(response);\r\n		}\r\n		catch (error) {\r\n			throw \'Failed to parse response received from API:\' + error;\r\n		}\r\n	}\r\n\r\n};\r\n\r\ntry {\r\n	YugabyteDB.setParams(JSON.parse(value));\r\n\r\n	cluster = YugabyteDB.request(\r\n		\'https://cloud.yugabyte.com/api/public/v1/accounts/\' + YugabyteDB.params.account_id + \'/projects/\' + YugabyteDB.params.project_id + \'/clusters/\' + YugabyteDB.params.cluster_id\r\n	)\r\n\r\n	YugabyteDB.clusters = cluster.data;\r\n}\r\ncatch (error) {\r\n	Zabbix.log(3, \'[ YugabyteDB ] ERROR: \' + error);\r\n	YugabyteDB.error_msg = \'Failed to get data from API:\' + error;\r\n}\r\n\r\nreturn JSON.stringify({\'data\': YugabyteDB.clusters, \'error\': YugabyteDB.error_msg});','','0','','','','','0',NULL,'Get raw data about clusters.','0','30d','0','',NULL,'10s','','','','200','1','0','','','0','0','0','0','0','0','0','d8f71197e0e147fea4de2a17d4b1ad81','0','2','0'),
('46663','15','','10611','Memory utilization','yugabytedb.cluster.memory.utilization','1m','31d','365d','0','0','','%','','',NULL,NULL,'(last(//yugabytedb.cluster.memory.usage)/last(//yugabytedb.cluster.memory.total))*100','','0','','','','','0',NULL,'Shows the amount of RAM used on the cluster, expressed in percent.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','18e6de024a7a4ae48901f455dbd0a373','0','2','0'),
('46664','21','','10611','Get cluster metrics','yugabytedb.cluster.metric.get','1m','0','0','0','4','','','','',NULL,NULL,'var YugabyteDB = {\r\n	params: {},\r\n	metrics: {},\r\n	error_msg: \'\',\r\n\r\n	setParams: function (params) {\r\n		[\'account_id\', \'project_id\', \'token\', \'cluster_id\'].forEach(function (field) {\r\n			if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n				throw \'Required param is not set: \' + field + \'.\';\r\n			}\r\n		});\r\n\r\n		YugabyteDB.params = params;\r\n	},\r\n\r\n\r\n	request: function (url, data) {\r\n		if (typeof data === \'undefined\' || data === null) {\r\n			data = \'\';\r\n		}\r\n\r\n		var response, request = new HttpRequest();\r\n		if (typeof YugabyteDB.params.proxy !== \'undefined\' && YugabyteDB.params.proxy !== \'\') {\r\n			request.setProxy(YugabyteDB.params.proxy);\r\n		}\r\n		if (YugabyteDB.params.token) {\r\n			request.addHeader(\'Accept: application/json\');\r\n			request.addHeader(\'Authorization: Bearer \' + YugabyteDB.params.token);\r\n		}\r\n\r\n		Zabbix.log(4, \'[ YugabyteDB ] Sending request: \' + url);\r\n\r\n		response = request.get(url);\r\n\r\n		Zabbix.log(4, \'[ YugabyteDB ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n\r\n		if (request.getStatus() !== 200 || response === null) {\r\n			throw \'Request failed with status code \' + request.getStatus() + \': \' + response;\r\n		}\r\n\r\n		try {\r\n			return JSON.parse(response);\r\n		}\r\n		catch (error) {\r\n			throw \'Failed to parse response received from API:\' + error;\r\n		}\r\n	},\r\n\r\n\r\n	get_last_values: function (values) {\r\n		var max_timestamp = 0;\r\n		var last_value = 0;\r\n		for (e in values) {\r\n			if (values[e][0] > max_timestamp) {\r\n				max_timestamp = values[e][0];\r\n				last_value = values[e][1];\r\n			};\r\n		};\r\n		return last_value;\r\n	},\r\n\r\n\r\n	get_start_time: function() {\r\n		return Math.floor(Date.now() / 1000 - 300);\r\n	}\r\n\r\n};\r\n\r\nmetrics = [\r\n	"CPU_USAGE",\r\n	"DISK_USAGE_GB",\r\n	"PROVISIONED_DISK_SPACE_GB",\r\n	"READ_OPS_PER_SEC",\r\n	"WRITE_OPS_PER_SEC",\r\n	"AVERAGE_READ_LATENCY_MS",\r\n	"AVERAGE_WRITE_LATENCY_MS",\r\n	"YSQL_CONNECTION_LIMIT",\r\n	"AVERAGE_YSQL_CONNECTION_COUNT",\r\n	"NODE_CLOCK_SKEW",\r\n	"DISK_BYTES_READ_MB_PER_SEC",\r\n	"DISK_BYTES_WRITTEN_MB_PER_SEC",\r\n	"FOLLOWER_LAG_MS",\r\n	"MEMORY_TOTAL_GB",\r\n	"MEMORY_USAGE_GB",\r\n	"NETWORK_RECEIVE_BYTES_MB_PER_SEC",\r\n	"NETWORK_TRANSMIT_BYTES_MB_PER_SEC",\r\n	"NETWORK_RECEIVE_ERRORS_PER_SEC",\r\n	"NETWORK_TRANSMIT_ERRORS_PER_SEC",\r\n	"MASTER_UP_STATUS",\r\n	"TSERVER_UP_STATUS",\r\n	"YSQL_MAX_CONNECTION_COUNT"\r\n]\r\n\r\ntry {\r\n	YugabyteDB.setParams(JSON.parse(value));\r\n\r\n	var size = 6\r\n\r\n	for (var i = 0; i < Math.ceil(metrics.length/size); i++)  {\r\n		var values = YugabyteDB.request(\r\n			\'https://cloud.yugabyte.com/api/public/v1/accounts/\' + YugabyteDB.params.account_id + \'/projects/\' + YugabyteDB.params.project_id + \'/clusters/\' + YugabyteDB.params.cluster_id + \'/metrics?metrics=\' + metrics.slice((i * size), (i * size) + size).join(\'%2C\') + \'&start_time=\' + YugabyteDB.get_start_time()\r\n		);\r\n\r\n		values.data.forEach(function (e) {\r\n			YugabyteDB.metrics[e.name] = YugabyteDB.get_last_values(e.values)\r\n		});\r\n	};\r\n}\r\ncatch (error) {\r\n	Zabbix.log(3, \'[ YugabyteDB ] ERROR: \' + error);\r\n	error_msg = \'Failed to get data from API:\' + error;\r\n}\r\n\r\nreturn JSON.stringify({\'metrics\': YugabyteDB.metrics, \'error\': YugabyteDB.error_msg});','','0','','','','','0',NULL,'Getting metrics for the cluster.','0','30d','0','',NULL,'5s','','','','200','1','0','','','0','0','0','0','0','0','0','9c51b3d15ac448388e23c74d4e5bba3a','0','2','0'),
('46665','21','','10611','Get cluster query statistic','yugabytedb.cluster.query.statistic.get','1m','0','0','0','4','','','','',NULL,NULL,'var YugabyteDB = {\r\n	params: {},\r\n	metrics: {},\r\n	error_msg: \'\',\r\n\r\n	setParams: function (params) {\r\n		[\'account_id\', \'project_id\', \'token\', \'cluster_id\'].forEach(function (field) {\r\n			if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n				throw \'Required param is not set: \' + field + \'.\';\r\n			}\r\n		});\r\n\r\n		YugabyteDB.params = params;\r\n	},\r\n\r\n\r\n	request: function (url, data) {\r\n		if (typeof data === \'undefined\' || data === null) {\r\n			data = \'\';\r\n		}\r\n\r\n		var response, request = new HttpRequest();\r\n		if (typeof YugabyteDB.params.proxy !== \'undefined\' && YugabyteDB.params.proxy !== \'\') {\r\n			request.setProxy(YugabyteDB.params.proxy);\r\n		}\r\n		if (YugabyteDB.params.token) {\r\n			request.addHeader(\'Accept: application/json\');\r\n			request.addHeader(\'Authorization: Bearer \' + YugabyteDB.params.token);\r\n		}\r\n\r\n		Zabbix.log(4, \'[ YugabyteDB ] Sending request: \' + url);\r\n\r\n		response = request.get(url);\r\n\r\n		Zabbix.log(4, \'[ YugabyteDB ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n\r\n		if (request.getStatus() !== 200 || response === null) {\r\n			throw \'Request failed with status code \' + request.getStatus() + \': \' + response;\r\n		}\r\n\r\n		try {\r\n			return JSON.parse(response);\r\n		}\r\n		catch (error) {\r\n			throw \'Failed to parse response received from API:\' + error;\r\n		}\r\n	},\r\n\r\n\r\n	get_last_values: function (values) {\r\n		var max_timestamp = 0;\r\n		var last_value = 0;\r\n		for (e in values) {\r\n			if (values[e][0] > max_timestamp) {\r\n				max_timestamp = values[e][0];\r\n				last_value = values[e][1];\r\n			};\r\n		};\r\n		return last_value;\r\n	},\r\n\r\n\r\n	get_start_time: function() {\r\n		return Math.floor(Date.now() / 1000 - 300);\r\n	}\r\n\r\n};\r\n\r\nmetrics = [\r\n	"YSQL_SELECT_OPS_PER_SEC",\r\n	"YSQL_DELETE_OPS_PER_SEC",\r\n	"YSQL_INSERT_OPS_PER_SEC",\r\n	"YSQL_UPDATE_OPS_PER_SEC",\r\n	"YSQL_OTHER_OPS_PER_SEC",\r\n	"YSQL_TRANSACTION_OPS_PER_SEC",\r\n	"YSQL_SELECT_LATENCY_MS",\r\n	"YSQL_DELETE_LATENCY_MS",\r\n	"YSQL_INSERT_LATENCY_MS",\r\n	"YSQL_UPDATE_LATENCY_MS",\r\n	"YSQL_OTHER_LATENCY_MS",\r\n	"YSQL_TRANSACTION_LATENCY_MS",\r\n	"YCQL_SELECT_OPS_PER_SEC",\r\n	"YCQL_DELETE_OPS_PER_SEC",\r\n	"YCQL_INSERT_OPS_PER_SEC",\r\n	"YCQL_OTHER_OPS_PER_SEC",\r\n	"YCQL_UPDATE_OPS_PER_SEC",\r\n	"YCQL_TRANSACTION_OPS_PER_SEC",\r\n	"YCQL_SELECT_LATENCY_MS",\r\n	"YCQL_DELETE_LATENCY_MS",\r\n	"YCQL_INSERT_LATENCY_MS",\r\n	"YCQL_OTHER_LATENCY_MS",\r\n	"YCQL_UPDATE_LATENCY_MS",\r\n	"YCQL_TRANSACTION_LATENCY_MS"\r\n]\r\n\r\ntry {\r\n	YugabyteDB.setParams(JSON.parse(value));\r\n\r\n	var size = 6\r\n\r\n	for (var i = 0; i < Math.ceil(metrics.length/size); i++)  {\r\n		var values = YugabyteDB.request(\r\n			\'https://cloud.yugabyte.com/api/public/v1/accounts/\' + YugabyteDB.params.account_id + \'/projects/\' + YugabyteDB.params.project_id + \'/clusters/\' + YugabyteDB.params.cluster_id + \'/metrics?metrics=\' + metrics.slice((i * size), (i * size) + size).join(\'%2C\') + \'&start_time=\' + YugabyteDB.get_start_time()\r\n		);\r\n\r\n		values.data.forEach(function (e) {\r\n			YugabyteDB.metrics[e.name] = YugabyteDB.get_last_values(e.values)\r\n		});\r\n	};\r\n}\r\ncatch (error) {\r\n	Zabbix.log(3, \'[ YugabyteDB ] ERROR: \' + error);\r\n	error_msg = \'Failed to get data from API:\' + error;\r\n	return JSON.stringify({\'error\': error_msg});\r\n}\r\n\r\nreturn JSON.stringify({\'metrics\': YugabyteDB.metrics, \'error\': YugabyteDB.error_msg});','','0','','','','','0',NULL,'Getting SQL statistics for the cluster.','0','30d','0','',NULL,'5s','','','','200','1','0','','','0','0','0','0','0','0','0','5497290f85d44d2c95ca0be3d2b030a3','0','2','0'),
('46666','21','','10611','Get keyspace','yugabytedb.keyspace.get','10m','0','0','0','4','','','','',NULL,NULL,'var YugabyteDB = {\r\n	params: {},\r\n	keyspaces: {},\r\n	error_msg: \'\',\r\n\r\n	setParams: function (params) {\r\n		[\'account_id\', \'project_id\', \'token\'].forEach(function (field) {\r\n			if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n				throw \'Required param is not set: \' + field + \'.\';\r\n			}\r\n		});\r\n\r\n		YugabyteDB.params = params;\r\n	},\r\n\r\n\r\n	request: function (url, data) {\r\n		if (typeof data === \'undefined\' || data === null) {\r\n			data = \'\';\r\n		}\r\n\r\n		var response, request = new HttpRequest();\r\n		if (typeof YugabyteDB.params.proxy !== \'undefined\' && YugabyteDB.params.proxy !== \'\') {\r\n			request.setProxy(YugabyteDB.params.proxy);\r\n		}\r\n		if (YugabyteDB.params.token) {\r\n			request.addHeader(\'Accept: application/json\');\r\n			request.addHeader(\'Authorization: Bearer \' + YugabyteDB.params.token);\r\n		}\r\n\r\n		Zabbix.log(4, \'[ YugabyteDB ] Sending request: \' + url);\r\n\r\n		response = request.get(url);\r\n\r\n		Zabbix.log(4, \'[ YugabyteDB ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n\r\n		if (request.getStatus() !== 200 || response === null) {\r\n			throw \'Request failed with status code \' + request.getStatus() + \': \' + response;\r\n		}\r\n\r\n		try {\r\n			return JSON.parse(response);\r\n		}\r\n		catch (error) {\r\n			throw \'Failed to parse response received from API:\' + error;\r\n		}\r\n	},\r\n\r\n\r\n	get_keyspace: function (tables) {\r\n		var table_info = {};\r\n		var result = [];\r\n		for (var table in tables[\'data\']) {\r\n			var table_name = tables[\'data\'][table][\'keyspace\'];\r\n			if (typeof table_info[table_name] !== \'undefined\') {\r\n				table_info[table_name][\'size_bytes\'] += tables[\'data\'][table][\'size_bytes\']\r\n				table_info[table_name][\'wal_size_bytes\'] += tables[\'data\'][table][\'wal_size_bytes\']\r\n			}\r\n			else {\r\n				table_info[table_name] = {\r\n					\'keyspace_name\': table_name,\r\n					\'size_bytes\': tables[\'data\'][table][\'size_bytes\'],\r\n					\'wal_size_bytes\': tables[\'data\'][table][\'wal_size_bytes\'],\r\n					\'type\': tables[\'data\'][table][\'type\']}\r\n			}\r\n		}\r\n		for (keyspace in table_info) {\r\n			result.push(table_info[keyspace])\r\n		}\r\n		return result;\r\n	}\r\n\r\n};\r\n\r\ntry {\r\n	YugabyteDB.setParams(JSON.parse(value));\r\n\r\n	var tables = YugabyteDB.request(\r\n		\'https://cloud.yugabyte.com/api/public/v1/accounts/\' + YugabyteDB.params.account_id + \'/projects/\' + YugabyteDB.params.project_id + \'/clusters/\' + YugabyteDB.params.cluster_id + \'/tables\'\r\n	)\r\n	\r\n	YugabyteDB.keyspaces = YugabyteDB.get_keyspace(tables);\r\n}\r\ncatch (error) {\r\n	Zabbix.log(3, \'[ YugabyteDB ] ERROR: \' + error);\r\n	error_msg = \'Failed to get data from API:\' + error;\r\n}\r\n\r\nreturn JSON.stringify({\'keyspaces\': YugabyteDB.keyspaces, \'error\': YugabyteDB.error_msg});','','0','','','','','0',NULL,'Get raw data about keyspaces.','0','30d','0','',NULL,'10s','','','','200','1','0','','','0','0','0','0','0','0','0','88c3b743cbe24ea9a0046dc0854a36be','0','2','0'),
('46667','21','','10611','Get node','yugabytedb.node.get','10m','0','0','0','4','','','','',NULL,NULL,'var YugabyteDB = {\r\n	params: {},\r\n	nodes: {},\r\n	error_msg: \'\',\r\n\r\n	setParams: function (params) {\r\n		[\'account_id\', \'project_id\', \'token\'].forEach(function (field) {\r\n			if (typeof params !== \'object\' || typeof params[field] === \'undefined\' || params[field] === \'\') {\r\n				throw \'Required param is not set: \' + field + \'.\';\r\n			}\r\n		});\r\n\r\n		YugabyteDB.params = params;\r\n	},\r\n\r\n\r\n	request: function (url, data) {\r\n		if (typeof data === \'undefined\' || data === null) {\r\n			data = \'\';\r\n		}\r\n\r\n		var response, request = new HttpRequest();\r\n		if (typeof YugabyteDB.params.proxy !== \'undefined\' && YugabyteDB.params.proxy !== \'\') {\r\n			request.setProxy(YugabyteDB.params.proxy);\r\n		}\r\n		if (YugabyteDB.params.token) {\r\n			request.addHeader(\'Accept: application/json\');\r\n			request.addHeader(\'Authorization: Bearer \' + YugabyteDB.params.token);\r\n		}\r\n\r\n		Zabbix.log(4, \'[ YugabyteDB ] Sending request: \' + url);\r\n\r\n		response = request.get(url);\r\n\r\n		Zabbix.log(4, \'[ YugabyteDB ] Received response with status code \' + request.getStatus() + \': \' + response);\r\n\r\n		if (request.getStatus() !== 200 || response === null) {\r\n			throw \'Request failed with status code \' + request.getStatus() + \': \' + response;\r\n		}\r\n\r\n		try {\r\n			return JSON.parse(response);\r\n		}\r\n		catch (error) {\r\n			throw \'Failed to parse response received from API:\' + error;\r\n		}\r\n	}\r\n\r\n};\r\n\r\ntry {\r\n	YugabyteDB.setParams(JSON.parse(value));\r\n\r\n	var node = YugabyteDB.request(\r\n		\'https://cloud.yugabyte.com/api/public/v1/accounts/\' + YugabyteDB.params.account_id + \'/projects/\' + YugabyteDB.params.project_id + \'/clusters/\' + YugabyteDB.params.cluster_id + \'/nodes\'\r\n	)\r\n	YugabyteDB.nodes = node.data;\r\n}\r\ncatch (error) {\r\n	Zabbix.log(3, \'[ YugabyteDB ] ERROR: \' + error);\r\n	error_msg = \'Failed to get data from API:\' + error;\r\n}\r\n\r\nreturn JSON.stringify({\'nodes\': YugabyteDB.nodes, \'error\': YugabyteDB.error_msg});','','0','','','','','0',NULL,'Get raw data about nodes.','0','30d','0','',NULL,'10s','','','','200','1','0','','','0','0','0','0','0','0','0','734486b27ba64138bae356c7b14c8dbc','0','2','0'),
('46726','15','','10611','YugabyteDB Node [{#NODE.NAME}]: Disk IOPS utilization','yugabytedb.node.iops.utilization[{#NODE.NAME}]','1m','31d','365d','0','0','','%','','',NULL,NULL,'((last(//yugabytedb.node.read.ops[{#NODE.NAME}]) + last(//yugabytedb.node.write.ops[{#NODE.NAME}]))/last(//yugabytedb.node.iops.limit[{#NODE.NAME}]))*100','','0','','','','','2',NULL,'Shows the utilization of provisioned IOPS.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','27e087e59b0f425584f57fda13398ea0','0','2','0'),
('46746','3','','10613','ICMP ping','icmpping','1m','31d','365d','0','3','','','','',NULL,'1189','','','0','','','','','0',NULL,'Host accessibility by ICMP.\r\n0 - ICMP ping fails.\r\n1 - ICMP ping successful.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','737cc32022044218bd0599bc9be1c6cf','0','2','0'),
('46747','3','','10613','ICMP loss','icmppingloss','1m','31d','365d','0','0','','%','','',NULL,NULL,'','','0','','','','','0',NULL,'Percentage of lost packets.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','584837895d324e5bbcbce686ec894fb4','0','2','0'),
('46748','3','','10613','ICMP response time','icmppingsec','1m','31d','365d','0','0','','s','','',NULL,NULL,'','','0','','','','','0',NULL,'ICMP ping response time (in seconds).','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','85013b32538f445d87955582857f2942','0','2','0'),
('46749','20','walk[1.3.6.1.2.1.2.2.1.8,1.3.6.1.2.1.2.2.1.7,1.3.6.1.2.1.31.1.1.1.18,1.3.6.1.2.1.31.1.1.1.1,1.3.6.1.2.1.2.2.1.2,1.3.6.1.2.1.2.2.1.3,1.3.6.1.2.1.31.1.1.1.6,1.3.6.1.2.1.31.1.1.1.10,1.3.6.1.2.1.2.2.1.14,1.3.6.1.2.1.2.2.1.20,1.3.6.1.2.1.2.2.1.19,1.3.6.1.2.1.2.2.1.13,1.3.6.1.2.1.31.1.1.1.15]','10613','SNMP walk network interfaces','net.if.walk','1m','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Used for discovering interfaces from IF-MIB.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','a81c01a9acfe49eabea71a3106bf43b8','0','2','0'),
('46750','20','discovery[{#SNMPVALUE},1.3.6.1.4.1.2620.500.9000.1.2]','10613','Remote Access users','remote.users.number','1m','31d','365d','0','3','','','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: CHECKPOINT-MIB\r\nNumber of remote access users.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','d50cbc1930c24647b1f5a7921c9c3b06','0','2','0'),
('46751','20','walk[1.3.6.1.4.1.2620.1.6.7.8.2.1.2,1.3.6.1.4.1.2620.1.6.7.8.2.1.3,1.3.6.1.4.1.2620.1.6.7.8.2.1.4,1.3.6.1.4.1.2620.1.6.7.8.2.1.6]','10613','SNMP walk fan sensors','sensor.fan.walk','1m','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Used for discovering fan sensors from CHECKPOINT-MIB.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','b943e400640e46498ba7ecf2ea3510dd','0','2','0'),
('46752','20','walk[1.3.6.1.4.1.2620.1.6.7.9.1.1.1,1.3.6.1.4.1.2620.1.6.7.9.1.1.2]','10613','SNMP walk PSU sensors','sensor.psu.walk','1m','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Used for discovering power supply sensors from CHECKPOINT-MIB.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','76167bb41de149d6a4b4af4ba68e1460','0','2','0'),
('46753','20','walk[1.3.6.1.4.1.2620.1.6.7.8.1.1.2,1.3.6.1.4.1.2620.1.6.7.8.1.1.3]','10613','SNMP walk temperature sensors','sensor.temp.walk','1m','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Used for discovering temperature sensors from CHECKPOINT-MIB.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','d5122dad11df4f6790d49d46614c3ea2','0','2','0'),
('46754','20','walk[1.3.6.1.4.1.2620.1.6.7.8.3.1.2,1.3.6.1.4.1.2620.1.6.7.8.3.1.3]','10613','SNMP walk voltage sensors','sensor.volt.walk','1m','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Used for discovering voltage sensors from CHECKPOINT-MIB.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','620126ff805d48aea5b7cac6d5ab4084','0','2','0'),
('46755','17','','10613','SNMP traps (fallback)','snmptrap.fallback','0','31d','0','0','2','','','','hh:mm:sszyyyy/MM/dd',NULL,NULL,'','','0','','','','','0',NULL,'Used to collect all SNMP traps unmatched by other `snmptrap` items.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','e04735bdbc4f453692902c0bc6596f3b','0','2','0'),
('46756','20','walk[1.3.6.1.4.1.2620.1.6.18.1.1.4,1.3.6.1.4.1.2620.1.6.18.1.1.5,1.3.6.1.4.1.2620.1.6.18.1.1.6,1.3.6.1.4.1.2620.1.6.18.1.1.8,1.3.6.1.4.1.2620.1.6.18.1.1.9,1.3.6.1.4.1.2620.1.6.18.1.1.10]','10613','SNMP walk svn features','svn.feature.walk','1m','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Used for discovering software blades and features from CHECKPOINT-MIB.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','847084d2b72a4c9688a4375a12fd7ea0','0','2','0'),
('46757','20','1.3.6.1.2.1.1.4.0','10613','System contact details','system.contact','15m','31d','0','0','1','','','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: SNMPv2-MIB\r\nName and contact information of the contact person for the node. If not provided, the value is a zero-length string.','23','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','499ee4e8eb2f481295625592ee215610','0','2','0'),
('46758','20','1.3.6.1.4.1.2620.1.6.7.2.3.0','10613','CPU idle time','system.cpu.idle','1m','31d','365d','0','0','','%','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: CHECKPOINT-MIB\r\nAverage time the CPU has spent doing nothing.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','07162e1ca0c44dc5979b17c258b34052','0','2','0'),
('46759','20','1.3.6.1.4.1.2620.1.6.7.2.6.0','10613','CPU interrupts per second','system.cpu.intr','1m','31d','365d','0','0','','','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: CHECKPOINT-MIB\r\nNumber of interrupts processed per second.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','5acef2ff22464f2c816bf1ab5ed8c66f','0','2','0'),
('46760','20','1.3.6.1.4.1.2021.10.1.3["index","1.3.6.1.4.1.2021.10.1.2", "Load-1"]','10613','Load average (1m avg)','system.cpu.load.avg1','1m','31d','365d','0','0','','','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: UCD-SNMP-MIB\r\nAverage number of processes being executed or waiting over the last minute.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','4b659e86f18146ca877b595c3151368a','0','2','0'),
('46761','20','1.3.6.1.4.1.2021.10.1.3["index","1.3.6.1.4.1.2021.10.1.2", "Load-5"]','10613','Load average (5m avg)','system.cpu.load.avg5','1m','31d','365d','0','0','','','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: UCD-SNMP-MIB\r\nAverage number of processes being executed or waiting over the last 5 minutes.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','534ad1fb2bec4db5aa25de1a42f28dc6','0','2','0'),
('46762','20','1.3.6.1.4.1.2021.10.1.3["index","1.3.6.1.4.1.2021.10.1.2", "Load-15"]','10613','Load average (15m avg)','system.cpu.load.avg15','1m','31d','365d','0','0','','','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: UCD-SNMP-MIB\r\nAverage number of processes being executed or waiting over the last 15 minutes.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','f23f2785833b4096ad65114c40fdaa9b','0','2','0'),
('46763','20','1.3.6.1.4.1.2620.1.6.7.2.7.0','10613','Number of CPUs','system.cpu.num','1m','31d','365d','0','3','','','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: CHECKPOINT-MIB\r\nNumber of processors.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','b42cc71d0b5143108b2314ab1fb1ceff','0','2','0'),
('46764','20','1.3.6.1.4.1.2021.11.60.0','10613','Context switches per second','system.cpu.switches','1m','31d','365d','0','0','','','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: UCD-SNMP-MIB\r\nNumber of context switches per second.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','ada3e8eb30bc4c4f863fca6e46dc1cd5','0','2','0'),
('46765','20','1.3.6.1.4.1.2620.1.6.7.2.2.0','10613','CPU system time','system.cpu.system','1m','31d','365d','0','0','','%','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: CHECKPOINT-MIB\r\nAverage time the CPU has spent running the kernel and its processes.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','bf0a80a981d248bdb2e4567ee8c084b3','0','2','0'),
('46766','20','1.3.6.1.4.1.2620.1.6.7.2.1.0','10613','CPU user time','system.cpu.user','1m','31d','365d','0','0','','%','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: CHECKPOINT-MIB\r\nAverage time the CPU has spent running user processes that are not niced.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','7a8a46d486404a5184a7fdba0832c50f','0','2','0'),
('46767','20','1.3.6.1.4.1.2620.1.6.7.2.4.0','10613','CPU utilization','system.cpu.util','1m','31d','365d','0','0','','%','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: CHECKPOINT-MIB\r\nCPU utilization per core in %.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','db554f92ee6a4ab297b75839c019a7fe','0','2','0'),
('46768','20','walk[1.3.6.1.4.1.2620.1.6.7.5.1.1,1.3.6.1.4.1.2620.1.6.7.5.1.2,1.3.6.1.4.1.2620.1.6.7.5.1.3,1.3.6.1.4.1.2620.1.6.7.5.1.4,1.3.6.1.4.1.2620.1.6.7.5.1.5]','10613','SNMP walk CPU','system.cpu.walk','1m','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Used for discovering CPU from CHECKPOINT-MIB.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','3628aac1e934408489153062d078e2e7','0','2','0'),
('46769','20','1.3.6.1.2.1.1.1.0','10613','System description','system.descr','15m','31d','0','0','1','','','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: SNMPv2-MIB\r\nFull name and version identification of the system\'s hardware type, software operating system, and networking software.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','a7ad79b572ab4e678011aa8ee810cd75','0','2','0'),
('46770','20','1.3.6.1.4.1.2620.1.6.16.9.0','10613','Appliance manufacturer','system.hw.manufacturer','1h','31d','0','0','1','','','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: CHECKPOINT-MIB\r\nAppliance manufacturer.','31','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','8385b6ee11b340f888676d013531a4d5','0','2','0'),
('46771','20','1.3.6.1.4.1.2620.1.6.16.7.0','10613','Appliance product name','system.hw.model','1h','31d','0','0','1','','','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: CHECKPOINT-MIB\r\nAppliance product name.','29','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','b461939fa04348f19c4f03ce3fd211b8','0','2','0'),
('46772','20','1.3.6.1.4.1.2620.1.6.16.3.0','10613','Appliance serial number','system.hw.serialnumber','1h','31d','0','0','1','','','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: CHECKPOINT-MIB\r\nAppliance serial number.','8','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','adb0bce1162a4e8990f4d299d8554d29','0','2','0'),
('46773','20','1.3.6.1.2.1.1.6.0','10613','System location','system.location','15m','31d','0','0','1','','','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: SNMPv2-MIB\r\nPhysical location of the node (e.g., `equipment room`, `3rd floor`). If not provided, the value is a zero-length string.','24','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','df1681db47dc40b987f7be51e640974e','0','2','0'),
('46774','20','1.3.6.1.2.1.1.5.0','10613','System name','system.name','15m','31d','0','0','1','','','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: SNMPv2-MIB\r\nAn administratively-assigned name for the node (the node\'s fully-qualified domain name). If not provided, the value is a zero-length string.','3','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','a18c50a7b53e49c09de5fa39d9a70a14','0','2','0'),
('46775','20','1.3.6.1.2.1.1.2.0','10613','System object ID','system.objectid','15m','31d','0','0','1','','','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: SNMPv2-MIB\r\nThe vendor\'s authoritative identification of the entity as part of the vendor\'s SMI enterprises subtree with the prefix 1.3.6.1.4.1 (e.g., a vendor with the identifier 1.3.6.1.4.1.4242 might assign a system object with the OID 1.3.6.1.4.1.4242.1.1).','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','bd2f23c23fff46b5b43e8283f1683927','0','2','0'),
('46776','20','1.3.6.1.2.1.25.1.1.0','10613','System uptime','system.uptime','1m','31d','365d','0','3','','uptime','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: HOST-RESOURCES-V2-MIB\r\nTime since the network management portion of the system was last re-initialized.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','b05995de7faf4d408b467c1024f2a438','0','2','0'),
('46777','20','walk[1.3.6.1.4.1.2620.1.6.7.6.1.2,1.3.6.1.4.1.2620.1.6.7.6.1.3,1.3.6.1.4.1.2620.1.6.7.6.1.4,1.3.6.1.4.1.2620.1.6.7.6.1.5,1.3.6.1.4.1.2620.1.6.7.6.1.6,1.3.6.1.4.1.2620.1.6.7.6.1.7]','10613','SNMP walk disks','vfs.fs.walk','1m','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Used for discovering storage disks from CHECKPOINT-MIB.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','d66ff3625ea74b5493a37d7b5e231c66','0','2','0'),
('46778','20','1.3.6.1.4.1.2620.1.6.7.4.4.0','10613','Active memory','vm.memory.active','1m','31d','365d','0','3','','B','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: CHECKPOINT-MIB\r\nActive real memory (memory used by applications that is not cached to the disk) in bytes.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','9c5fbaca93854ad3941cb95e159b0ee1','0','2','0'),
('46779','20','1.3.6.1.4.1.2620.1.6.7.4.5.0','10613','Free memory','vm.memory.free','1m','31d','365d','0','3','','B','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: CHECKPOINT-MIB\r\nFree memory available for applications in bytes.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','0a55ee1b84cb490494e27a4543db7691','0','2','0'),
('46780','20','1.3.6.1.4.1.2620.1.6.7.4.3.0','10613','Total memory','vm.memory.total','1m','31d','365d','0','3','','B','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: CHECKPOINT-MIB\r\nTotal real memory in bytes. Memory used by applications.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','517445d996d148bcb34d7898dca55df6','0','2','0'),
('46781','15','','10613','Used memory','vm.memory.used','1m','31d','365d','0','3','','B','','',NULL,NULL,'last(//vm.memory.total) - last(//vm.memory.free)','','0','','','','','0',NULL,'Used real memory calculated by total real memory and free real memory in bytes.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','8846be280ae14ee8a1af1be65bef1996','0','2','0'),
('46782','15','','10613','Memory utilization','vm.memory.util','1m','31d','365d','0','0','','%','','',NULL,NULL,'last(//vm.memory.used)/last(//vm.memory.total)*100','','0','','','','','0',NULL,'Memory utilization in %.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','6bb39f4c24f14cc6a90db2ce1492dbea','0','2','0'),
('46783','20','1.3.6.1.4.1.2620.1.2.5.4.6.0','10613','Decrypted packets per second','vpn.packets.decrypted','1m','31d','365d','0','3','','','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: CHECKPOINT-MIB\r\nNumber of decrypted packets per second.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','0eac75ac03af43d596b84cee15a8ddb4','0','2','0'),
('46784','20','1.3.6.1.4.1.2620.1.2.5.4.5.0','10613','Encrypted packets per second','vpn.packets.encrypted','1m','31d','365d','0','3','','','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: CHECKPOINT-MIB\r\nNumber of encrypted packets per second.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','5d2b872c90774b868d5ce086fabe5cb2','0','2','0'),
('46785','20','walk[1.3.6.1.4.1.2620.500.9002.1.1,1.3.6.1.4.1.2620.500.9002.1.2,1.3.6.1.4.1.2620.500.9002.1.3,1.3.6.1.4.1.2620.500.9002.1.4,1.3.6.1.4.1.2620.500.9002.1.6,1.3.6.1.4.1.2620.500.9002.1.7,1.3.6.1.4.1.2620.500.9002.1.8,1.3.6.1.4.1.2620.500.9002.1.9,1.3.6.1.4.1.2620.500.9002.1.10,1.3.6.1.4.1.2620.500.9002.1.11]','10613','SNMP walk VPN tunnels','vpn.tunnel.walk','1m','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Used for discovering VPN tunnels from CHECKPOINT-MIB.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','eb15e618aff347b3ba986a2c02deb6bd','0','2','0'),
('46786','5','','10613','SNMP agent availability','zabbix[host,snmp,available]','1m','31d','365d','0','3','','','','',NULL,'1195','','','0','','','','','0',NULL,'Availability of SNMP checks on the host. The value of this item corresponds to the availability icons in the host list.\r\n\r\nPossible values:\r\n0 - not available\r\n1 - available\r\n2 - unknown','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','843f5f01701e4d79b3e899134f87632d','0','2','0'),
('46789','20','discovery[{#FW.STATE},1.3.6.1.4.1.2620.1.1.1]','10613','Firewall discovery','fw.discovery','1h','31d','365d','0','4','','','','',NULL,NULL,'','','0','','','','','1',NULL,'This discovery will create a set of firewall metrics from CHECKPOINT-MIB if the firewall is installed.','0','7d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','5fa6a636f36f44069f83885bc2767e85','0','2','0'),
('46797','20','1.3.6.1.4.1.2620.1.1.25.6.{#SNMPINDEX}','10613','Check Point Firewall: Accepted packets per second{#SINGLETON}','fw.accepted[fwAccepted.{#SNMPINDEX}]','1m','31d','365d','0','3','','','','',NULL,NULL,'','','0','','','','','2',NULL,'MIB: CHECKPOINT-MIB\r\nNumber of accepted packets per second.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','ff64891849684cc88ae5414c0bc1b0bb','0','2','0'),
('46798','20','1.3.6.1.4.1.2620.1.1.25.4.{#SNMPINDEX}','10613','Check Point Firewall: Peak concurrent connections{#SINGLETON}','fw.conn.num.peak[fwPeakNumConn.{#SNMPINDEX}]','1m','31d','365d','0','3','','','','',NULL,NULL,'','','0','','','','','2',NULL,'MIB: CHECKPOINT-MIB\r\nPeak number of concurrent connections since last reboot.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','a26ba0c4eec04fb99160b15a8ff40cee','0','2','0'),
('46799','20','1.3.6.1.4.1.2620.1.1.25.3.{#SNMPINDEX}','10613','Check Point Firewall: Concurrent connections{#SINGLETON}','fw.conn.num[fwNumConn.{#SNMPINDEX}]','1m','31d','365d','0','3','','','','',NULL,NULL,'','','0','','','','','2',NULL,'MIB: CHECKPOINT-MIB\r\nNumber of concurrent IPv6 and IPv4 connections.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','3cf7583bcf2a43f4b7598689b6d8825d','0','2','0'),
('46800','20','1.3.6.1.4.1.2620.1.1.25.16.{#SNMPINDEX}','10613','Check Point Firewall: Dropped packets per second{#SINGLETON}','fw.dropped[fwDropped.{#SNMPINDEX}]','1m','31d','365d','0','3','','','','',NULL,NULL,'','','0','','','','','2',NULL,'MIB: CHECKPOINT-MIB\r\nNumber of dropped packets per second.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','b35e258430f04d7b96f70f0df97040ef','0','2','0'),
('46801','20','1.3.6.1.4.1.2620.1.1.3.{#SNMPINDEX}','10613','Check Point Firewall: Firewall filter install time{#SINGLETON}','fw.filter.installed[fwFilterDate.{#SNMPINDEX}]','1m','31d','365d','0','3','','unixtime','','',NULL,NULL,'','','0','','','','','2',NULL,'MIB: CHECKPOINT-MIB\r\nLast install time of the firewall filter.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','8dc145b5354940c88089df72ce59557e','0','2','0'),
('46802','20','1.3.6.1.4.1.2620.1.1.2.{#SNMPINDEX}','10613','Check Point Firewall: Firewall filter name{#SINGLETON}','fw.filter.name[fwFilterName.{#SNMPINDEX}]','1m','31d','0','0','1','','','','',NULL,NULL,'','','0','','','','','2',NULL,'MIB: CHECKPOINT-MIB\r\nName of the firewall filter.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','7c0837980dca4bdda426c5b22bae21e2','0','2','0'),
('46803','20','1.3.6.1.4.1.2620.1.1.25.13.{#SNMPINDEX}','10613','Check Point Firewall: Logged packets per second{#SINGLETON}','fw.logged[fwLogged.{#SNMPINDEX}]','1m','31d','365d','0','3','','','','',NULL,NULL,'','','0','','','','','2',NULL,'MIB: CHECKPOINT-MIB\r\nNumber of logged packets per second.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','03ec2d7d252d458fac388d915467af42','0','2','0'),
('46804','20','1.3.6.1.4.1.2620.1.1.25.14.{#SNMPINDEX}','10613','Check Point Firewall: Rejected packets per second{#SINGLETON}','fw.rejected[fwRejected.{#SNMPINDEX}]','1m','31d','365d','0','3','','','','',NULL,NULL,'','','0','','','','','2',NULL,'MIB: CHECKPOINT-MIB\r\nNumber of rejected packets per second.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','8ff79fb5ec1844ff9a502a81ec306f8b','0','2','0'),
('46805','20','1.3.6.1.4.1.2620.1.1.12.{#SNMPINDEX}','10613','Check Point Firewall: SIC Trust State{#SINGLETON}','fw.sic.trust.state[fwSICTrustState.{#SNMPINDEX}]','1m','31d','365d','0','3','','','','',NULL,'1185','','','0','','','','','2',NULL,'MIB: CHECKPOINT-MIB\r\nFirewall SIC Trust State.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','85d1ffccfcf44f41965efa37cbc21c61','0','2','0'),
('46806','20','1.3.6.1.4.1.2620.1.1.25.26.{#SNMPINDEX}','10613','Check Point Firewall: Utilized drops number per second{#SINGLETON}','fw.utilized.drops[fwFullyUtilizedDrops.{#SNMPINDEX}]','1m','31d','365d','0','3','','','','',NULL,NULL,'','','0','','','','','2',NULL,'MIB: CHECKPOINT-MIB\r\nNumber of dropped packets per second due to instance being fully utilized.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','589e8b27a2174380a8fee1080bd36471','0','2','0'),
('46807','20','discovery[{#MAJOR},1.3.6.1.4.1.2620.1.1.22,{#MINOR},1.3.6.1.4.1.2620.1.1.23]','10613','Check Point Firewall: Firewall version{#SINGLETON}','fw.version[fwVersion.{#SNMPINDEX}]','1m','31d','365d','0','0','','','','',NULL,NULL,'','','0','','','','','2',NULL,'MIB: CHECKPOINT-MIB\r\nCurrent version of the firewall.','0','30d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','f752805cc45647f290f32085edbb6843','0','2','0'),
('46845','21','','10614','Get frequent metrics','oci.aut.db.metrics.frequent.get','1m','0','0','0','4','','','','',NULL,NULL,'function validateZabbixParams(requiredParams, allParams) {\r\n	requiredParams.forEach(function (field) {\r\n		if (typeof allParams !== \'object\' || typeof allParams[field] === \'undefined\' || allParams[field] === \'\') {\r\n			throw \'Required param is not set: \' + field + \'.\';\r\n		}\r\n	});\r\n}\r\n\r\nfunction OCI(service, action, params) {\r\n	this.zabbixLogPrefix = \'[ OCI ] [ \' + service + \' ] [ \' + action + \' ]\';\r\n	this.request = new HttpRequest();\r\n\r\n	this.hash = function (string) {\r\n		return sha256(string);\r\n	};\r\n\r\n	this.sign = function (string) {\r\n		return sign(\'sha256\', params[\'private_key\'], string);\r\n	};\r\n\r\n	this.encode = function (hash) {\r\n		const hexArr = hash.match(/.{1,2}/g);\r\n		var uInt8Array = new Uint8Array(hexArr.length);\r\n		hexArr.forEach(function (hex, idx) {\r\n			uInt8Array[idx] = parseInt(hex, 16);\r\n		});\r\n		return btoa(uInt8Array);\r\n	};\r\n\r\n	this.getDate = function () {\r\n		const weekdayShortList = [\'Sun\', \'Mon\', \'Tue\', \'Wed\', \'Thu\', \'Fri\', \'Sat\'];\r\n		const monthShortList = [\'jan\', \'feb\', \'mar\', \'apr\', \'may\', \'jun\', \'jul\', \'aug\', \'sep\', \'oct\', \'nov\', \'dec\'];\r\n		const today = new Date();\r\n		return weekdayShortList[today.getUTCDay()] + \', \' + today.getUTCDate() + \' \' + monthShortList[today.getUTCMonth()] + \' \' + today.getUTCFullYear() + \' \' + today.getUTCHours() + \':\' + today.getUTCMinutes() + \':\' + today.getUTCSeconds() + \' GMT\';\r\n	};\r\n\r\n	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {\r\n		var headers = \'(request-target) date host\';\r\n		const contentTypeHeader = \'content-type: application/json\';\r\n		const dateHeader = \'date: \' + this.getDate();\r\n		const hostHeader = \'host: \' + params[\'api_host\'];\r\n		const requestTarget = \'(request-target): \' + httpMethod + \' \' + apiPath + apiParams;\r\n		var signingString = requestTarget + \'\\n\' + dateHeader + \'\\n\' + hostHeader;\r\n		var reqHeaders = [contentTypeHeader, dateHeader];\r\n\r\n		if (httpMethod === \'post\') {\r\n			var body = JSON.stringify({\r\n				\'namespace\': namespace,\r\n				\'query\': mql\r\n			});\r\n			headers = headers + \' x-content-sha256 content-type content-length\';\r\n			const bodyHeader = \'x-content-sha256: \' + this.encode(this.hash(body));\r\n			const bodyLengthHeader = \'content-length: \' + body.length;\r\n			signingString = signingString + \'\\n\' + bodyHeader + \'\\n\' + contentTypeHeader + \'\\n\' + bodyLengthHeader;\r\n			reqHeaders.push(bodyHeader, bodyLengthHeader);\r\n		}\r\n\r\n		const signature = this.encode(this.sign(signingString));\r\n\r\n		reqHeaders.push(\'Authorization: Signature version="1",keyId="\' + params[\'tenancy_ocid\'] + \'/\' + params[\'user_ocid\'] + \'/\' + params[\'fingerprint\'] + \'",algorithm="rsa-sha256",headers="\' + headers + \'",signature="\' + signature + \'"\');\r\n		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {\r\n			this.request.addHeader(reqHeaders[header]);\r\n		}\r\n\r\n		if (params[\'http_proxy\']) {\r\n			this.request.setProxy(params[\'http_proxy\']);\r\n			Zabbix.log(4, this.zabbixLogPrefix + \' Using http proxy: \' + params[\'http_proxy\']);\r\n		}\r\n\r\n		if (httpMethod === \'post\') {\r\n			var apiRateLimitExceeded = false;\r\n			do {\r\n				const response = this.request.post(\'https://\' + params[\'api_host\'] + apiPath + apiParams, body);\r\n\r\n				try {\r\n					if (JSON.parse(response)[\'code\'] === \'TooManyRequests\') {\r\n\r\n						apiRateLimitExceeded = true;\r\n						Zabbix.sleep(1000);\r\n					} else {\r\n						apiRateLimitExceeded = false;\r\n					}\r\n				} catch (error) {\r\n					Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the response: \' + JSON.stringify(response));\r\n					throw \'Could not parse the response. See logs for more information.\';\r\n				}\r\n			} while (apiRateLimitExceeded);\r\n		} else {\r\n			const response = this.request.get(\'https://\' + params[\'api_host\'] + apiPath + apiParams);\r\n		}\r\n\r\n		this.request.clearHeader();\r\n\r\n		if (this.request.getStatus() === parseInt(params[\'http_status_code\'])) {\r\n			return response;\r\n		} else {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Unexpected HTTP response code: \' + this.request.getStatus());\r\n			throw \'Unexpected HTTP response code: \' + this.request.getStatus();\r\n		}\r\n	};\r\n\r\n	this.extractData = function (httpMethod, data, keys, compartment) {\r\n		try {\r\n			data = JSON.parse(data);\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the received JSON object: \' + data);\r\n			throw \'Could not parse received JSON object. See logs for more information.\';\r\n		}\r\n\r\n		if (typeof keys == \'object\') {\r\n			var returnBuffer = [];\r\n			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {\r\n\r\n				var objectBuffer = {};\r\n				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {\r\n					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {\r\n						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];\r\n					} else {\r\n						Zabbix.log(3, this.zabbixLogPrefix + \' Received an unexpected JSON object. Could not get value for key "\' + keys[key] + \'" in JSON: \' + JSON.stringify(data[dataObj]));\r\n						throw \'Received an unexpected JSON object. See logs for more information.\';\r\n					}\r\n				}\r\n				if (typeof compartment != \'undefined\' && compartment != \'\') objectBuffer[\'compartment\'] = compartment;\r\n				returnBuffer.push(objectBuffer);\r\n			}\r\n			return returnBuffer;\r\n		}\r\n\r\n		try {\r\n			if (httpMethod === \'get\') {\r\n				return data[keys];\r\n			} else {\r\n				if (data.length === 0) {\r\n					return 0;\r\n				}\r\n				data = data[0][keys];\r\n				return data[data.length - 1][\'value\'];\r\n			}\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not find key "\' + keys + \'" in JSON: \' + JSON.stringify(data));\r\n			throw \'Could not find required key in JSON object. See logs for more information.\';\r\n		}\r\n	};\r\n}\r\n\r\nfunction buildMql(id, metrics, defaultStatistic, resourceType) {\r\n	resourceType = resourceType === \'\' || resourceType === undefined ? \'resourceId\' : resourceType;\r\n	this.query = \'[\' + params[\'req_interval\'] + \'m]{\' + resourceType + \'=\' + id + \'}.\';\r\n\r\n	for (var i = 0, metricsLength = metrics.length; i < metricsLength; i++) {\r\n		const metric = ((Array.isArray(metrics[i]) ? metrics[i] : [metrics[i], defaultStatistic]));\r\n		metrics[i] = [metric[0], this.query + metric[1]];\r\n	}\r\n}\r\n\r\n\r\nconst params = JSON.parse(value);\r\nvalidateZabbixParams([\'tenancy_ocid\', \'user_ocid\', \'private_key\', \'fingerprint\', \'api_host\', \'db_id\', \'http_status_code\', \'req_interval\', \'compartment_id\'], params);\r\nvar oci = new OCI(\'Autonomous DB\', \'Get metrics \' + params[\'req_interval\'] + \'m\', params);\r\n\r\nconst metrics = [\r\n	[\'CpuTime\', \'mean\'],\r\n	[\'CpuUtilization\', \'mean\'],\r\n	[\'CurrentLogons\', \'count\'],\r\n	\'DBBlockChanges\',\r\n	[\'DBTime\', \'mean\'],\r\n	\'ExecuteCount\',\r\n	\'FailedConnections\',\r\n	[\'FailedLogons\', \'mean\'],\r\n	\'HardParseCount\',\r\n	\'LogicalReads\',\r\n	\'ParseCount\',\r\n	\'ParseFailureCount\',\r\n	\'PhysicalReads\',\r\n	\'PhysicalReadTotalBytes\',\r\n	\'PhysicalWrites\',\r\n	\'PhysicalWriteTotalBytes\',\r\n	\'QueuedStatements\',\r\n	\'RedoGenerated\',\r\n	[\'RunningStatements\', \'mean\'],\r\n	\'Sessions\',\r\n	\'SQLNetBytesFromClient\',\r\n	\'SQLNetBytesFromDBLink\',\r\n	\'SQLNetBytesToClient\',\r\n	\'SQLNetBytesToDBLink\',\r\n	\'TransactionCount\',\r\n	\'UserCalls\',\r\n	\'UserCommits\',\r\n	\'UserRollbacks\',\r\n	[\'WaitTime\', \'mean\']\r\n];\r\nbuildMql(params[\'db_id\'], metrics, \'sum\');\r\n\r\nvar result = {};\r\nfor (var i = 0, metricsLength = metrics.length; i < metricsLength; i++) {\r\n	result[metrics[i][0]] = oci.extractData(\'post\', oci.executeRequest(\'post\', \'/20180401/metrics/actions/summarizeMetricsData\', \'?compartmentId=\' + encodeURIComponent(params[\'compartment_id\']), metrics[i][0] + metrics[i][1] + \'()\', \'oci_autonomous_database\'), \'aggregatedDatapoints\');\r\n}\r\nreturn JSON.stringify(result);','','0','','','','','0',NULL,'Gets all metrics related to the database that have a collection frequency of 1 minute.','0','7d','0','',NULL,'30s','','','','200','1','0','','','0','0','0','0','0','0','0','6104537179324cb48d82e05d64f3a19f','0','2','0'),
('46846','21','','10614','Get database stats','oci.aut.db.metrics.stats','5m','0','0','0','4','','','','',NULL,NULL,'function validateZabbixParams(requiredParams, allParams) {\r\n	requiredParams.forEach(function (field) {\r\n		if (typeof allParams !== \'object\' || typeof allParams[field] === \'undefined\' || allParams[field] === \'\') {\r\n			throw \'Required param is not set: \' + field + \'.\';\r\n		}\r\n	});\r\n}\r\n\r\nfunction OCI(service, action, params) {\r\n	this.zabbixLogPrefix = \'[ OCI ] [ \' + service + \' ] [ \' + action + \' ]\';\r\n	this.request = new HttpRequest();\r\n\r\n	this.hash = function (string) {\r\n		return sha256(string);\r\n	};\r\n\r\n	this.sign = function (string) {\r\n		return sign(\'sha256\', params[\'private_key\'], string);\r\n	};\r\n\r\n	this.encode = function (hash) {\r\n		const hexArr = hash.match(/.{1,2}/g);\r\n		var uInt8Array = new Uint8Array(hexArr.length);\r\n		hexArr.forEach(function (hex, idx) {\r\n			uInt8Array[idx] = parseInt(hex, 16);\r\n		});\r\n		return btoa(uInt8Array);\r\n	};\r\n\r\n	this.getDate = function () {\r\n		const weekdayShortList = [\'Sun\', \'Mon\', \'Tue\', \'Wed\', \'Thu\', \'Fri\', \'Sat\'];\r\n		const monthShortList = [\'jan\', \'feb\', \'mar\', \'apr\', \'may\', \'jun\', \'jul\', \'aug\', \'sep\', \'oct\', \'nov\', \'dec\'];\r\n		const today = new Date();\r\n		return weekdayShortList[today.getUTCDay()] + \', \' + today.getUTCDate() + \' \' + monthShortList[today.getUTCMonth()] + \' \' + today.getUTCFullYear() + \' \' + today.getUTCHours() + \':\' + today.getUTCMinutes() + \':\' + today.getUTCSeconds() + \' GMT\';\r\n	};\r\n\r\n	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {\r\n		var headers = \'(request-target) date host\';\r\n		const contentTypeHeader = \'content-type: application/json\';\r\n		const dateHeader = \'date: \' + this.getDate();\r\n		const hostHeader = \'host: \' + params[\'api_host\'];\r\n		const requestTarget = \'(request-target): \' + httpMethod + \' \' + apiPath + apiParams;\r\n		var signingString = requestTarget + \'\\n\' + dateHeader + \'\\n\' + hostHeader;\r\n		var reqHeaders = [contentTypeHeader, dateHeader];\r\n\r\n		if (httpMethod === \'post\') {\r\n			var body = JSON.stringify({\r\n				\'namespace\': namespace,\r\n				\'query\': mql\r\n			});\r\n			headers = headers + \' x-content-sha256 content-type content-length\';\r\n			const bodyHeader = \'x-content-sha256: \' + this.encode(this.hash(body));\r\n			const bodyLengthHeader = \'content-length: \' + body.length;\r\n			signingString = signingString + \'\\n\' + bodyHeader + \'\\n\' + contentTypeHeader + \'\\n\' + bodyLengthHeader;\r\n			reqHeaders.push(bodyHeader, bodyLengthHeader);\r\n		}\r\n\r\n		const signature = this.encode(this.sign(signingString));\r\n\r\n		reqHeaders.push(\'Authorization: Signature version="1",keyId="\' + params[\'tenancy_ocid\'] + \'/\' + params[\'user_ocid\'] + \'/\' + params[\'fingerprint\'] + \'",algorithm="rsa-sha256",headers="\' + headers + \'",signature="\' + signature + \'"\');\r\n		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {\r\n			this.request.addHeader(reqHeaders[header]);\r\n		}\r\n\r\n		if (params[\'http_proxy\']) {\r\n			this.request.setProxy(params[\'http_proxy\']);\r\n			Zabbix.log(4, this.zabbixLogPrefix + \' Using http proxy: \' + params[\'http_proxy\']);\r\n		}\r\n\r\n		if (httpMethod === \'post\') {\r\n			var apiRateLimitExceeded = false;\r\n			do {\r\n				const response = this.request.post(\'https://\' + params[\'api_host\'] + apiPath + apiParams, body);\r\n\r\n				try {\r\n					if (JSON.parse(response)[\'code\'] === \'TooManyRequests\') {\r\n\r\n						apiRateLimitExceeded = true;\r\n						Zabbix.sleep(1000);\r\n					} else {\r\n						apiRateLimitExceeded = false;\r\n					}\r\n				} catch (error) {\r\n					Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the response: \' + JSON.stringify(response));\r\n					throw \'Could not parse the response. See logs for more information.\';\r\n				}\r\n			} while (apiRateLimitExceeded);\r\n		} else {\r\n			const response = this.request.get(\'https://\' + params[\'api_host\'] + apiPath + apiParams);\r\n		}\r\n\r\n		this.request.clearHeader();\r\n\r\n		if (this.request.getStatus() === parseInt(params[\'http_status_code\'])) {\r\n			return response;\r\n		} else {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Unexpected HTTP response code: \' + this.request.getStatus());\r\n			throw \'Unexpected HTTP response code: \' + this.request.getStatus();\r\n		}\r\n	};\r\n\r\n	this.extractData = function (httpMethod, data, keys, compartment) {\r\n		try {\r\n			data = JSON.parse(data);\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the received JSON object: \' + data);\r\n			throw \'Could not parse received JSON object. See logs for more information.\';\r\n		}\r\n\r\n		if (typeof keys == \'object\') {\r\n			var returnBuffer = [];\r\n			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {\r\n\r\n				var objectBuffer = {};\r\n				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {\r\n					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {\r\n						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];\r\n					} else {\r\n						Zabbix.log(3, this.zabbixLogPrefix + \' Received an unexpected JSON object. Could not get value for key "\' + keys[key] + \'" in JSON: \' + JSON.stringify(data[dataObj]));\r\n						throw \'Received an unexpected JSON object. See logs for more information.\';\r\n					}\r\n				}\r\n				if (typeof compartment != \'undefined\' && compartment != \'\') objectBuffer[\'compartment\'] = compartment;\r\n				returnBuffer.push(objectBuffer);\r\n			}\r\n			return returnBuffer;\r\n		}\r\n\r\n		try {\r\n			if (httpMethod === \'get\') {\r\n				return data[keys];\r\n			} else {\r\n				if (data.length === 0) {\r\n					return 0;\r\n				}\r\n				data = data[0][keys];\r\n				return data[data.length - 1][\'value\'];\r\n			}\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not find key "\' + keys + \'" in JSON: \' + JSON.stringify(data));\r\n			throw \'Could not find required key in JSON object. See logs for more information.\';\r\n		}\r\n	};\r\n}\r\n\r\nfunction buildMql(id, metrics, defaultStatistic, resourceType) {\r\n	resourceType = resourceType === \'\' || resourceType === undefined ? \'resourceId\' : resourceType;\r\n	this.query = \'[\' + params[\'req_interval\'] + \'m]{\' + resourceType + \'=\' + id + \'}.\';\r\n\r\n	for (var i = 0, metricsLength = metrics.length; i < metricsLength; i++) {\r\n		const metric = ((Array.isArray(metrics[i]) ? metrics[i] : [metrics[i], defaultStatistic]));\r\n		metrics[i] = [metric[0], this.query + metric[1]];\r\n	}\r\n}\r\n\r\n\r\nconst params = JSON.parse(value);\r\nvalidateZabbixParams([\'tenancy_ocid\', \'user_ocid\', \'private_key\', \'fingerprint\', \'api_host\', \'db_id\', \'http_status_code\', \'req_interval\', \'compartment_id\'], params);\r\nvar oci = new OCI(\'Autonomous DB\', \'Get metrics \' + params[\'req_interval\'] + \'m\', params);\r\n\r\nconst metrics = [\r\n	[\'DatabaseAvailability\', \'last\'],\r\n	\'ConnectionLatency\',\r\n	\'QueryLatency\'\r\n];\r\nbuildMql(params[\'db_id\'], metrics, \'max\');\r\n\r\nvar result = {};\r\nfor (var i = 0, metricsLength = metrics.length; i < metricsLength; i++) {\r\n	result[metrics[i][0]] = oci.extractData(\'post\', oci.executeRequest(\'post\', \'/20180401/metrics/actions/summarizeMetricsData\', \'?compartmentId=\' + encodeURIComponent(params[\'compartment_id\']), metrics[i][0] + metrics[i][1] + \'()\', \'oci_autonomous_database\'), \'aggregatedDatapoints\');\r\n}\r\nreturn JSON.stringify(result);','','0','','','','','0',NULL,'Gets all metrics related to specific database that have a collection frequency of 5 minutes.','0','7d','0','',NULL,'30s','','','','200','1','0','','','0','0','0','0','0','0','0','87a25240776a4b8a9a17ac053b69fd99','0','2','0'),
('46847','21','','10614','Get storage stats','oci.aut.db.metrics.storage.stats','60m','0','0','0','4','','','','',NULL,NULL,'function validateZabbixParams(requiredParams, allParams) {\r\n	requiredParams.forEach(function (field) {\r\n		if (typeof allParams !== \'object\' || typeof allParams[field] === \'undefined\' || allParams[field] === \'\') {\r\n			throw \'Required param is not set: \' + field + \'.\';\r\n		}\r\n	});\r\n}\r\n\r\nfunction OCI(service, action, params) {\r\n	this.zabbixLogPrefix = \'[ OCI ] [ \' + service + \' ] [ \' + action + \' ]\';\r\n	this.request = new HttpRequest();\r\n\r\n	this.hash = function (string) {\r\n		return sha256(string);\r\n	};\r\n\r\n	this.sign = function (string) {\r\n		return sign(\'sha256\', params[\'private_key\'], string);\r\n	};\r\n\r\n	this.encode = function (hash) {\r\n		const hexArr = hash.match(/.{1,2}/g);\r\n		var uInt8Array = new Uint8Array(hexArr.length);\r\n		hexArr.forEach(function (hex, idx) {\r\n			uInt8Array[idx] = parseInt(hex, 16);\r\n		});\r\n		return btoa(uInt8Array);\r\n	};\r\n\r\n	this.getDate = function () {\r\n		const weekdayShortList = [\'Sun\', \'Mon\', \'Tue\', \'Wed\', \'Thu\', \'Fri\', \'Sat\'];\r\n		const monthShortList = [\'jan\', \'feb\', \'mar\', \'apr\', \'may\', \'jun\', \'jul\', \'aug\', \'sep\', \'oct\', \'nov\', \'dec\'];\r\n		const today = new Date();\r\n		return weekdayShortList[today.getUTCDay()] + \', \' + today.getUTCDate() + \' \' + monthShortList[today.getUTCMonth()] + \' \' + today.getUTCFullYear() + \' \' + today.getUTCHours() + \':\' + today.getUTCMinutes() + \':\' + today.getUTCSeconds() + \' GMT\';\r\n	};\r\n\r\n	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {\r\n		var headers = \'(request-target) date host\';\r\n		const contentTypeHeader = \'content-type: application/json\';\r\n		const dateHeader = \'date: \' + this.getDate();\r\n		const hostHeader = \'host: \' + params[\'api_host\'];\r\n		const requestTarget = \'(request-target): \' + httpMethod + \' \' + apiPath + apiParams;\r\n		var signingString = requestTarget + \'\\n\' + dateHeader + \'\\n\' + hostHeader;\r\n		var reqHeaders = [contentTypeHeader, dateHeader];\r\n\r\n		if (httpMethod === \'post\') {\r\n			var body = JSON.stringify({\r\n				\'namespace\': namespace,\r\n				\'query\': mql\r\n			});\r\n			headers = headers + \' x-content-sha256 content-type content-length\';\r\n			const bodyHeader = \'x-content-sha256: \' + this.encode(this.hash(body));\r\n			const bodyLengthHeader = \'content-length: \' + body.length;\r\n			signingString = signingString + \'\\n\' + bodyHeader + \'\\n\' + contentTypeHeader + \'\\n\' + bodyLengthHeader;\r\n			reqHeaders.push(bodyHeader, bodyLengthHeader);\r\n		}\r\n\r\n		const signature = this.encode(this.sign(signingString));\r\n\r\n		reqHeaders.push(\'Authorization: Signature version="1",keyId="\' + params[\'tenancy_ocid\'] + \'/\' + params[\'user_ocid\'] + \'/\' + params[\'fingerprint\'] + \'",algorithm="rsa-sha256",headers="\' + headers + \'",signature="\' + signature + \'"\');\r\n		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {\r\n			this.request.addHeader(reqHeaders[header]);\r\n		}\r\n\r\n		if (params[\'http_proxy\']) {\r\n			this.request.setProxy(params[\'http_proxy\']);\r\n			Zabbix.log(4, this.zabbixLogPrefix + \' Using http proxy: \' + params[\'http_proxy\']);\r\n		}\r\n\r\n		if (httpMethod === \'post\') {\r\n			var apiRateLimitExceeded = false;\r\n			do {\r\n				const response = this.request.post(\'https://\' + params[\'api_host\'] + apiPath + apiParams, body);\r\n\r\n				try {\r\n					if (JSON.parse(response)[\'code\'] === \'TooManyRequests\') {\r\n\r\n						apiRateLimitExceeded = true;\r\n						Zabbix.sleep(1000);\r\n					} else {\r\n						apiRateLimitExceeded = false;\r\n					}\r\n				} catch (error) {\r\n					Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the response: \' + JSON.stringify(response));\r\n					throw \'Could not parse the response. See logs for more information.\';\r\n				}\r\n			} while (apiRateLimitExceeded);\r\n		} else {\r\n			const response = this.request.get(\'https://\' + params[\'api_host\'] + apiPath + apiParams);\r\n		}\r\n\r\n		this.request.clearHeader();\r\n\r\n		if (this.request.getStatus() === parseInt(params[\'http_status_code\'])) {\r\n			return response;\r\n		} else {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Unexpected HTTP response code: \' + this.request.getStatus());\r\n			throw \'Unexpected HTTP response code: \' + this.request.getStatus();\r\n		}\r\n	};\r\n\r\n	this.extractData = function (httpMethod, data, keys, compartment) {\r\n		try {\r\n			data = JSON.parse(data);\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the received JSON object: \' + data);\r\n			throw \'Could not parse received JSON object. See logs for more information.\';\r\n		}\r\n\r\n		if (typeof keys == \'object\') {\r\n			var returnBuffer = [];\r\n			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {\r\n\r\n				var objectBuffer = {};\r\n				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {\r\n					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {\r\n						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];\r\n					} else {\r\n						Zabbix.log(3, this.zabbixLogPrefix + \' Received an unexpected JSON object. Could not get value for key "\' + keys[key] + \'" in JSON: \' + JSON.stringify(data[dataObj]));\r\n						throw \'Received an unexpected JSON object. See logs for more information.\';\r\n					}\r\n				}\r\n				if (typeof compartment != \'undefined\' && compartment != \'\') objectBuffer[\'compartment\'] = compartment;\r\n				returnBuffer.push(objectBuffer);\r\n			}\r\n			return returnBuffer;\r\n		}\r\n\r\n		try {\r\n			if (httpMethod === \'get\') {\r\n				return data[keys];\r\n			} else {\r\n				if (data.length === 0) {\r\n					return 0;\r\n				}\r\n				data = data[0][keys];\r\n				return data[data.length - 1][\'value\'];\r\n			}\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not find key "\' + keys + \'" in JSON: \' + JSON.stringify(data));\r\n			throw \'Could not find required key in JSON object. See logs for more information.\';\r\n		}\r\n	};\r\n}\r\n\r\nfunction buildMql(id, metrics, defaultStatistic, resourceType) {\r\n	resourceType = resourceType === \'\' || resourceType === undefined ? \'resourceId\' : resourceType;\r\n	this.query = \'[\' + params[\'req_interval\'] + \'m]{\' + resourceType + \'=\' + id + \'}.\';\r\n\r\n	for (var i = 0, metricsLength = metrics.length; i < metricsLength; i++) {\r\n		const metric = ((Array.isArray(metrics[i]) ? metrics[i] : [metrics[i], defaultStatistic]));\r\n		metrics[i] = [metric[0], this.query + metric[1]];\r\n	}\r\n}\r\n\r\n\r\nconst params = JSON.parse(value);\r\nvalidateZabbixParams([\'tenancy_ocid\', \'user_ocid\', \'private_key\', \'fingerprint\', \'api_host\', \'db_id\', \'http_status_code\', \'req_interval\', \'compartment_id\'], params);\r\nvar oci = new OCI(\'Autonomous DB\', \'Get metrics \' + params[\'req_interval\'] + \'m\', params);\r\n\r\nconst metrics = [\r\n	\'StorageAllocated\',\r\n	\'StorageMax\',\r\n	\'StorageUsed\',\r\n	[\'StorageUtilization\', \'mean\']\r\n];\r\nbuildMql(params[\'db_id\'], metrics, \'max\');\r\n\r\nvar result = {};\r\nfor (var i = 0, metricsLength = metrics.length; i < metricsLength; i++) {\r\n	result[metrics[i][0]] = oci.extractData(\'post\', oci.executeRequest(\'post\', \'/20180401/metrics/actions/summarizeMetricsData\', \'?compartmentId=\' + encodeURIComponent(params[\'compartment_id\']), metrics[i][0] + metrics[i][1] + \'()\', \'oci_autonomous_database\'), \'aggregatedDatapoints\');\r\n}\r\nreturn JSON.stringify(result);','','0','','','','','0',NULL,'Gets all storage metrics related to a specific database that have a collection frequency of 60 minutes.','0','7d','0','',NULL,'30s','','','','200','1','0','','','0','0','0','0','0','0','0','cb2936c594e4450096559b3023f6aa4f','0','2','0'),
('46848','21','','10614','State','oci.aut.db.state','1m','31d','365d','0','3','','','','',NULL,'1196','function validateZabbixParams(requiredParams, allParams) {\r\n	requiredParams.forEach(function (field) {\r\n		if (typeof allParams !== \'object\' || typeof allParams[field] === \'undefined\' || allParams[field] === \'\') {\r\n			throw \'Required param is not set: \' + field + \'.\';\r\n		}\r\n	});\r\n}\r\n\r\nfunction OCI(service, action, params) {\r\n	this.zabbixLogPrefix = \'[ OCI ] [ \' + service + \' ] [ \' + action + \' ]\';\r\n	this.request = new HttpRequest();\r\n\r\n	this.hash = function (string) {\r\n		return sha256(string);\r\n	};\r\n\r\n	this.sign = function (string) {\r\n		return sign(\'sha256\', params[\'private_key\'], string);\r\n	};\r\n\r\n	this.encode = function (hash) {\r\n		const hexArr = hash.match(/.{1,2}/g);\r\n		var uInt8Array = new Uint8Array(hexArr.length);\r\n		hexArr.forEach(function (hex, idx) {\r\n			uInt8Array[idx] = parseInt(hex, 16);\r\n		});\r\n		return btoa(uInt8Array);\r\n	};\r\n\r\n	this.getDate = function () {\r\n		const weekdayShortList = [\'Sun\', \'Mon\', \'Tue\', \'Wed\', \'Thu\', \'Fri\', \'Sat\'];\r\n		const monthShortList = [\'jan\', \'feb\', \'mar\', \'apr\', \'may\', \'jun\', \'jul\', \'aug\', \'sep\', \'oct\', \'nov\', \'dec\'];\r\n		const today = new Date();\r\n		return weekdayShortList[today.getUTCDay()] + \', \' + today.getUTCDate() + \' \' + monthShortList[today.getUTCMonth()] + \' \' + today.getUTCFullYear() + \' \' + today.getUTCHours() + \':\' + today.getUTCMinutes() + \':\' + today.getUTCSeconds() + \' GMT\';\r\n	};\r\n\r\n	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {\r\n		var headers = \'(request-target) date host\';\r\n		const contentTypeHeader = \'content-type: application/json\';\r\n		const dateHeader = \'date: \' + this.getDate();\r\n		const hostHeader = \'host: \' + params[\'api_host\'];\r\n		const requestTarget = \'(request-target): \' + httpMethod + \' \' + apiPath + apiParams;\r\n		var signingString = requestTarget + \'\\n\' + dateHeader + \'\\n\' + hostHeader;\r\n		var reqHeaders = [contentTypeHeader, dateHeader];\r\n\r\n		if (httpMethod === \'post\') {\r\n			var body = JSON.stringify({\r\n				\'namespace\': namespace,\r\n				\'query\': mql\r\n			});\r\n			headers = headers + \' x-content-sha256 content-type content-length\';\r\n			const bodyHeader = \'x-content-sha256: \' + this.encode(this.hash(body));\r\n			const bodyLengthHeader = \'content-length: \' + body.length;\r\n			signingString = signingString + \'\\n\' + bodyHeader + \'\\n\' + contentTypeHeader + \'\\n\' + bodyLengthHeader;\r\n			reqHeaders.push(bodyHeader, bodyLengthHeader);\r\n		}\r\n\r\n		const signature = this.encode(this.sign(signingString));\r\n\r\n		reqHeaders.push(\'Authorization: Signature version="1",keyId="\' + params[\'tenancy_ocid\'] + \'/\' + params[\'user_ocid\'] + \'/\' + params[\'fingerprint\'] + \'",algorithm="rsa-sha256",headers="\' + headers + \'",signature="\' + signature + \'"\');\r\n		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {\r\n			this.request.addHeader(reqHeaders[header]);\r\n		}\r\n\r\n		if (params[\'http_proxy\']) {\r\n			this.request.setProxy(params[\'http_proxy\']);\r\n			Zabbix.log(4, this.zabbixLogPrefix + \' Using http proxy: \' + params[\'http_proxy\']);\r\n		}\r\n\r\n		if (httpMethod === \'post\') {\r\n			var apiRateLimitExceeded = false;\r\n			do {\r\n				const response = this.request.post(\'https://\' + params[\'api_host\'] + apiPath + apiParams, body);\r\n\r\n				try {\r\n					if (JSON.parse(response)[\'code\'] === \'TooManyRequests\') {\r\n\r\n						apiRateLimitExceeded = true;\r\n						Zabbix.sleep(1000);\r\n					} else {\r\n						apiRateLimitExceeded = false;\r\n					}\r\n				} catch (error) {\r\n					Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the response: \' + JSON.stringify(response));\r\n					throw \'Could not parse the response. See logs for more information.\';\r\n				}\r\n			} while (apiRateLimitExceeded);\r\n		} else {\r\n			const response = this.request.get(\'https://\' + params[\'api_host\'] + apiPath + apiParams);\r\n		}\r\n\r\n		this.request.clearHeader();\r\n\r\n		if (this.request.getStatus() === parseInt(params[\'http_status_code\'])) {\r\n			return response;\r\n		} else {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Unexpected HTTP response code: \' + this.request.getStatus());\r\n			throw \'Unexpected HTTP response code: \' + this.request.getStatus();\r\n		}\r\n	};\r\n\r\n	this.extractData = function (httpMethod, data, keys, compartment) {\r\n		try {\r\n			data = JSON.parse(data);\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the received JSON object: \' + data);\r\n			throw \'Could not parse received JSON object. See logs for more information.\';\r\n		}\r\n\r\n		if (typeof keys == \'object\') {\r\n			var returnBuffer = [];\r\n			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {\r\n\r\n				var objectBuffer = {};\r\n				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {\r\n					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {\r\n						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];\r\n					} else {\r\n						Zabbix.log(3, this.zabbixLogPrefix + \' Received an unexpected JSON object. Could not get value for key "\' + keys[key] + \'" in JSON: \' + JSON.stringify(data[dataObj]));\r\n						throw \'Received an unexpected JSON object. See logs for more information.\';\r\n					}\r\n				}\r\n				if (typeof compartment != \'undefined\' && compartment != \'\') objectBuffer[\'compartment\'] = compartment;\r\n				returnBuffer.push(objectBuffer);\r\n			}\r\n			return returnBuffer;\r\n		}\r\n\r\n		try {\r\n			if (httpMethod === \'get\') {\r\n				return data[keys];\r\n			} else {\r\n				if (data.length === 0) {\r\n					return 0;\r\n				}\r\n				data = data[0][keys];\r\n				return data[data.length - 1][\'value\'];\r\n			}\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not find key "\' + keys + \'" in JSON: \' + JSON.stringify(data));\r\n			throw \'Could not find required key in JSON object. See logs for more information.\';\r\n		}\r\n	};\r\n}\r\n\r\n\r\nconst params = JSON.parse(value);\r\nvalidateZabbixParams([\'tenancy_ocid\', \'user_ocid\', \'private_key\', \'fingerprint\', \'api_host\', \'db_id\', \'http_status_code\'], params);\r\nvar oci = new OCI(\'Autonomous DB\', \'Get state\', params);\r\n\r\nreturn oci.extractData(\'get\', oci.executeRequest(\'get\', \'/20160918/autonomousDatabases/\' + encodeURIComponent(params[\'db_id\']), \'\'), \'lifecycleState\');','','0','','','','','0',NULL,'Gets the autonomous database state.','0','7d','0','',NULL,'10s','','','','200','1','0','','','0','0','0','0','0','0','0','48d69be6970c41fcb110f18e18ff6387','0','2','0'),
('46849','21','','10615','Get metrics','oci.block.volume.metrics.get','1m','0','0','0','4','','','','',NULL,NULL,'function validateZabbixParams(requiredParams, allParams) {\r\n	requiredParams.forEach(function (field) {\r\n		if (typeof allParams !== \'object\' || typeof allParams[field] === \'undefined\' || allParams[field] === \'\') {\r\n			throw \'Required param is not set: \' + field + \'.\';\r\n		}\r\n	});\r\n}\r\n\r\nfunction OCI(service, action, params) {\r\n	this.zabbixLogPrefix = \'[ OCI ] [ \' + service + \' ] [ \' + action + \' ]\';\r\n	this.request = new HttpRequest();\r\n\r\n	this.hash = function (string) {\r\n		return sha256(string);\r\n	};\r\n\r\n	this.sign = function (string) {\r\n		return sign(\'sha256\', params[\'private_key\'], string);\r\n	};\r\n\r\n	this.encode = function (hash) {\r\n		const hexArr = hash.match(/.{1,2}/g);\r\n		var uInt8Array = new Uint8Array(hexArr.length);\r\n		hexArr.forEach(function (hex, idx) {\r\n			uInt8Array[idx] = parseInt(hex, 16);\r\n		});\r\n		return btoa(uInt8Array);\r\n	};\r\n\r\n	this.getDate = function () {\r\n		const weekdayShortList = [\'Sun\', \'Mon\', \'Tue\', \'Wed\', \'Thu\', \'Fri\', \'Sat\'];\r\n		const monthShortList = [\'jan\', \'feb\', \'mar\', \'apr\', \'may\', \'jun\', \'jul\', \'aug\', \'sep\', \'oct\', \'nov\', \'dec\'];\r\n		const today = new Date();\r\n		return weekdayShortList[today.getUTCDay()] + \', \' + today.getUTCDate() + \' \' + monthShortList[today.getUTCMonth()] + \' \' + today.getUTCFullYear() + \' \' + today.getUTCHours() + \':\' + today.getUTCMinutes() + \':\' + today.getUTCSeconds() + \' GMT\';\r\n	};\r\n\r\n	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {\r\n		var headers = \'(request-target) date host\';\r\n		const contentTypeHeader = \'content-type: application/json\';\r\n		const dateHeader = \'date: \' + this.getDate();\r\n		const hostHeader = \'host: \' + params[\'api_host\'];\r\n		const requestTarget = \'(request-target): \' + httpMethod + \' \' + apiPath + apiParams;\r\n		var signingString = requestTarget + \'\\n\' + dateHeader + \'\\n\' + hostHeader;\r\n		var reqHeaders = [contentTypeHeader, dateHeader];\r\n\r\n		if (httpMethod === \'post\') {\r\n			var body = JSON.stringify({\r\n				\'namespace\': namespace,\r\n				\'query\': mql\r\n			});\r\n			headers = headers + \' x-content-sha256 content-type content-length\';\r\n			const bodyHeader = \'x-content-sha256: \' + this.encode(this.hash(body));\r\n			const bodyLengthHeader = \'content-length: \' + body.length;\r\n			signingString = signingString + \'\\n\' + bodyHeader + \'\\n\' + contentTypeHeader + \'\\n\' + bodyLengthHeader;\r\n			reqHeaders.push(bodyHeader, bodyLengthHeader);\r\n		}\r\n\r\n		const signature = this.encode(this.sign(signingString));\r\n\r\n		reqHeaders.push(\'Authorization: Signature version="1",keyId="\' + params[\'tenancy_ocid\'] + \'/\' + params[\'user_ocid\'] + \'/\' + params[\'fingerprint\'] + \'",algorithm="rsa-sha256",headers="\' + headers + \'",signature="\' + signature + \'"\');\r\n		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {\r\n			this.request.addHeader(reqHeaders[header]);\r\n		}\r\n\r\n		if (params[\'http_proxy\']) {\r\n			this.request.setProxy(params[\'http_proxy\']);\r\n			Zabbix.log(4, this.zabbixLogPrefix + \' Using http proxy: \' + params[\'http_proxy\']);\r\n		}\r\n\r\n		if (httpMethod === \'post\') {\r\n			var apiRateLimitExceeded = false;\r\n			do {\r\n				const response = this.request.post(\'https://\' + params[\'api_host\'] + apiPath + apiParams, body);\r\n\r\n				try {\r\n					if (JSON.parse(response)[\'code\'] === \'TooManyRequests\') {\r\n\r\n						apiRateLimitExceeded = true;\r\n						Zabbix.sleep(1000);\r\n					} else {\r\n						apiRateLimitExceeded = false;\r\n					}\r\n				} catch (error) {\r\n					Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the response: \' + JSON.stringify(response));\r\n					throw \'Could not parse the response. See logs for more information.\';\r\n				}\r\n			} while (apiRateLimitExceeded);\r\n		} else {\r\n			const response = this.request.get(\'https://\' + params[\'api_host\'] + apiPath + apiParams);\r\n		}\r\n\r\n		this.request.clearHeader();\r\n\r\n		if (this.request.getStatus() === parseInt(params[\'http_status_code\'])) {\r\n			return response;\r\n		} else {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Unexpected HTTP response code: \' + this.request.getStatus());\r\n			throw \'Unexpected HTTP response code: \' + this.request.getStatus();\r\n		}\r\n	};\r\n\r\n	this.extractData = function (httpMethod, data, keys, compartment) {\r\n		try {\r\n			data = JSON.parse(data);\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the received JSON object: \' + data);\r\n			throw \'Could not parse received JSON object. See logs for more information.\';\r\n		}\r\n\r\n		if (typeof keys == \'object\') {\r\n			var returnBuffer = [];\r\n			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {\r\n\r\n				var objectBuffer = {};\r\n				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {\r\n					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {\r\n						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];\r\n					} else {\r\n						Zabbix.log(3, this.zabbixLogPrefix + \' Received an unexpected JSON object. Could not get value for key "\' + keys[key] + \'" in JSON: \' + JSON.stringify(data[dataObj]));\r\n						throw \'Received an unexpected JSON object. See logs for more information.\';\r\n					}\r\n				}\r\n				if (typeof compartment != \'undefined\' && compartment != \'\') objectBuffer[\'compartment\'] = compartment;\r\n				returnBuffer.push(objectBuffer);\r\n			}\r\n			return returnBuffer;\r\n		}\r\n\r\n		try {\r\n			if (httpMethod === \'get\') {\r\n				return data[keys];\r\n			} else {\r\n				if (data.length === 0) {\r\n					return 0;\r\n				}\r\n				data = data[0][keys];\r\n				return data[data.length - 1][\'value\'];\r\n			}\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not find key "\' + keys + \'" in JSON: \' + JSON.stringify(data));\r\n			throw \'Could not find required key in JSON object. See logs for more information.\';\r\n		}\r\n	};\r\n}\r\n\r\nfunction buildMql(id, metrics, defaultStatistic, resourceType) {\r\n	resourceType = resourceType === \'\' || resourceType === undefined ? \'resourceId\' : resourceType;\r\n	this.query = \'[\' + params[\'req_interval\'] + \'m]{\' + resourceType + \'=\' + id + \'}.\';\r\n\r\n	for (var i = 0, metricsLength = metrics.length; i < metricsLength; i++) {\r\n		const metric = ((Array.isArray(metrics[i]) ? metrics[i] : [metrics[i], defaultStatistic]));\r\n		metrics[i] = [metric[0], this.query + metric[1]];\r\n	}\r\n}\r\n\r\n\r\nconst params = JSON.parse(value);\r\nvalidateZabbixParams([\'tenancy_ocid\', \'user_ocid\', \'private_key\', \'fingerprint\', \'api_host\', \'volume_id\', \'http_status_code\', \'req_interval\', \'compartment_id\'], params);\r\nvar oci = new OCI(\'Block volume\', \'Get metrics\', params);\r\n\r\nconst metrics = [\r\n	\'VolumeReadThroughput\',\r\n	\'VolumeWriteThroughput\',\r\n	\'VolumeReadOps\',\r\n	\'VolumeWriteOps\',\r\n	[\'VolumeThrottledIOs\', \'sum\'],\r\n	\'VolumeGuaranteedVPUsPerGB\',\r\n	\'VolumeGuaranteedIOPS\',\r\n	\'VolumeGuaranteedThroughput\'\r\n];\r\nbuildMql(params[\'volume_id\'], metrics, \'mean\');\r\n\r\nvar result = {};\r\nfor (var i = 0, metricsLength = metrics.length; i < metricsLength; i++) {\r\n	result[metrics[i][0]] = oci.extractData(\'post\', oci.executeRequest(\'post\', \'/20180401/metrics/actions/summarizeMetricsData\', \'?compartmentId=\' + encodeURIComponent(params[\'compartment_id\']), metrics[i][0] + metrics[i][1] + \'()\', \'oci_blockstore\'), \'aggregatedDatapoints\');\r\n}\r\nreturn JSON.stringify(result);','','0','','','','','0',NULL,'Gets block volume metrics.','0','7d','0','',NULL,'30s','','','','200','1','0','','','0','0','0','0','0','0','0','5c1d0fd1686e4c74b33dbe12956d7b7c','0','2','0'),
('46850','21','','10615','State','oci.block.volume.state','1m','31d','365d','0','3','','','','',NULL,'1198','function validateZabbixParams(requiredParams, allParams) {\r\n	requiredParams.forEach(function (field) {\r\n		if (typeof allParams !== \'object\' || typeof allParams[field] === \'undefined\' || allParams[field] === \'\') {\r\n			throw \'Required param is not set: \' + field + \'.\';\r\n		}\r\n	});\r\n}\r\n\r\nfunction OCI(service, action, params) {\r\n	this.zabbixLogPrefix = \'[ OCI ] [ \' + service + \' ] [ \' + action + \' ]\';\r\n	this.request = new HttpRequest();\r\n\r\n	this.hash = function (string) {\r\n		return sha256(string);\r\n	};\r\n\r\n	this.sign = function (string) {\r\n		return sign(\'sha256\', params[\'private_key\'], string);\r\n	};\r\n\r\n	this.encode = function (hash) {\r\n		const hexArr = hash.match(/.{1,2}/g);\r\n		var uInt8Array = new Uint8Array(hexArr.length);\r\n		hexArr.forEach(function (hex, idx) {\r\n			uInt8Array[idx] = parseInt(hex, 16);\r\n		});\r\n		return btoa(uInt8Array);\r\n	};\r\n\r\n	this.getDate = function () {\r\n		const weekdayShortList = [\'Sun\', \'Mon\', \'Tue\', \'Wed\', \'Thu\', \'Fri\', \'Sat\'];\r\n		const monthShortList = [\'jan\', \'feb\', \'mar\', \'apr\', \'may\', \'jun\', \'jul\', \'aug\', \'sep\', \'oct\', \'nov\', \'dec\'];\r\n		const today = new Date();\r\n		return weekdayShortList[today.getUTCDay()] + \', \' + today.getUTCDate() + \' \' + monthShortList[today.getUTCMonth()] + \' \' + today.getUTCFullYear() + \' \' + today.getUTCHours() + \':\' + today.getUTCMinutes() + \':\' + today.getUTCSeconds() + \' GMT\';\r\n	};\r\n\r\n	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {\r\n		var headers = \'(request-target) date host\';\r\n		const contentTypeHeader = \'content-type: application/json\';\r\n		const dateHeader = \'date: \' + this.getDate();\r\n		const hostHeader = \'host: \' + params[\'api_host\'];\r\n		const requestTarget = \'(request-target): \' + httpMethod + \' \' + apiPath + apiParams;\r\n		var signingString = requestTarget + \'\\n\' + dateHeader + \'\\n\' + hostHeader;\r\n		var reqHeaders = [contentTypeHeader, dateHeader];\r\n\r\n		if (httpMethod === \'post\') {\r\n			var body = JSON.stringify({\r\n				\'namespace\': namespace,\r\n				\'query\': mql\r\n			});\r\n			headers = headers + \' x-content-sha256 content-type content-length\';\r\n			const bodyHeader = \'x-content-sha256: \' + this.encode(this.hash(body));\r\n			const bodyLengthHeader = \'content-length: \' + body.length;\r\n			signingString = signingString + \'\\n\' + bodyHeader + \'\\n\' + contentTypeHeader + \'\\n\' + bodyLengthHeader;\r\n			reqHeaders.push(bodyHeader, bodyLengthHeader);\r\n		}\r\n\r\n		const signature = this.encode(this.sign(signingString));\r\n\r\n		reqHeaders.push(\'Authorization: Signature version="1",keyId="\' + params[\'tenancy_ocid\'] + \'/\' + params[\'user_ocid\'] + \'/\' + params[\'fingerprint\'] + \'",algorithm="rsa-sha256",headers="\' + headers + \'",signature="\' + signature + \'"\');\r\n		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {\r\n			this.request.addHeader(reqHeaders[header]);\r\n		}\r\n\r\n		if (params[\'http_proxy\']) {\r\n			this.request.setProxy(params[\'http_proxy\']);\r\n			Zabbix.log(4, this.zabbixLogPrefix + \' Using http proxy: \' + params[\'http_proxy\']);\r\n		}\r\n\r\n		if (httpMethod === \'post\') {\r\n			var apiRateLimitExceeded = false;\r\n			do {\r\n				const response = this.request.post(\'https://\' + params[\'api_host\'] + apiPath + apiParams, body);\r\n\r\n				try {\r\n					if (JSON.parse(response)[\'code\'] === \'TooManyRequests\') {\r\n\r\n						apiRateLimitExceeded = true;\r\n						Zabbix.sleep(1000);\r\n					} else {\r\n						apiRateLimitExceeded = false;\r\n					}\r\n				} catch (error) {\r\n					Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the response: \' + JSON.stringify(response));\r\n					throw \'Could not parse the response. See logs for more information.\';\r\n				}\r\n			} while (apiRateLimitExceeded);\r\n		} else {\r\n			const response = this.request.get(\'https://\' + params[\'api_host\'] + apiPath + apiParams);\r\n		}\r\n\r\n		this.request.clearHeader();\r\n\r\n		if (this.request.getStatus() === parseInt(params[\'http_status_code\'])) {\r\n			return response;\r\n		} else {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Unexpected HTTP response code: \' + this.request.getStatus());\r\n			throw \'Unexpected HTTP response code: \' + this.request.getStatus();\r\n		}\r\n	};\r\n\r\n	this.extractData = function (httpMethod, data, keys, compartment) {\r\n		try {\r\n			data = JSON.parse(data);\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the received JSON object: \' + data);\r\n			throw \'Could not parse received JSON object. See logs for more information.\';\r\n		}\r\n\r\n		if (typeof keys == \'object\') {\r\n			var returnBuffer = [];\r\n			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {\r\n\r\n				var objectBuffer = {};\r\n				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {\r\n					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {\r\n						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];\r\n					} else {\r\n						Zabbix.log(3, this.zabbixLogPrefix + \' Received an unexpected JSON object. Could not get value for key "\' + keys[key] + \'" in JSON: \' + JSON.stringify(data[dataObj]));\r\n						throw \'Received an unexpected JSON object. See logs for more information.\';\r\n					}\r\n				}\r\n				if (typeof compartment != \'undefined\' && compartment != \'\') objectBuffer[\'compartment\'] = compartment;\r\n				returnBuffer.push(objectBuffer);\r\n			}\r\n			return returnBuffer;\r\n		}\r\n\r\n		try {\r\n			if (httpMethod === \'get\') {\r\n				return data[keys];\r\n			} else {\r\n				if (data.length === 0) {\r\n					return 0;\r\n				}\r\n				data = data[0][keys];\r\n				return data[data.length - 1][\'value\'];\r\n			}\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not find key "\' + keys + \'" in JSON: \' + JSON.stringify(data));\r\n			throw \'Could not find required key in JSON object. See logs for more information.\';\r\n		}\r\n	};\r\n}\r\n\r\n\r\nconst params = JSON.parse(value);\r\nvalidateZabbixParams([\'tenancy_ocid\', \'user_ocid\', \'private_key\', \'fingerprint\', \'api_host\', \'volume_id\', \'http_status_code\'], params);\r\nvar oci = new OCI(\'Block volume\', \'Get volume state\', params);\r\n\r\nreturn oci.extractData(\'get\', oci.executeRequest(\'get\', \'/20160918/volumes/\' + encodeURIComponent(params[\'volume_id\']), \'\'), \'lifecycleState\');','','0','','','','','0',NULL,'Gets the block volume state.','0','7d','0','',NULL,'10s','','','','200','1','0','','','0','0','0','0','0','0','0','4fdab3067ada41219c8208862e7c8b14','0','2','0'),
('46851','21','','10616','Get metrics','oci.boot.volume.metrics.get','1m','0','0','0','4','','','','',NULL,NULL,'function validateZabbixParams(requiredParams, allParams) {\r\n	requiredParams.forEach(function (field) {\r\n		if (typeof allParams !== \'object\' || typeof allParams[field] === \'undefined\' || allParams[field] === \'\') {\r\n			throw \'Required param is not set: \' + field + \'.\';\r\n		}\r\n	});\r\n}\r\n\r\nfunction OCI(service, action, params) {\r\n	this.zabbixLogPrefix = \'[ OCI ] [ \' + service + \' ] [ \' + action + \' ]\';\r\n	this.request = new HttpRequest();\r\n\r\n	this.hash = function (string) {\r\n		return sha256(string);\r\n	};\r\n\r\n	this.sign = function (string) {\r\n		return sign(\'sha256\', params[\'private_key\'], string);\r\n	};\r\n\r\n	this.encode = function (hash) {\r\n		const hexArr = hash.match(/.{1,2}/g);\r\n		var uInt8Array = new Uint8Array(hexArr.length);\r\n		hexArr.forEach(function (hex, idx) {\r\n			uInt8Array[idx] = parseInt(hex, 16);\r\n		});\r\n		return btoa(uInt8Array);\r\n	};\r\n\r\n	this.getDate = function () {\r\n		const weekdayShortList = [\'Sun\', \'Mon\', \'Tue\', \'Wed\', \'Thu\', \'Fri\', \'Sat\'];\r\n		const monthShortList = [\'jan\', \'feb\', \'mar\', \'apr\', \'may\', \'jun\', \'jul\', \'aug\', \'sep\', \'oct\', \'nov\', \'dec\'];\r\n		const today = new Date();\r\n		return weekdayShortList[today.getUTCDay()] + \', \' + today.getUTCDate() + \' \' + monthShortList[today.getUTCMonth()] + \' \' + today.getUTCFullYear() + \' \' + today.getUTCHours() + \':\' + today.getUTCMinutes() + \':\' + today.getUTCSeconds() + \' GMT\';\r\n	};\r\n\r\n	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {\r\n		var headers = \'(request-target) date host\';\r\n		const contentTypeHeader = \'content-type: application/json\';\r\n		const dateHeader = \'date: \' + this.getDate();\r\n		const hostHeader = \'host: \' + params[\'api_host\'];\r\n		const requestTarget = \'(request-target): \' + httpMethod + \' \' + apiPath + apiParams;\r\n		var signingString = requestTarget + \'\\n\' + dateHeader + \'\\n\' + hostHeader;\r\n		var reqHeaders = [contentTypeHeader, dateHeader];\r\n\r\n		if (httpMethod === \'post\') {\r\n			var body = JSON.stringify({\r\n				\'namespace\': namespace,\r\n				\'query\': mql\r\n			});\r\n			headers = headers + \' x-content-sha256 content-type content-length\';\r\n			const bodyHeader = \'x-content-sha256: \' + this.encode(this.hash(body));\r\n			const bodyLengthHeader = \'content-length: \' + body.length;\r\n			signingString = signingString + \'\\n\' + bodyHeader + \'\\n\' + contentTypeHeader + \'\\n\' + bodyLengthHeader;\r\n			reqHeaders.push(bodyHeader, bodyLengthHeader);\r\n		}\r\n\r\n		const signature = this.encode(this.sign(signingString));\r\n\r\n		reqHeaders.push(\'Authorization: Signature version="1",keyId="\' + params[\'tenancy_ocid\'] + \'/\' + params[\'user_ocid\'] + \'/\' + params[\'fingerprint\'] + \'",algorithm="rsa-sha256",headers="\' + headers + \'",signature="\' + signature + \'"\');\r\n		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {\r\n			this.request.addHeader(reqHeaders[header]);\r\n		}\r\n\r\n		if (params[\'http_proxy\']) {\r\n			this.request.setProxy(params[\'http_proxy\']);\r\n			Zabbix.log(4, this.zabbixLogPrefix + \' Using http proxy: \' + params[\'http_proxy\']);\r\n		}\r\n\r\n		if (httpMethod === \'post\') {\r\n			var apiRateLimitExceeded = false;\r\n			do {\r\n				const response = this.request.post(\'https://\' + params[\'api_host\'] + apiPath + apiParams, body);\r\n\r\n				try {\r\n					if (JSON.parse(response)[\'code\'] === \'TooManyRequests\') {\r\n\r\n						apiRateLimitExceeded = true;\r\n						Zabbix.sleep(1000);\r\n					} else {\r\n						apiRateLimitExceeded = false;\r\n					}\r\n				} catch (error) {\r\n					Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the response: \' + JSON.stringify(response));\r\n					throw \'Could not parse the response. See logs for more information.\';\r\n				}\r\n			} while (apiRateLimitExceeded);\r\n		} else {\r\n			const response = this.request.get(\'https://\' + params[\'api_host\'] + apiPath + apiParams);\r\n		}\r\n\r\n		this.request.clearHeader();\r\n\r\n		if (this.request.getStatus() === parseInt(params[\'http_status_code\'])) {\r\n			return response;\r\n		} else {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Unexpected HTTP response code: \' + this.request.getStatus());\r\n			throw \'Unexpected HTTP response code: \' + this.request.getStatus();\r\n		}\r\n	};\r\n\r\n	this.extractData = function (httpMethod, data, keys, compartment) {\r\n		try {\r\n			data = JSON.parse(data);\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the received JSON object: \' + data);\r\n			throw \'Could not parse received JSON object. See logs for more information.\';\r\n		}\r\n\r\n		if (typeof keys == \'object\') {\r\n			var returnBuffer = [];\r\n			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {\r\n\r\n				var objectBuffer = {};\r\n				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {\r\n					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {\r\n						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];\r\n					} else {\r\n						Zabbix.log(3, this.zabbixLogPrefix + \' Received an unexpected JSON object. Could not get value for key "\' + keys[key] + \'" in JSON: \' + JSON.stringify(data[dataObj]));\r\n						throw \'Received an unexpected JSON object. See logs for more information.\';\r\n					}\r\n				}\r\n				if (typeof compartment != \'undefined\' && compartment != \'\') objectBuffer[\'compartment\'] = compartment;\r\n				returnBuffer.push(objectBuffer);\r\n			}\r\n			return returnBuffer;\r\n		}\r\n\r\n		try {\r\n			if (httpMethod === \'get\') {\r\n				return data[keys];\r\n			} else {\r\n				if (data.length === 0) {\r\n					return 0;\r\n				}\r\n				data = data[0][keys];\r\n				return data[data.length - 1][\'value\'];\r\n			}\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not find key "\' + keys + \'" in JSON: \' + JSON.stringify(data));\r\n			throw \'Could not find required key in JSON object. See logs for more information.\';\r\n		}\r\n	};\r\n}\r\n\r\nfunction buildMql(id, metrics, defaultStatistic, resourceType) {\r\n	resourceType = resourceType === \'\' || resourceType === undefined ? \'resourceId\' : resourceType;\r\n	this.query = \'[\' + params[\'req_interval\'] + \'m]{\' + resourceType + \'=\' + id + \'}.\';\r\n\r\n	for (var i = 0, metricsLength = metrics.length; i < metricsLength; i++) {\r\n		const metric = ((Array.isArray(metrics[i]) ? metrics[i] : [metrics[i], defaultStatistic]));\r\n		metrics[i] = [metric[0], this.query + metric[1]];\r\n	}\r\n}\r\n\r\n\r\nconst params = JSON.parse(value);\r\nvalidateZabbixParams([\'tenancy_ocid\', \'user_ocid\', \'private_key\', \'fingerprint\', \'api_host\', \'volume_id\', \'http_status_code\', \'req_interval\', \'compartment_id\'], params);\r\nvar oci = new OCI(\'Boot volume\', \'Get metrics\', params);\r\n\r\nconst metrics = [\r\n	\'VolumeReadThroughput\',\r\n	\'VolumeWriteThroughput\',\r\n	\'VolumeReadOps\',\r\n	\'VolumeWriteOps\',\r\n	[\'VolumeThrottledIOs\', \'sum\'],\r\n	\'VolumeGuaranteedVPUsPerGB\',\r\n	\'VolumeGuaranteedIOPS\',\r\n	\'VolumeGuaranteedThroughput\'\r\n];\r\nbuildMql(params[\'volume_id\'], metrics, \'mean\');\r\n\r\nvar result = {};\r\nfor (var i = 0, metricsLength = metrics.length; i < metricsLength; i++) {\r\n	result[metrics[i][0]] = oci.extractData(\'post\', oci.executeRequest(\'post\', \'/20180401/metrics/actions/summarizeMetricsData\', \'?compartmentId=\' + encodeURIComponent(params[\'compartment_id\']), metrics[i][0] + metrics[i][1] + \'()\', \'oci_blockstore\'), \'aggregatedDatapoints\');\r\n}\r\nreturn JSON.stringify(result);','','0','','','','','0',NULL,'Gets boot volume metrics.','0','7d','0','',NULL,'30s','','','','200','1','0','','','0','0','0','0','0','0','0','388e89b8e68149438d714237e785ccde','0','2','0'),
('46852','21','','10616','State','oci.boot.volume.state','1m','31d','365d','0','3','','','','',NULL,'1199','function validateZabbixParams(requiredParams, allParams) {\r\n	requiredParams.forEach(function (field) {\r\n		if (typeof allParams !== \'object\' || typeof allParams[field] === \'undefined\' || allParams[field] === \'\') {\r\n			throw \'Required param is not set: \' + field + \'.\';\r\n		}\r\n	});\r\n}\r\n\r\nfunction OCI(service, action, params) {\r\n	this.zabbixLogPrefix = \'[ OCI ] [ \' + service + \' ] [ \' + action + \' ]\';\r\n	this.request = new HttpRequest();\r\n\r\n	this.hash = function (string) {\r\n		return sha256(string);\r\n	};\r\n\r\n	this.sign = function (string) {\r\n		return sign(\'sha256\', params[\'private_key\'], string);\r\n	};\r\n\r\n	this.encode = function (hash) {\r\n		const hexArr = hash.match(/.{1,2}/g);\r\n		var uInt8Array = new Uint8Array(hexArr.length);\r\n		hexArr.forEach(function (hex, idx) {\r\n			uInt8Array[idx] = parseInt(hex, 16);\r\n		});\r\n		return btoa(uInt8Array);\r\n	};\r\n\r\n	this.getDate = function () {\r\n		const weekdayShortList = [\'Sun\', \'Mon\', \'Tue\', \'Wed\', \'Thu\', \'Fri\', \'Sat\'];\r\n		const monthShortList = [\'jan\', \'feb\', \'mar\', \'apr\', \'may\', \'jun\', \'jul\', \'aug\', \'sep\', \'oct\', \'nov\', \'dec\'];\r\n		const today = new Date();\r\n		return weekdayShortList[today.getUTCDay()] + \', \' + today.getUTCDate() + \' \' + monthShortList[today.getUTCMonth()] + \' \' + today.getUTCFullYear() + \' \' + today.getUTCHours() + \':\' + today.getUTCMinutes() + \':\' + today.getUTCSeconds() + \' GMT\';\r\n	};\r\n\r\n	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {\r\n		var headers = \'(request-target) date host\';\r\n		const contentTypeHeader = \'content-type: application/json\';\r\n		const dateHeader = \'date: \' + this.getDate();\r\n		const hostHeader = \'host: \' + params[\'api_host\'];\r\n		const requestTarget = \'(request-target): \' + httpMethod + \' \' + apiPath + apiParams;\r\n		var signingString = requestTarget + \'\\n\' + dateHeader + \'\\n\' + hostHeader;\r\n		var reqHeaders = [contentTypeHeader, dateHeader];\r\n\r\n		if (httpMethod === \'post\') {\r\n			var body = JSON.stringify({\r\n				\'namespace\': namespace,\r\n				\'query\': mql\r\n			});\r\n			headers = headers + \' x-content-sha256 content-type content-length\';\r\n			const bodyHeader = \'x-content-sha256: \' + this.encode(this.hash(body));\r\n			const bodyLengthHeader = \'content-length: \' + body.length;\r\n			signingString = signingString + \'\\n\' + bodyHeader + \'\\n\' + contentTypeHeader + \'\\n\' + bodyLengthHeader;\r\n			reqHeaders.push(bodyHeader, bodyLengthHeader);\r\n		}\r\n\r\n		const signature = this.encode(this.sign(signingString));\r\n\r\n		reqHeaders.push(\'Authorization: Signature version="1",keyId="\' + params[\'tenancy_ocid\'] + \'/\' + params[\'user_ocid\'] + \'/\' + params[\'fingerprint\'] + \'",algorithm="rsa-sha256",headers="\' + headers + \'",signature="\' + signature + \'"\');\r\n		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {\r\n			this.request.addHeader(reqHeaders[header]);\r\n		}\r\n\r\n		if (params[\'http_proxy\']) {\r\n			this.request.setProxy(params[\'http_proxy\']);\r\n			Zabbix.log(4, this.zabbixLogPrefix + \' Using http proxy: \' + params[\'http_proxy\']);\r\n		}\r\n\r\n		if (httpMethod === \'post\') {\r\n			var apiRateLimitExceeded = false;\r\n			do {\r\n				const response = this.request.post(\'https://\' + params[\'api_host\'] + apiPath + apiParams, body);\r\n\r\n				try {\r\n					if (JSON.parse(response)[\'code\'] === \'TooManyRequests\') {\r\n\r\n						apiRateLimitExceeded = true;\r\n						Zabbix.sleep(1000);\r\n					} else {\r\n						apiRateLimitExceeded = false;\r\n					}\r\n				} catch (error) {\r\n					Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the response: \' + JSON.stringify(response));\r\n					throw \'Could not parse the response. See logs for more information.\';\r\n				}\r\n			} while (apiRateLimitExceeded);\r\n		} else {\r\n			const response = this.request.get(\'https://\' + params[\'api_host\'] + apiPath + apiParams);\r\n		}\r\n\r\n		this.request.clearHeader();\r\n\r\n		if (this.request.getStatus() === parseInt(params[\'http_status_code\'])) {\r\n			return response;\r\n		} else {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Unexpected HTTP response code: \' + this.request.getStatus());\r\n			throw \'Unexpected HTTP response code: \' + this.request.getStatus();\r\n		}\r\n	};\r\n\r\n	this.extractData = function (httpMethod, data, keys, compartment) {\r\n		try {\r\n			data = JSON.parse(data);\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the received JSON object: \' + data);\r\n			throw \'Could not parse received JSON object. See logs for more information.\';\r\n		}\r\n\r\n		if (typeof keys == \'object\') {\r\n			var returnBuffer = [];\r\n			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {\r\n\r\n				var objectBuffer = {};\r\n				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {\r\n					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {\r\n						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];\r\n					} else {\r\n						Zabbix.log(3, this.zabbixLogPrefix + \' Received an unexpected JSON object. Could not get value for key "\' + keys[key] + \'" in JSON: \' + JSON.stringify(data[dataObj]));\r\n						throw \'Received an unexpected JSON object. See logs for more information.\';\r\n					}\r\n				}\r\n				if (typeof compartment != \'undefined\' && compartment != \'\') objectBuffer[\'compartment\'] = compartment;\r\n				returnBuffer.push(objectBuffer);\r\n			}\r\n			return returnBuffer;\r\n		}\r\n\r\n		try {\r\n			if (httpMethod === \'get\') {\r\n				return data[keys];\r\n			} else {\r\n				if (data.length === 0) {\r\n					return 0;\r\n				}\r\n				data = data[0][keys];\r\n				return data[data.length - 1][\'value\'];\r\n			}\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not find key "\' + keys + \'" in JSON: \' + JSON.stringify(data));\r\n			throw \'Could not find required key in JSON object. See logs for more information.\';\r\n		}\r\n	};\r\n}\r\n\r\n\r\nconst params = JSON.parse(value);\r\nvalidateZabbixParams([\'tenancy_ocid\', \'user_ocid\', \'private_key\', \'fingerprint\', \'api_host\', \'volume_id\', \'http_status_code\'], params);\r\nvar oci = new OCI(\'Boot volume\', \'Get volume state\', params);\r\n\r\nreturn oci.extractData(\'get\', oci.executeRequest(\'get\', \'/20160918/bootVolumes/\' + encodeURIComponent(params[\'volume_id\']), \'\'), \'lifecycleState\');','','0','','','','','0',NULL,'Gets the boot volume state.','0','7d','0','',NULL,'10s','','','','200','1','0','','','0','0','0','0','0','0','0','3f0e4bed1fd14293b40b23595f01ebb1','0','2','0'),
('46853','21','','10618','Get instance availability','oci.compute.availability.get','5m','31d','365d','0','3','','','','',NULL,'1200','function validateZabbixParams(requiredParams, allParams) {\r\n	requiredParams.forEach(function (field) {\r\n		if (typeof allParams !== \'object\' || typeof allParams[field] === \'undefined\' || allParams[field] === \'\') {\r\n			throw \'Required param is not set: \' + field + \'.\';\r\n		}\r\n	});\r\n}\r\n\r\nfunction OCI(service, action, params) {\r\n	this.zabbixLogPrefix = \'[ OCI ] [ \' + service + \' ] [ \' + action + \' ]\';\r\n	this.request = new HttpRequest();\r\n\r\n	this.hash = function (string) {\r\n		return sha256(string);\r\n	};\r\n\r\n	this.sign = function (string) {\r\n		return sign(\'sha256\', params[\'private_key\'], string);\r\n	};\r\n\r\n	this.encode = function (hash) {\r\n		const hexArr = hash.match(/.{1,2}/g);\r\n		var uInt8Array = new Uint8Array(hexArr.length);\r\n		hexArr.forEach(function (hex, idx) {\r\n			uInt8Array[idx] = parseInt(hex, 16);\r\n		});\r\n		return btoa(uInt8Array);\r\n	};\r\n\r\n	this.getDate = function () {\r\n		const weekdayShortList = [\'Sun\', \'Mon\', \'Tue\', \'Wed\', \'Thu\', \'Fri\', \'Sat\'];\r\n		const monthShortList = [\'jan\', \'feb\', \'mar\', \'apr\', \'may\', \'jun\', \'jul\', \'aug\', \'sep\', \'oct\', \'nov\', \'dec\'];\r\n		const today = new Date();\r\n		return weekdayShortList[today.getUTCDay()] + \', \' + today.getUTCDate() + \' \' + monthShortList[today.getUTCMonth()] + \' \' + today.getUTCFullYear() + \' \' + today.getUTCHours() + \':\' + today.getUTCMinutes() + \':\' + today.getUTCSeconds() + \' GMT\';\r\n	};\r\n\r\n	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {\r\n		var headers = \'(request-target) date host\';\r\n		const contentTypeHeader = \'content-type: application/json\';\r\n		const dateHeader = \'date: \' + this.getDate();\r\n		const hostHeader = \'host: \' + params[\'api_host\'];\r\n		const requestTarget = \'(request-target): \' + httpMethod + \' \' + apiPath + apiParams;\r\n		var signingString = requestTarget + \'\\n\' + dateHeader + \'\\n\' + hostHeader;\r\n		var reqHeaders = [contentTypeHeader, dateHeader];\r\n\r\n		if (httpMethod === \'post\') {\r\n			var body = JSON.stringify({\r\n				\'namespace\': namespace,\r\n				\'query\': mql\r\n			});\r\n			headers = headers + \' x-content-sha256 content-type content-length\';\r\n			const bodyHeader = \'x-content-sha256: \' + this.encode(this.hash(body));\r\n			const bodyLengthHeader = \'content-length: \' + body.length;\r\n			signingString = signingString + \'\\n\' + bodyHeader + \'\\n\' + contentTypeHeader + \'\\n\' + bodyLengthHeader;\r\n			reqHeaders.push(bodyHeader, bodyLengthHeader);\r\n		}\r\n\r\n		const signature = this.encode(this.sign(signingString));\r\n\r\n		reqHeaders.push(\'Authorization: Signature version="1",keyId="\' + params[\'tenancy_ocid\'] + \'/\' + params[\'user_ocid\'] + \'/\' + params[\'fingerprint\'] + \'",algorithm="rsa-sha256",headers="\' + headers + \'",signature="\' + signature + \'"\');\r\n		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {\r\n			this.request.addHeader(reqHeaders[header]);\r\n		}\r\n\r\n		if (params[\'http_proxy\']) {\r\n			this.request.setProxy(params[\'http_proxy\']);\r\n			Zabbix.log(4, this.zabbixLogPrefix + \' Using http proxy: \' + params[\'http_proxy\']);\r\n		}\r\n\r\n		if (httpMethod === \'post\') {\r\n			var apiRateLimitExceeded = false;\r\n			do {\r\n				const response = this.request.post(\'https://\' + params[\'api_host\'] + apiPath + apiParams, body);\r\n\r\n				try {\r\n					if (JSON.parse(response)[\'code\'] === \'TooManyRequests\') {\r\n\r\n						apiRateLimitExceeded = true;\r\n						Zabbix.sleep(1000);\r\n					} else {\r\n						apiRateLimitExceeded = false;\r\n					}\r\n				} catch (error) {\r\n					Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the response: \' + JSON.stringify(response));\r\n					throw \'Could not parse the response. See logs for more information.\';\r\n				}\r\n			} while (apiRateLimitExceeded);\r\n		} else {\r\n			const response = this.request.get(\'https://\' + params[\'api_host\'] + apiPath + apiParams);\r\n		}\r\n\r\n		this.request.clearHeader();\r\n\r\n		if (this.request.getStatus() === parseInt(params[\'http_status_code\'])) {\r\n			return response;\r\n		} else {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Unexpected HTTP response code: \' + this.request.getStatus());\r\n			throw \'Unexpected HTTP response code: \' + this.request.getStatus();\r\n		}\r\n	};\r\n\r\n	this.extractData = function (httpMethod, data, keys, compartment) {\r\n		try {\r\n			data = JSON.parse(data);\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the received JSON object: \' + data);\r\n			throw \'Could not parse received JSON object. See logs for more information.\';\r\n		}\r\n\r\n		if (typeof keys == \'object\') {\r\n			var returnBuffer = [];\r\n			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {\r\n\r\n				var objectBuffer = {};\r\n				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {\r\n					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {\r\n						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];\r\n					} else {\r\n						Zabbix.log(3, this.zabbixLogPrefix + \' Received an unexpected JSON object. Could not get value for key "\' + keys[key] + \'" in JSON: \' + JSON.stringify(data[dataObj]));\r\n						throw \'Received an unexpected JSON object. See logs for more information.\';\r\n					}\r\n				}\r\n				if (typeof compartment != \'undefined\' && compartment != \'\') objectBuffer[\'compartment\'] = compartment;\r\n				returnBuffer.push(objectBuffer);\r\n			}\r\n			return returnBuffer;\r\n		}\r\n\r\n		try {\r\n			if (httpMethod === \'get\') {\r\n				return data[keys];\r\n			} else {\r\n				if (data.length === 0) {\r\n					return 0;\r\n				}\r\n				data = data[0][keys];\r\n				return data[data.length - 1][\'value\'];\r\n			}\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not find key "\' + keys + \'" in JSON: \' + JSON.stringify(data));\r\n			throw \'Could not find required key in JSON object. See logs for more information.\';\r\n		}\r\n	};\r\n}\r\n\r\n\r\nconst params = JSON.parse(value);\r\nvalidateZabbixParams([\'tenancy_ocid\', \'user_ocid\', \'private_key\', \'fingerprint\', \'api_host\', \'instance_id\', \'http_status_code\', \'req_interval\', \'compartment_id\'], params);\r\nvar oci = new OCI(\'Compute\', \'Get health\', params);\r\nconst mql = \'InstanceAccessibilityStatus[\' + params[\'req_interval\'] + \'m]{resourceId=\' + params[\'instance_id\'] + \'}.max()\';\r\n\r\nreturn JSON.stringify(oci.extractData(\'post\', oci.executeRequest(\'post\', \'/20180401/metrics/actions/summarizeMetricsData\', \'?compartmentId=\' + encodeURIComponent(params[\'compartment_id\']), mql, \'oci_compute_instance_health\'), \'aggregatedDatapoints\'));','','0','','','','','0',NULL,'The accessibility status of a virtual machine instance.\r\nA value of "1" indicates that the instance is unresponsive due to an issue with\r\nthe infrastructure or the instance itself.\r\nA value of "0" indicates that an accessibility issue has not been detected.\r\nIf the instance is stopped, then the metric does not have a value.','0','7d','0','',NULL,'10s','','','','200','1','0','','','0','0','0','0','0','0','0','657ad1d54de4454696573418f5f17f11','0','2','0'),
('46854','21','','10618','Get compute metrics','oci.compute.metrics.get','1m','0','0','0','4','','','','',NULL,NULL,'function validateZabbixParams(requiredParams, allParams) {\r\n	requiredParams.forEach(function (field) {\r\n		if (typeof allParams !== \'object\' || typeof allParams[field] === \'undefined\' || allParams[field] === \'\') {\r\n			throw \'Required param is not set: \' + field + \'.\';\r\n		}\r\n	});\r\n}\r\n\r\nfunction OCI(service, action, params) {\r\n	this.zabbixLogPrefix = \'[ OCI ] [ \' + service + \' ] [ \' + action + \' ]\';\r\n	this.request = new HttpRequest();\r\n\r\n	this.hash = function (string) {\r\n		return sha256(string);\r\n	};\r\n\r\n	this.sign = function (string) {\r\n		return sign(\'sha256\', params[\'private_key\'], string);\r\n	};\r\n\r\n	this.encode = function (hash) {\r\n		const hexArr = hash.match(/.{1,2}/g);\r\n		var uInt8Array = new Uint8Array(hexArr.length);\r\n		hexArr.forEach(function (hex, idx) {\r\n			uInt8Array[idx] = parseInt(hex, 16);\r\n		});\r\n		return btoa(uInt8Array);\r\n	};\r\n\r\n	this.getDate = function () {\r\n		const weekdayShortList = [\'Sun\', \'Mon\', \'Tue\', \'Wed\', \'Thu\', \'Fri\', \'Sat\'];\r\n		const monthShortList = [\'jan\', \'feb\', \'mar\', \'apr\', \'may\', \'jun\', \'jul\', \'aug\', \'sep\', \'oct\', \'nov\', \'dec\'];\r\n		const today = new Date();\r\n		return weekdayShortList[today.getUTCDay()] + \', \' + today.getUTCDate() + \' \' + monthShortList[today.getUTCMonth()] + \' \' + today.getUTCFullYear() + \' \' + today.getUTCHours() + \':\' + today.getUTCMinutes() + \':\' + today.getUTCSeconds() + \' GMT\';\r\n	};\r\n\r\n	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {\r\n		var headers = \'(request-target) date host\';\r\n		const contentTypeHeader = \'content-type: application/json\';\r\n		const dateHeader = \'date: \' + this.getDate();\r\n		const hostHeader = \'host: \' + params[\'api_host\'];\r\n		const requestTarget = \'(request-target): \' + httpMethod + \' \' + apiPath + apiParams;\r\n		var signingString = requestTarget + \'\\n\' + dateHeader + \'\\n\' + hostHeader;\r\n		var reqHeaders = [contentTypeHeader, dateHeader];\r\n\r\n		if (httpMethod === \'post\') {\r\n			var body = JSON.stringify({\r\n				\'namespace\': namespace,\r\n				\'query\': mql\r\n			});\r\n			headers = headers + \' x-content-sha256 content-type content-length\';\r\n			const bodyHeader = \'x-content-sha256: \' + this.encode(this.hash(body));\r\n			const bodyLengthHeader = \'content-length: \' + body.length;\r\n			signingString = signingString + \'\\n\' + bodyHeader + \'\\n\' + contentTypeHeader + \'\\n\' + bodyLengthHeader;\r\n			reqHeaders.push(bodyHeader, bodyLengthHeader);\r\n		}\r\n\r\n		const signature = this.encode(this.sign(signingString));\r\n\r\n		reqHeaders.push(\'Authorization: Signature version="1",keyId="\' + params[\'tenancy_ocid\'] + \'/\' + params[\'user_ocid\'] + \'/\' + params[\'fingerprint\'] + \'",algorithm="rsa-sha256",headers="\' + headers + \'",signature="\' + signature + \'"\');\r\n		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {\r\n			this.request.addHeader(reqHeaders[header]);\r\n		}\r\n\r\n		if (params[\'http_proxy\']) {\r\n			this.request.setProxy(params[\'http_proxy\']);\r\n			Zabbix.log(4, this.zabbixLogPrefix + \' Using http proxy: \' + params[\'http_proxy\']);\r\n		}\r\n\r\n		if (httpMethod === \'post\') {\r\n			var apiRateLimitExceeded = false;\r\n			do {\r\n				const response = this.request.post(\'https://\' + params[\'api_host\'] + apiPath + apiParams, body);\r\n\r\n				try {\r\n					if (JSON.parse(response)[\'code\'] === \'TooManyRequests\') {\r\n\r\n						apiRateLimitExceeded = true;\r\n						Zabbix.sleep(1000);\r\n					} else {\r\n						apiRateLimitExceeded = false;\r\n					}\r\n				} catch (error) {\r\n					Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the response: \' + JSON.stringify(response));\r\n					throw \'Could not parse the response. See logs for more information.\';\r\n				}\r\n			} while (apiRateLimitExceeded);\r\n		} else {\r\n			const response = this.request.get(\'https://\' + params[\'api_host\'] + apiPath + apiParams);\r\n		}\r\n\r\n		this.request.clearHeader();\r\n\r\n		if (this.request.getStatus() === parseInt(params[\'http_status_code\'])) {\r\n			return response;\r\n		} else {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Unexpected HTTP response code: \' + this.request.getStatus());\r\n			throw \'Unexpected HTTP response code: \' + this.request.getStatus();\r\n		}\r\n	};\r\n\r\n	this.extractData = function (httpMethod, data, keys, compartment) {\r\n		try {\r\n			data = JSON.parse(data);\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the received JSON object: \' + data);\r\n			throw \'Could not parse received JSON object. See logs for more information.\';\r\n		}\r\n\r\n		if (typeof keys == \'object\') {\r\n			var returnBuffer = [];\r\n			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {\r\n\r\n				var objectBuffer = {};\r\n				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {\r\n					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {\r\n						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];\r\n					} else {\r\n						Zabbix.log(3, this.zabbixLogPrefix + \' Received an unexpected JSON object. Could not get value for key "\' + keys[key] + \'" in JSON: \' + JSON.stringify(data[dataObj]));\r\n						throw \'Received an unexpected JSON object. See logs for more information.\';\r\n					}\r\n				}\r\n				if (typeof compartment != \'undefined\' && compartment != \'\') objectBuffer[\'compartment\'] = compartment;\r\n				returnBuffer.push(objectBuffer);\r\n			}\r\n			return returnBuffer;\r\n		}\r\n\r\n		try {\r\n			if (httpMethod === \'get\') {\r\n				return data[keys];\r\n			} else {\r\n				if (data.length === 0) {\r\n					return 0;\r\n				}\r\n				data = data[0][keys];\r\n				return data[data.length - 1][\'value\'];\r\n			}\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not find key "\' + keys + \'" in JSON: \' + JSON.stringify(data));\r\n			throw \'Could not find required key in JSON object. See logs for more information.\';\r\n		}\r\n	};\r\n}\r\n\r\nfunction buildMql(id, metrics, defaultStatistic, resourceType) {\r\n	resourceType = resourceType === \'\' || resourceType === undefined ? \'resourceId\' : resourceType;\r\n	this.query = \'[\' + params[\'req_interval\'] + \'m]{\' + resourceType + \'=\' + id + \'}.\';\r\n\r\n	for (var i = 0, metricsLength = metrics.length; i < metricsLength; i++) {\r\n		const metric = ((Array.isArray(metrics[i]) ? metrics[i] : [metrics[i], defaultStatistic]));\r\n		metrics[i] = [metric[0], this.query + metric[1]];\r\n	}\r\n}\r\n\r\n\r\nconst params = JSON.parse(value);\r\nvalidateZabbixParams([\'tenancy_ocid\', \'user_ocid\', \'private_key\', \'fingerprint\', \'api_host\', \'instance_id\', \'http_status_code\', \'req_interval\', \'compartment_id\'], params);\r\nvar oci = new OCI(\'Compute\', \'Get metrics\', params);\r\n\r\nconst metrics = [\r\n	[\'CpuUtilization\', \'mean\'],\r\n	[\'MemoryUtilization\', \'mean\'],\r\n	[\'LoadAverage\', \'mean\'],\r\n	[\'MemoryAllocationStalls\', \'mean\'],\r\n	\'DiskBytesRead\',\r\n	\'DiskBytesWritten\',\r\n	\'DiskIopsRead\',\r\n	\'DiskIopsWritten\',\r\n	\'NetworksBytesIn\',\r\n	\'NetworksBytesOut\'\r\n];\r\nbuildMql(params[\'instance_id\'], metrics, \'rate\');\r\n\r\nvar result = {};\r\nfor (var i = 0, metricsLength = metrics.length; i < metricsLength; i++) {\r\n	result[metrics[i][0]] = oci.extractData(\'post\', oci.executeRequest(\'post\', \'/20180401/metrics/actions/summarizeMetricsData\', \'?compartmentId=\' + encodeURIComponent(params[\'compartment_id\']), metrics[i][0] + metrics[i][1] + \'()\', \'oci_computeagent\'), \'aggregatedDatapoints\');\r\n}\r\nreturn JSON.stringify(result);','','0','','','','','0',NULL,'Gets compute instance metrics.','0','7d','0','',NULL,'30s','','','','200','1','0','','','0','0','0','0','0','0','0','65ff665a67374bb082f260ca473dfb1b','0','2','0'),
('46855','21','','10618','State','oci.compute.state.get','1m','31d','365d','0','3','','','','',NULL,'1201','function validateZabbixParams(requiredParams, allParams) {\r\n	requiredParams.forEach(function (field) {\r\n		if (typeof allParams !== \'object\' || typeof allParams[field] === \'undefined\' || allParams[field] === \'\') {\r\n			throw \'Required param is not set: \' + field + \'.\';\r\n		}\r\n	});\r\n}\r\n\r\nfunction OCI(service, action, params) {\r\n	this.zabbixLogPrefix = \'[ OCI ] [ \' + service + \' ] [ \' + action + \' ]\';\r\n	this.request = new HttpRequest();\r\n\r\n	this.hash = function (string) {\r\n		return sha256(string);\r\n	};\r\n\r\n	this.sign = function (string) {\r\n		return sign(\'sha256\', params[\'private_key\'], string);\r\n	};\r\n\r\n	this.encode = function (hash) {\r\n		const hexArr = hash.match(/.{1,2}/g);\r\n		var uInt8Array = new Uint8Array(hexArr.length);\r\n		hexArr.forEach(function (hex, idx) {\r\n			uInt8Array[idx] = parseInt(hex, 16);\r\n		});\r\n		return btoa(uInt8Array);\r\n	};\r\n\r\n	this.getDate = function () {\r\n		const weekdayShortList = [\'Sun\', \'Mon\', \'Tue\', \'Wed\', \'Thu\', \'Fri\', \'Sat\'];\r\n		const monthShortList = [\'jan\', \'feb\', \'mar\', \'apr\', \'may\', \'jun\', \'jul\', \'aug\', \'sep\', \'oct\', \'nov\', \'dec\'];\r\n		const today = new Date();\r\n		return weekdayShortList[today.getUTCDay()] + \', \' + today.getUTCDate() + \' \' + monthShortList[today.getUTCMonth()] + \' \' + today.getUTCFullYear() + \' \' + today.getUTCHours() + \':\' + today.getUTCMinutes() + \':\' + today.getUTCSeconds() + \' GMT\';\r\n	};\r\n\r\n	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {\r\n		var headers = \'(request-target) date host\';\r\n		const contentTypeHeader = \'content-type: application/json\';\r\n		const dateHeader = \'date: \' + this.getDate();\r\n		const hostHeader = \'host: \' + params[\'api_host\'];\r\n		const requestTarget = \'(request-target): \' + httpMethod + \' \' + apiPath + apiParams;\r\n		var signingString = requestTarget + \'\\n\' + dateHeader + \'\\n\' + hostHeader;\r\n		var reqHeaders = [contentTypeHeader, dateHeader];\r\n\r\n		if (httpMethod === \'post\') {\r\n			var body = JSON.stringify({\r\n				\'namespace\': namespace,\r\n				\'query\': mql\r\n			});\r\n			headers = headers + \' x-content-sha256 content-type content-length\';\r\n			const bodyHeader = \'x-content-sha256: \' + this.encode(this.hash(body));\r\n			const bodyLengthHeader = \'content-length: \' + body.length;\r\n			signingString = signingString + \'\\n\' + bodyHeader + \'\\n\' + contentTypeHeader + \'\\n\' + bodyLengthHeader;\r\n			reqHeaders.push(bodyHeader, bodyLengthHeader);\r\n		}\r\n\r\n		const signature = this.encode(this.sign(signingString));\r\n\r\n		reqHeaders.push(\'Authorization: Signature version="1",keyId="\' + params[\'tenancy_ocid\'] + \'/\' + params[\'user_ocid\'] + \'/\' + params[\'fingerprint\'] + \'",algorithm="rsa-sha256",headers="\' + headers + \'",signature="\' + signature + \'"\');\r\n		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {\r\n			this.request.addHeader(reqHeaders[header]);\r\n		}\r\n\r\n		if (params[\'http_proxy\']) {\r\n			this.request.setProxy(params[\'http_proxy\']);\r\n			Zabbix.log(4, this.zabbixLogPrefix + \' Using http proxy: \' + params[\'http_proxy\']);\r\n		}\r\n\r\n		if (httpMethod === \'post\') {\r\n			var apiRateLimitExceeded = false;\r\n			do {\r\n				const response = this.request.post(\'https://\' + params[\'api_host\'] + apiPath + apiParams, body);\r\n\r\n				try {\r\n					if (JSON.parse(response)[\'code\'] === \'TooManyRequests\') {\r\n\r\n						apiRateLimitExceeded = true;\r\n						Zabbix.sleep(1000);\r\n					} else {\r\n						apiRateLimitExceeded = false;\r\n					}\r\n				} catch (error) {\r\n					Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the response: \' + JSON.stringify(response));\r\n					throw \'Could not parse the response. See logs for more information.\';\r\n				}\r\n			} while (apiRateLimitExceeded);\r\n		} else {\r\n			const response = this.request.get(\'https://\' + params[\'api_host\'] + apiPath + apiParams);\r\n		}\r\n\r\n		this.request.clearHeader();\r\n\r\n		if (this.request.getStatus() === parseInt(params[\'http_status_code\'])) {\r\n			return response;\r\n		} else {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Unexpected HTTP response code: \' + this.request.getStatus());\r\n			throw \'Unexpected HTTP response code: \' + this.request.getStatus();\r\n		}\r\n	};\r\n\r\n	this.extractData = function (httpMethod, data, keys, compartment) {\r\n		try {\r\n			data = JSON.parse(data);\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the received JSON object: \' + data);\r\n			throw \'Could not parse received JSON object. See logs for more information.\';\r\n		}\r\n\r\n		if (typeof keys == \'object\') {\r\n			var returnBuffer = [];\r\n			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {\r\n\r\n				var objectBuffer = {};\r\n				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {\r\n					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {\r\n						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];\r\n					} else {\r\n						Zabbix.log(3, this.zabbixLogPrefix + \' Received an unexpected JSON object. Could not get value for key "\' + keys[key] + \'" in JSON: \' + JSON.stringify(data[dataObj]));\r\n						throw \'Received an unexpected JSON object. See logs for more information.\';\r\n					}\r\n				}\r\n				if (typeof compartment != \'undefined\' && compartment != \'\') objectBuffer[\'compartment\'] = compartment;\r\n				returnBuffer.push(objectBuffer);\r\n			}\r\n			return returnBuffer;\r\n		}\r\n\r\n		try {\r\n			if (httpMethod === \'get\') {\r\n				return data[keys];\r\n			} else {\r\n				if (data.length === 0) {\r\n					return 0;\r\n				}\r\n				data = data[0][keys];\r\n				return data[data.length - 1][\'value\'];\r\n			}\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not find key "\' + keys + \'" in JSON: \' + JSON.stringify(data));\r\n			throw \'Could not find required key in JSON object. See logs for more information.\';\r\n		}\r\n	};\r\n}\r\n\r\n\r\nconst params = JSON.parse(value);\r\nvalidateZabbixParams([\'tenancy_ocid\', \'user_ocid\', \'private_key\', \'fingerprint\', \'api_host\', \'instance_id\', \'http_status_code\'], params);\r\nvar oci = new OCI(\'Compute\', \'Get state\', params);\r\n\r\nreturn oci.extractData(\'get\', oci.executeRequest(\'get\', \'/20160918/instances/\' + encodeURIComponent(params[\'instance_id\']), \'\'), \'lifecycleState\');','','0','','','','','0',NULL,'The current state of the instance.','0','7d','0','',NULL,'10s','','','','200','1','0','','','0','0','0','0','0','0','0','3c4a11c3c8fe40fca36635e2a6882816','0','2','0'),
('46856','21','','10618','Get VNICs','oci.compute.vnic.get','1m','0','0','0','4','','','','',NULL,NULL,'function validateZabbixParams(requiredParams, allParams) {\r\n	requiredParams.forEach(function (field) {\r\n		if (typeof allParams !== \'object\' || typeof allParams[field] === \'undefined\' || allParams[field] === \'\') {\r\n			throw \'Required param is not set: \' + field + \'.\';\r\n		}\r\n	});\r\n}\r\n\r\nfunction OCI(service, action, params) {\r\n	this.zabbixLogPrefix = \'[ OCI ] [ \' + service + \' ] [ \' + action + \' ]\';\r\n	this.request = new HttpRequest();\r\n\r\n	this.hash = function (string) {\r\n		return sha256(string);\r\n	};\r\n\r\n	this.sign = function (string) {\r\n		return sign(\'sha256\', params[\'private_key\'], string);\r\n	};\r\n\r\n	this.encode = function (hash) {\r\n		const hexArr = hash.match(/.{1,2}/g);\r\n		var uInt8Array = new Uint8Array(hexArr.length);\r\n		hexArr.forEach(function (hex, idx) {\r\n			uInt8Array[idx] = parseInt(hex, 16);\r\n		});\r\n		return btoa(uInt8Array);\r\n	};\r\n\r\n	this.getDate = function () {\r\n		const weekdayShortList = [\'Sun\', \'Mon\', \'Tue\', \'Wed\', \'Thu\', \'Fri\', \'Sat\'];\r\n		const monthShortList = [\'jan\', \'feb\', \'mar\', \'apr\', \'may\', \'jun\', \'jul\', \'aug\', \'sep\', \'oct\', \'nov\', \'dec\'];\r\n		const today = new Date();\r\n		return weekdayShortList[today.getUTCDay()] + \', \' + today.getUTCDate() + \' \' + monthShortList[today.getUTCMonth()] + \' \' + today.getUTCFullYear() + \' \' + today.getUTCHours() + \':\' + today.getUTCMinutes() + \':\' + today.getUTCSeconds() + \' GMT\';\r\n	};\r\n\r\n	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {\r\n		var headers = \'(request-target) date host\';\r\n		const contentTypeHeader = \'content-type: application/json\';\r\n		const dateHeader = \'date: \' + this.getDate();\r\n		const hostHeader = \'host: \' + params[\'api_host\'];\r\n		const requestTarget = \'(request-target): \' + httpMethod + \' \' + apiPath + apiParams;\r\n		var signingString = requestTarget + \'\\n\' + dateHeader + \'\\n\' + hostHeader;\r\n		var reqHeaders = [contentTypeHeader, dateHeader];\r\n\r\n		if (httpMethod === \'post\') {\r\n			var body = JSON.stringify({\r\n				\'namespace\': namespace,\r\n				\'query\': mql\r\n			});\r\n			headers = headers + \' x-content-sha256 content-type content-length\';\r\n			const bodyHeader = \'x-content-sha256: \' + this.encode(this.hash(body));\r\n			const bodyLengthHeader = \'content-length: \' + body.length;\r\n			signingString = signingString + \'\\n\' + bodyHeader + \'\\n\' + contentTypeHeader + \'\\n\' + bodyLengthHeader;\r\n			reqHeaders.push(bodyHeader, bodyLengthHeader);\r\n		}\r\n\r\n		const signature = this.encode(this.sign(signingString));\r\n\r\n		reqHeaders.push(\'Authorization: Signature version="1",keyId="\' + params[\'tenancy_ocid\'] + \'/\' + params[\'user_ocid\'] + \'/\' + params[\'fingerprint\'] + \'",algorithm="rsa-sha256",headers="\' + headers + \'",signature="\' + signature + \'"\');\r\n		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {\r\n			this.request.addHeader(reqHeaders[header]);\r\n		}\r\n\r\n		if (params[\'http_proxy\']) {\r\n			this.request.setProxy(params[\'http_proxy\']);\r\n			Zabbix.log(4, this.zabbixLogPrefix + \' Using http proxy: \' + params[\'http_proxy\']);\r\n		}\r\n\r\n		if (httpMethod === \'post\') {\r\n			var apiRateLimitExceeded = false;\r\n			do {\r\n				const response = this.request.post(\'https://\' + params[\'api_host\'] + apiPath + apiParams, body);\r\n\r\n				try {\r\n					if (JSON.parse(response)[\'code\'] === \'TooManyRequests\') {\r\n\r\n						apiRateLimitExceeded = true;\r\n						Zabbix.sleep(1000);\r\n					} else {\r\n						apiRateLimitExceeded = false;\r\n					}\r\n				} catch (error) {\r\n					Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the response: \' + JSON.stringify(response));\r\n					throw \'Could not parse the response. See logs for more information.\';\r\n				}\r\n			} while (apiRateLimitExceeded);\r\n		} else {\r\n			const response = this.request.get(\'https://\' + params[\'api_host\'] + apiPath + apiParams);\r\n		}\r\n\r\n		this.request.clearHeader();\r\n\r\n		if (this.request.getStatus() === parseInt(params[\'http_status_code\'])) {\r\n			return response;\r\n		} else {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Unexpected HTTP response code: \' + this.request.getStatus());\r\n			throw \'Unexpected HTTP response code: \' + this.request.getStatus();\r\n		}\r\n	};\r\n\r\n	this.extractData = function (httpMethod, data, keys, compartment) {\r\n		try {\r\n			data = JSON.parse(data);\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the received JSON object: \' + data);\r\n			throw \'Could not parse received JSON object. See logs for more information.\';\r\n		}\r\n\r\n		if (typeof keys == \'object\') {\r\n			var returnBuffer = [];\r\n			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {\r\n\r\n				var objectBuffer = {};\r\n				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {\r\n					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {\r\n						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];\r\n					} else {\r\n						Zabbix.log(3, this.zabbixLogPrefix + \' Received an unexpected JSON object. Could not get value for key "\' + keys[key] + \'" in JSON: \' + JSON.stringify(data[dataObj]));\r\n						throw \'Received an unexpected JSON object. See logs for more information.\';\r\n					}\r\n				}\r\n				if (typeof compartment != \'undefined\' && compartment != \'\') objectBuffer[\'compartment\'] = compartment;\r\n				returnBuffer.push(objectBuffer);\r\n			}\r\n			return returnBuffer;\r\n		}\r\n\r\n		try {\r\n			if (httpMethod === \'get\') {\r\n				return data[keys];\r\n			} else {\r\n				if (data.length === 0) {\r\n					return 0;\r\n				}\r\n				data = data[0][keys];\r\n				return data[data.length - 1][\'value\'];\r\n			}\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not find key "\' + keys + \'" in JSON: \' + JSON.stringify(data));\r\n			throw \'Could not find required key in JSON object. See logs for more information.\';\r\n		}\r\n	};\r\n}\r\n\r\n\r\nconst params = JSON.parse(value);\r\nvalidateZabbixParams([\'tenancy_ocid\', \'user_ocid\', \'private_key\', \'fingerprint\', \'api_host\', \'instance_id\', \'availability_domain\', \'http_status_code\', \'compartment_id\'], params);\r\nvar oci = new OCI(\'Compute\', \'Get VNICs\', params);\r\n\r\nreturn JSON.stringify(oci.extractData(\'get\', oci.executeRequest(\'get\', \'/20160918/vnicAttachments\', \'?compartmentId=\' + encodeURIComponent(params[\'compartment_id\']) + \'&availabilityDomain=\' + encodeURIComponent(params[\'availability_domain\']) + \'&instanceId=\' + encodeURIComponent(params[\'instance_id\'])), [\'vnicId\', \'displayName\', \'lifecycleState\']));','','0','','','','','0',NULL,'Gets information about all virtual network interface cards attached to the instance.','0','7d','0','',NULL,'30s','','','','200','1','0','','','0','0','0','0','0','0','0','c0e74098afb14984af6355ac0711662e','0','2','0'),
('46857','21','','10619','Get VCN state','oci.vcn.state.get','5m','31d','365d','0','3','','','','',NULL,'1204','function validateZabbixParams(requiredParams, allParams) {\r\n	requiredParams.forEach(function (field) {\r\n		if (typeof allParams !== \'object\' || typeof allParams[field] === \'undefined\' || allParams[field] === \'\') {\r\n			throw \'Required param is not set: \' + field + \'.\';\r\n		}\r\n	});\r\n}\r\n\r\nfunction OCI(service, action, params) {\r\n	this.zabbixLogPrefix = \'[ OCI ] [ \' + service + \' ] [ \' + action + \' ]\';\r\n	this.request = new HttpRequest();\r\n\r\n	this.hash = function (string) {\r\n		return sha256(string);\r\n	};\r\n\r\n	this.sign = function (string) {\r\n		return sign(\'sha256\', params[\'private_key\'], string);\r\n	};\r\n\r\n	this.encode = function (hash) {\r\n		const hexArr = hash.match(/.{1,2}/g);\r\n		var uInt8Array = new Uint8Array(hexArr.length);\r\n		hexArr.forEach(function (hex, idx) {\r\n			uInt8Array[idx] = parseInt(hex, 16);\r\n		});\r\n		return btoa(uInt8Array);\r\n	};\r\n\r\n	this.getDate = function () {\r\n		const weekdayShortList = [\'Sun\', \'Mon\', \'Tue\', \'Wed\', \'Thu\', \'Fri\', \'Sat\'];\r\n		const monthShortList = [\'jan\', \'feb\', \'mar\', \'apr\', \'may\', \'jun\', \'jul\', \'aug\', \'sep\', \'oct\', \'nov\', \'dec\'];\r\n		const today = new Date();\r\n		return weekdayShortList[today.getUTCDay()] + \', \' + today.getUTCDate() + \' \' + monthShortList[today.getUTCMonth()] + \' \' + today.getUTCFullYear() + \' \' + today.getUTCHours() + \':\' + today.getUTCMinutes() + \':\' + today.getUTCSeconds() + \' GMT\';\r\n	};\r\n\r\n	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {\r\n		var headers = \'(request-target) date host\';\r\n		const contentTypeHeader = \'content-type: application/json\';\r\n		const dateHeader = \'date: \' + this.getDate();\r\n		const hostHeader = \'host: \' + params[\'api_host\'];\r\n		const requestTarget = \'(request-target): \' + httpMethod + \' \' + apiPath + apiParams;\r\n		var signingString = requestTarget + \'\\n\' + dateHeader + \'\\n\' + hostHeader;\r\n		var reqHeaders = [contentTypeHeader, dateHeader];\r\n\r\n		if (httpMethod === \'post\') {\r\n			var body = JSON.stringify({\r\n				\'namespace\': namespace,\r\n				\'query\': mql\r\n			});\r\n			headers = headers + \' x-content-sha256 content-type content-length\';\r\n			const bodyHeader = \'x-content-sha256: \' + this.encode(this.hash(body));\r\n			const bodyLengthHeader = \'content-length: \' + body.length;\r\n			signingString = signingString + \'\\n\' + bodyHeader + \'\\n\' + contentTypeHeader + \'\\n\' + bodyLengthHeader;\r\n			reqHeaders.push(bodyHeader, bodyLengthHeader);\r\n		}\r\n\r\n		const signature = this.encode(this.sign(signingString));\r\n\r\n		reqHeaders.push(\'Authorization: Signature version="1",keyId="\' + params[\'tenancy_ocid\'] + \'/\' + params[\'user_ocid\'] + \'/\' + params[\'fingerprint\'] + \'",algorithm="rsa-sha256",headers="\' + headers + \'",signature="\' + signature + \'"\');\r\n		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {\r\n			this.request.addHeader(reqHeaders[header]);\r\n		}\r\n\r\n		if (params[\'http_proxy\']) {\r\n			this.request.setProxy(params[\'http_proxy\']);\r\n			Zabbix.log(4, this.zabbixLogPrefix + \' Using http proxy: \' + params[\'http_proxy\']);\r\n		}\r\n\r\n		if (httpMethod === \'post\') {\r\n			var apiRateLimitExceeded = false;\r\n			do {\r\n				const response = this.request.post(\'https://\' + params[\'api_host\'] + apiPath + apiParams, body);\r\n\r\n				try {\r\n					if (JSON.parse(response)[\'code\'] === \'TooManyRequests\') {\r\n\r\n						apiRateLimitExceeded = true;\r\n						Zabbix.sleep(1000);\r\n					} else {\r\n						apiRateLimitExceeded = false;\r\n					}\r\n				} catch (error) {\r\n					Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the response: \' + JSON.stringify(response));\r\n					throw \'Could not parse the response. See logs for more information.\';\r\n				}\r\n			} while (apiRateLimitExceeded);\r\n		} else {\r\n			const response = this.request.get(\'https://\' + params[\'api_host\'] + apiPath + apiParams);\r\n		}\r\n\r\n		this.request.clearHeader();\r\n\r\n		if (this.request.getStatus() === parseInt(params[\'http_status_code\'])) {\r\n			return response;\r\n		} else {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Unexpected HTTP response code: \' + this.request.getStatus());\r\n			throw \'Unexpected HTTP response code: \' + this.request.getStatus();\r\n		}\r\n	};\r\n\r\n	this.extractData = function (httpMethod, data, keys, compartment) {\r\n		try {\r\n			data = JSON.parse(data);\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the received JSON object: \' + data);\r\n			throw \'Could not parse received JSON object. See logs for more information.\';\r\n		}\r\n\r\n		if (typeof keys == \'object\') {\r\n			var returnBuffer = [];\r\n			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {\r\n\r\n				var objectBuffer = {};\r\n				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {\r\n					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {\r\n						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];\r\n					} else {\r\n						Zabbix.log(3, this.zabbixLogPrefix + \' Received an unexpected JSON object. Could not get value for key "\' + keys[key] + \'" in JSON: \' + JSON.stringify(data[dataObj]));\r\n						throw \'Received an unexpected JSON object. See logs for more information.\';\r\n					}\r\n				}\r\n				if (typeof compartment != \'undefined\' && compartment != \'\') objectBuffer[\'compartment\'] = compartment;\r\n				returnBuffer.push(objectBuffer);\r\n			}\r\n			return returnBuffer;\r\n		}\r\n\r\n		try {\r\n			if (httpMethod === \'get\') {\r\n				return data[keys];\r\n			} else {\r\n				if (data.length === 0) {\r\n					return 0;\r\n				}\r\n				data = data[0][keys];\r\n				return data[data.length - 1][\'value\'];\r\n			}\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not find key "\' + keys + \'" in JSON: \' + JSON.stringify(data));\r\n			throw \'Could not find required key in JSON object. See logs for more information.\';\r\n		}\r\n	};\r\n}\r\n\r\n\r\nconst params = JSON.parse(value);\r\nvalidateZabbixParams([\'tenancy_ocid\', \'user_ocid\', \'private_key\', \'fingerprint\', \'api_host\', \'vcn_id\', \'http_status_code\'], params);\r\nvar oci = new OCI(\'VCN\', \'Get VCN status\', params);\r\n\r\nreturn JSON.stringify(oci.extractData(\'get\', oci.executeRequest(\'get\', \'/20160918/vcns/\' + encodeURIComponent(params[\'vcn_id\']), \'\'), \'lifecycleState\'));','','0','','','','','0',NULL,'State of the virtual cloud network.','0','7d','0','',NULL,'10s','','','','200','1','0','','','0','0','0','0','0','0','0','7b2fdfb034ba4657a731ab11ffa175f6','0','2','0'),
('46858','21','','10619','Get subnets','oci.vcn.subnets.get','5m','0','0','0','4','','','','',NULL,NULL,'function validateZabbixParams(requiredParams, allParams) {\r\n	requiredParams.forEach(function (field) {\r\n		if (typeof allParams !== \'object\' || typeof allParams[field] === \'undefined\' || allParams[field] === \'\') {\r\n			throw \'Required param is not set: \' + field + \'.\';\r\n		}\r\n	});\r\n}\r\n\r\nfunction OCI(service, action, params) {\r\n	this.zabbixLogPrefix = \'[ OCI ] [ \' + service + \' ] [ \' + action + \' ]\';\r\n	this.request = new HttpRequest();\r\n\r\n	this.hash = function (string) {\r\n		return sha256(string);\r\n	};\r\n\r\n	this.sign = function (string) {\r\n		return sign(\'sha256\', params[\'private_key\'], string);\r\n	};\r\n\r\n	this.encode = function (hash) {\r\n		const hexArr = hash.match(/.{1,2}/g);\r\n		var uInt8Array = new Uint8Array(hexArr.length);\r\n		hexArr.forEach(function (hex, idx) {\r\n			uInt8Array[idx] = parseInt(hex, 16);\r\n		});\r\n		return btoa(uInt8Array);\r\n	};\r\n\r\n	this.getDate = function () {\r\n		const weekdayShortList = [\'Sun\', \'Mon\', \'Tue\', \'Wed\', \'Thu\', \'Fri\', \'Sat\'];\r\n		const monthShortList = [\'jan\', \'feb\', \'mar\', \'apr\', \'may\', \'jun\', \'jul\', \'aug\', \'sep\', \'oct\', \'nov\', \'dec\'];\r\n		const today = new Date();\r\n		return weekdayShortList[today.getUTCDay()] + \', \' + today.getUTCDate() + \' \' + monthShortList[today.getUTCMonth()] + \' \' + today.getUTCFullYear() + \' \' + today.getUTCHours() + \':\' + today.getUTCMinutes() + \':\' + today.getUTCSeconds() + \' GMT\';\r\n	};\r\n\r\n	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {\r\n		var headers = \'(request-target) date host\';\r\n		const contentTypeHeader = \'content-type: application/json\';\r\n		const dateHeader = \'date: \' + this.getDate();\r\n		const hostHeader = \'host: \' + params[\'api_host\'];\r\n		const requestTarget = \'(request-target): \' + httpMethod + \' \' + apiPath + apiParams;\r\n		var signingString = requestTarget + \'\\n\' + dateHeader + \'\\n\' + hostHeader;\r\n		var reqHeaders = [contentTypeHeader, dateHeader];\r\n\r\n		if (httpMethod === \'post\') {\r\n			var body = JSON.stringify({\r\n				\'namespace\': namespace,\r\n				\'query\': mql\r\n			});\r\n			headers = headers + \' x-content-sha256 content-type content-length\';\r\n			const bodyHeader = \'x-content-sha256: \' + this.encode(this.hash(body));\r\n			const bodyLengthHeader = \'content-length: \' + body.length;\r\n			signingString = signingString + \'\\n\' + bodyHeader + \'\\n\' + contentTypeHeader + \'\\n\' + bodyLengthHeader;\r\n			reqHeaders.push(bodyHeader, bodyLengthHeader);\r\n		}\r\n\r\n		const signature = this.encode(this.sign(signingString));\r\n\r\n		reqHeaders.push(\'Authorization: Signature version="1",keyId="\' + params[\'tenancy_ocid\'] + \'/\' + params[\'user_ocid\'] + \'/\' + params[\'fingerprint\'] + \'",algorithm="rsa-sha256",headers="\' + headers + \'",signature="\' + signature + \'"\');\r\n		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {\r\n			this.request.addHeader(reqHeaders[header]);\r\n		}\r\n\r\n		if (params[\'http_proxy\']) {\r\n			this.request.setProxy(params[\'http_proxy\']);\r\n			Zabbix.log(4, this.zabbixLogPrefix + \' Using http proxy: \' + params[\'http_proxy\']);\r\n		}\r\n\r\n		if (httpMethod === \'post\') {\r\n			var apiRateLimitExceeded = false;\r\n			do {\r\n				const response = this.request.post(\'https://\' + params[\'api_host\'] + apiPath + apiParams, body);\r\n\r\n				try {\r\n					if (JSON.parse(response)[\'code\'] === \'TooManyRequests\') {\r\n\r\n						apiRateLimitExceeded = true;\r\n						Zabbix.sleep(1000);\r\n					} else {\r\n						apiRateLimitExceeded = false;\r\n					}\r\n				} catch (error) {\r\n					Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the response: \' + JSON.stringify(response));\r\n					throw \'Could not parse the response. See logs for more information.\';\r\n				}\r\n			} while (apiRateLimitExceeded);\r\n		} else {\r\n			const response = this.request.get(\'https://\' + params[\'api_host\'] + apiPath + apiParams);\r\n		}\r\n\r\n		this.request.clearHeader();\r\n\r\n		if (this.request.getStatus() === parseInt(params[\'http_status_code\'])) {\r\n			return response;\r\n		} else {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Unexpected HTTP response code: \' + this.request.getStatus());\r\n			throw \'Unexpected HTTP response code: \' + this.request.getStatus();\r\n		}\r\n	};\r\n\r\n	this.extractData = function (httpMethod, data, keys, compartment) {\r\n		try {\r\n			data = JSON.parse(data);\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the received JSON object: \' + data);\r\n			throw \'Could not parse received JSON object. See logs for more information.\';\r\n		}\r\n\r\n		if (typeof keys == \'object\') {\r\n			var returnBuffer = [];\r\n			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {\r\n\r\n				var objectBuffer = {};\r\n				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {\r\n					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {\r\n						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];\r\n					} else {\r\n						Zabbix.log(3, this.zabbixLogPrefix + \' Received an unexpected JSON object. Could not get value for key "\' + keys[key] + \'" in JSON: \' + JSON.stringify(data[dataObj]));\r\n						throw \'Received an unexpected JSON object. See logs for more information.\';\r\n					}\r\n				}\r\n				if (typeof compartment != \'undefined\' && compartment != \'\') objectBuffer[\'compartment\'] = compartment;\r\n				returnBuffer.push(objectBuffer);\r\n			}\r\n			return returnBuffer;\r\n		}\r\n\r\n		try {\r\n			if (httpMethod === \'get\') {\r\n				return data[keys];\r\n			} else {\r\n				if (data.length === 0) {\r\n					return 0;\r\n				}\r\n				data = data[0][keys];\r\n				return data[data.length - 1][\'value\'];\r\n			}\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not find key "\' + keys + \'" in JSON: \' + JSON.stringify(data));\r\n			throw \'Could not find required key in JSON object. See logs for more information.\';\r\n		}\r\n	};\r\n}\r\n\r\n\r\nconst params = JSON.parse(value);\r\nvalidateZabbixParams([\'tenancy_ocid\', \'user_ocid\', \'private_key\', \'fingerprint\', \'api_host\', \'vcn_id\', \'http_status_code\', \'compartment_id\'], params);\r\nvar oci = new OCI(\'VCN\', \'Get subnets\', params);\r\n\r\nreturn JSON.stringify(oci.extractData(\'get\', oci.executeRequest(\'get\', \'/20160918/subnets\', \'?compartmentId=\' + encodeURIComponent(params[\'compartment_id\']) + \'&vcnId=\' + encodeURIComponent(params[\'vcn_id\'])), [\'id\', \'displayName\', \'lifecycleState\', \'freeformTags\']));','','0','','','','','0',NULL,'Get data about subnets linked to the particular VCN.','0','7d','0','',NULL,'30s','','','','200','1','0','','','0','0','0','0','0','0','0','83236aeedf5e4ba39f0425c21f745690','0','2','0'),
('46859','21','','10620','Get frequent metrics','oci.obj.storage.metrics.frequent.get','1m','0','0','0','4','','','','',NULL,NULL,'function validateZabbixParams(requiredParams, allParams) {\r\n	requiredParams.forEach(function (field) {\r\n		if (typeof allParams !== \'object\' || typeof allParams[field] === \'undefined\' || allParams[field] === \'\') {\r\n			throw \'Required param is not set: \' + field + \'.\';\r\n		}\r\n	});\r\n}\r\n\r\nfunction OCI(service, action, params) {\r\n	this.zabbixLogPrefix = \'[ OCI ] [ \' + service + \' ] [ \' + action + \' ]\';\r\n	this.request = new HttpRequest();\r\n\r\n	this.hash = function (string) {\r\n		return sha256(string);\r\n	};\r\n\r\n	this.sign = function (string) {\r\n		return sign(\'sha256\', params[\'private_key\'], string);\r\n	};\r\n\r\n	this.encode = function (hash) {\r\n		const hexArr = hash.match(/.{1,2}/g);\r\n		var uInt8Array = new Uint8Array(hexArr.length);\r\n		hexArr.forEach(function (hex, idx) {\r\n			uInt8Array[idx] = parseInt(hex, 16);\r\n		});\r\n		return btoa(uInt8Array);\r\n	};\r\n\r\n	this.getDate = function () {\r\n		const weekdayShortList = [\'Sun\', \'Mon\', \'Tue\', \'Wed\', \'Thu\', \'Fri\', \'Sat\'];\r\n		const monthShortList = [\'jan\', \'feb\', \'mar\', \'apr\', \'may\', \'jun\', \'jul\', \'aug\', \'sep\', \'oct\', \'nov\', \'dec\'];\r\n		const today = new Date();\r\n		return weekdayShortList[today.getUTCDay()] + \', \' + today.getUTCDate() + \' \' + monthShortList[today.getUTCMonth()] + \' \' + today.getUTCFullYear() + \' \' + today.getUTCHours() + \':\' + today.getUTCMinutes() + \':\' + today.getUTCSeconds() + \' GMT\';\r\n	};\r\n\r\n	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {\r\n		var headers = \'(request-target) date host\';\r\n		const contentTypeHeader = \'content-type: application/json\';\r\n		const dateHeader = \'date: \' + this.getDate();\r\n		const hostHeader = \'host: \' + params[\'api_host\'];\r\n		const requestTarget = \'(request-target): \' + httpMethod + \' \' + apiPath + apiParams;\r\n		var signingString = requestTarget + \'\\n\' + dateHeader + \'\\n\' + hostHeader;\r\n		var reqHeaders = [contentTypeHeader, dateHeader];\r\n\r\n		if (httpMethod === \'post\') {\r\n			var body = JSON.stringify({\r\n				\'namespace\': namespace,\r\n				\'query\': mql\r\n			});\r\n			headers = headers + \' x-content-sha256 content-type content-length\';\r\n			const bodyHeader = \'x-content-sha256: \' + this.encode(this.hash(body));\r\n			const bodyLengthHeader = \'content-length: \' + body.length;\r\n			signingString = signingString + \'\\n\' + bodyHeader + \'\\n\' + contentTypeHeader + \'\\n\' + bodyLengthHeader;\r\n			reqHeaders.push(bodyHeader, bodyLengthHeader);\r\n		}\r\n\r\n		const signature = this.encode(this.sign(signingString));\r\n\r\n		reqHeaders.push(\'Authorization: Signature version="1",keyId="\' + params[\'tenancy_ocid\'] + \'/\' + params[\'user_ocid\'] + \'/\' + params[\'fingerprint\'] + \'",algorithm="rsa-sha256",headers="\' + headers + \'",signature="\' + signature + \'"\');\r\n		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {\r\n			this.request.addHeader(reqHeaders[header]);\r\n		}\r\n\r\n		if (params[\'http_proxy\']) {\r\n			this.request.setProxy(params[\'http_proxy\']);\r\n			Zabbix.log(4, this.zabbixLogPrefix + \' Using http proxy: \' + params[\'http_proxy\']);\r\n		}\r\n\r\n		if (httpMethod === \'post\') {\r\n			var apiRateLimitExceeded = false;\r\n			do {\r\n				const response = this.request.post(\'https://\' + params[\'api_host\'] + apiPath + apiParams, body);\r\n\r\n				try {\r\n					if (JSON.parse(response)[\'code\'] === \'TooManyRequests\') {\r\n\r\n						apiRateLimitExceeded = true;\r\n						Zabbix.sleep(1000);\r\n					} else {\r\n						apiRateLimitExceeded = false;\r\n					}\r\n				} catch (error) {\r\n					Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the response: \' + JSON.stringify(response));\r\n					throw \'Could not parse the response. See logs for more information.\';\r\n				}\r\n			} while (apiRateLimitExceeded);\r\n		} else {\r\n			const response = this.request.get(\'https://\' + params[\'api_host\'] + apiPath + apiParams);\r\n		}\r\n\r\n		this.request.clearHeader();\r\n\r\n		if (this.request.getStatus() === parseInt(params[\'http_status_code\'])) {\r\n			return response;\r\n		} else {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Unexpected HTTP response code: \' + this.request.getStatus());\r\n			throw \'Unexpected HTTP response code: \' + this.request.getStatus();\r\n		}\r\n	};\r\n\r\n	this.extractData = function (httpMethod, data, keys, compartment) {\r\n		try {\r\n			data = JSON.parse(data);\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the received JSON object: \' + data);\r\n			throw \'Could not parse received JSON object. See logs for more information.\';\r\n		}\r\n\r\n		if (typeof keys == \'object\') {\r\n			var returnBuffer = [];\r\n			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {\r\n\r\n				var objectBuffer = {};\r\n				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {\r\n					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {\r\n						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];\r\n					} else {\r\n						Zabbix.log(3, this.zabbixLogPrefix + \' Received an unexpected JSON object. Could not get value for key "\' + keys[key] + \'" in JSON: \' + JSON.stringify(data[dataObj]));\r\n						throw \'Received an unexpected JSON object. See logs for more information.\';\r\n					}\r\n				}\r\n				if (typeof compartment != \'undefined\' && compartment != \'\') objectBuffer[\'compartment\'] = compartment;\r\n				returnBuffer.push(objectBuffer);\r\n			}\r\n			return returnBuffer;\r\n		}\r\n\r\n		try {\r\n			if (httpMethod === \'get\') {\r\n				return data[keys];\r\n			} else {\r\n				if (data.length === 0) {\r\n					return 0;\r\n				}\r\n				data = data[0][keys];\r\n				return data[data.length - 1][\'value\'];\r\n			}\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not find key "\' + keys + \'" in JSON: \' + JSON.stringify(data));\r\n			throw \'Could not find required key in JSON object. See logs for more information.\';\r\n		}\r\n	};\r\n}\r\n\r\nfunction buildMql(id, metrics, defaultStatistic, resourceType) {\r\n	resourceType = resourceType === \'\' || resourceType === undefined ? \'resourceId\' : resourceType;\r\n	this.query = \'[\' + params[\'req_interval\'] + \'m]{\' + resourceType + \'=\' + id + \'}.\';\r\n\r\n	for (var i = 0, metricsLength = metrics.length; i < metricsLength; i++) {\r\n		const metric = ((Array.isArray(metrics[i]) ? metrics[i] : [metrics[i], defaultStatistic]));\r\n		metrics[i] = [metric[0], this.query + metric[1]];\r\n	}\r\n}\r\n\r\n\r\nconst params = JSON.parse(value);\r\nvalidateZabbixParams([\'tenancy_ocid\', \'user_ocid\', \'private_key\', \'fingerprint\', \'api_host\', \'bucket_name\', \'http_status_code\', \'req_interval\', \'compartment_id\'], params);\r\nvar oci = new OCI(\'Object storage\', \'Get metrics \' + params[\'req_interval\'] + \'m\', params);\r\n\r\nconst metrics = [\r\n	\'AllRequests\',\r\n	\'ClientErrors\',\r\n	\'FirstByteLatency\',\r\n	\'PostRequests\',\r\n	\'PutRequests\',\r\n	\'TotalRequestLatency\'\r\n];\r\nbuildMql(params[\'bucket_name\'], metrics, \'mean\', \'resourceDisplayName\');\r\n\r\nvar result = {};\r\nfor (var i = 0, metricsLength = metrics.length; i < metricsLength; i++) {\r\n	result[metrics[i][0]] = oci.extractData(\'post\', oci.executeRequest(\'post\', \'/20180401/metrics/actions/summarizeMetricsData\', \'?compartmentId=\' + encodeURIComponent(params[\'compartment_id\']), metrics[i][0] + metrics[i][1] + \'()\', \'oci_objectstorage\'), \'aggregatedDatapoints\');\r\n}\r\nreturn JSON.stringify(result);','','0','','','','','0',NULL,'Gets all metrics related to a specific bucket that have frequent update time (100 milliseconds).','0','7d','0','',NULL,'30s','','','','200','1','0','','','0','0','0','0','0','0','0','5463c35f2c48408997532001025989fa','0','2','0'),
('46860','21','','10620','Get hourly metrics','oci.obj.storage.metrics.hourly.get','1h','0','0','0','4','','','','',NULL,NULL,'function validateZabbixParams(requiredParams, allParams) {\r\n	requiredParams.forEach(function (field) {\r\n		if (typeof allParams !== \'object\' || typeof allParams[field] === \'undefined\' || allParams[field] === \'\') {\r\n			throw \'Required param is not set: \' + field + \'.\';\r\n		}\r\n	});\r\n}\r\n\r\nfunction OCI(service, action, params) {\r\n	this.zabbixLogPrefix = \'[ OCI ] [ \' + service + \' ] [ \' + action + \' ]\';\r\n	this.request = new HttpRequest();\r\n\r\n	this.hash = function (string) {\r\n		return sha256(string);\r\n	};\r\n\r\n	this.sign = function (string) {\r\n		return sign(\'sha256\', params[\'private_key\'], string);\r\n	};\r\n\r\n	this.encode = function (hash) {\r\n		const hexArr = hash.match(/.{1,2}/g);\r\n		var uInt8Array = new Uint8Array(hexArr.length);\r\n		hexArr.forEach(function (hex, idx) {\r\n			uInt8Array[idx] = parseInt(hex, 16);\r\n		});\r\n		return btoa(uInt8Array);\r\n	};\r\n\r\n	this.getDate = function () {\r\n		const weekdayShortList = [\'Sun\', \'Mon\', \'Tue\', \'Wed\', \'Thu\', \'Fri\', \'Sat\'];\r\n		const monthShortList = [\'jan\', \'feb\', \'mar\', \'apr\', \'may\', \'jun\', \'jul\', \'aug\', \'sep\', \'oct\', \'nov\', \'dec\'];\r\n		const today = new Date();\r\n		return weekdayShortList[today.getUTCDay()] + \', \' + today.getUTCDate() + \' \' + monthShortList[today.getUTCMonth()] + \' \' + today.getUTCFullYear() + \' \' + today.getUTCHours() + \':\' + today.getUTCMinutes() + \':\' + today.getUTCSeconds() + \' GMT\';\r\n	};\r\n\r\n	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {\r\n		var headers = \'(request-target) date host\';\r\n		const contentTypeHeader = \'content-type: application/json\';\r\n		const dateHeader = \'date: \' + this.getDate();\r\n		const hostHeader = \'host: \' + params[\'api_host\'];\r\n		const requestTarget = \'(request-target): \' + httpMethod + \' \' + apiPath + apiParams;\r\n		var signingString = requestTarget + \'\\n\' + dateHeader + \'\\n\' + hostHeader;\r\n		var reqHeaders = [contentTypeHeader, dateHeader];\r\n\r\n		if (httpMethod === \'post\') {\r\n			var body = JSON.stringify({\r\n				\'namespace\': namespace,\r\n				\'query\': mql\r\n			});\r\n			headers = headers + \' x-content-sha256 content-type content-length\';\r\n			const bodyHeader = \'x-content-sha256: \' + this.encode(this.hash(body));\r\n			const bodyLengthHeader = \'content-length: \' + body.length;\r\n			signingString = signingString + \'\\n\' + bodyHeader + \'\\n\' + contentTypeHeader + \'\\n\' + bodyLengthHeader;\r\n			reqHeaders.push(bodyHeader, bodyLengthHeader);\r\n		}\r\n\r\n		const signature = this.encode(this.sign(signingString));\r\n\r\n		reqHeaders.push(\'Authorization: Signature version="1",keyId="\' + params[\'tenancy_ocid\'] + \'/\' + params[\'user_ocid\'] + \'/\' + params[\'fingerprint\'] + \'",algorithm="rsa-sha256",headers="\' + headers + \'",signature="\' + signature + \'"\');\r\n		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {\r\n			this.request.addHeader(reqHeaders[header]);\r\n		}\r\n\r\n		if (params[\'http_proxy\']) {\r\n			this.request.setProxy(params[\'http_proxy\']);\r\n			Zabbix.log(4, this.zabbixLogPrefix + \' Using http proxy: \' + params[\'http_proxy\']);\r\n		}\r\n\r\n		if (httpMethod === \'post\') {\r\n			var apiRateLimitExceeded = false;\r\n			do {\r\n				const response = this.request.post(\'https://\' + params[\'api_host\'] + apiPath + apiParams, body);\r\n\r\n				try {\r\n					if (JSON.parse(response)[\'code\'] === \'TooManyRequests\') {\r\n\r\n						apiRateLimitExceeded = true;\r\n						Zabbix.sleep(1000);\r\n					} else {\r\n						apiRateLimitExceeded = false;\r\n					}\r\n				} catch (error) {\r\n					Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the response: \' + JSON.stringify(response));\r\n					throw \'Could not parse the response. See logs for more information.\';\r\n				}\r\n			} while (apiRateLimitExceeded);\r\n		} else {\r\n			const response = this.request.get(\'https://\' + params[\'api_host\'] + apiPath + apiParams);\r\n		}\r\n\r\n		this.request.clearHeader();\r\n\r\n		if (this.request.getStatus() === parseInt(params[\'http_status_code\'])) {\r\n			return response;\r\n		} else {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Unexpected HTTP response code: \' + this.request.getStatus());\r\n			throw \'Unexpected HTTP response code: \' + this.request.getStatus();\r\n		}\r\n	};\r\n\r\n	this.extractData = function (httpMethod, data, keys, compartment) {\r\n		try {\r\n			data = JSON.parse(data);\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the received JSON object: \' + data);\r\n			throw \'Could not parse received JSON object. See logs for more information.\';\r\n		}\r\n\r\n		if (typeof keys == \'object\') {\r\n			var returnBuffer = [];\r\n			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {\r\n\r\n				var objectBuffer = {};\r\n				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {\r\n					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {\r\n						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];\r\n					} else {\r\n						Zabbix.log(3, this.zabbixLogPrefix + \' Received an unexpected JSON object. Could not get value for key "\' + keys[key] + \'" in JSON: \' + JSON.stringify(data[dataObj]));\r\n						throw \'Received an unexpected JSON object. See logs for more information.\';\r\n					}\r\n				}\r\n				if (typeof compartment != \'undefined\' && compartment != \'\') objectBuffer[\'compartment\'] = compartment;\r\n				returnBuffer.push(objectBuffer);\r\n			}\r\n			return returnBuffer;\r\n		}\r\n\r\n		try {\r\n			if (httpMethod === \'get\') {\r\n				return data[keys];\r\n			} else {\r\n				if (data.length === 0) {\r\n					return 0;\r\n				}\r\n				data = data[0][keys];\r\n				return data[data.length - 1][\'value\'];\r\n			}\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not find key "\' + keys + \'" in JSON: \' + JSON.stringify(data));\r\n			throw \'Could not find required key in JSON object. See logs for more information.\';\r\n		}\r\n	};\r\n}\r\n\r\nfunction buildMql(id, metrics, defaultStatistic, resourceType) {\r\n	resourceType = resourceType === \'\' || resourceType === undefined ? \'resourceId\' : resourceType;\r\n	this.query = \'[\' + params[\'req_interval\'] + \'m]{\' + resourceType + \'=\' + id + \'}.\';\r\n\r\n	for (var i = 0, metricsLength = metrics.length; i < metricsLength; i++) {\r\n		const metric = ((Array.isArray(metrics[i]) ? metrics[i] : [metrics[i], defaultStatistic]));\r\n		metrics[i] = [metric[0], this.query + metric[1]];\r\n	}\r\n}\r\n\r\n\r\nconst params = JSON.parse(value);\r\nvalidateZabbixParams([\'tenancy_ocid\', \'user_ocid\', \'private_key\', \'fingerprint\', \'api_host\', \'bucket_name\', \'http_status_code\', \'req_interval\', \'compartment_id\'], params);\r\nvar oci = new OCI(\'Object storage\', \'Get metrics \' + params[\'req_interval\'] + \'m\', params);\r\n\r\nconst metrics = [\r\n	\'ObjectCount\',\r\n	\'StoredBytes\',\r\n	\'UncommittedParts\'\r\n];\r\nbuildMql(params[\'bucket_name\'], metrics, \'mean\', \'resourceDisplayName\')\r\n\r\nvar result = {};\r\nfor (var i = 0, metricsLength = metrics.length; i < metricsLength; i++) {\r\n	result[metrics[i][0]] = oci.extractData(\'post\', oci.executeRequest(\'post\', \'/20180401/metrics/actions/summarizeMetricsData\', \'?compartmentId=\' + encodeURIComponent(params[\'compartment_id\']), metrics[i][0] + metrics[i][1] + \'()\', \'oci_objectstorage\'), \'aggregatedDatapoints\');\r\n}\r\nreturn JSON.stringify(result);','','0','','','','','0',NULL,'Gets all metrics related to specific bucket that have update time of 1 hour.','0','7d','0','',NULL,'30s','','','','200','1','0','','','0','0','0','0','0','0','0','4a12f1c73e8f40be9136a095ad147775','0','2','0'),
('46861','21','','10620','Get enabled object lifecycle management','oci.obj.storage.metrics.olm.get','3h','31d','365d','0','3','','','','',NULL,NULL,'function validateZabbixParams(requiredParams, allParams) {\r\n	requiredParams.forEach(function (field) {\r\n		if (typeof allParams !== \'object\' || typeof allParams[field] === \'undefined\' || allParams[field] === \'\') {\r\n			throw \'Required param is not set: \' + field + \'.\';\r\n		}\r\n	});\r\n}\r\n\r\nfunction OCI(service, action, params) {\r\n	this.zabbixLogPrefix = \'[ OCI ] [ \' + service + \' ] [ \' + action + \' ]\';\r\n	this.request = new HttpRequest();\r\n\r\n	this.hash = function (string) {\r\n		return sha256(string);\r\n	};\r\n\r\n	this.sign = function (string) {\r\n		return sign(\'sha256\', params[\'private_key\'], string);\r\n	};\r\n\r\n	this.encode = function (hash) {\r\n		const hexArr = hash.match(/.{1,2}/g);\r\n		var uInt8Array = new Uint8Array(hexArr.length);\r\n		hexArr.forEach(function (hex, idx) {\r\n			uInt8Array[idx] = parseInt(hex, 16);\r\n		});\r\n		return btoa(uInt8Array);\r\n	};\r\n\r\n	this.getDate = function () {\r\n		const weekdayShortList = [\'Sun\', \'Mon\', \'Tue\', \'Wed\', \'Thu\', \'Fri\', \'Sat\'];\r\n		const monthShortList = [\'jan\', \'feb\', \'mar\', \'apr\', \'may\', \'jun\', \'jul\', \'aug\', \'sep\', \'oct\', \'nov\', \'dec\'];\r\n		const today = new Date();\r\n		return weekdayShortList[today.getUTCDay()] + \', \' + today.getUTCDate() + \' \' + monthShortList[today.getUTCMonth()] + \' \' + today.getUTCFullYear() + \' \' + today.getUTCHours() + \':\' + today.getUTCMinutes() + \':\' + today.getUTCSeconds() + \' GMT\';\r\n	};\r\n\r\n	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {\r\n		var headers = \'(request-target) date host\';\r\n		const contentTypeHeader = \'content-type: application/json\';\r\n		const dateHeader = \'date: \' + this.getDate();\r\n		const hostHeader = \'host: \' + params[\'api_host\'];\r\n		const requestTarget = \'(request-target): \' + httpMethod + \' \' + apiPath + apiParams;\r\n		var signingString = requestTarget + \'\\n\' + dateHeader + \'\\n\' + hostHeader;\r\n		var reqHeaders = [contentTypeHeader, dateHeader];\r\n\r\n		if (httpMethod === \'post\') {\r\n			var body = JSON.stringify({\r\n				\'namespace\': namespace,\r\n				\'query\': mql\r\n			});\r\n			headers = headers + \' x-content-sha256 content-type content-length\';\r\n			const bodyHeader = \'x-content-sha256: \' + this.encode(this.hash(body));\r\n			const bodyLengthHeader = \'content-length: \' + body.length;\r\n			signingString = signingString + \'\\n\' + bodyHeader + \'\\n\' + contentTypeHeader + \'\\n\' + bodyLengthHeader;\r\n			reqHeaders.push(bodyHeader, bodyLengthHeader);\r\n		}\r\n\r\n		const signature = this.encode(this.sign(signingString));\r\n\r\n		reqHeaders.push(\'Authorization: Signature version="1",keyId="\' + params[\'tenancy_ocid\'] + \'/\' + params[\'user_ocid\'] + \'/\' + params[\'fingerprint\'] + \'",algorithm="rsa-sha256",headers="\' + headers + \'",signature="\' + signature + \'"\');\r\n		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {\r\n			this.request.addHeader(reqHeaders[header]);\r\n		}\r\n\r\n		if (params[\'http_proxy\']) {\r\n			this.request.setProxy(params[\'http_proxy\']);\r\n			Zabbix.log(4, this.zabbixLogPrefix + \' Using http proxy: \' + params[\'http_proxy\']);\r\n		}\r\n\r\n		if (httpMethod === \'post\') {\r\n			var apiRateLimitExceeded = false;\r\n			do {\r\n				const response = this.request.post(\'https://\' + params[\'api_host\'] + apiPath + apiParams, body);\r\n\r\n				try {\r\n					if (JSON.parse(response)[\'code\'] === \'TooManyRequests\') {\r\n\r\n						apiRateLimitExceeded = true;\r\n						Zabbix.sleep(1000);\r\n					} else {\r\n						apiRateLimitExceeded = false;\r\n					}\r\n				} catch (error) {\r\n					Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the response: \' + JSON.stringify(response));\r\n					throw \'Could not parse the response. See logs for more information.\';\r\n				}\r\n			} while (apiRateLimitExceeded);\r\n		} else {\r\n			const response = this.request.get(\'https://\' + params[\'api_host\'] + apiPath + apiParams);\r\n		}\r\n\r\n		this.request.clearHeader();\r\n\r\n		if (this.request.getStatus() === parseInt(params[\'http_status_code\'])) {\r\n			return response;\r\n		} else {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Unexpected HTTP response code: \' + this.request.getStatus());\r\n			throw \'Unexpected HTTP response code: \' + this.request.getStatus();\r\n		}\r\n	};\r\n\r\n	this.extractData = function (httpMethod, data, keys, compartment) {\r\n		try {\r\n			data = JSON.parse(data);\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the received JSON object: \' + data);\r\n			throw \'Could not parse received JSON object. See logs for more information.\';\r\n		}\r\n\r\n		if (typeof keys == \'object\') {\r\n			var returnBuffer = [];\r\n			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {\r\n\r\n				var objectBuffer = {};\r\n				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {\r\n					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {\r\n						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];\r\n					} else {\r\n						Zabbix.log(3, this.zabbixLogPrefix + \' Received an unexpected JSON object. Could not get value for key "\' + keys[key] + \'" in JSON: \' + JSON.stringify(data[dataObj]));\r\n						throw \'Received an unexpected JSON object. See logs for more information.\';\r\n					}\r\n				}\r\n				if (typeof compartment != \'undefined\' && compartment != \'\') objectBuffer[\'compartment\'] = compartment;\r\n				returnBuffer.push(objectBuffer);\r\n			}\r\n			return returnBuffer;\r\n		}\r\n\r\n		try {\r\n			if (httpMethod === \'get\') {\r\n				return data[keys];\r\n			} else {\r\n				if (data.length === 0) {\r\n					return 0;\r\n				}\r\n				data = data[0][keys];\r\n				return data[data.length - 1][\'value\'];\r\n			}\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not find key "\' + keys + \'" in JSON: \' + JSON.stringify(data));\r\n			throw \'Could not find required key in JSON object. See logs for more information.\';\r\n		}\r\n	};\r\n}\r\n\r\n\r\nconst params = JSON.parse(value);\r\nvalidateZabbixParams([\'tenancy_ocid\', \'user_ocid\', \'private_key\', \'fingerprint\', \'api_host\', \'bucket_name\', \'http_status_code\', \'req_interval\', \'compartment_id\'], params);\r\nvar oci = new OCI(\'Object storage\', \'Get metrics \' + params[\'req_interval\'] + \'m\', params);\r\nconst mql = \'EnabledOLM[\' + params[\'req_interval\'] + \'m]{resourceDisplayName=\' + params[\'bucket_name\'] + \'}.mean()\';\r\n\r\nreturn JSON.stringify(oci.extractData(\'post\', oci.executeRequest(\'post\', \'/20180401/metrics/actions/summarizeMetricsData\', \'?compartmentId=\' + encodeURIComponent(params[\'compartment_id\']), mql, \'oci_objectstorage\'), \'aggregatedDatapoints\'));','','0','','','','','0',NULL,'Indicates whether a bucket has any executable Object Lifecycle Management policies configured. `EnabledOLM` emits:\r\n\r\n    1 - if policies are configured\r\n    0 - if no policies are configured','0','7d','0','',NULL,'10s','','','','200','1','0','','','0','0','0','0','0','0','0','5bb5ba3011e94e43bb1fdc79668c9537','0','2','0'),
('46933','21','','10617','Block volumes discovery','oci.block.volumes.discovery','1h','31d','365d','0','4','','','','',NULL,NULL,'function validateZabbixParams(requiredParams, allParams) {\r\n	requiredParams.forEach(function (field) {\r\n		if (typeof allParams !== \'object\' || typeof allParams[field] === \'undefined\' || allParams[field] === \'\') {\r\n			throw \'Required param is not set: \' + field + \'.\';\r\n		}\r\n	});\r\n}\r\n\r\nfunction prepareCompartments(compartments, tenancy) {\r\n	if (typeof compartments === \'undefined\' || compartments === \'\') {\r\n		return [tenancy];\r\n	} else {\r\n		return compartments.split(\',\')\r\n	}\r\n}\r\n\r\nfunction OCI(service, action, params) {\r\n	this.zabbixLogPrefix = \'[ OCI ] [ \' + service + \' ] [ \' + action + \' ]\';\r\n	this.request = new HttpRequest();\r\n\r\n	this.hash = function (string) {\r\n		return sha256(string);\r\n	};\r\n\r\n	this.sign = function (string) {\r\n		return sign(\'sha256\', params[\'private_key\'], string);\r\n	};\r\n\r\n	this.encode = function (hash) {\r\n		const hexArr = hash.match(/.{1,2}/g);\r\n		var uInt8Array = new Uint8Array(hexArr.length);\r\n		hexArr.forEach(function (hex, idx) {\r\n			uInt8Array[idx] = parseInt(hex, 16);\r\n		});\r\n		return btoa(uInt8Array);\r\n	};\r\n\r\n	this.getDate = function () {\r\n		const weekdayShortList = [\'Sun\', \'Mon\', \'Tue\', \'Wed\', \'Thu\', \'Fri\', \'Sat\'];\r\n		const monthShortList = [\'jan\', \'feb\', \'mar\', \'apr\', \'may\', \'jun\', \'jul\', \'aug\', \'sep\', \'oct\', \'nov\', \'dec\'];\r\n		const today = new Date();\r\n		return weekdayShortList[today.getUTCDay()] + \', \' + today.getUTCDate() + \' \' + monthShortList[today.getUTCMonth()] + \' \' + today.getUTCFullYear() + \' \' + today.getUTCHours() + \':\' + today.getUTCMinutes() + \':\' + today.getUTCSeconds() + \' GMT\';\r\n	};\r\n\r\n	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {\r\n		var headers = \'(request-target) date host\';\r\n		const contentTypeHeader = \'content-type: application/json\';\r\n		const dateHeader = \'date: \' + this.getDate();\r\n		const hostHeader = \'host: \' + params[\'api_host\'];\r\n		const requestTarget = \'(request-target): \' + httpMethod + \' \' + apiPath + apiParams;\r\n		var signingString = requestTarget + \'\\n\' + dateHeader + \'\\n\' + hostHeader;\r\n		var reqHeaders = [contentTypeHeader, dateHeader];\r\n\r\n		if (httpMethod === \'post\') {\r\n			var body = JSON.stringify({\r\n				\'namespace\': namespace,\r\n				\'query\': mql\r\n			});\r\n			headers = headers + \' x-content-sha256 content-type content-length\';\r\n			const bodyHeader = \'x-content-sha256: \' + this.encode(this.hash(body));\r\n			const bodyLengthHeader = \'content-length: \' + body.length;\r\n			signingString = signingString + \'\\n\' + bodyHeader + \'\\n\' + contentTypeHeader + \'\\n\' + bodyLengthHeader;\r\n			reqHeaders.push(bodyHeader, bodyLengthHeader);\r\n		}\r\n\r\n		const signature = this.encode(this.sign(signingString));\r\n\r\n		reqHeaders.push(\'Authorization: Signature version="1",keyId="\' + params[\'tenancy_ocid\'] + \'/\' + params[\'user_ocid\'] + \'/\' + params[\'fingerprint\'] + \'",algorithm="rsa-sha256",headers="\' + headers + \'",signature="\' + signature + \'"\');\r\n		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {\r\n			this.request.addHeader(reqHeaders[header]);\r\n		}\r\n\r\n		if (params[\'http_proxy\']) {\r\n			this.request.setProxy(params[\'http_proxy\']);\r\n			Zabbix.log(4, this.zabbixLogPrefix + \' Using http proxy: \' + params[\'http_proxy\']);\r\n		}\r\n\r\n		if (httpMethod === \'post\') {\r\n			var apiRateLimitExceeded = false;\r\n			do {\r\n				const response = this.request.post(\'https://\' + params[\'api_host\'] + apiPath + apiParams, body);\r\n\r\n				try {\r\n					if (JSON.parse(response)[\'code\'] === \'TooManyRequests\') {\r\n\r\n						apiRateLimitExceeded = true;\r\n						Zabbix.sleep(1000);\r\n					} else {\r\n						apiRateLimitExceeded = false;\r\n					}\r\n				} catch (error) {\r\n					Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the response: \' + JSON.stringify(response));\r\n					throw \'Could not parse the response. See logs for more information.\';\r\n				}\r\n			} while (apiRateLimitExceeded);\r\n		} else {\r\n			const response = this.request.get(\'https://\' + params[\'api_host\'] + apiPath + apiParams);\r\n		}\r\n\r\n		this.request.clearHeader();\r\n\r\n		if (this.request.getStatus() === parseInt(params[\'http_status_code\'])) {\r\n			return response;\r\n		} else {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Unexpected HTTP response code: \' + this.request.getStatus());\r\n			throw \'Unexpected HTTP response code: \' + this.request.getStatus();\r\n		}\r\n	};\r\n\r\n	this.extractData = function (httpMethod, data, keys, compartment) {\r\n		try {\r\n			data = JSON.parse(data);\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the received JSON object: \' + data);\r\n			throw \'Could not parse received JSON object. See logs for more information.\';\r\n		}\r\n\r\n		if (typeof keys == \'object\') {\r\n			var returnBuffer = [];\r\n			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {\r\n\r\n				var objectBuffer = {};\r\n				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {\r\n					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {\r\n						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];\r\n					} else {\r\n						Zabbix.log(3, this.zabbixLogPrefix + \' Received an unexpected JSON object. Could not get value for key "\' + keys[key] + \'" in JSON: \' + JSON.stringify(data[dataObj]));\r\n						throw \'Received an unexpected JSON object. See logs for more information.\';\r\n					}\r\n				}\r\n				if (typeof compartment != \'undefined\' && compartment != \'\') objectBuffer[\'compartment\'] = compartment;\r\n				returnBuffer.push(objectBuffer);\r\n			}\r\n			return returnBuffer;\r\n		}\r\n\r\n		try {\r\n			if (httpMethod === \'get\') {\r\n				return data[keys];\r\n			} else {\r\n				if (data.length === 0) {\r\n					return 0;\r\n				}\r\n				data = data[0][keys];\r\n				return data[data.length - 1][\'value\'];\r\n			}\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not find key "\' + keys + \'" in JSON: \' + JSON.stringify(data));\r\n			throw \'Could not find required key in JSON object. See logs for more information.\';\r\n		}\r\n	};\r\n}\r\n\r\n\r\nconst params = JSON.parse(value);\r\nvalidateZabbixParams([\'tenancy_ocid\', \'user_ocid\', \'private_key\', \'fingerprint\', \'api_host\', \'http_status_code\'], params);\r\nvar oci = new OCI(\'Block volume\', \'Get volumes\', params);\r\nvar compartments = prepareCompartments(params[\'compartment_ocid\'], params[\'tenancy_ocid\']);\r\n\r\nvar buffer = [];\r\ncompartments.forEach(function (compartment) {\r\n	Array.prototype.push.apply(buffer, oci.extractData(\'get\', oci.executeRequest(\'get\', \'/20160918/volumes\', \'?compartmentId=\' + encodeURIComponent(compartment)), [\'id\', \'displayName\', \'lifecycleState\', \'freeformTags\'], compartment));\r\n})\r\nreturn JSON.stringify(buffer);','','0','','','','','1',NULL,'Discover block volumes.','0','7d','1','',NULL,'10s','','','','200','1','0','','','0','0','0','0','0','0','0','72fa6dfedfd8497298c5930f48594e72','0','2','0'),
('46934','21','','10617','Boot volumes discovery','oci.boot.volumes.discovery','1h','31d','365d','0','4','','','','',NULL,NULL,'function validateZabbixParams(requiredParams, allParams) {\r\n	requiredParams.forEach(function (field) {\r\n		if (typeof allParams !== \'object\' || typeof allParams[field] === \'undefined\' || allParams[field] === \'\') {\r\n			throw \'Required param is not set: \' + field + \'.\';\r\n		}\r\n	});\r\n}\r\n\r\nfunction prepareCompartments(compartments, tenancy) {\r\n	if (typeof compartments === \'undefined\' || compartments === \'\') {\r\n		return [tenancy];\r\n	} else {\r\n		return compartments.split(\',\')\r\n	}\r\n}\r\n\r\nfunction OCI(service, action, params) {\r\n	this.zabbixLogPrefix = \'[ OCI ] [ \' + service + \' ] [ \' + action + \' ]\';\r\n	this.request = new HttpRequest();\r\n\r\n	this.hash = function (string) {\r\n		return sha256(string);\r\n	};\r\n\r\n	this.sign = function (string) {\r\n		return sign(\'sha256\', params[\'private_key\'], string);\r\n	};\r\n\r\n	this.encode = function (hash) {\r\n		const hexArr = hash.match(/.{1,2}/g);\r\n		var uInt8Array = new Uint8Array(hexArr.length);\r\n		hexArr.forEach(function (hex, idx) {\r\n			uInt8Array[idx] = parseInt(hex, 16);\r\n		});\r\n		return btoa(uInt8Array);\r\n	};\r\n\r\n	this.getDate = function () {\r\n		const weekdayShortList = [\'Sun\', \'Mon\', \'Tue\', \'Wed\', \'Thu\', \'Fri\', \'Sat\'];\r\n		const monthShortList = [\'jan\', \'feb\', \'mar\', \'apr\', \'may\', \'jun\', \'jul\', \'aug\', \'sep\', \'oct\', \'nov\', \'dec\'];\r\n		const today = new Date();\r\n		return weekdayShortList[today.getUTCDay()] + \', \' + today.getUTCDate() + \' \' + monthShortList[today.getUTCMonth()] + \' \' + today.getUTCFullYear() + \' \' + today.getUTCHours() + \':\' + today.getUTCMinutes() + \':\' + today.getUTCSeconds() + \' GMT\';\r\n	};\r\n\r\n	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {\r\n		var headers = \'(request-target) date host\';\r\n		const contentTypeHeader = \'content-type: application/json\';\r\n		const dateHeader = \'date: \' + this.getDate();\r\n		const hostHeader = \'host: \' + params[\'api_host\'];\r\n		const requestTarget = \'(request-target): \' + httpMethod + \' \' + apiPath + apiParams;\r\n		var signingString = requestTarget + \'\\n\' + dateHeader + \'\\n\' + hostHeader;\r\n		var reqHeaders = [contentTypeHeader, dateHeader];\r\n\r\n		if (httpMethod === \'post\') {\r\n			var body = JSON.stringify({\r\n				\'namespace\': namespace,\r\n				\'query\': mql\r\n			});\r\n			headers = headers + \' x-content-sha256 content-type content-length\';\r\n			const bodyHeader = \'x-content-sha256: \' + this.encode(this.hash(body));\r\n			const bodyLengthHeader = \'content-length: \' + body.length;\r\n			signingString = signingString + \'\\n\' + bodyHeader + \'\\n\' + contentTypeHeader + \'\\n\' + bodyLengthHeader;\r\n			reqHeaders.push(bodyHeader, bodyLengthHeader);\r\n		}\r\n\r\n		const signature = this.encode(this.sign(signingString));\r\n\r\n		reqHeaders.push(\'Authorization: Signature version="1",keyId="\' + params[\'tenancy_ocid\'] + \'/\' + params[\'user_ocid\'] + \'/\' + params[\'fingerprint\'] + \'",algorithm="rsa-sha256",headers="\' + headers + \'",signature="\' + signature + \'"\');\r\n		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {\r\n			this.request.addHeader(reqHeaders[header]);\r\n		}\r\n\r\n		if (params[\'http_proxy\']) {\r\n			this.request.setProxy(params[\'http_proxy\']);\r\n			Zabbix.log(4, this.zabbixLogPrefix + \' Using http proxy: \' + params[\'http_proxy\']);\r\n		}\r\n\r\n		if (httpMethod === \'post\') {\r\n			var apiRateLimitExceeded = false;\r\n			do {\r\n				const response = this.request.post(\'https://\' + params[\'api_host\'] + apiPath + apiParams, body);\r\n\r\n				try {\r\n					if (JSON.parse(response)[\'code\'] === \'TooManyRequests\') {\r\n\r\n						apiRateLimitExceeded = true;\r\n						Zabbix.sleep(1000);\r\n					} else {\r\n						apiRateLimitExceeded = false;\r\n					}\r\n				} catch (error) {\r\n					Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the response: \' + JSON.stringify(response));\r\n					throw \'Could not parse the response. See logs for more information.\';\r\n				}\r\n			} while (apiRateLimitExceeded);\r\n		} else {\r\n			const response = this.request.get(\'https://\' + params[\'api_host\'] + apiPath + apiParams);\r\n		}\r\n\r\n		this.request.clearHeader();\r\n\r\n		if (this.request.getStatus() === parseInt(params[\'http_status_code\'])) {\r\n			return response;\r\n		} else {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Unexpected HTTP response code: \' + this.request.getStatus());\r\n			throw \'Unexpected HTTP response code: \' + this.request.getStatus();\r\n		}\r\n	};\r\n\r\n	this.extractData = function (httpMethod, data, keys, compartment) {\r\n		try {\r\n			data = JSON.parse(data);\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the received JSON object: \' + data);\r\n			throw \'Could not parse received JSON object. See logs for more information.\';\r\n		}\r\n\r\n		if (typeof keys == \'object\') {\r\n			var returnBuffer = [];\r\n			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {\r\n\r\n				var objectBuffer = {};\r\n				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {\r\n					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {\r\n						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];\r\n					} else {\r\n						Zabbix.log(3, this.zabbixLogPrefix + \' Received an unexpected JSON object. Could not get value for key "\' + keys[key] + \'" in JSON: \' + JSON.stringify(data[dataObj]));\r\n						throw \'Received an unexpected JSON object. See logs for more information.\';\r\n					}\r\n				}\r\n				if (typeof compartment != \'undefined\' && compartment != \'\') objectBuffer[\'compartment\'] = compartment;\r\n				returnBuffer.push(objectBuffer);\r\n			}\r\n			return returnBuffer;\r\n		}\r\n\r\n		try {\r\n			if (httpMethod === \'get\') {\r\n				return data[keys];\r\n			} else {\r\n				if (data.length === 0) {\r\n					return 0;\r\n				}\r\n				data = data[0][keys];\r\n				return data[data.length - 1][\'value\'];\r\n			}\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not find key "\' + keys + \'" in JSON: \' + JSON.stringify(data));\r\n			throw \'Could not find required key in JSON object. See logs for more information.\';\r\n		}\r\n	};\r\n}\r\n\r\n\r\nconst params = JSON.parse(value);\r\nvalidateZabbixParams([\'tenancy_ocid\', \'user_ocid\', \'private_key\', \'fingerprint\', \'api_host\', \'http_status_code\'], params);\r\nvar oci = new OCI(\'Boot volume\', \'Get volumes\', params);\r\nvar compartments = prepareCompartments(params[\'compartment_ocid\'], params[\'tenancy_ocid\']);\r\n\r\nvar buffer = [];\r\ncompartments.forEach(function (compartment) {\r\n	Array.prototype.push.apply(buffer, oci.extractData(\'get\', oci.executeRequest(\'get\', \'/20160918/bootVolumes\', \'?compartmentId=\' + encodeURIComponent(compartment)), [\'id\', \'displayName\', \'lifecycleState\', \'freeformTags\'], compartment));\r\n})\r\nreturn JSON.stringify(buffer);','','0','','','','','1',NULL,'Discover boot volumes.','0','7d','1','',NULL,'10s','','','','200','1','0','','','0','0','0','0','0','0','0','90982afdf2f9430bb1c5a3755d8e6c6d','0','2','0'),
('46935','21','','10617','Compute instances discovery','oci.compute.discovery','1h','31d','365d','0','4','','','','',NULL,NULL,'function validateZabbixParams(requiredParams, allParams) {\r\n	requiredParams.forEach(function (field) {\r\n		if (typeof allParams !== \'object\' || typeof allParams[field] === \'undefined\' || allParams[field] === \'\') {\r\n			throw \'Required param is not set: \' + field + \'.\';\r\n		}\r\n	});\r\n}\r\n\r\nfunction prepareCompartments(compartments, tenancy) {\r\n	if (typeof compartments === \'undefined\' || compartments === \'\') {\r\n		return [tenancy];\r\n	} else {\r\n		return compartments.split(\',\')\r\n	}\r\n}\r\n\r\nfunction OCI(service, action, params) {\r\n	this.zabbixLogPrefix = \'[ OCI ] [ \' + service + \' ] [ \' + action + \' ]\';\r\n	this.request = new HttpRequest();\r\n\r\n	this.hash = function (string) {\r\n		return sha256(string);\r\n	};\r\n\r\n	this.sign = function (string) {\r\n		return sign(\'sha256\', params[\'private_key\'], string);\r\n	};\r\n\r\n	this.encode = function (hash) {\r\n		const hexArr = hash.match(/.{1,2}/g);\r\n		var uInt8Array = new Uint8Array(hexArr.length);\r\n		hexArr.forEach(function (hex, idx) {\r\n			uInt8Array[idx] = parseInt(hex, 16);\r\n		});\r\n		return btoa(uInt8Array);\r\n	};\r\n\r\n	this.getDate = function () {\r\n		const weekdayShortList = [\'Sun\', \'Mon\', \'Tue\', \'Wed\', \'Thu\', \'Fri\', \'Sat\'];\r\n		const monthShortList = [\'jan\', \'feb\', \'mar\', \'apr\', \'may\', \'jun\', \'jul\', \'aug\', \'sep\', \'oct\', \'nov\', \'dec\'];\r\n		const today = new Date();\r\n		return weekdayShortList[today.getUTCDay()] + \', \' + today.getUTCDate() + \' \' + monthShortList[today.getUTCMonth()] + \' \' + today.getUTCFullYear() + \' \' + today.getUTCHours() + \':\' + today.getUTCMinutes() + \':\' + today.getUTCSeconds() + \' GMT\';\r\n	};\r\n\r\n	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {\r\n		var headers = \'(request-target) date host\';\r\n		const contentTypeHeader = \'content-type: application/json\';\r\n		const dateHeader = \'date: \' + this.getDate();\r\n		const hostHeader = \'host: \' + params[\'api_host\'];\r\n		const requestTarget = \'(request-target): \' + httpMethod + \' \' + apiPath + apiParams;\r\n		var signingString = requestTarget + \'\\n\' + dateHeader + \'\\n\' + hostHeader;\r\n		var reqHeaders = [contentTypeHeader, dateHeader];\r\n\r\n		if (httpMethod === \'post\') {\r\n			var body = JSON.stringify({\r\n				\'namespace\': namespace,\r\n				\'query\': mql\r\n			});\r\n			headers = headers + \' x-content-sha256 content-type content-length\';\r\n			const bodyHeader = \'x-content-sha256: \' + this.encode(this.hash(body));\r\n			const bodyLengthHeader = \'content-length: \' + body.length;\r\n			signingString = signingString + \'\\n\' + bodyHeader + \'\\n\' + contentTypeHeader + \'\\n\' + bodyLengthHeader;\r\n			reqHeaders.push(bodyHeader, bodyLengthHeader);\r\n		}\r\n\r\n		const signature = this.encode(this.sign(signingString));\r\n\r\n		reqHeaders.push(\'Authorization: Signature version="1",keyId="\' + params[\'tenancy_ocid\'] + \'/\' + params[\'user_ocid\'] + \'/\' + params[\'fingerprint\'] + \'",algorithm="rsa-sha256",headers="\' + headers + \'",signature="\' + signature + \'"\');\r\n		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {\r\n			this.request.addHeader(reqHeaders[header]);\r\n		}\r\n\r\n		if (params[\'http_proxy\']) {\r\n			this.request.setProxy(params[\'http_proxy\']);\r\n			Zabbix.log(4, this.zabbixLogPrefix + \' Using http proxy: \' + params[\'http_proxy\']);\r\n		}\r\n\r\n		if (httpMethod === \'post\') {\r\n			var apiRateLimitExceeded = false;\r\n			do {\r\n				const response = this.request.post(\'https://\' + params[\'api_host\'] + apiPath + apiParams, body);\r\n\r\n				try {\r\n					if (JSON.parse(response)[\'code\'] === \'TooManyRequests\') {\r\n\r\n						apiRateLimitExceeded = true;\r\n						Zabbix.sleep(1000);\r\n					} else {\r\n						apiRateLimitExceeded = false;\r\n					}\r\n				} catch (error) {\r\n					Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the response: \' + JSON.stringify(response));\r\n					throw \'Could not parse the response. See logs for more information.\';\r\n				}\r\n			} while (apiRateLimitExceeded);\r\n		} else {\r\n			const response = this.request.get(\'https://\' + params[\'api_host\'] + apiPath + apiParams);\r\n		}\r\n\r\n		this.request.clearHeader();\r\n\r\n		if (this.request.getStatus() === parseInt(params[\'http_status_code\'])) {\r\n			return response;\r\n		} else {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Unexpected HTTP response code: \' + this.request.getStatus());\r\n			throw \'Unexpected HTTP response code: \' + this.request.getStatus();\r\n		}\r\n	};\r\n\r\n	this.extractData = function (httpMethod, data, keys, compartment) {\r\n		try {\r\n			data = JSON.parse(data);\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the received JSON object: \' + data);\r\n			throw \'Could not parse received JSON object. See logs for more information.\';\r\n		}\r\n\r\n		if (typeof keys == \'object\') {\r\n			var returnBuffer = [];\r\n			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {\r\n\r\n				var objectBuffer = {};\r\n				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {\r\n					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {\r\n						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];\r\n					} else {\r\n						Zabbix.log(3, this.zabbixLogPrefix + \' Received an unexpected JSON object. Could not get value for key "\' + keys[key] + \'" in JSON: \' + JSON.stringify(data[dataObj]));\r\n						throw \'Received an unexpected JSON object. See logs for more information.\';\r\n					}\r\n				}\r\n				if (typeof compartment != \'undefined\' && compartment != \'\') objectBuffer[\'compartment\'] = compartment;\r\n				returnBuffer.push(objectBuffer);\r\n			}\r\n			return returnBuffer;\r\n		}\r\n\r\n		try {\r\n			if (httpMethod === \'get\') {\r\n				return data[keys];\r\n			} else {\r\n				if (data.length === 0) {\r\n					return 0;\r\n				}\r\n				data = data[0][keys];\r\n				return data[data.length - 1][\'value\'];\r\n			}\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not find key "\' + keys + \'" in JSON: \' + JSON.stringify(data));\r\n			throw \'Could not find required key in JSON object. See logs for more information.\';\r\n		}\r\n	};\r\n}\r\n\r\n\r\nconst params = JSON.parse(value);\r\nvalidateZabbixParams([\'tenancy_ocid\', \'user_ocid\', \'private_key\', \'fingerprint\', \'api_host\', \'http_status_code\'], params);\r\nvar oci = new OCI(\'Compute\', \'Get instances\', params);\r\nvar compartments = prepareCompartments(params[\'compartment_ocid\'], params[\'tenancy_ocid\']);\r\n\r\nvar buffer = [];\r\ncompartments.forEach(function (compartment) {\r\n	Array.prototype.push.apply(buffer, oci.extractData(\'get\', oci.executeRequest(\'get\', \'/20160918/instances\', \'?compartmentId=\' + encodeURIComponent(compartment)), [\'id\', \'displayName\', \'lifecycleState\', \'freeformTags\', \'availabilityDomain\'], compartment));\r\n})\r\nreturn JSON.stringify(buffer);','','0','','','','','1',NULL,'Discover compute instances.','0','7d','1','',NULL,'10s','','','','200','1','0','','','0','0','0','0','0','0','0','ea4bbd0e9737406693aa0051cf861115','0','2','0'),
('46936','21','','10617','Autonomous database discovery','oci.object.autonomous.db.discovery','1h','31d','365d','0','4','','','','',NULL,NULL,'function validateZabbixParams(requiredParams, allParams) {\r\n	requiredParams.forEach(function (field) {\r\n		if (typeof allParams !== \'object\' || typeof allParams[field] === \'undefined\' || allParams[field] === \'\') {\r\n			throw \'Required param is not set: \' + field + \'.\';\r\n		}\r\n	});\r\n}\r\n\r\nfunction prepareCompartments(compartments, tenancy) {\r\n	if (typeof compartments === \'undefined\' || compartments === \'\') {\r\n		return [tenancy];\r\n	} else {\r\n		return compartments.split(\',\')\r\n	}\r\n}\r\n\r\nfunction OCI(service, action, params) {\r\n	this.zabbixLogPrefix = \'[ OCI ] [ \' + service + \' ] [ \' + action + \' ]\';\r\n	this.request = new HttpRequest();\r\n\r\n	this.hash = function (string) {\r\n		return sha256(string);\r\n	};\r\n\r\n	this.sign = function (string) {\r\n		return sign(\'sha256\', params[\'private_key\'], string);\r\n	};\r\n\r\n	this.encode = function (hash) {\r\n		const hexArr = hash.match(/.{1,2}/g);\r\n		var uInt8Array = new Uint8Array(hexArr.length);\r\n		hexArr.forEach(function (hex, idx) {\r\n			uInt8Array[idx] = parseInt(hex, 16);\r\n		});\r\n		return btoa(uInt8Array);\r\n	};\r\n\r\n	this.getDate = function () {\r\n		const weekdayShortList = [\'Sun\', \'Mon\', \'Tue\', \'Wed\', \'Thu\', \'Fri\', \'Sat\'];\r\n		const monthShortList = [\'jan\', \'feb\', \'mar\', \'apr\', \'may\', \'jun\', \'jul\', \'aug\', \'sep\', \'oct\', \'nov\', \'dec\'];\r\n		const today = new Date();\r\n		return weekdayShortList[today.getUTCDay()] + \', \' + today.getUTCDate() + \' \' + monthShortList[today.getUTCMonth()] + \' \' + today.getUTCFullYear() + \' \' + today.getUTCHours() + \':\' + today.getUTCMinutes() + \':\' + today.getUTCSeconds() + \' GMT\';\r\n	};\r\n\r\n	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {\r\n		var headers = \'(request-target) date host\';\r\n		const contentTypeHeader = \'content-type: application/json\';\r\n		const dateHeader = \'date: \' + this.getDate();\r\n		const hostHeader = \'host: \' + params[\'api_host\'];\r\n		const requestTarget = \'(request-target): \' + httpMethod + \' \' + apiPath + apiParams;\r\n		var signingString = requestTarget + \'\\n\' + dateHeader + \'\\n\' + hostHeader;\r\n		var reqHeaders = [contentTypeHeader, dateHeader];\r\n\r\n		if (httpMethod === \'post\') {\r\n			var body = JSON.stringify({\r\n				\'namespace\': namespace,\r\n				\'query\': mql\r\n			});\r\n			headers = headers + \' x-content-sha256 content-type content-length\';\r\n			const bodyHeader = \'x-content-sha256: \' + this.encode(this.hash(body));\r\n			const bodyLengthHeader = \'content-length: \' + body.length;\r\n			signingString = signingString + \'\\n\' + bodyHeader + \'\\n\' + contentTypeHeader + \'\\n\' + bodyLengthHeader;\r\n			reqHeaders.push(bodyHeader, bodyLengthHeader);\r\n		}\r\n\r\n		const signature = this.encode(this.sign(signingString));\r\n\r\n		reqHeaders.push(\'Authorization: Signature version="1",keyId="\' + params[\'tenancy_ocid\'] + \'/\' + params[\'user_ocid\'] + \'/\' + params[\'fingerprint\'] + \'",algorithm="rsa-sha256",headers="\' + headers + \'",signature="\' + signature + \'"\');\r\n		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {\r\n			this.request.addHeader(reqHeaders[header]);\r\n		}\r\n\r\n		if (params[\'http_proxy\']) {\r\n			this.request.setProxy(params[\'http_proxy\']);\r\n			Zabbix.log(4, this.zabbixLogPrefix + \' Using http proxy: \' + params[\'http_proxy\']);\r\n		}\r\n\r\n		if (httpMethod === \'post\') {\r\n			var apiRateLimitExceeded = false;\r\n			do {\r\n				const response = this.request.post(\'https://\' + params[\'api_host\'] + apiPath + apiParams, body);\r\n\r\n				try {\r\n					if (JSON.parse(response)[\'code\'] === \'TooManyRequests\') {\r\n\r\n						apiRateLimitExceeded = true;\r\n						Zabbix.sleep(1000);\r\n					} else {\r\n						apiRateLimitExceeded = false;\r\n					}\r\n				} catch (error) {\r\n					Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the response: \' + JSON.stringify(response));\r\n					throw \'Could not parse the response. See logs for more information.\';\r\n				}\r\n			} while (apiRateLimitExceeded);\r\n		} else {\r\n			const response = this.request.get(\'https://\' + params[\'api_host\'] + apiPath + apiParams);\r\n		}\r\n\r\n		this.request.clearHeader();\r\n\r\n		if (this.request.getStatus() === parseInt(params[\'http_status_code\'])) {\r\n			return response;\r\n		} else {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Unexpected HTTP response code: \' + this.request.getStatus());\r\n			throw \'Unexpected HTTP response code: \' + this.request.getStatus();\r\n		}\r\n	};\r\n\r\n	this.extractData = function (httpMethod, data, keys, compartment) {\r\n		try {\r\n			data = JSON.parse(data);\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not parse the received JSON object: \' + data);\r\n			throw \'Could not parse received JSON object. See logs for more information.\';\r\n		}\r\n\r\n		if (typeof keys == \'object\') {\r\n			var returnBuffer = [];\r\n			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {\r\n\r\n				var objectBuffer = {};\r\n				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {\r\n					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {\r\n						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];\r\n					} else {\r\n						Zabbix.log(3, this.zabbixLogPrefix + \' Received an unexpected JSON object. Could not get value for key "\' + keys[key] + \'" in JSON: \' + JSON.stringify(data[dataObj]));\r\n						throw \'Received an unexpected JSON object. See logs for more information.\';\r\n					}\r\n				}\r\n				if (typeof compartment != \'undefined\' && compartment != \'\') objectBuffer[\'compartment\'] = compartment;\r\n				returnBuffer.push(objectBuffer);\r\n			}\r\n			return returnBuffer;\r\n		}\r\n\r\n		try {\r\n			if (httpMethod === \'get\') {\r\n				return data[keys];\r\n			} else {\r\n				if (data.length === 0) {\r\n					return 0;\r\n				}\r\n				data = data[0][keys];\r\n				return data[data.length - 1][\'value\'];\r\n			}\r\n		} catch (error) {\r\n			Zabbix.log(3, this.zabbixLogPrefix + \' Could not find key "\' + keys + \'" in JSON: \' + JSON.stringify(data));\r\n			throw \'Could not find required key in JSON object. See logs for more information.\';\r\n		}\r\n	};\r\n}\r\n\r\n\r\nconst params = JSON.parse(value);\r\nvalidateZabbixParams([\'tenancy_ocid\', \'user_ocid\', \'private_key\', \'fingerprint\', \'api_host\', \'http_status_code\'], params);\r\nvar oci = new OCI(\'Autonomous DB\', \'Get DBs\', params);\r\nvar compartments = prepareCompartments(params[\'compartment_ocid\'], params[\'tenancy_ocid\']);\r\n\r\nvar buffer = [];\r\ncompartments.forEach(function (compartment) {\r\n	Array.prototype.push.apply(buffer, oci.extractData(\'get\', oci.executeRequest(\'get\', \'/20160918/autonomousDatabases\', \'?compartmentId=\' + encodeURIComponent(compartment)), [\'id\', \'dbName\', \'lifecycleState\', \'freeformTags\'], compartment));\r\n})\r\nreturn JSON.stringify(buffer);','','0','','','','','1',NULL,'Discover autonomous databases.','0','7d','1','',NULL,'10s','','','','200','1','0','','','0','0','0','0','0','0','0','c69611c5b86043b28c8ce2bc0627b377','0','2','0'),
