							dimensions = dimensions.concat(metric.MetricStat.Metric.Dimensions);
						}
					});
				}
				for (var i in dimensions) {
					if (dimensions[i].Name === ''ClusterName'' && dimensions[i].Value === AWS.params.cluster_name) {
						result.push(alarm);
						break;
					}
				}
			});
		}

		return result;
	}
}

try {
	AWS.setParams(JSON.parse(value));

	return JSON.stringify(AWS.getAlarms());
}
catch (error) {
	error += (String(error).endsWith(''.'')) ? '''' : ''.'';
	Zabbix.log(3, ''[ AWS ECS ] ERROR: '' + error);

	return JSON.stringify({ ''error'': error });
}','','0','','','','','0',NULL,'Get alarms data.
DescribeAlarms 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,E'var AWS = {
	params: {},
	metadata: ''http://169.254.169.254/latest/'',

	setParams: function (params) {
		AWS.params[''proxy''] = params.proxy;
		switch (AWS.getField(params, ''auth_type'')) {
			case ''role_base'':
				AWS.params[''auth_type''] = ''role_base'';
				var request = new HttpRequest();
				if (typeof AWS.params.proxy !== ''undefined'' && AWS.params.proxy !== '''') {
					request.setProxy(AWS.params.proxy);
				}
				request.addHeader(''X-aws-ec2-metadata-token-ttl-seconds: 21600'');
				var token = request.put(AWS.metadata + ''api/token'');

				if (request.getStatus() !== 200 || token === null || token === '''') {
					throw ''Error getting IMDSv2 session token.'';
				}
				request.addHeader(''X-aws-ec2-metadata-token: '' + token);
				var IamRoleName = request.get(AWS.metadata + ''meta-data/iam/security-credentials'');

				if (request.getStatus() !== 200 || IamRoleName === null || IamRoleName === '''') {
					throw ''Error getting security credentials from instance metadata. Role not found.'';
				}

				credentials = request.get(AWS.metadata + ''meta-data/iam/security-credentials/'' + encodeURI(IamRoleName));

				if (request.getStatus() !== 200 || credentials === null || credentials === '''') {
					throw ''Error getting security credentials from instance metadata.'';
				}

				try {
					credentials = JSON.parse(credentials);
				}
				catch (error) {
					throw ''Failed to parse response received from instance metadata. Check debug log for more information.'';
				}

				[''AccessKeyId'', ''SecretAccessKey'', ''Token''].forEach(function (field) {
					if (typeof credentials !== ''object'' || typeof credentials[field] === ''undefined'' || credentials[field] === '''') {
						throw ''Required credentials are not set: "'' + field + ''".'';
					};
					AWS.params[field] = credentials[field];
				});
				break;
			case ''assume_role'':
				AWS.params[''auth_type''] = ''assume_role'';

				[''AccessKeyId'', ''SecretAccessKey'', ''sts_region'', ''role_arn''].forEach(function (field) {
					if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
						throw ''Required param is not set: "'' + field + ''".'';
					}
					AWS.params[field] = params[field];
				});

				role_arn_regex = /role\\/(.+)$/;

				var payload = {
					''Action'': ''AssumeRole'',
					''Version'': ''2011-06-15'',
					''RoleArn'': AWS.params.role_arn,
					''RoleSessionName'': AWS.params.role_arn.match(role_arn_regex)[1] + ''Session'',
				};

				credentials = AWS.getField(AWS.request(''GET'', AWS.params.sts_region, ''sts'', AWS.prepareParams(payload)), ''AssumeRoleResponse.AssumeRoleResult.Credentials'');
				[''AccessKeyId'', ''SecretAccessKey'', ''SessionToken''].forEach(function (field) {
					if (typeof credentials !== ''object'' || typeof credentials[field] === ''undefined'' || credentials[field] === '''') {
						throw ''Required credentials are not set: "'' + field + ''".'';
					};
					AWS.params[field] = credentials[field];
				});
				break;
			default:
				AWS.params[''auth_type''] = ''access_key'';
				[''AccessKeyId'', ''SecretAccessKey''].forEach(function (field) {
					if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
						throw ''Required param is not set: "'' + field + ''".'';
					}
					AWS.params[field] = params[field];
				});
		}
		[''region'', ''cluster_name''].forEach(function (field) {
			if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
				throw ''Required param is not set: "'' + field + ''".'';
			}
			AWS.params[field] = params[field];
		});
	},

	getField: function (data, path) {
		var steps = path.split(''.'');
		for (var i = 0; i < steps.length; i++) {
			var step = steps[i];
			if (typeof data !== ''object'' || typeof data[step] === ''undefined'') {
				throw ''Required field was not found: '' + path;
			}

			data = data[step];
		}

		return data;
	},

	sign: function (key, message) {
		var hex = hmac(''sha256'', key, message);

		if ((hex.length % 2) === 1) {
			throw ''Invalid length of a hex string!'';
		}

		var result = new Int8Array(hex.length / 2);
		for (var i = 0, b = 0; i < hex.length; i += 2, b++) {
			result[b] = parseInt(hex.substring(i, i + 2), 16);
		}

		return result;
	},

	prepareParams: function (params) {
		var result = [];

		Object.keys(params).sort().forEach(function (key) {
			if (typeof params[key] !== ''object'') {
				result.push(key + ''='' + encodeURIComponent(params[key]));
			}
			else {
				result.push(prepareObject(key, params[key]));
			}
		});

		return result.join(''&'');
	},

	request: function (method, region, service, params, data) {
		if (typeof data === ''undefined'' || data === null) {
			data = '''';
		}

		var amzdate = (new Date()).toISOString().replace(/\\.\\d+Z/, ''Z'').replace(/[-:]/g, ''''),
			date = amzdate.replace(/T\\d+Z/, ''''),
			canonical_uri = ''/'',
			host = service + ''.'' + region + ''.amazonaws.com'',
			canonical_headers = ''content-encoding:amz-1.0\\n'' + ''host:'' + host + ''\\n'' + ''x-amz-date:'' + amzdate + ''\\n'',
			signed_headers = ''content-encoding;host;x-amz-date'',
			canonical_request = method + ''\\n'' + canonical_uri + ''\\n'' + params + ''\\n'' + canonical_headers + ''\\n'' + signed_headers + ''\\n'' + sha256(data),
			credential_scope = date + ''/'' + region + ''/'' + service + ''/'' + ''aws4_request'',
			request_string = ''AWS4-HMAC-SHA256'' + ''\\n'' + amzdate + ''\\n'' + credential_scope + ''\\n'' + sha256(canonical_request),
			key = AWS.sign(''AWS4'' + AWS.params.SecretAccessKey, date),
			key = AWS.sign(key, region),
			key = AWS.sign(key, service),
			key = AWS.sign(key, ''aws4_request''),
			request = new HttpRequest(),
			url = ''https://'' + host + canonical_uri + ''?'' + params;

		if (typeof AWS.params.proxy !== ''undefined'' && AWS.params.proxy !== '''') {
			request.setProxy(AWS.params.proxy);
		}
		request.addHeader(''x-amz-date: '' + amzdate);
		request.addHeader(''x-amz-content-sha256:'' + sha256(data));
		request.addHeader(''Accept: application/json'');
		request.addHeader(''Content-Type: application/x-www-form-urlencoded'');
		request.addHeader(''Content-Encoding: amz-1.0'');
		request.addHeader(''Authorization: '' + ''AWS4-HMAC-SHA256 Credential='' + AWS.params.AccessKeyId + ''/'' + credential_scope + '', '' + ''SignedHeaders='' + signed_headers + '', '' + ''Signature='' + hmac(''sha256'', key, request_string));
		if (AWS.params.auth_type === ''role_base'' || (AWS.params.auth_type === ''assume_role'' & !params.includes(''AssumeRole''))) {
			request.addHeader(''X-Amz-Security-Token: '' + (AWS.params.auth_type === ''role_base'' ? AWS.params.Token : AWS.params.SessionToken));
		}

		Zabbix.log(4, ''[ AWS ECS ] Sending request: '' + url);
		response = request.get(url);
		Zabbix.log(4, ''[ AWS ECS ] Received response with status code '' + request.getStatus() + '': '' + response);

		if (request.getStatus() !== 200) {
			throw ''Request failed with status code '' + request.getStatus() + '': '' + response;
		}

		try {
			response = JSON.parse(response);
		}
		catch (error) {
			try {
				response = JSON.parse(XML.toJson(response));
			}
			catch (error) {
				throw ''Failed to parse response received from AWS CloudWatch API. Check debug log for more information.'';
			}
		}

		return response;
	},

	listServices: function () {
		var payload = {
			''Action'': ''ListServices'',
			''Version'': ''2014-11-13'',
			''cluster'': AWS.params.cluster_name
		},
			services = [];

		ECSClusters_Services = AWS.getField(AWS.request(''GET'', AWS.params.region, ''ecs'', AWS.prepareParams(payload)), ''ListServicesResponse.ListServicesResult.serviceArns'');

		for (k in ECSClusters_Services) {
			id = ECSClusters_Services[k];

			json = {};
			input = id.split(AWS.params.cluster_name + ''/'');
			for (var i = 1; i < input.length; i += 2) {
				json[input[i]] = input[i + 1];
			}
			services.push({
				''service_name'': input[1],
			});
		}

		if (Array.isArray(services))
			return services;
		else
			return [services];
	}
};

try {
	AWS.setParams(JSON.parse(value));
	return JSON.stringify(AWS.listServices());
}
catch (error) {
	error += (String(error).endsWith(''.'')) ? '''' : ''.'';
	Zabbix.log(3, ''[ AWS ECS ] ERROR: '' + error);
	return JSON.stringify({ ''error'': error });
}','','0','','','','','0',NULL,'Get cluster services.
Full 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,E'var AWS = {
	params: {},
	request_period: 600,
	metadata: ''http://169.254.169.254/latest/'',

	setParams: function (params) {
		AWS.params[''proxy''] = params.proxy;
		switch (AWS.getField(params, ''auth_type'')) {
			case ''role_base'':
				AWS.params[''auth_type''] = ''role_base'';
				var request = new HttpRequest();
				if (typeof AWS.params.proxy !== ''undefined'' && AWS.params.proxy !== '''') {
					request.setProxy(AWS.params.proxy);
				}
				request.addHeader(''X-aws-ec2-metadata-token-ttl-seconds: 21600'');
				var token = request.put(AWS.metadata + ''api/token'');

				if (request.getStatus() !== 200 || token === null || token === '''') {
					throw ''Error getting IMDSv2 session token.'';
				}
				request.addHeader(''X-aws-ec2-metadata-token: '' + token);
				var IamRoleName = request.get(AWS.metadata + ''meta-data/iam/security-credentials'');

				if (request.getStatus() !== 200 || IamRoleName === null || IamRoleName === '''') {
					throw ''Error getting security credentials from instance metadata. Role not found.'';
				}

				credentials = request.get(AWS.metadata + ''meta-data/iam/security-credentials/'' + encodeURI(IamRoleName));

				if (request.getStatus() !== 200 || credentials === null || credentials === '''') {
					throw ''Error getting security credentials from instance metadata.'';
				}

				try {
					credentials = JSON.parse(credentials);
				}
				catch (error) {
					throw ''Failed to parse response received from instance metadata. Check debug log for more information.'';
				}

				[''AccessKeyId'', ''SecretAccessKey'', ''Token''].forEach(function (field) {
					if (typeof credentials !== ''object'' || typeof credentials[field] === ''undefined'' || credentials[field] === '''') {
						throw ''Required credentials are not set: "'' + field + ''".'';
					};
					AWS.params[field] = credentials[field];
				});
				break;
			case ''assume_role'':
				AWS.params[''auth_type''] = ''assume_role'';

				[''AccessKeyId'', ''SecretAccessKey'', ''sts_region'', ''role_arn''].forEach(function (field) {
					if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
						throw ''Required param is not set: "'' + field + ''".'';
					}
					AWS.params[field] = params[field];
				});

				role_arn_regex = /role\\/(.+)$/;

				var payload = {
					''Action'': ''AssumeRole'',
					''Version'': ''2011-06-15'',
					''RoleArn'': AWS.params.role_arn,
					''RoleSessionName'': AWS.params.role_arn.match(role_arn_regex)[1] + ''Session'',
				};

				credentials = AWS.getField(AWS.request(''GET'', AWS.params.sts_region, ''sts'', AWS.prepareParams(payload), ''''), ''AssumeRoleResponse.AssumeRoleResult.Credentials'');

				[''AccessKeyId'', ''SecretAccessKey'', ''SessionToken''].forEach(function (field) {
					if (typeof credentials !== ''object'' || typeof credentials[field] === ''undefined'' || credentials[field] === '''') {
						throw ''Required credentials are not set: "'' + field + ''".'';
					};
					AWS.params[field] = credentials[field];
				});
				break;
			default:
				AWS.params[''auth_type''] = ''access_key'';
				[''AccessKeyId'', ''SecretAccessKey''].forEach(function (field) {
					if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
						throw ''Required param is not set: "'' + field + ''".'';
					}
					AWS.params[field] = params[field];
				});
		}
		[''region'', ''cluster_name''].forEach(function (field) {
			if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
				throw ''Required param is not set: "'' + field + ''".'';
			}
			AWS.params[field] = params[field];
		});
	},

	getField: function (data, path) {
		var steps = path.split(''.'');
		for (var i = 0; i < steps.length; i++) {
			var step = steps[i];
			if (typeof data !== ''object'' || typeof data[step] === ''undefined'') {
				throw ''Required field was not found: '' + path;
			}

			data = data[step];
		}

		return data;
	},

	sign: function (key, message) {
		var hex = hmac(''sha256'', key, message);

		if ((hex.length % 2) === 1) {
			throw ''Invalid length of a hex string!'';
		}

		var result = new Int8Array(hex.length / 2);
		for (var i = 0, b = 0; i < hex.length; i += 2, b++) {
			result[b] = parseInt(hex.substring(i, i + 2), 16);
		}

		return result;
	},

	prepareRecursive: function (prefix, param) {
		var result = {};

		if (typeof param === ''object'') {
			if (Array.isArray(param)) {
				param.forEach(function (value, index) {
					var nested = AWS.prepareRecursive(prefix + ''.member.'' + (index + 1), value);
					Object.keys(nested).forEach(function (key) {
						result[key] = nested[key];
					});
				});
			}
			else {
				Object.keys(param).forEach(function (k) {
					var nested = AWS.prepareRecursive(prefix + ''.'' + k, param[k]);
					Object.keys(nested).forEach(function (key) {
						result[key] = nested[key];
					});
				});
			}
		}
		else {
			result[prefix] = param;
		}

		return result;
	},

	renderPayload: function (period, cluster_name) {
		var metrics_list = [
			''ContainerInstanceCount:Count'',
			''ServiceCount:Count'',
			''CpuReserved:None'',
			''CpuUtilized:None'',
			''MemoryReserved:Megabytes'',
			''MemoryUtilized:Megabytes'',
			''NetworkRxBytes:Bytes/Second'',
			''NetworkTxBytes:Bytes/Second'',
			''StorageReadBytes:Bytes'',
			''StorageWriteBytes:Bytes'',
			''TaskCount:Count'',
			''EphemeralStorageReserved:Gigabytes'',
			''EphemeralStorageUtilized:Gigabytes''
		];

		var metric_payload = [];
		metrics_list.forEach(function (metric) {
			var parts = metric.split('':'', 2);
			var name = parts[0].replace(/[^a-zA-Z0-9]/g, '''');
			metric_payload.push({
				''Id'': name.charAt(0).toLowerCase() + name.slice(1),
				''MetricStat'': {
					''Metric'': {
						''MetricName'': parts[0],
						''Namespace'': ''ECS/ContainerInsights'',
						''Dimensions'': [
							{
								''Name'': ''ClusterName'',
								''Value'': cluster_name
							}
						]
					},
					''Period'': period,
					''Stat'': ''Average'',
					''Unit'': parts[1]
				}
			});
		});

		return metric_payload;
	},

	prepareParams: function (params) {
		var result = [];

		Object.keys(params).sort().forEach(function (key) {
			if (typeof params[key] !== ''object'') {
				result.push(key + ''='' + encodeURIComponent(params[key]));
			}
			else {
				result.push(prepareObject(key, params[key]));
			}
		});

		return result.join(''&'');
	},

	request: function (method, region, service, params, data) {
		if (typeof data === ''undefined'' || data === null) {
			data = '''';
		}

		var amzdate = (new Date()).toISOString().replace(/\\.\\d+Z/, ''Z'').replace(/[-:]/g, ''''),
			date = amzdate.replace(/T\\d+Z/, ''''),
			host = service + ''.'' + region + ''.amazonaws.com'',
			canonical_uri = ''/'',
			canonical_headers = ''content-encoding:amz-1.0\\n'' + ''host:'' + host + ''\\n'' + ''x-amz-date:'' + amzdate + ''\\n'',
			signed_headers = ''content-encoding;host;x-amz-date'',
			canonical_request = method + ''\\n'' + canonical_uri + ''\\n'' + params + ''\\n'' + canonical_headers + ''\\n'' + signed_headers + ''\\n'' + sha256(data),
			credential_scope = date + ''/'' + region + ''/'' + service + ''/'' + ''aws4_request'',
			request_string = ''AWS4-HMAC-SHA256'' + ''\\n'' + amzdate + ''\\n'' + credential_scope + ''\\n'' + sha256(canonical_request),
			key = AWS.sign(''AWS4'' + AWS.params.SecretAccessKey, date),
			key = AWS.sign(key, region),
			key = AWS.sign(key, service),
			key = AWS.sign(key, ''aws4_request''),
			request = new HttpRequest(),
			url = ''https://'' + host + canonical_uri + ''?'' + params;

		if (typeof AWS.params.proxy !== ''undefined'' && AWS.params.proxy !== '''') {
			request.setProxy(AWS.params.proxy);
		}
		request.addHeader(''x-amz-date: '' + amzdate);
		request.addHeader(''Accept: application/json'');
		request.addHeader(''Content-Type: application/json'');
		request.addHeader(''Content-Encoding: amz-1.0'');
		request.addHeader(''Authorization: '' + ''AWS4-HMAC-SHA256 Credential='' + AWS.params.AccessKeyId + ''/'' + credential_scope + '', '' + ''SignedHeaders='' + signed_headers + '', '' + ''Signature='' + hmac(''sha256'', key, request_string));
		if (AWS.params.auth_type === ''role_base'' || (AWS.params.auth_type === ''assume_role'' & !params.includes(''AssumeRole''))) {
			request.addHeader(''X-Amz-Security-Token: '' + (AWS.params.auth_type === ''role_base'' ? AWS.params.Token : AWS.params.SessionToken));
		}

		Zabbix.log(4, ''[ AWS ECS  ] Sending request: '' + url);
		response = request.get(url);
		Zabbix.log(4, ''[ AWS ECS ] Received response with status code '' + request.getStatus() + '': '' + response);

		if (request.getStatus() !== 200) {
			throw ''Request failed with status code '' + request.getStatus() + '': '' + response;
		}

		try {
			response = JSON.parse(response);
		}
		catch (error) {
			try {
				response = JSON.parse(XML.toJson(response));
			}
			catch (error) {
				throw ''Failed to parse response received from AWS CloudWatch API. Check debug log for more information.'';
			}
		}

		return response;
	},

	getMetricsData: function () {
		var timestamp = new Date().getTime(),
			MetricData = [],
			CPUUtilization,
			MemoryUtilization,
			DiskUtilization,
			obj = {},
			metrics = [''CpuReserved'', ''CpuUtilized'', ''MemoryReserved'', ''MemoryUtilized'', ''EphemeralStorageReserved'', ''EphemeralStorageUtilized''],
			end_time = new Date(timestamp).toISOString().replace(/\\.\\d+Z/, ''Z''),
			start_time = new Date(timestamp - AWS.request_period * 1000).toISOString().replace(/\\.\\d+Z/, ''Z''),
			payload = AWS.prepareRecursive(''MetricDataQueries'', AWS.renderPayload(AWS.request_period, AWS.params.cluster_name));

		payload[''Action''] = ''GetMetricData'';
		payload[''Version''] = ''2010-08-01'';
		payload[''StartTime''] = start_time;
		payload[''EndTime''] = end_time;
		payload[''ScanBy''] = ''TimestampDescending'';

		result = AWS.request(''GET'', AWS.params.region, ''monitoring'', AWS.prepareParams(payload));
		MetricData = AWS.getField(result, ''GetMetricDataResponse.GetMetricDataResult.MetricDataResults'')

		MetricData.forEach(function (id) {
			for (i in metrics) {
				if (AWS.getField(id, ''Label'') === metrics[i]) {
					obj[metrics[i]] = AWS.getField(id, ''Values'');
				}
			}
		});
		CPUUtilization = Math.abs(obj.CpuUtilized * 100 / obj.CpuReserved);
		MemoryUtilization = Math.abs(obj.MemoryUtilized * 100 / obj.MemoryReserved);
		DiskUtilization = Math.abs(obj.EphemeralStorageUtilized * 100 / obj.EphemeralStorageReserved);
		return ({ MetricData, MemoryUtilization, CPUUtilization, DiskUtilization });
	}
};

try {
	AWS.setParams(JSON.parse(value));

	return JSON.stringify(AWS.getMetricsData());
}
catch (error) {
	error += (String(error).endsWith(''.'')) ? '''' : ''.'';
	Zabbix.log(3, ''[ AWS ECS ] ERROR: '' + error);

	return JSON.stringify({ ''error'': error });
}','','0','','','','','0',NULL,'Get cluster metrics.
Full 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,E'var AWS = {
	params: {},
	request_period: 600,
	metadata: ''http://169.254.169.254/latest/'',

	setParams: function (params) {
		AWS.params[''proxy''] = params.proxy;
		switch (AWS.getField(params, ''auth_type'')) {
			case ''role_base'':
				AWS.params[''auth_type''] = ''role_base'';
				var request = new HttpRequest();
				if (typeof AWS.params.proxy !== ''undefined'' && AWS.params.proxy !== '''') {
					request.setProxy(AWS.params.proxy);
				}
				request.addHeader(''X-aws-ec2-metadata-token-ttl-seconds: 21600'');
				var token = request.put(AWS.metadata + ''api/token'');

				if (request.getStatus() !== 200 || token === null || token === '''') {
					throw ''Error getting IMDSv2 session token.'';
				}
				request.addHeader(''X-aws-ec2-metadata-token: '' + token);
				var IamRoleName = request.get(AWS.metadata + ''meta-data/iam/security-credentials'');

				if (request.getStatus() !== 200 || IamRoleName === null || IamRoleName === '''') {
					throw ''Error getting security credentials from instance metadata. Role not found.'';
				}

				credentials = request.get(AWS.metadata + ''meta-data/iam/security-credentials/'' + encodeURI(IamRoleName));

				if (request.getStatus() !== 200 || credentials === null || credentials === '''') {
					throw ''Error getting security credentials from instance metadata.'';
				}

				try {
					credentials = JSON.parse(credentials);
				}
				catch (error) {
					throw ''Failed to parse response received from instance metadata. Check debug log for more information.'';
				}

				[''AccessKeyId'', ''SecretAccessKey'', ''Token''].forEach(function (field) {
					if (typeof credentials !== ''object'' || typeof credentials[field] === ''undefined'' || credentials[field] === '''') {
						throw ''Required credentials are not set: "'' + field + ''".'';
					};
					AWS.params[field] = credentials[field];
				});
				break;
			case ''assume_role'':
				AWS.params[''auth_type''] = ''assume_role'';

				[''AccessKeyId'', ''SecretAccessKey'', ''sts_region'', ''role_arn''].forEach(function (field) {
					if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
						throw ''Required param is not set: "'' + field + ''".'';
					}
					AWS.params[field] = params[field];
				});

				role_arn_regex = /role\\/(.+)$/;

				var payload = {
					''Action'': ''AssumeRole'',
					''Version'': ''2011-06-15'',
					''RoleArn'': AWS.params.role_arn,
					''RoleSessionName'': AWS.params.role_arn.match(role_arn_regex)[1] + ''Session'',
				};

				credentials = AWS.getField(AWS.request(''GET'', AWS.params.sts_region, ''sts'', AWS.prepareParams(payload), ''''), ''AssumeRoleResponse.AssumeRoleResult.Credentials'');

				[''AccessKeyId'', ''SecretAccessKey'', ''SessionToken''].forEach(function (field) {
					if (typeof credentials !== ''object'' || typeof credentials[field] === ''undefined'' || credentials[field] === '''') {
						throw ''Required credentials are not set: "'' + field + ''".'';
					};
					AWS.params[field] = credentials[field];
				});
				break;
			default:
				AWS.params[''auth_type''] = ''access_key'';
				[''AccessKeyId'', ''SecretAccessKey''].forEach(function (field) {
					if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
						throw ''Required param is not set: "'' + field + ''".'';
					}
					AWS.params[field] = params[field];
				});
		}
		[''region'', ''cluster_name'', ''service_name''].forEach(function (field) {
			if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
				throw ''Required param is not set: "'' + field + ''".'';
			}
			AWS.params[field] = params[field];
		});
	},

	getField: function (data, path) {
		var steps = path.split(''.'');
		for (var i = 0; i < steps.length; i++) {
			var step = steps[i];
			if (typeof data !== ''object'' || typeof data[step] === ''undefined'') {
				throw ''Required field was not found: '' + path;
			}

			data = data[step];
		}

		return data;
	},

	sign: function (key, message) {
		var hex = hmac(''sha256'', key, message);

		if ((hex.length % 2) === 1) {
			throw ''Invalid length of a hex string!'';
		}

		var result = new Int8Array(hex.length / 2);
		for (var i = 0, b = 0; i < hex.length; i += 2, b++) {
			result[b] = parseInt(hex.substring(i, i + 2), 16);
		}

		return result;
	},

	prepareRecursive: function (prefix, param) {
		var result = {};

		if (typeof param === ''object'') {
			if (Array.isArray(param)) {
				param.forEach(function (value, index) {
					var nested = AWS.prepareRecursive(prefix + ''.member.'' + (index + 1), value);
					Object.keys(nested).forEach(function (key) {
						result[key] = nested[key];
					});
				});
			}
			else {
				Object.keys(param).forEach(function (k) {
					var nested = AWS.prepareRecursive(prefix + ''.'' + k, param[k]);
					Object.keys(nested).forEach(function (key) {
						result[key] = nested[key];
					});
				});
			}
		}
		else {
			result[prefix] = param;
		}

		return result;
	},

	renderPayload: function (period, cluster_name, service_name) {
		var metrics_list = [
			''CpuReserved:None:ECS/ContainerInsights'',
			''CpuUtilized:None:ECS/ContainerInsights'',
			''CPUUtilization:Percent:AWS/ECS'',
			''MemoryUtilization:Percent:AWS/ECS'',
			''MemoryReserved:Megabytes:ECS/ContainerInsights'',
			''MemoryUtilized:Megabytes:ECS/ContainerInsights'',
			''NetworkRxBytes:Bytes/Second:ECS/ContainerInsights'',
			''NetworkTxBytes:Bytes/Second:ECS/ContainerInsights'',
			''StorageReadBytes:Bytes:ECS/ContainerInsights'',
			''StorageWriteBytes:Bytes:ECS/ContainerInsights'',
			''DeploymentCount:Count:ECS/ContainerInsights'',
			''TaskSetCount:Count:ECS/ContainerInsights'',
			''DesiredTaskCount:Count:ECS/ContainerInsights'',
			''PendingTaskCount:Count:ECS/ContainerInsights'',
			''RunningTaskCount:Count:ECS/ContainerInsights'',
			''EphemeralStorageReserved:Gigabytes:ECS/ContainerInsights'',
			''EphemeralStorageUtilized:Gigabytes:ECS/ContainerInsights''
		];

		var metric_payload = [];
		metrics_list.forEach(function (metric) {
			var parts = metric.split('':'', 3);
			var name = parts[0].replace(/[^a-zA-Z0-9]/g, '''');
			metric_payload.push({
				''Id'': name.charAt(0).toLowerCase() + name.slice(1),
				''MetricStat'': {
					''Metric'': {
						''MetricName'': parts[0],
						''Namespace'': parts[2],
						''Dimensions'': [
							{
								''Name'': ''ClusterName'',
								''Value'': cluster_name
							}
							,
							{
								''Name'': ''ServiceName'',
								''Value'': service_name
							}
						]
					},
					''Period'': period,
					''Stat'': ''Average'',
					''Unit'': parts[1]
				}
			});
		});

		return metric_payload;
	},

	prepareParams: function (params) {
		var result = [];

		Object.keys(params).sort().forEach(function (key) {
			if (typeof params[key] !== ''object'') {
				result.push(key + ''='' + encodeURIComponent(params[key]));
			}
			else {
				result.push(prepareObject(key, params[key]));
			}
		});

		return result.join(''&'');
	},

	request: function (method, region, service, params, data) {
		if (typeof data === ''undefined'' || data === null) {
			data = '''';
		}

		var amzdate = (new Date()).toISOString().replace(/\\.\\d+Z/, ''Z'').replace(/[-:]/g, ''''),
			date = amzdate.replace(/T\\d+Z/, ''''),
			host = service + ''.'' + region + ''.amazonaws.com'',
			canonical_uri = ''/'',
			canonical_headers = ''content-encoding:amz-1.0\\n'' + ''host:'' + host + ''\\n'' + ''x-amz-date:'' + amzdate + ''\\n'',
			signed_headers = ''content-encoding;host;x-amz-date'',
			canonical_request = method + ''\\n'' + canonical_uri + ''\\n'' + params + ''\\n'' + canonical_headers + ''\\n'' + signed_headers + ''\\n'' + sha256(data),
			credential_scope = date + ''/'' + region + ''/'' + service + ''/'' + ''aws4_request'',
			request_string = ''AWS4-HMAC-SHA256'' + ''\\n'' + amzdate + ''\\n'' + credential_scope + ''\\n'' + sha256(canonical_request),
			key = AWS.sign(''AWS4'' + AWS.params.SecretAccessKey, date),
			key = AWS.sign(key, region),
			key = AWS.sign(key, service),
			key = AWS.sign(key, ''aws4_request''),
			request = new HttpRequest(),
			url = ''https://'' + host + canonical_uri + ''?'' + params;

		if (typeof AWS.params.proxy !== ''undefined'' && AWS.params.proxy !== '''') {
			request.setProxy(AWS.params.proxy);
		}
		request.addHeader(''x-amz-date: '' + amzdate);
		request.addHeader(''Accept: application/json'');
		request.addHeader(''Content-Type: application/json'');
		request.addHeader(''Content-Encoding: amz-1.0'');
		request.addHeader(''Authorization: '' + ''AWS4-HMAC-SHA256 Credential='' + AWS.params.AccessKeyId + ''/'' + credential_scope + '', '' + ''SignedHeaders='' + signed_headers + '', '' + ''Signature='' + hmac(''sha256'', key, request_string));
		if (AWS.params.auth_type === ''role_base'' || (AWS.params.auth_type === ''assume_role'' & !params.includes(''AssumeRole''))) {
			request.addHeader(''X-Amz-Security-Token: '' + (AWS.params.auth_type === ''role_base'' ? AWS.params.Token : AWS.params.SessionToken));
		}

		Zabbix.log(4, ''[ AWS ECS  ] Sending request: '' + url);
		response = request.get(url);
		Zabbix.log(4, ''[ AWS ECS ] Received response with status code '' + request.getStatus() + '': '' + response);

		if (request.getStatus() !== 200) {
			throw ''Request failed with status code '' + request.getStatus() + '': '' + response;
		}

		try {
			response = JSON.parse(response);
		}
		catch (error) {
			try {
				response = JSON.parse(XML.toJson(response));
			}
			catch (error) {
				throw ''Failed to parse response received from AWS CloudWatch API. Check debug log for more information.'';
			}
		}

		return response;
	},

	getMetricsData: function () {
		var timestamp = new Date().getTime(),
			end_time = new Date(timestamp).toISOString().replace(/\\.\\d+Z/, ''Z''),
			start_time = new Date(timestamp - AWS.request_period * 1000).toISOString().replace(/\\.\\d+Z/, ''Z''),
			payload = AWS.prepareRecursive(''MetricDataQueries'', AWS.renderPayload(AWS.request_period, AWS.params.cluster_name, AWS.params.service_name));

		payload[''Action''] = ''GetMetricData'';
		payload[''Version''] = ''2010-08-01'';
		payload[''StartTime''] = start_time;
		payload[''EndTime''] = end_time;
		payload[''ScanBy''] = ''TimestampDescending'';

		result = AWS.request(''GET'', AWS.params.region, ''monitoring'', AWS.prepareParams(payload));
		MetricData = AWS.getField(result, ''GetMetricDataResponse.GetMetricDataResult.MetricDataResults'')

		return MetricData;
	}
};

try {
	AWS.setParams(JSON.parse(value));

	return JSON.stringify(AWS.getMetricsData());
}
catch (error) {
	error += (String(error).endsWith(''.'')) ? '''' : ''.'';
	Zabbix.log(3, ''[ AWS ECS ] ERROR: '' + error);

	return JSON.stringify({ ''error'': error });
}','','0','','','','','2',NULL,'Get metrics of ESC services.
Full 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,E'var AWS = {
	params: {},
	metadata: ''http://169.254.169.254/latest/'',

	setParams: function (params) {
		AWS.params[''proxy''] = params.proxy;
		switch (AWS.getField(params, ''auth_type'')) {
			case ''role_base'':
				AWS.params[''auth_type''] = ''role_base'';
				var request = new HttpRequest();
				if (typeof AWS.params.proxy !== ''undefined'' && AWS.params.proxy !== '''') {
					request.setProxy(AWS.params.proxy);
				}
				request.addHeader(''X-aws-ec2-metadata-token-ttl-seconds: 21600'');
				var token = request.put(AWS.metadata + ''api/token'');

				if (request.getStatus() !== 200 || token === null || token === '''') {
					throw ''Error getting IMDSv2 session token.'';
				}
				request.addHeader(''X-aws-ec2-metadata-token: '' + token);
				var IamRoleName = request.get(AWS.metadata + ''meta-data/iam/security-credentials'');

				if (request.getStatus() !== 200 || IamRoleName === null || IamRoleName === '''') {
					throw ''Error getting security credentials from instance metadata. Role not found.'';
				}

				credentials = request.get(AWS.metadata + ''meta-data/iam/security-credentials/'' + encodeURI(IamRoleName));

				if (request.getStatus() !== 200 || credentials === null || credentials === '''') {
					throw ''Error getting security credentials from instance metadata.'';
				}

				try {
					credentials = JSON.parse(credentials);
				}
				catch (error) {
					throw ''Failed to parse response received from instance metadata. Check debug log for more information.'';
				}

				[''AccessKeyId'', ''SecretAccessKey'', ''Token''].forEach(function (field) {
					if (typeof credentials !== ''object'' || typeof credentials[field] === ''undefined'' || credentials[field] === '''') {
						throw ''Required credentials are not set: "'' + field + ''".'';
					};
					AWS.params[field] = credentials[field];
				});
				break;
			case ''assume_role'':
				AWS.params[''auth_type''] = ''assume_role'';

				[''AccessKeyId'', ''SecretAccessKey'', ''sts_region'', ''role_arn''].forEach(function (field) {
					if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
						throw ''Required param is not set: "'' + field + ''".'';
					}
					AWS.params[field] = params[field];
				});

				role_arn_regex = /role\\/(.+)$/;

				var payload = {
					''Action'': ''AssumeRole'',
					''Version'': ''2011-06-15'',
					''RoleArn'': AWS.params.role_arn,
					''RoleSessionName'': AWS.params.role_arn.match(role_arn_regex)[1] + ''Session'',
				};

				credentials = AWS.getField(AWS.request(''GET'', AWS.params.sts_region, ''sts'', AWS.prepareParams(payload)), ''AssumeRoleResponse.AssumeRoleResult.Credentials'');

				[''AccessKeyId'', ''SecretAccessKey'', ''SessionToken''].forEach(function (field) {
					if (typeof credentials !== ''object'' || typeof credentials[field] === ''undefined'' || credentials[field] === '''') {
						throw ''Required credentials are not set: "'' + field + ''".'';
					};
					AWS.params[field] = credentials[field];
				});
				break;
			default:
				AWS.params[''auth_type''] = ''access_key'';
				[''AccessKeyId'', ''SecretAccessKey''].forEach(function (field) {
					if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
						throw ''Required param is not set: "'' + field + ''".'';
					}
					AWS.params[field] = params[field];
				});
		}
		[''describe_region'', ''region_match'', ''region_not_match''].forEach(function (field) {
			if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
				throw ''Required param is not set: "'' + field + ''".'';
			}
			AWS.params[field] = params[field];
		});
	},

	getField: function (data, path) {
		var steps = path.split(''.'');
		for (var i = 0; i < steps.length; i++) {
			var step = steps[i];
			if (typeof data !== ''object'' || typeof data[step] === ''undefined'') {
				throw ''Required field was not found: '' + path;
			}
			data = data[step];
		}

		return data;

	},

	sign: function (key, message) {
		var hex = hmac(''sha256'', key, message);
		if ((hex.length % 2) === 1) {
			throw ''Invalid length of a hex string!'';
		}
		var result = new Int8Array(hex.length / 2);
		for (var i = 0, b = 0; i < hex.length; i += 2, b++) {
			result[b] = parseInt(hex.substring(i, i + 2), 16);
		}

		return result;

	},

	prepareParams: function (params) {
		var result = [];
		Object.keys(params).sort().forEach(function (key) {
			if (typeof params[key] !== ''object'') {
				result.push(key + ''='' + encodeURIComponent(params[key]));
			}
			else {
				result.push(prepareObject(key, params[key]));
			}
		});

		return result.join(''&'');

	},

	request: function (method, region, service, params, data) {
		if (typeof data === ''undefined'' || data === null) {
			data = '''';
		}
		var amzdate = (new Date()).toISOString().replace(/\\.\\d+Z/, ''Z'').replace(/[-:]/g, ''''),
			date = amzdate.replace(/T\\d+Z/, ''''),
			canonical_uri = ''/'',
			host = service + ''.'' + region + ''.amazonaws.com'',
			canonical_headers = ''content-encoding:amz-1.0\\n'' + ''host:'' + host + ''\\n'' + ''x-amz-date:'' + amzdate + ''\\n'',
			signed_headers = ''content-encoding;host;x-amz-date'',
			canonical_request = method + ''\\n'' + canonical_uri + ''\\n'' + params + ''\\n'' + canonical_headers + ''\\n'' + signed_headers + ''\\n'' + sha256(data),
			credential_scope = date + ''/'' + region + ''/'' + service + ''/'' + ''aws4_request'',
			request_string = ''AWS4-HMAC-SHA256'' + ''\\n'' + amzdate + ''\\n'' + credential_scope + ''\\n'' + sha256(canonical_request),
			key = AWS.sign(''AWS4'' + AWS.params.SecretAccessKey, date),
			key = AWS.sign(key, region),
			key = AWS.sign(key, service),
			key = AWS.sign(key, ''aws4_request''),
			request = new HttpRequest(),
			url = ''https://'' + host + canonical_uri + ''?'' + params;

		if (typeof AWS.params.proxy !== ''undefined'' && AWS.params.proxy !== '''') {
			request.setProxy(AWS.params.proxy);
		}
		request.addHeader(''x-amz-date: '' + amzdate);
		request.addHeader(''x-amz-content-sha256:'' + sha256(data));
		request.addHeader(''Accept: application/json'');
		request.addHeader(''Content-Type: application/x-www-form-urlencoded'');
		request.addHeader(''Content-Encoding: amz-1.0'');
		request.addHeader(''Authorization: '' + ''AWS4-HMAC-SHA256 Credential='' + AWS.params.AccessKeyId + ''/'' + credential_scope + '', '' + ''SignedHeaders='' + signed_headers + '', '' + ''Signature='' + hmac(''sha256'', key, request_string));
		if (AWS.params.auth_type === ''role_base'' || (AWS.params.auth_type === ''assume_role'' & !params.includes(''AssumeRole''))) {
			request.addHeader(''X-Amz-Security-Token: '' + (AWS.params.auth_type === ''role_base'' ? AWS.params.Token : AWS.params.SessionToken));
		}

		Zabbix.log(4, ''[ AWS ECS ] Sending request: '' + url);
		response = request.get(url);
		Zabbix.log(4, ''[ AWS ECS ] Received response with status code '' + request.getStatus() + '': '' + response);

		if (request.getStatus() !== 200) {
			throw ''Request failed with status code '' + request.getStatus() + '': '' + response;
		}
		try {
			response = JSON.parse(response);
		}
		catch (error) {
			try {
				response = JSON.parse(XML.toJson(response));
			}
			catch (error) {
				throw ''Failed to parse response received from AWS API. Check debug log for more information.'';
			}
		}

		return response;

	},

	listRegions: function () {
		var payload = {
			''Action'': ''DescribeRegions'',
			''Version'': ''2016-11-15''
		};

		regions = AWS.getField(AWS.request(''GET'', AWS.params.describe_region, ''ec2'', AWS.prepareParams(payload)), ''DescribeRegionsResponse.regionInfo.item'');

		if (!Array.isArray(regions))
			regions = [regions]

		return regions
	},

	listClusters: function () {
		var data = [],
			regions = AWS.listRegions(),
			result,
			ECSClusters,
			payload = {
				''Action'': ''ListClusters'',
				''Version'': ''2014-11-13''
			};

		regions.forEach(function (region) {
			var region_name = AWS.getField(region, ''regionName'');
			if (region_name.match(AWS.params.region_match) === null ||
				region_name.match(AWS.params.region_not_match) !== null)
				return;

			result = AWS.request(''GET'', region_name, ''ecs'', AWS.prepareParams(payload));
			ECSClusters = AWS.getField(result, ''ListClustersResponse.ListClustersResult.clusterArns'')
			for (k in ECSClusters) {
				clusters = ECSClusters[k];
				json = {};
				input = clusters.split(''/'');
				for (var i = 1; i < input.length; i += 2) {
					json[input[i]] = input[i + 1];
				}
				data.push({
					''clusters_name'': input[1],
					''region'': region_name
				});
			}
		});

		return data;
	},

	decribeClusters: function (cluster_name, region_name) {
		var payload = {
			''Action'': ''DescribeClusters'',
			''Version'': ''2014-11-13'',
			''clusters.clusterName'': cluster_name,
			''include.statistics'': ''STATISTICS''
		};
		result = AWS.request(''GET'', region_name, ''ecs'', AWS.prepareParams(payload));

		return result;

	}

};

try {
	AWS.setParams(JSON.parse(value));
	var clusters = AWS.listClusters(),
		infrastructure = [],
		metrics = [''runningEC2TasksCount'', ''pendingEC2TasksCount'', ''activeEC2ServiceCount'', ''drainingEC2ServiceCount''],
		ECSClusters = [],
		DescribeClusters = [];
	DescribeClusters = clusters.map(function (cluster) {
		ECSClusters = AWS.getField(AWS.decribeClusters(cluster.clusters_name, cluster.region), ''DescribeClustersResponse.DescribeClustersResult.clusters'')
		for (k in ECSClusters) {
			var ECS2 = 0;
			statistic = AWS.getField(ECSClusters[k], ''statistics'');
			statistic.forEach(function (id) {
				for (i in metrics) {
					if (AWS.getField(id, ''name'') === metrics[i]) {
						ECS2 += Number(AWS.getField(id, ''value''));
					}
				}
			})
			infrastructure = (ECS2 > 0) ? ''use_ecs2'' : ''serverless'';

			return {
				''clusterName'': ECSClusters[k].clusterName,
				''status'': ECSClusters[k].status,
				''infrastructure'': infrastructure,
				''region'': cluster.region
			}

		}
	})

	return JSON.stringify(DescribeClusters);

}
catch (error) {
	error += (String(error).endsWith(''.'')) ? '''' : ''.'';
	Zabbix.log(3, ''[ AWS ECS ] ERROR: '' + error);
	return JSON.stringify({ ''error'': error });
}','','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,'
const request_path = ''/v3/auth/tokens'';

function checkParams(params) {
	[''api_url'', ''app_cred_id'', ''app_cred_secret''].forEach(function (field) {
		if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
			throw ''Required param is not set: '' + field + ''.'';
		}
	});
	return params;
}

function getHttpData(url, params, app_cred_id, app_cred_secret) {
	const request = new HttpRequest();

	request.addHeader(''Content-Type: application/json'');

	const request_body = {
		"auth": {
			"identity": {
				"methods": [
					"application_credential"
				],
				"application_credential": {
					"id": app_cred_id,
					"secret": app_cred_secret
				}
			}
		}
	};

	if (params[''http_proxy'']) {
		request.setProxy(params[''http_proxy''])
		Zabbix.log(4, ''[ Openstack Nova API ] Using http proxy: '' + params[''http_proxy'']);
	}

	const response = request.post(url, JSON.stringify(request_body));
	Zabbix.log(4, ''[ Openstack Identity API ] [ '' + url + '' ] Received response with status code '' + request.getStatus() + '': '' + response);

	if (request.getStatus() !== 201) {
		if (typeof (response.error && response.error.message) !== ''undefined'') {
			throw response.error.message;
		} else {
			throw ''Failed to receive data: invalid response status code. Check debug log for more information.'';
		}
	}

	return {''request'': request, ''response'': response};
}

function parseHttpData(http_data) {
	var token;
	const headers = http_data[''request''].getHeaders(true);
	if (typeof headers === "object") {
		if (headers !== null) {
			try {
				token = headers["X-Subject-Token"][0];
			} catch (error) {
				throw ''Failed to parse response received from OpenStack Identity API. Check debug log for more information.'';
			}
		} else {
			throw ''Response object is empty. Check debug log for more information.'';
		}
	} else {
		throw ''Cannot process response data: received data is not an object. Check debug log for more information.'';
	}

	const supported_services = [''nova''];

	var ret = [];
	const data = JSON.parse(http_data[''response'']);
	if (data[''token''][''catalog'']) {
		const service_catalog = data[''token''][''catalog''];
	} else {
		throw ''Cannot find service catalog in HTTP response.''
	}

	service_catalog.forEach(function (service) {
		if (supported_services.indexOf(service.name) > -1) {
			service.endpoints.forEach(function (endpoint) {
				if (endpoint.interface === ''public'') {
					ret.push({
						''service_name'': service.name[0].toUpperCase() + service.name.slice(1),
						''service_url'': endpoint.url,
						''token'': token
					});
				}
			})
		}
	});

	return JSON.stringify(ret);
}

const params = checkParams(JSON.parse(value)),
	url = params.api_url,
	auth_cred_id = params.app_cred_id,
	auth_cred_secret = params.app_cred_secret;

const httpData = getHttpData(url + request_path, params, auth_cred_id, auth_cred_secret);
return 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,'
const request_path = ''/os-simple-tenant-usage'';

function checkParams(params) {
	[''api_url'', ''api_token'', ''period''].forEach(function (field) {
		if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
			throw ''Required param is not set: '' + field + ''.'';
		}
		if (field === ''period'') {
			const supported_values = [''y'', ''m'', ''w'', ''d'']
			if (supported_values.indexOf(params[field]) === -1) {
				throw ''Tenant period not correctly set. Expected one of "y", "m", "w", "d"; received: '' + field + ''.'';
			}
		}
	});
	return params;
}

function buildUrl(url, period) {
	const current_date = new Date();
	var datetime_formatted = ''''
	switch (period) {
		case ''y'':
			datetime_formatted =
				current_date.getFullYear() + ''-'' +
				''1-'' +
				''1T'' +
				''00:00:00''
			break;
		case ''m'':
			datetime_formatted =
			current_date.getFullYear() + ''-'' +
				(current_date.getMonth() + 1) + ''-'' +
			''1T'' +
			''00:00:00''
			break;
		case ''w'':
			const first_date_of_week = current_date.getDate() - current_date.getDay() + 1
			datetime_formatted =
				current_date.getFullYear() + ''-'' +
				(current_date.getMonth() + 1) + ''-'' +
				first_date_of_week + ''T'' +
				''00:00:00''
			break;
		case ''d'':
			datetime_formatted =
				current_date.getFullYear() + ''-'' +
				(current_date.getMonth() + 1) + ''-'' +
				current_date.getDate() + ''T'' +
				''00:00:00''
			break;
	}

	return url + request_path + ''?'' +
		''start='' + encodeURIComponent(datetime_formatted)
}

function getHttpData(url, params, api_token) {
	const request = new HttpRequest();

	request.addHeader(''Content-Type: application/json'');
	request.addHeader(''X-Auth-Token: '' + api_token);
	if (params[''http_proxy'']) {
		request.setProxy(params[''http_proxy''])
		Zabbix.log(4, ''[ Openstack Nova API ] Using http proxy: '' + params[''http_proxy'']);
	}

	const response = request.get(url, JSON.stringify(params));
	Zabbix.log(4, ''[ Openstack Nova API ] [ '' + url + '' ] Received response with status code '' + request.getStatus() + '': '' + response);

	if (request.getStatus() !== 200) {
		if (typeof (response.error && response.error.message) !== ''undefined'') {
			throw response.error.message;
		} else {
			throw ''Failed to receive data: invalid response status code ( '' + request.getStatus() + '' ). Check debug log for more information.'';
		}
	}

	return response;
}

const params = checkParams(JSON.parse(value)),
	url = params.api_url,
	token = params.api_token,
	period = params.period;

return 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 (
  SELECT
    4096/(ceil(pg_settings.setting::numeric/1024/1024))::int AS segment_parts_count,
    setting::bigint AS segment_size,
    (''x'' || substring(pg_stat_archiver.last_archived_wal from 9 for 8))::bit(32)::int AS last_wal_div,
    (''x'' || substring(pg_stat_archiver.last_archived_wal from 17 for 8))::bit(32)::int AS last_wal_mod,
    CASE WHEN pg_is_in_recovery() THEN NULL 
      ELSE (''x'' || substring(pg_walfile_name(pg_current_wal_lsn()) from 9 for 8))::bit(32)::int END AS current_wal_div,
    CASE WHEN pg_is_in_recovery() THEN NULL 
      ELSE (''x'' || substring(pg_walfile_name(pg_current_wal_lsn()) from 17 for 8))::bit(32)::int END AS current_wal_mod
  FROM pg_settings, pg_stat_archiver
  WHERE pg_settings.name = ''wal_segment_size'')
SELECT json_build_object(
  ''archived_count'', (SELECT archived_count FROM pg_stat_archiver),
  ''failed_count'', (SELECT failed_count FROM pg_stat_archiver),
  ''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),
  ''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)
) 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
  CASE
    WHEN NOT pg_is_in_recovery() OR pg_last_wal_receive_lsn() = pg_last_wal_replay_lsn() THEN 0
      ELSE COALESCE(EXTRACT(EPOCH FROM now() - pg_last_xact_replay_timestamp())::integer, 0)
    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(*)
  FROM pg_catalog.pg_stat_activity
    WHERE backend_type = ''autovacuum worker''
      AND state <> ''idle''
      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)
  FROM (
    SELECT
      CASE
        WHEN pg_is_in_recovery() THEN 0
        ELSE pg_wal_lsn_diff(pg_current_wal_lsn(),''0/00000000'')
      END AS WRITE,
      CASE 
        WHEN NOT pg_is_in_recovery() THEN 0
        ELSE pg_wal_lsn_diff(pg_last_wal_receive_lsn(),''0/00000000'')
      END AS RECEIVE,
      count(*)
      FROM pg_ls_waldir() AS COUNT
  ) 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
  CASE
    WHEN NOT pg_is_in_recovery() THEN 2
    ELSE (SELECT count(*) FROM pg_stat_wal_receiver)
  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
  CASE
    WHEN NOT pg_is_in_recovery() OR pg_last_wal_receive_lsn() = pg_last_wal_replay_lsn() THEN 0
      ELSE COALESCE(EXTRACT(EPOCH FROM now() - pg_last_xact_replay_timestamp())::integer, 0)
    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))
  FROM (
    SELECT
      application_name,
      EXTRACT(epoch FROM COALESCE(flush_lag,''0''::interval)) AS flush_lag,
      EXTRACT(epoch FROM COALESCE(replay_lag,''0''::interval)) AS replay_lag,
      EXTRACT(epoch FROM COALESCE(write_lag, ''0''::interval)) AS write_lag
    FROM pg_stat_replication
  ) 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)))
  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
  (SELECT db.datname dbname,
      lower(replace(Q.mode, ''Lock'', '''')) AS MODE,
      coalesce(T.qty, 0) val
  FROM pg_database db
  JOIN (
      VALUES (''AccessShareLock'') ,(''RowShareLock'') ,(''RowExclusiveLock'') ,(''ShareUpdateExclusiveLock'') ,(''ShareLock'') ,(''ShareRowExclusiveLock'') ,(''ExclusiveLock'') ,(''AccessExclusiveLock'')) Q(MODE) ON TRUE NATURAL
  LEFT JOIN
    (SELECT datname,
      MODE,
      count(MODE) qty
    FROM pg_locks lc
    RIGHT JOIN pg_database db ON db.oid = lc.database
    GROUP BY 1, 2) T
  WHERE NOT db.datistemplate
  ORDER BY 1, 2)
SELECT json_object_agg(dbname, row_to_json(T2))
FROM
  (SELECT dbname,
      sum(val) AS total,
      sum(CASE
          WHEN MODE = ''accessexclusive'' THEN val
        END) AS accessexclusive,
      sum(CASE
          WHEN MODE = ''accessshare'' THEN val
        END) AS accessshare,
      sum(CASE
          WHEN MODE = ''exclusive'' THEN val
        END) AS EXCLUSIVE,
      sum(CASE
          WHEN MODE = ''rowexclusive'' THEN val
        END) AS rowexclusive,
      sum(CASE
          WHEN MODE = ''rowshare'' THEN val
        END) AS rowshare,
      sum(CASE
          WHEN MODE = ''share'' THEN val
        END) AS SHARE,
      sum(CASE
          WHEN MODE = ''sharerowexclusive'' THEN val
        END) AS sharerowexclusive,
      sum(CASE
          WHEN MODE = ''shareupdateexclusive'' THEN val
        END) AS shareupdateexclusive
  FROM T
  GROUP BY dbname) T2','','0','{$PG.USER}','{$PG.PASSWORD}','','','0',NULL,'Collect all metrics from pg_locks per database:
https://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 (
  SELECT sum(numbackends) AS numbackends,
    sum(xact_commit) AS xact_commit,
    sum(xact_rollback) AS xact_rollback,
    sum(blks_read) AS blks_read,
    sum(blks_hit) AS blks_hit,
    sum(tup_returned) AS tup_returned,
    sum(tup_fetched) AS tup_fetched,
    sum(tup_inserted) AS tup_inserted,
    sum(tup_updated) AS tup_updated,
    sum(tup_deleted) AS tup_deleted,
    sum(conflicts) AS conflicts,
    sum(temp_files) AS temp_files,
    sum(temp_bytes) AS temp_bytes,
    sum(deadlocks) AS deadlocks,
    sum(blk_read_time) AS blk_read_time,
    sum(blk_write_time) AS blk_write_time
  FROM pg_stat_database) T','','0','{$PG.USER}','{$PG.PASSWORD}','','','0',NULL,'Collect all metrics from pg_stat_database as sums for all databases:
https://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 (
  SELECT datname,
    numbackends AS numbackends,
    xact_commit AS xact_commit,
    xact_rollback AS xact_rollback,
    blks_read AS blks_read,
    blks_hit AS blks_hit,
    tup_returned AS tup_returned,
    tup_fetched AS tup_fetched,
    tup_inserted AS tup_inserted,
    tup_updated AS tup_updated,
    tup_deleted AS tup_deleted,
    conflicts AS conflicts,
    temp_files AS temp_files,
    temp_bytes AS temp_bytes,
    deadlocks AS deadlocks,
    blk_read_time AS blk_read_time,
    blk_write_time AS blk_write_time
  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:
https://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,E'WITH T AS
  (SELECT db.datname,
    coalesce(T.query_time_max, 0) query_time_max,
    coalesce(T.tx_time_max, 0) tx_time_max,
    coalesce(T.mro_time_max, 0) mro_time_max,
    coalesce(T.query_time_sum, 0) query_time_sum,
    coalesce(T.tx_time_sum, 0) tx_time_sum,
    coalesce(T.mro_time_sum, 0) mro_time_sum,
    coalesce(T.query_slow_count, 0) query_slow_count,
    coalesce(T.tx_slow_count, 0) tx_slow_count,
    coalesce(T.mro_slow_count, 0) mro_slow_count
  FROM pg_database db NATURAL
  LEFT JOIN (
    SELECT datname,
      extract(epoch FROM now())::integer ts,
      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,
      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,
      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,
      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,
      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,
      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,

      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,
      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,
      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
    FROM pg_stat_activity
    WHERE pid <> pg_backend_pid()
    GROUP BY 1) T
  WHERE NOT db.datistemplate )
SELECT json_object_agg(datname, row_to_json(T))
FROM 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 (
  SELECT checkpoints_timed,
    checkpoints_req,
    checkpoint_write_time,
    checkpoint_sync_time,
    current_setting(''block_size'')::int*buffers_checkpoint AS buffers_checkpoint,
    current_setting(''block_size'')::int*buffers_clean AS buffers_clean,
    maxwritten_clean,
    current_setting(''block_size'')::int*buffers_backend AS buffers_backend,
    buffers_backend_fsync,
    current_setting(''block_size'')::int*buffers_alloc AS buffers_alloc
  FROM pg_stat_bgwriter) T','','0','{$PG.USER}','{$PG.PASSWORD}','','','0',NULL,'Collect all metrics from pg_stat_bgwriter:
https://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)
  FROM (
    SELECT
      sum(CASE WHEN state = ''active'' THEN 1 ELSE 0 END) AS active,
      sum(CASE WHEN state = ''idle'' THEN 1 ELSE 0 END) AS idle,
      sum(CASE WHEN state = ''idle in transaction'' THEN 1 ELSE 0 END) AS idle_in_transaction,
      sum(CASE WHEN state = ''idle in transaction (aborted)'' THEN 1 ELSE 0 END) AS idle_in_transaction_aborted,
      sum(CASE WHEN state = ''fastpath function call'' THEN 1 ELSE 0 END) AS fastpath_function_call,
      sum(CASE WHEN state = ''disabled'' THEN 1 ELSE 0 END) AS disabled,
      count(*) AS total,
      count(*)*100/(SELECT current_setting(''max_connections'')::int) AS total_pct,
      sum(CASE WHEN wait_event IS NOT NULL THEN 1 ELSE 0 END) AS waiting,
      (SELECT count(*) FROM pg_prepared_xacts) AS prepared
    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:
https://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,E'WITH T AS (
  SELECT
    datname AS "{#DBNAME}"
  FROM pg_database
  WHERE
    NOT datistemplate
    AND datallowconn
    AND datname != ''postgres''
)
SELECT ''{"data":''|| regexp_replace(coalesce(json_agg(T), ''[]''::json)::text, E''[\\\\n\\\\r\\\\s]+'', '''', ''g'') || ''}''
FROM T','','0','{$PG.USER}','{$PG.PASSWORD}','','','1',NULL,'Discovers databases (DB) in the database management system (DBMS), except:
- templates;
- default "postgres" DB;
- 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)), ''[]''))		
FROM 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)
  FROM pg_catalog.pg_database
  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(*)
FROM pg_catalog.pg_stat_all_tables
WHERE (n_dead_tup/(n_live_tup+n_dead_tup)::float8) > 0.2
  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,E'var params = JSON.parse(value),
	request = new HttpRequest(),
	cookies = [],
	token = "",
	error_msg = "";

function authenticate(url) {
	var payload = ''j_username='' + encodeURIComponent(params.username)
		+ ''&j_password='' + encodeURIComponent(params.password);
	request.addHeader(''Content-Type'', ''application/x-www-form-urlencoded'');
	response = request.post(url, payload);
	Zabbix.log(4, ''[ SD-WAN API ] [ '' + url + '' ] Received response with status code '' + request.getStatus() + '': '' + response);

	if (request.getStatus() !== 200) {
		throw ''Failed to receive data: invalid response status code.'';
	}

	if (response !== null && response != "") {
		throw ''Authentication failed.'';
	}

	var headers = request.getHeaders();
	for (key in headers) {
		if (key.toLowerCase() == ''set-cookie'') {
			var entries = headers[key].split('','');
			for (idx in entries) {
				var value = entries[idx].split('';'')[0];
				cookies.push(value);
			}
		}
	}
};

function getToken(url) {
	response = request.get(url);
	Zabbix.log(4, ''[ SD-WAN API ] [ '' + url + '' ] Received response with status code '' + request.getStatus() + '': '' + response);

	if (request.getStatus() !== 200) {
		throw ''Failed to receive data: invalid response status code.'';
	}

	var headers = request.getHeaders();
	for (key in headers) {
		if (key.toLowerCase() == ''content-type'' && headers[key] != ''application/json'') {
			throw ''Something went wrong while getting the authentication token. Check debug log for more information.'';
		}
	}

	return response;
};

try {

	[''username'', ''password'', ''url''].forEach(function (field) {
		var macro = ''{$SDWAN.API.'' + field.toUpperCase() + ''}'';
		if (params[field] === macro || params[field] === '''') {
			throw ''Please change '' + macro + '' macro to the proper value.'';
		}
		if (typeof params[field] === ''undefined'') {
			throw ''Please set \\'''' + field + ''\\'' script input parameter to '' + macro + '' macro value.'';
		}
	});

	if (params.url.indexOf(''http://'') === -1 && params.url.indexOf(''https://'') === -1) {
		params.url = ''https://'' + params.url;
	}

	if (!params.url.endsWith(''/'')) {
		params.url += ''/'';
	}

	if (typeof params.http_proxy !== ''undefined'' && params.http_proxy !== ''{'' + ''$SDWAN.HTTP_PROXY}'' && params.http_proxy !== '''') {
		request.setProxy(params.http_proxy);
	}

	authenticate(params.url + ''j_security_check'');
	token = getToken(params.url + ''dataservice/client/token'');

} catch (err) {
	error_msg = err;
};

return JSON.stringify({
	''cookie'': cookies.join(''; ''),
	''token'': token,
	''error'': error_msg.toString()
});','','0','','','','','0',NULL,'Cisco SD-WAN authentication with service account parameters and temporary-generated token usage.
Returns an authentication token and session id; it is required only once and is used for all dependent script items.
A session will expire after 30 minutes of inactivity or after 24 hours, which is the total lifespan of a session.
Check 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,E'var params = JSON.parse(value),
	request = new HttpRequest(),
	result = { "data": [], "error": "" },
	error_msg = "";

function getHttpData(url, data, token, cookie) {
	request.addHeader(''Cookie: '' + cookie);
	request.addHeader(''Content-Type: application/json'');
	request.addHeader(''X-XSRF-TOKEN: '' + token);

	if (typeof data !== ''undefined'') {
		data = JSON.stringify(data);
	}

	response = request.post(url, data);
	Zabbix.log(4, ''[ Cisco SD-WAN ] [ '' + url + '' ] Received response with status code '' + request.getStatus() + '': '' + response);

	if (request.getStatus() !== 200) {
		throw ''Failed to receive data: invalid response status code.'';
	}

	if (response !== null) {
		try {
			response = JSON.parse(response);
		}
		catch (error) {
			throw ''Failed to parse response received from Cisco SD-WAN API. Check debug log for more information.'';
		}
	}

	if (typeof (response) !== ''object'' || response === null) {
		throw ''Cannot process response data: received data is not an object.'';
	}

	return response;
};

try {
	[''auth.token'', ''auth.cookie'', ''api.url'', ''device_id''].forEach(function (field) {
		var macro = ''{$SDWAN.'' + field.toUpperCase() + ''}'';
		var key = field.split(''.'').slice(-1);
		if (params[key] === macro || params[key] === '''') {
			throw ''Please change '' + macro + '' macro to the proper value.'';
		}
		if (typeof params[key] === ''undefined'') {
			throw ''Please set \\'''' + key + ''\\'' script input parameter to '' + macro + '' macro value.'';
		}
	});

	if (params.url.indexOf(''http://'') === -1 && params.url.indexOf(''https://'') === -1) {
		params.url = ''https://'' + params.url;
	}

	if (!params.url.endsWith(''/'')) {
		params.url += ''/'';
	}

	if (typeof params.http_proxy !== ''undefined'' && params.http_proxy !== ''{'' + ''$SDWAN.HTTP_PROXY}'' && params.http_proxy !== '''') {
		request.setProxy(params.http_proxy);
	}

	if (!params.interval.endsWith(''h'')) {
		throw ''The value of {'' + ''$SDWAN.ROUTES.INTERVAL} must be expressed in hours.'';
	}
	else {
		try {
			params.interval = Number(params.interval.replace(''h'', ''''));
		}
		catch (error) {
			throw ''Please change {'' + ''$SDWAN.ROUTES.INTERVAL} macro to the proper value.'';
		}
	}

	var req_data = {
		"query": {
			"condition": "AND",
			"rules": [
				{
					"value": [
						String(params.interval)
					],
					"field": "entry_time",
					"type": "date",
					"operator": "last_n_hours"
				},
				{
					"value": [
						params.device_id
					],
					"field": "vdevice_name",
					"type": "string",
					"operator": "in"
				}
			]
		},
		"aggregation": {
			"field": [
				{
					"property": "local_color",
					"order": "asc",
					"sequence": 1
				},
				{
					"property": "remote_color",
					"order": "asc",
					"sequence": 1
				}
			],
			"metrics": [
				{
					"property": "loss_percentage",
					"type": "avg"
				},
				{
					"property": "latency",
					"type": "avg"
				},
				{
					"property": "jitter",
					"type": "avg"
				}
			]
		}
	};

	var routes = getHttpData(
		params.url + ''dataservice/statistics/approute/aggregation'',
		req_data,
		params.token,
		params.cookie
	);

	if (Array.isArray(routes.data)) {
		result["data"] = routes.data;
	}
	else {
		throw ''Failed to parse response received from Cisco SD-WAN API. Check debug log for more information.'';
	}
} catch (error) {
	error_msg = error.toString();
	error_msg += (error_msg.endsWith(''.'')) ? '''' : ''.'';
	Zabbix.log(3, ''[ Cisco SD-WAN ] ERROR: '' + error_msg);
};

result.error = error_msg;

return 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,E'var params = JSON.parse(value),
	request = new HttpRequest(),
	result = { "data": [], "error": "" },
	error_msg = "";

function getHttpData(url, token, cookie) {
	request.addHeader(''Cookie: '' + cookie);
	request.addHeader(''X-XSRF-TOKEN: '' + token);
	response = request.get(url);
	Zabbix.log(4, ''[ Cisco SD-WAN ] [ '' + url + '' ] Received response with status code '' + request.getStatus() + '': '' + response);

	if (request.getStatus() !== 200) {
		throw ''Failed to receive data: invalid response status code.'';
	}

	if (response !== null) {
		try {
			response = JSON.parse(response);
		}
		catch (error) {
			throw ''Failed to parse response received from Cisco SD-WAN API. Check debug log for more information.'';
		}
	}

	if (typeof (response) !== ''object'' || response === null) {
		throw ''Cannot process response data: received data is not an object.'';
	}

	return response;
};

try {
	[''auth.token'', ''auth.cookie'', ''api.url'', ''device_id''].forEach(function (field) {
		var macro = ''{$SDWAN.'' + field.toUpperCase() + ''}'';
		var key = field.split(''.'').slice(-1);
		if (params[key] === macro || params[key] === '''') {
			throw ''Please change '' + macro + '' macro to the proper value.'';
		}
		if (typeof params[key] === ''undefined'') {
			throw ''Please set \\'''' + key + ''\\'' script input parameter to '' + macro + '' macro value.'';
		}
	});

	if (params.url.indexOf(''http://'') === -1 && params.url.indexOf(''https://'') === -1) {
		params.url = ''https://'' + params.url;
	}

	if (!params.url.endsWith(''/'')) {
		params.url += ''/'';
	}

	if (typeof params.http_proxy !== ''undefined'' && params.http_proxy !== ''{'' + ''$SDWAN.HTTP_PROXY}'' && params.http_proxy !== '''') {
		request.setProxy(params.http_proxy);
	}

	var interface_list = getHttpData(
		params.url + ''dataservice/device/interface?deviceId='' + encodeURIComponent(params.device_id),
		params.token,
		params.cookie
	);

	if (Array.isArray(interface_list.data) && interface_list.data.length > 0) {
		var interfaces = {};
		interface_list.data.forEach(function (if_item) {
			var if_key = if_item[''vdevice-name''] + ''_'' + if_item.ifname + ''_'' + if_item.ifindex;
			interfaces[if_key] = (typeof interfaces[if_key] !== ''undefined'') ? interfaces[if_key] : {};
			if (typeof if_item[''af-type''] !== ''undefined'') {
				if (if_item[''af-type''].includes(''ipv6'')) {
					Object.keys(if_item).sort().forEach(function (key) {
						if (key.match(/([tr]x-)/g)) {
							interfaces[if_key][''ipv6-'' + key] = if_item[key];
						}
					});
				}
				else {
					interfaces[if_key] = if_item;
				}
			}
			else {
				interfaces[if_key] = if_item;
			}
		});
		Object.keys(interfaces).forEach(function (key) {
			result.data.push(interfaces[key]);
		});
	}
	else {
		throw ''Failed to parse response received from Cisco SD-WAN API. Check debug log for more information.'';
	}
} catch (error) {
	error_msg = error.toString();
	error_msg += (error_msg.endsWith(''.'')) ? '''' : ''.'';
	Zabbix.log(3, ''[ Cisco SD-WAN ] ERROR: '' + error_msg);
};

result.error = error_msg;

return 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,E'var params = JSON.parse(value),
	request = new HttpRequest(),
	device_info = {},
	error_msg = "";

function getHttpData(url, token, cookie) {
	request.addHeader(''Cookie: '' + cookie);
	request.addHeader(''X-XSRF-TOKEN: '' + token);
	response = request.get(url);
	Zabbix.log(4, ''[ Cisco SD-WAN ] [ '' + url + '' ] Received response with status code '' + request.getStatus() + '': '' + response);

	if (request.getStatus() !== 200) {
		throw ''Failed to receive data: invalid response status code.'';
	}

	if (response !== null) {
		try {
			response = JSON.parse(response);
		}
		catch (error) {
			throw ''Failed to parse response received from Cisco SD-WAN API. Check debug log for more information.'';
		}
	}

	if (typeof (response) !== ''object'' || response === null) {
		throw ''Cannot process response data: received data is not an object.'';
	}

	return response;
};

try {
	[''auth.token'', ''auth.cookie'', ''api.url'', ''device_id''].forEach(function (field) {
		var macro = ''{$SDWAN.'' + field.toUpperCase() + ''}'';
		var key = field.split(''.'').slice(-1);
		if (params[key] === macro || params[key] === '''') {
			throw ''Please change '' + macro + '' macro to the proper value.'';
		}
		if (typeof params[key] === ''undefined'') {
			throw ''Please set \\'''' + key + ''\\'' script input parameter to '' + macro + '' macro value.'';
		}
	});

	if (params.url.indexOf(''http://'') === -1 && params.url.indexOf(''https://'') === -1) {
		params.url = ''https://'' + params.url;
	}

	if (!params.url.endsWith(''/'')) {
		params.url += ''/'';
	}

	if (typeof params.http_proxy !== ''undefined'' && params.http_proxy !== ''{'' + ''$SDWAN.HTTP_PROXY}'' && params.http_proxy !== '''') {
		request.setProxy(params.http_proxy);
	}

	device_info = getHttpData(
		params.url + ''dataservice/device?deviceId='' + encodeURIComponent(params.device_id),
		params.token,
		params.cookie
	);

	if (Array.isArray(device_info.data) && device_info.data.length > 0) {
		device_info = device_info.data[0];
	}
	else {
		throw ''Failed to parse response received from Cisco SD-WAN API. Check debug log for more information.'';
	}

	var system_info = getHttpData(
		params.url + ''dataservice/device/system/status?deviceId='' + params.device_id,
		params.token,
		params.cookie
	);

	if (Array.isArray(system_info.data) && system_info.data.length > 0) {
		device_info = Object.assign(device_info, system_info.data[0]);
	}
	else {
		throw ''Failed to parse response received from Cisco SD-WAN API. Check debug log for more information.'';
	}
} catch (error) {
	error_msg = error.toString();
	error_msg += (error_msg.endsWith(''.'')) ? '''' : ''.'';
	Zabbix.log(3, ''[ Cisco SD-WAN ] ERROR: '' + error_msg);
};

device_info.error = error_msg;

return 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 = {
	setParams: function (params) {
		[''api_endpoint''].forEach(function (field) {
			if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
				throw ''Required param is not set: "'' + field + ''".'';
			}
		});

		Nomad.params = params;
		if (typeof Nomad.params.api_endpoint === ''string'' && !Nomad.params.api_endpoint.endsWith(''/'')) {
			Nomad.params.api_endpoint += ''/'';
		}
	},

	request: function (query) {
		var response,
			request = new HttpRequest(),
			url = Nomad.params.api_endpoint + query;

		request.addHeader(''Content-Type: application/json'');
		request.addHeader(''X-Nomad-Token: '' + Nomad.params.token);
		if (Nomad.params.http_proxy) {
			request.setProxy(Nomad.params.http_proxy)
			Zabbix.log(4, ''[ Nomad ] Using http proxy: '' + Nomad.params.http_proxy);
		}

		Zabbix.log(4, ''[ Nomad ] Sending request: '' + url);
		response = request.get(url);

		Zabbix.log(4, ''[ Nomad ] Received response with status code '' + request.getStatus() + '': '' + response);

		if (response !== null) {
			try {
				response = JSON.parse(response);
			}
			catch (error) {
				throw ''Failed to parse response received from Nomad agent API.'';
			}
		}

		return {
			status: request.getStatus(),
			response: response
		};
	},

	getField: function (data, path) {
		var steps = path.split(''.'');
		for (var i = 0; i < steps.length; i++) {
			var step = steps[i];
			if (typeof data !== ''object'' || typeof data[step] === ''undefined'') {
				throw ''Required field was not found: '' + path;
			}

			data = data[step];
		}

		return data;
	},

	getIds: function () {
		var result = this.request(''v1/operator/raft/configuration'');

		if (typeof result.response !== ''object'' || result.status != 200) {
			throw ''Cannot get servers list from Nomad agent API.'';
		}

		return this.getField(result, ''response.Servers'')
			.map(function (srv) {
				return srv[''ID''];
			});
	},

	getServers: function () {
		var ids = this.getIds();
		result = Nomad.request(''v1/agent/members'');

		if (typeof result.response !== ''object'' || result.status != 200) {
			throw ''Cannot get servers list from Nomad agent API.'';
		}

		return this.getField(result,''response.Members'').filter(function (s) {
			return ids.indexOf(s.Tags.id) >= 0;
		});

	},
};

try {
	Nomad.setParams(JSON.parse(value));

	var servers = Nomad.getServers();

	return JSON.stringify(servers);

}
catch (error) {
	error += ((String(error).endsWith(''.'')) ? '''' : ''.'');
	Zabbix.log(3, ''[ Nomad ] ERROR: '' + error);

	return JSON.stringify({ error: error + '' Check debug log for more information.'' });
}','','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',E'[{"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',E'[{"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',E'[{"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
X-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
Authorization: Bearer {$ACRONIS.CPC.ACCESS_TOKEN}
X-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
Authorization: Bearer {$ACRONIS.CPC.ACCESS_TOKEN}
X-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
Authorization: Bearer {$ACRONIS.CPC.ACCESS_TOKEN}
X-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,'
const request_path = ''/api/integration_management/v2/status'';
const app_id = ''5619386d-de56-49ec-8508-f5c399d3b9bd'';

function checkParams(params) {
	[''api_url'', ''api_token'', ''tenant_uuid''].forEach(function (field) {
		if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
			throw ''Required param is not set: '' + field + ''.'';
		}
	});
	return params;
}

function getHttpData(url, register, params, api_token, tenant_uuid) {
	const request = new HttpRequest();

	request.addHeader(''Content-Type: application/json'');
	request.addHeader(''Authorization: Bearer '' + api_token);
	request.addHeader(''X-Application-Secret: '' + app_id);

	if (params[''http_proxy'']) {
		request.setProxy(params[''http_proxy'']);
		Zabbix.log(4, ''[ ACRONIS CYBER PROTECT CLOUD API ] Using http proxy: '' + params[''http_proxy'']);
	}

	if (!register) {
		const response = request.get(url + ''?tenantID='' + encodeURIComponent(tenant_uuid));
		Zabbix.log(4, ''[ ACRONIS CYBER PROTECT CLOUD API ] [ '' + url + '' ] Received response with status code '' + request.getStatus() + '': '' + response);

		if (request.getStatus() !== 200) {
			if (typeof (response.error && response.error.message) !== ''undefined'') {
				throw response.error.message;
			} else {
				throw ''Failed to receive data: invalid response status code. Check debug log for more information.'';
			}
		}

		return response;

	} else {

		const request_body = {
			"application_id": app_id,
			"module": {
				"name": "Zabbix integration with Acronis Cyber Protect Cloud",
				"version": "1.0.0"
			},
			"vendor_system": {
				"name": "Product integrated with Acronis",
				"version": "23.07"
			},
			"events": [
				{
					"category": "activation",
					"action": "activated integration",
					"activation_event": true
				}
			]
		};

		const response = request.post(url + ''?tenantID='' + encodeURIComponent(tenant_uuid), JSON.stringify(request_body));
		Zabbix.log(4, ''[ ACRONIS CYBER PROTECT CLOUD API ] [ '' + url + '' ] Received response with status code '' + request.getStatus() + '': '' + response);

		if (request.getStatus() !== 204) {
			if (typeof (response.error && response.error.message) !== ''undefined'') {
				throw response.error.message;
			} else {
				throw ''Failed to receive data: invalid response status code. Check debug log for more information.'';
			}
		}

		return 1;
	}
}

function parseGetStatusData(http_response) {
	const data = JSON.parse(http_response);
	if (data[''items'']) {
		data[''items''].forEach(function (app) {
			if (app[''application_id''] && app[''application_id''] === app_id) {
				return app[''active''];
			}
		});
		return false;
	} else {
		throw ''Unexpected data structure in HTTP response.'';
	}
}

const params = checkParams(JSON.parse(value)),
	url = params.api_url,
	api_token = params.api_token,
	tenant_uuid = params.tenant_uuid;

const current_activation_status = parseGetStatusData(getHttpData(url + request_path, false, params, api_token, tenant_uuid));

if (!current_activation_status) {
	return getHttpData(url + request_path, true, params, api_token, tenant_uuid);
} else {
	return 0;
}','','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
Authorization: Bearer {$ACRONIS.CPC.ACCESS_TOKEN}
X-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.
https://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),
	request = new HttpRequest(),
	result = {"data": {}, "lld": [], "error": ""},
	api_url = "",
	error_msg = "";

function getHttpData(url) {
	response = request.get(url);
	Zabbix.log(4, ''[ FortiGate ] [ '' + url + '' ] Received response with status code '' + request.getStatus() + '': '' + response);

	if (request.getStatus() !== 200) {
		throw ''Failed to receive data: invalid response status code. Check debug log for more information.'';
	}

	if (response !== null) {
		try {
			response = JSON.parse(response);
		}
		catch (error) {
			throw ''Failed to parse response received from FortiGate API. Check debug log for more information.'';
		}
	}

	if (typeof response !== ''object'' || response === null) {
		throw ''Cannot process response data: received data is not an object.'';
	}

	if ((typeof response.status !== ''undefined'' && response.status != ''success'') || typeof response.results === ''undefined'') {
		var uri = ''/'' + response.path + ''/'' + response.name + ((typeof response.action !== ''undefined'') ? ''?action='' + response.action : "");
		throw ''Failed to parse response received from '' + uri + ''. Check debug log for more information.'';
	}

	return response;
};

function capitalize(word, idx) {
	return upAcronymCase(word.charAt(idx).toUpperCase() + word.slice(idx+1));
}

function upAcronymCase(word) {
	if (word.length < 4) {
		return word.toUpperCase()
	}
	return word;
}

function prepareServiceName(key) {
	var result = [];
	key.split(''_'').forEach(function (w) {
		var forti_idx = w.indexOf(''forti'');
		w = upAcronymCase(w);
		if (forti_idx !== -1)
			w = ''Forti'' + capitalize(w, forti_idx + 5);
		else
			w = capitalize(w, 0)
		result.push(w);
	});

	return result.join('' '');
};

try {
	[''scheme'', ''api.token'', ''api.fqdn'', ''api.port''].forEach(function (field) {
		var macro = ''{$FGATE.'' + field.toUpperCase() + ''}'';
		var key = field.split(''.'').pop();
		if (params[key] === macro || params[key] === '''') {
			throw ''Please change '' + macro + '' macro to the proper value.'';
		}
		if (typeof params[key] === ''undefined'') {
			throw ''Please set "'' + key + ''" script input parameter to '' + macro + '' macro value.'';
		}
	});

	api_url = params.scheme + ''://'' + params.fqdn + '':'' + params.port;

	if (typeof params.http_proxy !== ''undefined'' && params.http_proxy !== ''{'' + ''$FGATE.HTTP.PROXY}'' && params.http_proxy !== '''') {
		request.setProxy(params.http_proxy);
	}

	var licence_list = getHttpData(
		api_url + ''/api/v2/monitor/license/status?access_token='' + encodeURIComponent(params.token)
	);

	result.data = licence_list.results;
	Object.keys(licence_list.results).forEach(function (key) {
		var resource = licence_list.results[key];
		if (typeof resource.status !== ''undefined'' && typeof resource.type !== ''undefined'') {
			result.lld.push({
				"key": key,
				"name": prepareServiceName(key),
				"status": resource.status,
				"type": resource.type,
			});
		}
	});
} catch (error) {
	error_msg = error.toString();
	error_msg += error_msg.endsWith(''.'') ? '''' : ''.'';
	Zabbix.log(3, ''[ FortiGate ] ERROR: '' + error_msg);
};

result.error = error_msg;

return 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),
	request = new HttpRequest(),
	result = {"data": {}, "error": ""},
	api_url = "",
	health_members = [],
	health_checks = [],
	members = {},
	error_msg = "";

function getHttpData(url) {
	response = request.get(url);
	Zabbix.log(4, ''[ FortiGate ] [ '' + url + '' ] Received response with status code '' + request.getStatus() + '': '' + response);

	if (request.getStatus() !== 200) {
		throw ''Failed to receive data: invalid response status code. Check debug log for more information.'';
	}

	if (response !== null) {
		try {
			response = JSON.parse(response);
		}
		catch (error) {
			throw ''Failed to parse response received from FortiGate API. Check debug log for more information.'';
		}
	}

	if (typeof response !== ''object'' || response === null) {
		throw ''Cannot process response data: received data is not an object.'';
	}

	if ((typeof response.status !== ''undefined'' && response.status != ''success'') || typeof response.results === ''undefined'') {
		var uri = ''/'' + response.path + ''/'' + response.name + ((typeof response.action !== ''undefined'') ? ''?action='' + response.action : "");
		throw ''Failed to parse response received from '' + uri + ''. Check debug log for more information.'';
	}

	return response;
};

try {
	[''scheme'', ''api.token'', ''api.fqdn'', ''api.port''].forEach(function (field) {
		var macro = ''{$FGATE.'' + field.toUpperCase() + ''}'';
		var key = field.split(''.'').pop();
		if (params[key] === macro || params[key] === '''') {
			throw ''Please change '' + macro + '' macro to the proper value.'';
		}
		if (typeof params[key] === ''undefined'') {
			throw ''Please set "'' + key + ''" script input parameter to '' + macro + '' macro value.'';
		}
	});

	if (typeof params.http_proxy !== ''undefined'' && params.http_proxy !== ''{'' + ''$FGATE.HTTP.PROXY}'' && params.http_proxy !== '''') {
		request.setProxy(params.http_proxy);
	}

	api_url = params.scheme + ''://'' + params.fqdn + '':'' + params.port;

	var sdwan_member_data = getHttpData(
		api_url + ''/api/v2/monitor/virtual-wan/members?access_token='' + encodeURIComponent(params.token)
	);

	var sdwan_health_data = getHttpData(
		api_url + ''/api/v2/monitor/virtual-wan/health-check?access_token='' + encodeURIComponent(params.token)
	);

	var sdwan_list = getHttpData(
		api_url + ''/api/v2/cmdb/system/sdwan?access_token='' + encodeURIComponent(params.token)
	);

	sdwan_list.results[''health-check''].forEach(function (item) {
		health_checks[item.q_origin_key] = item.members.length;
		item.members.forEach(function (m) {
			health_members.push({
				''member_id'': m.q_origin_key,
				''health_id'': item.q_origin_key,
				''health_name'': item.name,
			});
		});
	});

	sdwan_list.results.members.forEach(function (item) {
		members[item.q_origin_key] = item;
	});

	result.data = {
		''member_lld'': sdwan_list.results.members.filter(function (v) {
			if (v.interface.length > 0) {
				return v;
			}
		}).map(function (v) {
			if (typeof v.interface !== ''undefined'' && typeof sdwan_member_data.results[v.interface] !== ''undefined'') {
				Object.assign(v, sdwan_member_data.results[v.interface]);
			}
			return v;
		}),
		''health_lld'': health_members.map(function (m) {
			var item = {};
			if (typeof members[String(m.member_id)] !== ''undefined'') {
				[''interface'', ''status''].forEach(function (k) {
					item[k] = members[String(m.member_id)][k];
				});
				Object.assign(item, m);
			};
			return item;
		}).filter(function (v) {
			if (v.interface.length > 0) {
				return v;
			}
		}),
		''health_data'': sdwan_list.results[''health-check''].filter(function (v) {
			if (typeof health_checks[String(v.q_origin_key)] !== ''undefined'' && health_checks[String(v.q_origin_key)] > 0) {
				return v;
			}
		}).map(function (v) {
			delete v.members;
			if (typeof v.name !== ''undefined'' && typeof sdwan_health_data.results[v.name] !== ''undefined'') {
				Object.assign(v, sdwan_health_data.results[v.name]);
			}
			return v;
		})
	}
} catch (error) {
	error_msg = error.toString();
	error_msg += error_msg.endsWith(''.'') ? '''' : ''.'';
	Zabbix.log(3, ''[ FortiGate ] ERROR: '' + error_msg);
};

result.error = error_msg;

return 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),
	request = new HttpRequest(),
	result = {"data": {}, "error": ""},
	api_url = "",
	error_msg = "";

function getHttpData(url) {
	response = request.get(url);
	Zabbix.log(4, ''[ FortiGate ] [ '' + url + '' ] Received response with status code '' + request.getStatus() + '': '' + response);

	if (request.getStatus() !== 200) {
		throw ''Failed to receive data: invalid response status code. Check debug log for more information.'';
	}

	if (response !== null) {
		try {
			response = JSON.parse(response);
		}
		catch (error) {
			throw ''Failed to parse response received from FortiGate API. Check debug log for more information.'';
		}
	}

	if (typeof response !== ''object'' || response === null) {
		throw ''Cannot process response data: received data is not an object.'';
	}

	if ((typeof response.status !== ''undefined'' && response.status != ''success'') || typeof response.results === ''undefined'') {
		var uri = ''/'' + response.path + ''/'' + response.name + ((typeof response.action !== ''undefined'') ? ''?action='' + response.action : "");
		throw ''Failed to parse response received from '' + uri + ''. Check debug log for more information.'';
	}

	return response;
};

try {
	[''scheme'', ''api.token'', ''api.fqdn'', ''api.port''].forEach(function (field) {
		var macro = ''{$FGATE.'' + field.toUpperCase() + ''}'';
		var key = field.split(''.'').pop();
		if (params[key] === macro || params[key] === '''') {
			throw ''Please change '' + macro + '' macro to the proper value.'';
		}
		if (typeof params[key] === ''undefined'') {
			throw ''Please set "'' + key + ''" script input parameter to '' + macro + '' macro value.'';
		}
	});

	if (typeof params.http_proxy !== ''undefined'' && params.http_proxy !== ''{'' + ''$FGATE.HTTP.PROXY}'' && params.http_proxy !== '''') {
		request.setProxy(params.http_proxy);
	}

	api_url = params.scheme + ''://'' + params.fqdn + '':'' + params.port;

	var resource_list = getHttpData(
		api_url + ''/api/v2/monitor/system/resource/usage?access_token='' + encodeURIComponent(params.token) + ''&interval=1-min''
	);

	var disk_info = getHttpData(
		api_url + ''/api/v2/monitor/log/current-disk-usage?access_token='' + encodeURIComponent(params.token)
	);

	if (typeof resource_list.results !== ''undefined'' && typeof resource_list.results === ''object'') {
		Object.keys(resource_list.results).forEach(function (key) {
			var resource = resource_list.results[key];
			if (resource.length > 0) {
				result.data[key] = resource[0].current;
			}
		});
	}
	else {
		throw ''Failed to parse response received from FortiGate API. Check debug log for more information.'';
	}

	Object.keys(disk_info.results).forEach(function (key) {
		result.data[''disk_'' + key.split(''_'')[0]] = disk_info.results[key];
	});
} catch (error) {
	error_msg = error.toString();
	error_msg += error_msg.endsWith(''.'') ? '''' : ''.'';
	Zabbix.log(3, ''[ FortiGate ] ERROR: '' + error_msg);
};

result.error = error_msg;

return 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),
	request = new HttpRequest(),
	result = {"data": {}, "error": ""},
	api_url = "",
	interfaces = {},
	error_msg = "";

function getHttpData(url) {
	response = request.get(url);
	Zabbix.log(4, ''[ FortiGate ] [ '' + url + '' ] Received response with status code '' + request.getStatus() + '': '' + response);

	if (request.getStatus() !== 200) {
		throw ''Failed to receive data: invalid response status code. Check debug log for more information.'';
	}

	if (response !== null) {
		try {
			response = JSON.parse(response);
		}
		catch (error) {
			throw ''Failed to parse response received from FortiGate API. Check debug log for more information.'';
		}
	}

	if (typeof response !== ''object'' || response === null) {
		throw ''Cannot process response data: received data is not an object.'';
	}

	if ((typeof response.status !== ''undefined'' && response.status != ''success'') || typeof response.results === ''undefined'') {
		var uri = ''/'' + response.path + ''/'' + response.name + ((typeof response.action !== ''undefined'') ? ''?action='' + response.action : "");
		throw ''Failed to parse response received from '' + uri + ''. Check debug log for more information.'';
	}

	return response;
};

try {
	[''scheme'', ''api.token'', ''api.fqdn'', ''api.port''].forEach(function (field) {
		var macro = ''{$FGATE.'' + field.toUpperCase() + ''}'';
		var key = field.split(''.'').pop();
		if (params[key] === macro || params[key] === '''') {
			throw ''Please change '' + macro + '' macro to the proper value.'';
		}
		if (typeof params[key] === ''undefined'') {
			throw ''Please set "'' + key + ''" script input parameter to '' + macro + '' macro value.'';
		}
	});

	if (typeof params.http_proxy !== ''undefined'' && params.http_proxy !== ''{'' + ''$FGATE.HTTP.PROXY}'' && params.http_proxy !== '''') {
		request.setProxy(params.http_proxy);
	}

	api_url = params.scheme + ''://'' + params.fqdn + '':'' + params.port;

	var netif_data = getHttpData(
		api_url + ''/api/v2/monitor/system/interface?access_token='' + encodeURIComponent(params.token)
	);

	var netif_list = getHttpData(
		api_url + ''/api/v2/cmdb/system/interface?access_token='' + encodeURIComponent(params.token)
	);

	result.data = netif_list.results.map(function (v) {
		var item = {};
		[''q_origin_key'', ''name'', ''mode'', ''type'', ''description''].forEach(function (k) {
			item[k] = v[k];
		});
		if (typeof item.q_origin_key !== ''undefined'' && typeof netif_data.results[String(item.q_origin_key)] !== ''undefined'') {
			Object.assign(item, netif_data.results[String(item.q_origin_key)]);
		}
		if (typeof item.alias !== ''undefined'') {
			item.alias = item.alias.slice(1,-1);
		}
		else {
			item.alias = '''';
		}
		if (typeof item.link === ''undefined'') {
			item.link = false;
		}
		if (typeof item.id === ''undefined'') {
			item.id = item.q_origin_key;
		}
		return item;
	});
} catch (error) {
	error_msg = error.toString();
	error_msg += error_msg.endsWith(''.'') ? '''' : ''.'';
	Zabbix.log(3, ''[ FortiGate ] ERROR: '' + error_msg);
};

result.error = error_msg;

return 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),
	request = new HttpRequest(),
	result = {"data": {}, "error": ""},
	api_url = "",
	policies = {},
	error_msg = "";

function getHttpData(url) {
	response = request.get(url);
	Zabbix.log(4, ''[ FortiGate ] [ '' + url + '' ] Received response with status code '' + request.getStatus() + '': '' + response);

	if (request.getStatus() !== 200) {
		throw ''Failed to receive data: invalid response status code. Check debug log for more information.'';
	}

	if (response !== null) {
		try {
			response = JSON.parse(response);
		}
		catch (error) {
			throw ''Failed to parse response received from FortiGate API. Check debug log for more information.'';
		}
	}

	if (typeof response !== ''object'' || response === null) {
		throw ''Cannot process response data: received data is not an object.'';
	}

	if ((typeof response.status !== ''undefined'' && response.status != ''success'') || typeof response.results === ''undefined'') {
		var uri = ''/'' + response.path + ''/'' + response.name + ((typeof response.action !== ''undefined'') ? ''?action='' + response.action : "");
		throw ''Failed to parse response received from '' + uri + ''. Check debug log for more information.'';
	}

	return response;
};

try {
	[''scheme'', ''api.token'', ''api.fqdn'', ''api.port''].forEach(function (field) {
		var macro = ''{$FGATE.'' + field.toUpperCase() + ''}'';
		var key = field.split(''.'').pop();
		if (params[key] === macro || params[key] === '''') {
			throw ''Please change '' + macro + '' macro to the proper value.'';
		}
		if (typeof params[key] === ''undefined'') {
			throw ''Please set "'' + key + ''" script input parameter to '' + macro + '' macro value.'';
		}
	});

	if (typeof params.http_proxy !== ''undefined'' && params.http_proxy !== ''{'' + ''$FGATE.HTTP.PROXY}'' && params.http_proxy !== '''') {
		request.setProxy(params.http_proxy);
	}

	api_url = params.scheme + ''://'' + params.fqdn + '':'' + params.port;

	var firewall_data = getHttpData(
		api_url + ''/api/v2/monitor/firewall/policy?access_token='' + encodeURIComponent(params.token)
	);

	var firewall_list = getHttpData(
		api_url + ''/api/v2/cmdb/firewall/policy?access_token='' + encodeURIComponent(params.token)
	);

	firewall_list.results.forEach(function (v) {
		var item = {};
		[''q_origin_key'', ''status'', ''name'', ''uuid'', ''action'', ''ip-version-type'', ''label''].forEach(function (k) {
			item[k] = v[k];
		});
		policies[v.policyid] = item;
	});

	result.data = firewall_data.results.map(function (v) {
		if (typeof v.policyid !== ''undefined'' && typeof policies[String(v.policyid)] !== ''undefined'') {
			Object.assign(v, policies[String(v.policyid)]);
		}
		return v;
	}).filter(function (v) {
		if (typeof v.name !== ''undefined'') {
			return v;
		}
	});
} catch (error) {
	error_msg = error.toString();
	error_msg += error_msg.endsWith(''.'') ? '''' : ''.'';
	Zabbix.log(3, ''[ FortiGate ] ERROR: '' + error_msg);
};

result.error = error_msg;

return 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.
0 - ICMP ping failed.
1 - 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
An 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
Physical 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
Total 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
Time 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
The 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
Physical 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
Serial 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
Model 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
Firmware 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
A 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
CPU 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
Number 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
Name 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.
Possible values:
0 - not available
1 - available
2 - 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}
User-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}
User-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);

var request = new HttpRequest();

request.addHeader(''X-Cisco-Meraki-API-Key:'' + params.token);
request.addHeader(''User-Agent: ZabbixServer/1.1 Zabbix'');

var response,
	error_msg = '''',
	organization_devices = [],
	licenses = [];

function getField(data, path) {
	var steps = path.split(''.'');
	for (var i = 0; i < steps.length; i++) {
		var step = steps[i];
		if (typeof data !== ''object'' || typeof data[step] === ''undefined'') {
			throw ''Required field was not found: '' + path;
		}
		data = data[step];
	}

	return data;

};

function getHttpData(url) {
	response = request.get(url);
	Zabbix.log(4, ''[ Meraki API ] [ '' + url + '' ] Received response with status code '' + request.getStatus() + '': '' + response);

	if (response !== null) {
		try {
			response = JSON.parse(response);
		}
		catch (error) {
			throw ''Failed to parse response received from Meraki API. Check debug log for more information.'';
		}
	}

	if (request.getStatus() !== 200) {
		if (response.errors) {
			throw response.errors.join('', '');
		} else {
			throw ''Failed to receive data: invalid response status code.'';
		}
	}

	if (typeof (response) !== ''object'' || response === null) {
		throw ''Cannot process response data: received data is not an object.'';
	}

	return response;
};

try {

	if (params.token === ''{'' + ''$MERAKI.TOKEN}'') {
		throw ''Please change {'' + ''$MERAKI.TOKEN} macro to the proper value.'';
	}

	if (params.url.indexOf(''http://'') === -1 && params.url.indexOf(''https://'') === -1) {
		params.url = ''https://'' + params.url;
	}

	if (!params.url.endsWith(''/'')) {
		params.url += ''/'';
	}

	if (typeof params.httpproxy !== ''undefined'' && params.httpproxy !== '''') {
		request.setProxy(params.httpproxy);
	}

	licenses = getHttpData(params.url + ''organizations/'' + encodeURIComponent(params.organizationId) + ''/licenses'');

	organization_devices = getHttpData(params.url + ''organizations/'' + encodeURIComponent(params.organizationId) + ''/devices/statuses'');

	licenses.forEach(function (license) {

		license.deviceName = getField(license, ''deviceSerial'');

		for (i in organization_devices) {

			if (getField(license, ''deviceSerial'') === getField(organization_devices[i], ''serial'')) {

				device_name = getField(organization_devices[i], ''name'');

				if (!device_name) {
					device_name = getField(organization_devices[i], ''serial'');
				}
				license.deviceName = device_name;
			}
		}
	});


} catch (error) {
	error_msg = error;
};

return JSON.stringify({
	''licenses'': licenses,
	''error'': error_msg.toString()
});','','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}
User-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}
User-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.
Proxy 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:

  0 - disk (also returned when memory buffer is disabled);
  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 = {
	params: {},
	session_token: "",
	session_url: "",

	setParams: function (params) {
		[''ilo_url'', ''user'', ''password''].forEach(function (field) {
			if (typeof params !== ''object'' || typeof params[field] === ''undefined''
				|| params[field] === '''') {
				throw ''Required parameter is not set: "'' + field + ''".'';
			}
		});

		ilo.params = params;

		if (typeof ilo.params.ilo_url === ''string'' && !ilo.params.ilo_url.endsWith(''/'')) {
			ilo.params.ilo_url += ''/'';
		}
	},

	apiAuth: function () {
		var request = new HttpRequest(),
			response,
			headers,
			url = encodeURI(ilo.params.ilo_url + ''redfish/v1/SessionService/Sessions/''),
			auth_data = {
				UserName: ilo.params.user,
				Password: ilo.params.password
			};

		request.addHeader(''Content-Type: application/json'');
		request.addHeader(''Authorization: Basic '' + btoa(ilo.params.user + '':'' + ilo.params.password));

		if (typeof ilo.params.http_proxy !== ''undefined'' && ilo.params.http_proxy !== '''') {
			request.setProxy(ilo.params.http_proxy);
			Zabbix.log(4, ''[ HPE iLO ] Using HTTP proxy: '' + ilo.params.http_proxy);
		}

		Zabbix.log(4, ''[ HPE iLO ] Sending request: '' + url);

		response = request.post(url, JSON.stringify(auth_data));

		Zabbix.log(4, ''[ HPE iLO ] Received response with status code '' + request.getStatus() + '': '' + response);

		if (request.getStatus() != 201) {
			throw ''Authentication failed with status code '' + request.getStatus() + '': '' + response;
		}

		try {
			response = JSON.parse(response);
		}
		catch (error) {
			throw ''Failed to parse auth response received from API. Check debug log for more information.'';
		}

		try {
			headers = request.getHeaders();
		}
		catch (error) {
			throw ''Failed to parse auth headers received from API. Check debug log for more information.'';
		}

		try {
			ilo.session_token = headers[''X-Auth-Token''];
			ilo.session_url = headers[''Location''];
		}
		catch (error) {
			throw ''Failed to retrieve auth token or session URL from API. Check debug log for more information.'';
		}

		delete request;
	},

	apiLogout: function () {
		var request = new HttpRequest(),
			response,
			url = encodeURI(ilo.session_url);

		request.addHeader(''X-Auth-Token: '' + ilo.session_token);

		if (typeof ilo.params.http_proxy !== ''undefined'' && ilo.params.http_proxy !== '''') {
			request.setProxy(ilo.params.http_proxy);
			Zabbix.log(4, ''[ HPE iLO ] Using HTTP proxy: '' + ilo.params.http_proxy);
		}

		Zabbix.log(4, ''[ HPE iLO ] Sending request: '' + url);

		response = request.delete(url);

		Zabbix.log(4, ''[ HPE iLO ] Received response with status code '' + request.getStatus() + '': '' + response);

		if (request.getStatus() != 200) {
			throw ''Deleting of session failed with status code '' + request.getStatus() + '': '' + response;
		}

		delete request;
	},

	apiRequest: function (query) {
		var request = new HttpRequest(),
			response,
			url = encodeURI(ilo.params.ilo_url + query);

		if (typeof ilo.params.http_proxy !== ''undefined'' && ilo.params.http_proxy !== '''') {
			request.setProxy(ilo.params.http_proxy);
			Zabbix.log(4, ''[ HPE iLO ] Using HTTP proxy: '' + ilo.params.http_proxy);
		}

		request.addHeader(''X-Auth-Token: '' + ilo.session_token);

		Zabbix.log(4, ''[ HPE iLO ] Sending request: '' + url);

		response = request.get(url);

		Zabbix.log(4, ''[ HPE iLO ] Received response with status code '' + request.getStatus() + '': '' + response);

		if (request.getStatus() < 200 || request.getStatus() >= 300) {
			throw ''Request failed with status code '' + request.getStatus() + '': '' + response;
		}

		try {
			response = JSON.parse(response);
		}
		catch (error) {
			throw ''Failed to parse response received from API. Check debug log for more information.'';
		}

		delete request;

		return response;
	},

	checkArray: function (array) {
		return typeof array !== ''undefined'' && Array.isArray(array) && array.length > 0 ? true : false;
	}
};

try {
	ilo.setParams(JSON.parse(value));
	ilo.apiAuth();
	var systems = [],
		storages = [],
		controllers = [],
		drives = [],
		volumes = [],
		chassis = [],
		fans = [],
		sensors = [],
		psu = [],
		managers = [];

	var get_systems = ilo.apiRequest(''redfish/v1/Systems?$expand=.'');

	if (ilo.checkArray(get_systems.Members)) {
		for (i in get_systems.Members) {
			if (''Id'' in get_systems.Members[i]) {
				if (get_systems.Members[i].HostName === null) {
					get_systems.Members[i].HostName = get_systems.Members[i].Id;
				}

				systems.push(get_systems.Members[i]);

				var system_storages = ilo.apiRequest(''redfish/v1/Systems/'' + get_systems.Members[i].Id + ''/Storage?$expand=.'');

				if (ilo.checkArray(system_storages.Members)) {
					for (j in system_storages.Members) {
						system_storages.Members[j].systemHostname = get_systems.Members[i].HostName;
						system_storages.Members[j].systemType = get_systems.Members[i].SystemType;
						system_storages.Members[j].systemId = get_systems.Members[i].Id;

						storages.push(system_storages.Members[j]);

						if (''Id'' in system_storages.Members[j]) {
							var storage_controllers = ilo.apiRequest(''redfish/v1/Systems/'' + get_systems.Members[i].Id + ''/Storage/'' + system_storages.Members[j].Id + ''/Controllers?$expand=.'');

							if (ilo.checkArray(storage_controllers.Members)) {
								for (k in storage_controllers.Members) {
									storage_controllers.Members[k].systemHostname = get_systems.Members[i].HostName;
									storage_controllers.Members[k].systemType = get_systems.Members[i].SystemType;
									storage_controllers.Members[k].systemId = get_systems.Members[i].Id;
									storage_controllers.Members[k].storageId = system_storages.Members[j].Id;

									controllers.push(storage_controllers.Members[k]);
								}
							}

							var storage_drives = ilo.apiRequest(''redfish/v1/Systems/'' + get_systems.Members[i].Id + ''/Storage/'' + system_storages.Members[j].Id + ''?$expand=.'');

							if (ilo.checkArray(storage_drives.Drives)) {
								for (k in storage_drives.Drives) {
									storage_drives.Drives[k].systemHostname = get_systems.Members[i].HostName;
									storage_drives.Drives[k].systemType = get_systems.Members[i].SystemType;
									storage_drives.Drives[k].systemId = get_systems.Members[i].Id;
									storage_drives.Drives[k].storageId = system_storages.Members[j].Id;

									drives.push(storage_drives.Drives[k]);
								}
							}

							if (''Volumes'' in system_storages.Members[j]) {
								var storage_volumes = ilo.apiRequest(''redfish/v1/Systems/'' + get_systems.Members[i].Id + ''/Storage/'' + system_storages.Members[j].Id + ''/Volumes?$expand=.'');

								if (ilo.checkArray(storage_volumes.Members)) {
									for (k in storage_volumes.Members) {
										storage_volumes.Members[k].systemHostname = get_systems.Members[i].HostName;
										storage_volumes.Members[k].systemType = get_systems.Members[i].SystemType;
										storage_volumes.Members[k].systemId = get_systems.Members[i].Id;
										storage_volumes.Members[k].storageId = system_storages.Members[j].Id;

										volumes.push(storage_volumes.Members[k]);
									}
								}
							}
						}
					}
				}
			}
		}
	}

	var get_chassis = ilo.apiRequest(''redfish/v1/Chassis?$expand=.'');

	if (ilo.checkArray(get_chassis.Members)) {
		for (i in get_chassis.Members) {
			if (''Id'' in get_chassis.Members[i]) {
				chassis.push(get_chassis.Members[i]);

				chassis_thermal = ilo.apiRequest(''redfish/v1/Chassis/'' + get_chassis.Members[i].Id + ''/Thermal/'');

				if (ilo.checkArray(chassis_thermal.Fans)) {
					for (j in chassis_thermal.Fans) {
						chassis_thermal.Fans[j].chassisId = get_chassis.Members[i].Id;

						fans.push(chassis_thermal.Fans[j]);
					}
				}

				if (ilo.checkArray(chassis_thermal.Temperatures)) {
					for (j in chassis_thermal.Temperatures) {
						chassis_thermal.Temperatures[j].chassisId = get_chassis.Members[i].Id;

						sensors.push(chassis_thermal.Temperatures[j]);
					}
				}

				chassis_power = ilo.apiRequest(''redfish/v1/Chassis/'' + get_chassis.Members[i].Id + ''/Power/'');

				if (ilo.checkArray(chassis_power.PowerSupplies)) {
					for (j in chassis_power.PowerSupplies) {
						chassis_power.PowerSupplies[j].chassisId = get_chassis.Members[i].Id;

						psu.push(chassis_power.PowerSupplies[j]);
					}
				}
			}
		}
	}

	var get_managers = ilo.apiRequest(''redfish/v1/Managers?$expand=.'');

	if (ilo.checkArray(get_managers.Members)) {
		for (i in get_managers.Members) {
			if (''Id'' in get_managers.Members[i]) {
				managers.push(get_managers.Members[i]);
			}
		}
	}

	ilo.apiLogout();

	return JSON.stringify({
		''systems'': systems,
		''storages'': storages,
		''controllers'': controllers,
		''drives'': drives,
		''volumes'': volumes,
		''chassis'': chassis,
		''fans'': fans,
		''sensors'': sensors,
		''psu'': psu,
		''managers'': managers
	});
}
catch (error) {
	error += (String(error).endsWith(''.'')) ? '''' : ''.'';
	Zabbix.log(3, ''[ HPE iLO ] ERROR: '' + error);
	return JSON.stringify({ error: error });
}','','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,E'var AWS = {
	params: {},
	metadata: ''http://169.254.169.254/latest/'',

	getField: function (data, path) {
		var steps = path.split(''.'');
		for (var i = 0; i < steps.length; i++) {
			var step = steps[i];
			if (typeof data !== ''object'' || typeof data[step] === ''undefined'') {
				throw ''Required field was not found: '' + path;
			}

			data = data[step];
		}

		return data;
	},

	isFloat: function (n) {
		n = parseFloat(n);
		return Number(n) === n && n % 1 !== 0;
	},

	checkNumber: function checkNumber(string) {
		if (typeof string !== "string" || isNaN(string) || AWS.isFloat(string)) {
			throw ''Incorrect "timespan" parameter given: '' + string + '' Must be an unsigned number'';
		}
		return string;
	},

	setParams: function (params) {
		AWS.params[''proxy''] = params.proxy;
		switch (AWS.getField(params, ''auth_type'')) {
			case ''role_base'':
				AWS.params[''auth_type''] = ''role_base'';
				var request = new HttpRequest();
				if (typeof AWS.params.proxy !== ''undefined'' && AWS.params.proxy !== '''') {
					request.setProxy(AWS.params.proxy);
				}
				request.addHeader(''X-aws-ec2-metadata-token-ttl-seconds: 21600'');
				var token = request.put(AWS.metadata + ''api/token'');

				if (request.getStatus() !== 200 || token === null || token === '''') {
					throw ''Error getting IMDSv2 session token.'';
				}
				request.addHeader(''X-aws-ec2-metadata-token: '' + token);
				var IamRoleName = request.get(AWS.metadata + ''meta-data/iam/security-credentials'');

				if (request.getStatus() !== 200 || IamRoleName === null || IamRoleName === '''') {
					throw ''Error getting security credentials from instance metadata. Role not found.'';
				}

				credentials = request.get(AWS.metadata + ''meta-data/iam/security-credentials/'' + encodeURI(IamRoleName));

				if (request.getStatus() !== 200 || credentials === null || credentials === '''') {
					throw ''Error getting security credentials from instance metadata.'';
				}

				try {
					credentials = JSON.parse(credentials);
				}
				catch (error) {
					throw ''Failed to parse response received from instance metadata. Check debug log for more information.'';
				}

				[''AccessKeyId'', ''SecretAccessKey'', ''Token''].forEach(function (field) {
					if (typeof credentials !== ''object'' || typeof credentials[field] === ''undefined'' || credentials[field] === '''') {
						throw ''Required credentials are not set: "'' + field + ''".'';
					};
					AWS.params[field] = credentials[field];
				});
				break;
			case ''assume_role'':
				AWS.params[''auth_type''] = ''assume_role'';

				[''AccessKeyId'', ''SecretAccessKey'', ''sts_region'', ''role_arn''].forEach(function (field) {
					if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
						throw ''Required param is not set: "'' + field + ''".'';
					}
					AWS.params[field] = params[field];
				});

				role_arn_regex = /role\\/(.+)$/;

				var payload = {
					''Action'': ''AssumeRole'',
					''Version'': ''2011-06-15'',
					''RoleArn'': AWS.params.role_arn,
					''RoleSessionName'': AWS.params.role_arn.match(role_arn_regex)[1] + ''Session'',
				};

				credentials = AWS.getField(AWS.request(''POST'', AWS.params.sts_region, ''sts'', AWS.prepareParams(payload), ''''), ''AssumeRoleResponse.AssumeRoleResult.Credentials'');

				[''AccessKeyId'', ''SecretAccessKey'', ''SessionToken''].forEach(function (field) {
					if (typeof credentials !== ''object'' || typeof credentials[field] === ''undefined'' || credentials[field] === '''') {
						throw ''Required credentials are not set: "'' + field + ''".'';
					};
					AWS.params[field] = credentials[field];
				});
				break;
			default:
				AWS.params[''auth_type''] = ''access_key'';
				[''AccessKeyId'', ''SecretAccessKey''].forEach(function (field) {
					if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
						throw ''Required param is not set: "'' + field + ''".'';
					}
					AWS.params[field] = params[field];
				});
		}
		[''region'', ''bucket_name'', ''filter_id''].forEach(function (field) {
			if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
				throw ''Required param is not set: "'' + field + ''".'';
			}
			AWS.params[field] = params[field];
		});

		updateInterval = AWS.checkNumber(''{$AWS.S3.UPDATE.INTERVAL}'');

		if (updateInterval > 86400 || updateInterval < 1) {
			throw ''Incorrect "update interval" parameter given: '' + updateInterval + '' Must be between 1 and 86400 seconds.'';
		}
	},

	sign: function (key, message) {
		var hex = hmac(''sha256'', key, message);

		if ((hex.length % 2) === 1) {
			throw ''Invalid length of a hex string!'';
		}

		var result = new Int8Array(hex.length / 2);
		for (var i = 0, b = 0; i < hex.length; i += 2, b++) {
			result[b] = parseInt(hex.substring(i, i + 2), 16);
		}

		return result;
	},

	renderMetricQuery: function (period, bucket_name, filter_id) {
		var metrics_list = [
			''AllRequests:Count:Sum'',
			''GetRequests:Count:Sum'',
			''PutRequests:Count:Sum'',
			''DeleteRequests:Count:Sum'',
			''HeadRequests:Count:Sum'',
			''PostRequests:Count:Sum'',
			''SelectRequests:Count:Sum'',
			''SelectBytesScanned:Bytes:Average'',
			''SelectBytesReturned:Bytes:Average'',
			''ListRequests:Count:Sum'',
			''BytesDownloaded:Bytes:Average'',
			''BytesUploaded:Bytes:Average'',
			''4xxErrors:Count:Average'',
			''5xxErrors:Count:Average'',
			''TotalRequestLatency:Milliseconds:p90'',
			''FirstByteLatency:Milliseconds:p90'',
			''ReplicationLatency:Seconds:Average'',
			''BytesPendingReplication:Bytes:Average'',
			''OperationsPendingReplication:Count:Average'',

		];

		var metric_payload = [];
		metrics_list.forEach(function (metric, index) {
			var parts = metric.split('':'', 3);
			metric_payload.push({
				''Id'': ''m'' + index,
				''MetricStat'': {
					''Metric'': {
						''MetricName'': parts[0],
						''Namespace'': ''AWS/S3'',
						''Dimensions'': [
							{
								''Name'': ''BucketName'',
								''Value'': bucket_name
							},
							{
								''Name'': ''FilterId'',
								''Value'': filter_id
							}
						]
					},
					''Period'': period,
					''Stat'': parts[2],
					''Unit'': parts[1]
				}
			});
		});

		return metric_payload;

	},
	prepareParams: function (params) {
		var result = [];

		Object.keys(params).sort().forEach(function (key) {
			if (typeof params[key] !== ''object'') {
				result.push(key + ''='' + encodeURIComponent(params[key]));
			}
			else {
				result.push(prepareObject(key, params[key]));
			}
		});

		return result.join(''&'');
	},

	request: function (method, region, service, params, data) {
		if (typeof data === ''undefined'' || data === null) {
			data = '''';
		}
		else {
			data = JSON.stringify(data)
		}

		var amzdate = (new Date()).toISOString().replace(/\\.\\d+Z/, ''Z'').replace(/[-:]/g, ''''),
			date = amzdate.replace(/T\\d+Z/, ''''),
			host = service + ''.'' + region + ''.amazonaws.com'',
			canonical_uri = ''/'';

		if (AWS.params.auth_type === ''role_base'' || (AWS.params.auth_type === ''assume_role'' & !params.includes(''AssumeRole''))) {
			token = AWS.params.auth_type === ''role_base'' ? AWS.params.Token : AWS.params.SessionToken;
			var canonical_headers = ''content-encoding:amz-1.0\\n'' + ''host:'' + host + ''\\n'' + ''x-amz-date:'' + amzdate + ''\\n'' + ''x-amz-security-token:'' + token + ''\\n'',
				signed_headers = ''content-encoding;host;x-amz-date;x-amz-security-token'';
		}
		else {
			var canonical_headers = ''content-encoding:amz-1.0\\n'' + ''host:'' + host + ''\\n'' + ''x-amz-date:'' + amzdate + ''\\n'',
				signed_headers = ''content-encoding;host;x-amz-date'';
		}

		var canonical_request = method + ''\\n'' + canonical_uri + ''\\n'' + params + ''\\n'' + canonical_headers + ''\\n'' + signed_headers + ''\\n'' + sha256(data),
			credential_scope = date + ''/'' + region + ''/'' + service + ''/'' + ''aws4_request'',
			request_string = ''AWS4-HMAC-SHA256'' + ''\\n'' + amzdate + ''\\n'' + credential_scope + ''\\n'' + sha256(canonical_request),
			key = AWS.sign(''AWS4'' + AWS.params.SecretAccessKey, date),
			key = AWS.sign(key, region),
			key = AWS.sign(key, service),
			key = AWS.sign(key, ''aws4_request''),
			request = new HttpRequest(),
			url = ''https://'' + host + canonical_uri + ''?'' + params;

		if (typeof AWS.params.proxy !== ''undefined'' && AWS.params.proxy !== '''') {
			request.setProxy(AWS.params.proxy);
		}
		request.addHeader(''x-amz-date: '' + amzdate);
		request.addHeader(''X-Amz-Target: GraniteServiceVersion20100801.GetMetricData'')
		request.addHeader(''Accept: application/json'');
		request.addHeader(''Content-Type: application/json'');
		request.addHeader(''Content-Encoding: amz-1.0'');
		request.addHeader(''Authorization: '' + ''AWS4-HMAC-SHA256 Credential='' + AWS.params.AccessKeyId + ''/'' + credential_scope + '', '' + ''SignedHeaders='' + signed_headers + '', '' + ''Signature='' + hmac(''sha256'', key, request_string));
		if (AWS.params.auth_type === ''role_base'' || (AWS.params.auth_type === ''assume_role'' & !params.includes(''AssumeRole''))) {
			request.addHeader(''X-Amz-Security-Token: '' + token);
		}

		Zabbix.log(4, ''[ AWS S3 ] Sending request: '' + url);
		response = request.post(url, data);
		Zabbix.log(4, ''[ AWS S3 ] Received response with status code '' + request.getStatus() + '': '' + response);

		if (request.getStatus() !== 200) {
			throw ''Request failed with status code '' + request.getStatus() + '': '' + response;
		}

		try {
			response = JSON.parse(response);
		}
		catch (error) {
			try {
				response = JSON.parse(XML.toJson(response));
			}
			catch (error) {
				throw ''Failed to parse response received from AWS CloudWatch API. Check debug log for more information.'';
			}
		}

		return response;
	},

	getMetricsData: function () {
		var payload = {},
			end_time = Math.floor((new Date().getTime()) / 1000),
			start_time = end_time - updateInterval;

		payload[''StartTime''] = start_time;
		payload[''EndTime''] = end_time;
		payload[''ScanBy''] = ''TimestampDescending'';
		payload[''MetricDataQueries''] = AWS.renderMetricQuery(60, AWS.params.bucket_name, AWS.params.filter_id);
		result = AWS.request(''POST'', AWS.params.region, ''monitoring'', '''', payload);
		if (typeof result !== ''object'' || typeof result.MetricDataResults !== ''object'') {
			throw ''Cannot get metrics data from AWS CloudWatch API. Check debug log for more information.'';
		}

		return result.MetricDataResults;
	}
};

try {
	AWS.setParams(JSON.parse(value));

	return JSON.stringify(AWS.getMetricsData());
}
catch (error) {
	error += (String(error).endsWith(''.'')) ? '''' : ''.'';
	Zabbix.log(3, ''[ AWS S3 ] ERROR: '' + error);

	return JSON.stringify({ ''error'': error });
}','','0','','','','','2',NULL,'Get bucket request metrics filter: ''{#AWS.S3.FILTER.ID.NAME}''.
Full 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,E'var AzureCost = {
	params: {},
	token: null,

	setParams: function (params) {
		[''app_id'', ''password'', ''tenant_id'', ''subscription_id''].forEach(function (field) {
			if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
				throw ''Required param is not set: '' + field + ''.'';
			}
		});
		AzureCost.params = params;
	},

	login: function () {
		var response,
			login = new HttpRequest();

		if (typeof AzureCost.params.proxy !== ''undefined'' && AzureCost.params.proxy !== '''') {
			login.setProxy(AzureCost.params.proxy);
		}

		login.addHeader(''Content-Type: application/x-www-form-urlencoded'');
		response = login.post(
			''https://login.microsoftonline.com/'' + encodeURIComponent(AzureCost.params.tenant_id) + ''/oauth2/token'',
			''grant_type=client_credentials&resource='' + encodeURIComponent(''https://management.azure.com/'') + ''&client_id='' + encodeURIComponent(AzureCost.params.app_id) + ''&client_secret='' + encodeURIComponent(AzureCost.params.password)
		);

		if (login.getStatus() !== 200) {
			throw ''Login failed with status code '' + login.getStatus() + '': '' + response;
		}
		try {
			response = JSON.parse(response);
		}
		catch (error) {
			throw ''Failed to parse login session response.'';
		}
		if (!response.hasOwnProperty(''access_token'')) {
			throw ''Authentication response does not contain access token.'';
		}

		AzureCost.token = response[''access_token''];
	},

	request: function (url, body) {
		if (typeof body === ''undefined'' || body === null) {
			body = '''';
		}
		var response,
			headers,
			regex = /-retry-after":"(\\d+)"/,
			ratelimit,
			request = new HttpRequest();

		if (typeof AzureCost.params.proxy !== ''undefined'' && AzureCost.params.proxy !== '''') {
			request.setProxy(AzureCost.params.proxy);
		}
		if (!AzureCost.token) {
			throw ''Request does not contain access token.'';
		}
		request.addHeader(''Accept: application/json'');
		request.addHeader(''Content-Type: application/json'');
		request.addHeader(''Authorization: Bearer '' + AzureCost.token);

		Zabbix.log(4, ''[ AzureCost ] request url: '' + url);

		response = request.post(url, body);
		headers = JSON.stringify(request.getHeaders());

		if (headers.match(regex) !== null && request.getStatus() === 429) {
			ratelimit = headers.match(regex)[1];
			Zabbix.log(4, ''[ AzureCost ] Microsoft Cost Management have rate limit requests per 1 minute, retrying after '' + ratelimit + '' seconds'');
			Zabbix.sleep(ratelimit * 1010);
			response = request.post(url, body);
		}
		if (request.getStatus() !== 200) {
			throw ''Request failed with status code '' + request.getStatus() + '': '' + response;
		}

		try {
			return JSON.parse(response);
		}
		catch (error) {
			throw ''Failed to parse response received from API.'';
		}
	},

	getField: function (data, path) {
		var steps = path.split(''.'');
		for (var i = 0; i < steps.length; i++) {
			var step = steps[i];
			if (typeof data !== ''object'' || typeof data[step] === ''undefined'') {
				throw ''Required field was not found: '' + path;
			}
			data = data[step];
		}

		return data;
	},

	getCost: function () {
		var metricData = {},
			today = new Date(),
			start_date = new Date(today);
		start_date.setDate(today.getDate() - 1);

		bodyRawCost = {
			type: ''Usage'',
			''timeframe'': ''Custom'',
			''timePeriod'': {
				''from'': start_date,
				''to'': start_date
			},
			dataset: {
				granularity: ''Daily'',
				aggregation: {
					totalCost: {
						name: ''PreTaxCost'',
						function: ''Sum''
					}
				},
				grouping: [
					{
						type: ''Dimension'',
						name: ''Meter'',
					},
					{
						type: ''Dimension'',
						name: ''MeterSubcategory'',
					},
					{
						type: ''Dimension'',
						name: ''ResourceGroup'',
					},
					{
						type: ''Dimension'',
						name: ''ServiceName'',
					},
					{
						type: ''Dimension'',
						name: ''ResourceLocation'',
					}
				]
			}
		};
		metricData = AzureCost.request(''https://management.azure.com/subscriptions/'' + AzureCost.params.subscription_id + ''/providers/Microsoft.CostManagement/query?api-version=2023-11-01'', JSON.stringify(bodyRawCost));

		var columns = AzureCost.getField(metricData, ''properties.columns'');

		return transformedData = {
			data: AzureCost.getField(metricData, ''properties.rows'').map(function (row) {
				rowData = {};
				columns.forEach(function (column, i) {
					columnName = columns[i].name;
					columnType = columns[i].type;
					cellValue = row[i];
					rowData[columnName] = column.type === "Number" ? cellValue.toString() : cellValue;
				});
				rowData.UsageDate = rowData.UsageDate.replace(/(\\d{4})(\\d{2})(\\d{2})/, "$1-$2-$3");

				return rowData;
			})
		};
	}
};

try {
	AzureCost.setParams(JSON.parse(value));
	AzureCost.login();

	return JSON.stringify(AzureCost.getCost());
}
catch (error) {
	error += (String(error).endsWith(''.'')) ? '''' : ''.'';
	Zabbix.log(3, ''[ AzureCost ] ERROR: '' + error);

	return JSON.stringify({ ''error'': error });
}','','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,E'var AzureCost = {
	params: {},
	token: null,

	setParams: function (params) {
		[''app_id'', ''password'', ''tenant_id'', ''subscription_id'', ''month''].forEach(function (field) {
			if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
				throw ''Required param is not set: '' + field + ''.'';
			}
		});
		AzureCost.params = params;

		today = new Date();
		AzureCost.params.end_date = today.toISOString();
		month = today.getMonth();
		today.setMonth(month - params.month);
		AzureCost.params.start_time = new Date(today.getFullYear(), today.getMonth()).toISOString();
	},

	login: function () {
		var response,
			login = new HttpRequest();

		if (typeof AzureCost.params.proxy !== ''undefined'' && AzureCost.params.proxy !== '''') {
			login.setProxy(AzureCost.params.proxy);
		}

		login.addHeader(''Content-Type: application/x-www-form-urlencoded'');
		response = login.post(
			''https://login.microsoftonline.com/'' + encodeURIComponent(AzureCost.params.tenant_id) + ''/oauth2/token'',
			''grant_type=client_credentials&resource='' + encodeURIComponent(''https://management.azure.com/'') + ''&client_id='' + encodeURIComponent(AzureCost.params.app_id) + ''&client_secret='' + encodeURIComponent(AzureCost.params.password)
		);

		if (login.getStatus() !== 200) {
			throw ''Login failed with status code '' + login.getStatus() + '': '' + response;
		}
		try {
			response = JSON.parse(response);
		}
		catch (error) {
			throw ''Failed to parse login session response.'';
		}
		if (!response.hasOwnProperty(''access_token'')) {
			throw ''Authentication response does not contain access token.'';
		}

		AzureCost.token = response[''access_token''];
	},

	request: function (url, body) {
		if (typeof body === ''undefined'' || body === null) {
			body = '''';
		}
		var response,
			headers,
			regex = /-retry-after":"(\\d+)"/,
			ratelimit,
			request = new HttpRequest();

		if (typeof AzureCost.params.proxy !== ''undefined'' && AzureCost.params.proxy !== '''') {
			request.setProxy(AzureCost.params.proxy);
		}
		if (!AzureCost.token) {
			throw ''Request does not contain access token.'';
		}
		request.addHeader(''Accept: application/json'');
		request.addHeader(''Content-Type: application/json'');
		request.addHeader(''Authorization: Bearer '' + AzureCost.token);

		Zabbix.log(4, ''[ AzureCost ] request url: '' + url);

		response = request.post(url, body);
		headers = JSON.stringify(request.getHeaders());

		if (headers.match(regex) !== null && request.getStatus() === 429) {
			ratelimit = headers.match(regex)[1];
			Zabbix.log(4, ''[ AzureCost ] Microsoft Cost Management have rate limit requests per 1 minute, retrying after '' + ratelimit + '' seconds'');
			Zabbix.sleep(ratelimit * 1010);
			response = request.post(url, body);
		}
		if (request.getStatus() !== 200) {
			throw ''Request failed with status code '' + request.getStatus() + '': '' + response;
		}

		try {
			return JSON.parse(response);
		}
		catch (error) {
			throw ''Failed to parse response received from API.'';
		}
	},

	getField: function (data, path) {
		var steps = path.split(''.'');
		for (var i = 0; i < steps.length; i++) {
			var step = steps[i];
			if (typeof data !== ''object'' || typeof data[step] === ''undefined'') {
				throw ''Required field was not found: '' + path;
			}
			data = data[step];
		}

		return data;
	},

	getCost: function (grouping) {
		var metricData = {},
			bodyRawCost = {
				type: ''Usage'',
				timeframe: ''Custom'',
				timePeriod: {
					from: AzureCost.params.start_time,
					to: AzureCost.params.end_date
				},
				dataset: {
					aggregation: {
						totalCost: {
							name: ''PreTaxCost'',
							function: ''Sum''
						}
					},
					grouping: [
						{
							type: ''Dimension'',
							name: ''BillingMonth''
						},
						{
							type: ''Dimension'',
							name: grouping
						},
					]
				}
			};

		metricData = AzureCost.request(''https://management.azure.com/subscriptions/'' + AzureCost.params.subscription_id + ''/providers/Microsoft.CostManagement/query?api-version=2023-11-01'', JSON.stringify(bodyRawCost));

		var columns = AzureCost.getField(metricData, ''properties.columns'');

		return transformedData = {
			data: AzureCost.getField(metricData, ''properties.rows'').map(function (row) {
				rowData = {};
				columns.forEach(function (column, i) {
					columnName = columns[i].name;
					cellValue = row[i];
					rowData[columnName] = column.type === "Number" ? cellValue.toString() : cellValue;
				});
				rowData.BillingMonth = rowData.BillingMonth.slice(0, 7);

				return rowData;
			})
		};
	}
};

try {
	AzureCost.setParams(JSON.parse(value));
	AzureCost.login();

	serviceCost = AzureCost.getCost(''ServiceName'');
	resourceGroupCost = AzureCost.getCost(''ResourceGroup'');
	resourceLocationCost = AzureCost.getCost(''ResourceLocation'');
	monthCost = AzureCost.getCost(''SubscriptionId'');

	return JSON.stringify({ resourceGroupCost, resourceLocationCost, serviceCost, monthCost });
}
catch (error) {
	error += (String(error).endsWith(''.'')) ? '''' : ''.'';
	Zabbix.log(3, ''[ AzureCost ] ERROR: '' + error);

	return JSON.stringify({ ''error'': error });
}','','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
  ag.name as group_name,
  ISNULL(ags.primary_recovery_health, 2) as primary_recovery_health,
  ISNULL(ags.primary_replica, ''Unknown'') as primary_replica,
  ISNULL(
    ags.secondary_recovery_health, 2
  ) as secondary_recovery_health,
  ags.synchronization_health as synchronization_health
FROM
  sys.dm_hadr_availability_group_states ags
JOIN 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
FROM 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
  ISNULL(m.mirroring_role, 0) as mirroring_role,
  ISNULL(m.mirroring_role_sequence, 0) as mirroring_role_sequence,
  ISNULL(m.mirroring_state, 7) as mirroring_state,
  ISNULL(m.mirroring_witness_state, 3) as mirroring_witness_state,
  ISNULL(m.mirroring_safety_level, 3) as mirroring_safety_level,
  db_name(m.database_id) as dbname
FROM
  sys.database_mirroring as m
WHERE
  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, 
  drs.database_state as database_state, 
  drs.is_suspended as is_suspended, 
  drs.synchronization_health as synchronization_health, 
  arcs.replica_server_name AS replica_name,
  db_name(drs.database_id) AS dbname, 
  drs.is_local
FROM sys.dm_hadr_database_replica_states drs 
JOIN sys.dm_hadr_availability_replica_cluster_states arcs
  ON arcs.replica_id = drs.replica_id
JOIN sys.availability_groups ag 
  ON ag.group_id = arcs.group_id
JOIN sys.dm_hadr_availability_replica_states ars 
  ON ars.replica_id = arcs.replica_id
WHERE 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, 
  ISNULL(drs.log_send_queue_size, 0) as log_send_queue_size, 
  ISNULL(drs.redo_queue_size, 0) as redo_queue_size, 
  arcs.replica_server_name AS replica_name,
  db_name(drs.database_id) AS dbname, 
  drs.is_local
FROM sys.dm_hadr_database_replica_states drs 
JOIN sys.dm_hadr_availability_replica_cluster_states arcs
  ON arcs.replica_id = drs.replica_id
JOIN sys.availability_groups ag 
  ON ag.group_id = arcs.group_id
JOIN sys.dm_hadr_availability_replica_states ars 
  ON ars.replica_id = arcs.replica_id
WHERE 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
FROM 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 member_name, member_type, member_state, number_of_quorum_votes
FROM sys.dm_hadr_cluster_members','','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 
  ars.connected_state as connected_state, 
  ars.is_local as is_local, 
  arcs.join_state as join_state, 
  ISNULL(ars.operational_state, 6) as operational_state, 
  ISNULL(ars.recovery_health, 2) as recovery_health, 
  ars.role as role, 
  ars.synchronization_health as synchronization_health, 
  ag.name as group_name, 
  arcs.replica_server_name as replica_name 
FROM 
  sys.dm_hadr_availability_replica_cluster_states as arcs 
JOIN sys.availability_groups ag ON ag.group_id = arcs.group_id 
JOIN 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}
User-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,E'var AWS = {
	params: {},
	metadata: ''http://169.254.169.254/latest/'',

	getField: function (data, path) {
		var steps = path.split(''.'');
		for (var i = 0; i < steps.length; i++) {
			var step = steps[i];
			if (typeof data !== ''object'' || typeof data[step] === ''undefined'') {
				throw ''Required field was not found: '' + path;
			}

			data = data[step];
		}

		return data;
	},

	setParams: function (params) {
		AWS.params[''proxy''] = params.proxy;
		switch (AWS.getField(params, ''auth_type'')) {
			case ''role_base'':
				AWS.params[''auth_type''] = ''role_base'';
				var request = new HttpRequest();
				if (typeof AWS.params.proxy !== ''undefined'' && AWS.params.proxy !== '''') {
					request.setProxy(AWS.params.proxy);
				}
				request.addHeader(''X-aws-ec2-metadata-token-ttl-seconds: 21600'');
				var token = request.put(AWS.metadata + ''api/token'');

				if (request.getStatus() !== 200 || token === null || token === '''') {
					throw ''Error getting IMDSv2 session token.'';
				}
				request.addHeader(''X-aws-ec2-metadata-token: '' + token);
				var IamRoleName = request.get(AWS.metadata + ''meta-data/iam/security-credentials'');

				if (request.getStatus() !== 200 || IamRoleName === null || IamRoleName === '''') {
					throw ''Error getting security credentials from instance metadata. Role not found.'';
				}

				credentials = request.get(AWS.metadata + ''meta-data/iam/security-credentials/'' + encodeURI(IamRoleName));

				if (request.getStatus() !== 200 || credentials === null || credentials === '''') {
					throw ''Error getting security credentials from instance metadata.'';
				}

				try {
					credentials = JSON.parse(credentials);
				}
				catch (error) {
					throw ''Failed to parse response received from instance metadata. Check debug log for more information.'';
				}

				[''AccessKeyId'', ''SecretAccessKey'', ''Token''].forEach(function (field) {
					if (typeof credentials !== ''object'' || typeof credentials[field] === ''undefined'' || credentials[field] === '''') {
						throw ''Required credentials are not set: "'' + field + ''".'';
					};
					AWS.params[field] = credentials[field];
				});
				break;
			case ''assume_role'':
				AWS.params[''auth_type''] = ''assume_role'';

				[''AccessKeyId'', ''SecretAccessKey'', ''sts_region'', ''role_arn''].forEach(function (field) {
					if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
						throw ''Required param is not set: "'' + field + ''".'';
					}
					AWS.params[field] = params[field];
				});

				role_arn_regex = /role\\/(.+)$/;

				var payload = {
					''Action'': ''AssumeRole'',
					''Version'': ''2011-06-15'',
					''RoleArn'': AWS.params.role_arn,
					''RoleSessionName'': AWS.params.role_arn.match(role_arn_regex)[1] + ''Session'',
				};

				credentials = AWS.getField(AWS.request(''GET'', AWS.params.sts_region, ''sts'', AWS.prepareParams(payload), ''''), ''AssumeRoleResponse.AssumeRoleResult.Credentials'');

				[''AccessKeyId'', ''SecretAccessKey'', ''SessionToken''].forEach(function (field) {
					if (typeof credentials !== ''object'' || typeof credentials[field] === ''undefined'' || credentials[field] === '''') {
						throw ''Required credentials are not set: "'' + field + ''".'';
					};
					AWS.params[field] = credentials[field];
				});
				break;
			default:
				AWS.params[''auth_type''] = ''access_key'';
				[''AccessKeyId'', ''SecretAccessKey''].forEach(function (field) {
					if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
						throw ''Required param is not set: "'' + field + ''".'';
					}
					AWS.params[field] = params[field];
				});
		}
		[''region'', ''arn'', ''loadbalancer_name''].forEach(function (field) {
			if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
				throw ''Required param is not set: "'' + field + ''".'';
			}
			AWS.params[field] = params[field];
		});
	},

	sign: function (key, message) {
		var hex = hmac(''sha256'', key, message);

		if ((hex.length % 2) === 1) {
			throw ''Invalid length of a hex string!'';
		}

		var result = new Int8Array(hex.length / 2);
		for (var i = 0, b = 0; i < hex.length; i += 2, b++) {
			result[b] = parseInt(hex.substring(i, i + 2), 16);
		}

		return result;
	},

	prepareParams: function (params) {
		var result = [];

		Object.keys(params).sort().forEach(function (key) {
			if (typeof params[key] !== ''object'') {
				result.push(key + ''='' + encodeURIComponent(params[key]));
			}
			else {
				result.push(prepareObject(key, params[key]));
			}
		});

		return result.join(''&'');
	},

	request: function (method, region, service, params, data) {
		if (typeof data === ''undefined'' || data === null) {
			data = '''';
		}

		var amzdate = (new Date()).toISOString().replace(/\\.\\d+Z/, ''Z'').replace(/[-:]/g, ''''),
			date = amzdate.replace(/T\\d+Z/, ''''),
			host = service + ''.'' + region + ''.amazonaws.com'',
			canonical_uri = ''/'',
			canonical_headers = ''content-encoding:amz-1.0\\n'' + ''host:'' + host + ''\\n'' + ''x-amz-date:'' + amzdate + ''\\n'',
			signed_headers = ''content-encoding;host;x-amz-date'',
			canonical_request = method + ''\\n'' + canonical_uri + ''\\n'' + params + ''\\n'' + canonical_headers + ''\\n'' + signed_headers + ''\\n'' + sha256(data),
			credential_scope = date + ''/'' + region + ''/'' + service + ''/'' + ''aws4_request'',
			request_string = ''AWS4-HMAC-SHA256'' + ''\\n'' + amzdate + ''\\n'' + credential_scope + ''\\n'' + sha256(canonical_request),
			key = AWS.sign(''AWS4'' + AWS.params.SecretAccessKey, date),
			key = AWS.sign(key, region),
			key = AWS.sign(key, service),
			key = AWS.sign(key, ''aws4_request''),
			request = new HttpRequest(),
			url = ''https://'' + host + canonical_uri + ''?'' + params;

		if (typeof AWS.params.proxy !== ''undefined'' && AWS.params.proxy !== '''') {
			request.setProxy(AWS.params.proxy);
		}
		request.addHeader(''x-amz-date: '' + amzdate);
		request.addHeader(''Accept: application/json'');
		request.addHeader(''Content-Type: application/json'');
		request.addHeader(''Content-Encoding: amz-1.0'');
		request.addHeader(''Authorization: '' + ''AWS4-HMAC-SHA256 Credential='' + AWS.params.AccessKeyId + ''/'' + credential_scope + '', '' + ''SignedHeaders='' + signed_headers + '', '' + ''Signature='' + hmac(''sha256'', key, request_string));
		if (AWS.params.auth_type === ''role_base'' || (AWS.params.auth_type === ''assume_role'' & !params.includes(''AssumeRole''))) {
			request.addHeader(''X-Amz-Security-Token: '' + (AWS.params.auth_type === ''role_base'' ? AWS.params.Token : AWS.params.SessionToken));
		}

		Zabbix.log(4, ''[ AWS ELB ] Sending request: '' + url);
		response = request.get(url);
		Zabbix.log(4, ''[ AWS ELB ] Received response with status code '' + request.getStatus() + '': '' + response);

		if (request.getStatus() !== 200) {
			throw ''Request failed with status code '' + request.getStatus() + '': '' + response;
		}

		try {
			response = JSON.parse(response);
		}
		catch (error) {
			try {
				response = JSON.parse(XML.toJson(response));
			}
			catch (error) {
				throw ''Failed to parse response received from AWS CloudWatch API. Check debug log for more information.'';
			}
		}

		return response;
	},

	getAlarms: function () {
		var payload = {
			''Action'': ''DescribeAlarms'',
			''Version'': ''2010-08-01'',
			''MaxRecords'': 100
		},
			result = [];

		while (payload.NextToken !== '''') {
			var alarms = AWS.getField(AWS.request(''GET'', AWS.params.region, ''monitoring'', AWS.prepareParams(payload)), ''DescribeAlarmsResponse.DescribeAlarmsResult'');
			payload.NextToken = alarms.NextToken || '''';
			alarms_list = AWS.getField(alarms, ''MetricAlarms'');
			regex = /loadbalancer\\/(.+)$/;

			if (!Array.isArray(alarms_list))
				alarms_list = [alarms_list];
			alarms_list.forEach(function (alarm) {
				var dimensions = alarm.Dimensions;

				if (Array.isArray(alarm.Metrics)) {
					alarm.Metrics.forEach(function (metric) {
						if (typeof metric.MetricStat === ''object'' && metric.MetricStat !== null
							&& typeof metric.MetricStat.Metric === ''object'' && metric.MetricStat.Metric !== null
							&& Array.isArray(metric.MetricStat.Metric.Dimensions)) {
							dimensions = dimensions.concat(metric.MetricStat.Metric.Dimensions);
						}
					});
				}
				for (var i in dimensions) {
					if ((dimensions[i].Name === ''LoadBalancer'' && dimensions[i].Value === AWS.params.arn.match(regex)[1])
						|| (dimensions[i].Name === ''LoadBalancerName'' && dimensions[i].Value === AWS.params.loadbalancer_name)) {
						result.push(alarm);
						break;
					}
				}
			});
		}

		return result;
	}
};

try {
	AWS.setParams(JSON.parse(value));

	return JSON.stringify(AWS.getAlarms());
}
catch (error) {
	error += (String(error).endsWith(''.'')) ? '''' : ''.'';
	Zabbix.log(3, ''[ AWS ELB Alarms ] ERROR: '' + error);

	return JSON.stringify({ ''error'': error });
}','','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,E'var AWS = {
	params: {},
	metadata: ''http://169.254.169.254/latest/'',
	request_period: 60,

	getField: function (data, path) {
		var steps = path.split(''.'');
		for (var i = 0; i < steps.length; i++) {
			var step = steps[i];
			if (typeof data !== ''object'' || typeof data[step] === ''undefined'') {
				throw ''Required field was not found: '' + path;
			}

			data = data[step];
		}

		return data;
	},

	setParams: function (params) {
		AWS.params[''proxy''] = params.proxy;
		switch (AWS.getField(params, ''auth_type'')) {
			case ''role_base'':
				AWS.params[''auth_type''] = ''role_base'';
				var request = new HttpRequest();
				if (typeof AWS.params.proxy !== ''undefined'' && AWS.params.proxy !== '''') {
					request.setProxy(AWS.params.proxy);
				}
				request.addHeader(''X-aws-ec2-metadata-token-ttl-seconds: 21600'');
				var token = request.put(AWS.metadata + ''api/token'');

				if (request.getStatus() !== 200 || token === null || token === '''') {
					throw ''Error getting IMDSv2 session token.'';
				}
				request.addHeader(''X-aws-ec2-metadata-token: '' + token);
				var IamRoleName = request.get(AWS.metadata + ''meta-data/iam/security-credentials'');

				if (request.getStatus() !== 200 || IamRoleName === null || IamRoleName === '''') {
					throw ''Error getting security credentials from instance metadata. Role not found.'';
				}

				credentials = request.get(AWS.metadata + ''meta-data/iam/security-credentials/'' + encodeURI(IamRoleName));

				if (request.getStatus() !== 200 || credentials === null || credentials === '''') {
					throw ''Error getting security credentials from instance metadata.'';
				}

				try {
					credentials = JSON.parse(credentials);
				}
				catch (error) {
					throw ''Failed to parse response received from instance metadata. Check debug log for more information.'';
				}

				[''AccessKeyId'', ''SecretAccessKey'', ''Token''].forEach(function (field) {
					if (typeof credentials !== ''object'' || typeof credentials[field] === ''undefined'' || credentials[field] === '''') {
						throw ''Required credentials are not set: "'' + field + ''".'';
					};
					AWS.params[field] = credentials[field];
				});
				break;
			case ''assume_role'':
				AWS.params[''auth_type''] = ''assume_role'';

				[''AccessKeyId'', ''SecretAccessKey'', ''sts_region'', ''role_arn''].forEach(function (field) {
					if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
						throw ''Required param is not set: "'' + field + ''".'';
					}
					AWS.params[field] = params[field];
				});

				role_arn_regex = /role\\/(.+)$/;

				var payload = {
					''Action'': ''AssumeRole'',
					''Version'': ''2011-06-15'',
					''RoleArn'': AWS.params.role_arn,
					''RoleSessionName'': AWS.params.role_arn.match(role_arn_regex)[1] + ''Session'',
				};

				credentials = AWS.getField(AWS.request(''POST'', AWS.params.sts_region, ''sts'', AWS.prepareParams(payload), ''''), ''AssumeRoleResponse.AssumeRoleResult.Credentials'');

				[''AccessKeyId'', ''SecretAccessKey'', ''SessionToken''].forEach(function (field) {
					if (typeof credentials !== ''object'' || typeof credentials[field] === ''undefined'' || credentials[field] === '''') {
						throw ''Required credentials are not set: "'' + field + ''".'';
					};
					AWS.params[field] = credentials[field];
				});
				break;
			default:
				AWS.params[''auth_type''] = ''access_key'';
				[''AccessKeyId'', ''SecretAccessKey''].forEach(function (field) {
					if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
						throw ''Required param is not set: "'' + field + ''".'';
					}
					AWS.params[field] = params[field];
				});
		}
		[''region'', ''arn''].forEach(function (field) {
			if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
				throw ''Required param is not set: "'' + field + ''".'';
			}
			AWS.params[field] = params[field];
		});
	},

	sign: function (key, message) {
		var hex = hmac(''sha256'', key, message);

		if ((hex.length % 2) === 1) {
			throw ''Invalid length of a hex string!'';
		}

		var result = new Int8Array(hex.length / 2);
		for (var i = 0, b = 0; i < hex.length; i += 2, b++) {
			result[b] = parseInt(hex.substring(i, i + 2), 16);
		}

		return result;
	},

	prepareParams: function (params) {
		var result = [];

		Object.keys(params).sort().forEach(function (key) {
			if (typeof params[key] !== ''object'') {
				result.push(key + ''='' + encodeURIComponent(params[key]));
			}
			else {
				result.push(prepareObject(key, params[key]));
			}
		});

		return result.join(''&'');
	},

	renderMetricQuery: function (period, arn) {
		var metrics_list = [
			''ActiveConnectionCount:Sum'',
			''ClientTLSNegotiationErrorCount:Sum'',
			''ConsumedLCUs:Sum'',
			''DesyncMitigationMode_NonCompliant_Request_Count:Sum'',
			''HTTP_Fixed_Response_Count:Sum'',
			''HTTP_Redirect_Count:Sum'',
			''HTTP_Redirect_Url_Limit_Exceeded_Count:Sum'',
			''HTTPCode_ELB_3XX_Count:Sum'',
			''HTTPCode_ELB_4XX_Count:Sum'',
			''HTTPCode_ELB_5XX_Count:Sum'',
			''HTTPCode_ELB_500_Count:Sum'',
			''HTTPCode_ELB_502_Count:Sum'',
			''HTTPCode_ELB_503_Count:Sum'',
			''HTTPCode_ELB_504_Count:Sum'',
			''NewConnectionCount:Sum'',
			''ProcessedBytes:Sum'',
			''RejectedConnectionCount:Sum'',
			''RequestCount:Sum'',
			''RuleEvaluations:Sum'',
			''TargetResponseTime:Average'',
			''TargetTLSNegotiationErrorCount:Sum'',
			''TargetConnectionErrorCount:Sum'',
			''ELBAuthError:Sum'',
			''ELBAuthFailure:Sum'',
			''ELBAuthLatency:Sum'',
			''ELBAuthSuccess:Sum'',
			''ELBAuthUserClaimsSizeExceeded:Sum'',
		],
			regex = /loadbalancer\\/(.+)$/;

		var metric_payload = [];
		metrics_list.forEach(function (metric, index) {
			var parts = metric.split('':'', 2);
			metric_payload.push({
				''Id'': ''m'' + index,
				''MetricStat'': {
					''Metric'': {
						''MetricName'': parts[0],
						''Namespace'': ''AWS/ApplicationELB'',
						''Dimensions'': [
							{
								''Name'': ''LoadBalancer'',
								''Value'': arn.match(regex)[1],
							}
						]
					},
					''Period'': period,
					''Stat'': parts[1],
				}
			});
		});

		return metric_payload;
	},

	request: function (method, region, service, params, data) {
		if (typeof data === ''undefined'' || data === null) {
			data = JSON.stringify([]);
		}
		else {
			data = JSON.stringify(data)
		}
		var amzdate = (new Date()).toISOString().replace(/\\.\\d+Z/, ''Z'').replace(/[-:]/g, ''''),
			date = amzdate.replace(/T\\d+Z/, ''''),
			canonical_uri = ''/'',
			host = service + ''.'' + region + ''.amazonaws.com'',
			canonical_headers = ''content-encoding:amz-1.0\\n'' + ''host:'' + host + ''\\n'' + ''x-amz-date:'' + amzdate + ''\\n'',
			signed_headers = ''content-encoding;host;x-amz-date'',
			canonical_request = method + ''\\n'' + canonical_uri + ''\\n'' + params + ''\\n'' + canonical_headers + ''\\n'' + signed_headers + ''\\n'' + sha256(data),
			credential_scope = date + ''/'' + region + ''/'' + service + ''/'' + ''aws4_request'',
			request_string = ''AWS4-HMAC-SHA256'' + ''\\n'' + amzdate + ''\\n'' + credential_scope + ''\\n'' + sha256(canonical_request),
			key = AWS.sign(''AWS4'' + AWS.params.SecretAccessKey, date),
			key = AWS.sign(key, region),
			key = AWS.sign(key, service),
			key = AWS.sign(key, ''aws4_request''),
			request = new HttpRequest(),
			url = ''https://'' + host + canonical_uri + ''?'' + params;

		if (typeof AWS.params.proxy !== ''undefined'' && AWS.params.proxy !== '''') {
			request.setProxy(AWS.params.proxy);
		}
		request.addHeader(''x-amz-date: '' + amzdate);
		request.addHeader(''x-amz-content-sha256:'' + sha256(data));
		request.addHeader(''X-Amz-Target: GraniteServiceVersion20100801.GetMetricData'')
		request.addHeader(''Accept: application/json'');
		request.addHeader(''Content-Type: application/json'');
		request.addHeader(''Content-Encoding: amz-1.0'');
		request.addHeader(''Authorization: '' + ''AWS4-HMAC-SHA256 Credential='' + AWS.params.AccessKeyId + ''/'' + credential_scope + '', '' + ''SignedHeaders='' + signed_headers + '', '' + ''Signature='' + hmac(''sha256'', key, request_string));
		if (AWS.params.auth_type === ''role_base'' || (AWS.params.auth_type === ''assume_role'' & !params.includes(''AssumeRole''))) {
			request.addHeader(''X-Amz-Security-Token: '' + (AWS.params.auth_type === ''role_base'' ? AWS.params.Token : AWS.params.SessionToken));
		}

		Zabbix.log(4, ''[ AWS ELB ] Sending request: '' + url);
		response = request.post(url, data);
		Zabbix.log(4, ''[ AWS ELB ] Received response with status code '' + request.getStatus() + '': '' + response);
		if (request.getStatus() !== 200) {
			throw ''Request failed with status code '' + request.getStatus() + '': '' + response;
		}

		return JSON.parse(response);
	},

	getMetricsData: function () {
		var end_time = Math.floor((new Date().getTime()) / 1000),
			start_time = end_time - AWS.request_period * 60;
		payload = {
			''StartTime'': start_time,
			''EndTime'': end_time,
			''ScanBy'': ''TimestampDescending'',
			''MetricDataQueries'': AWS.renderMetricQuery(AWS.request_period, AWS.params.arn)
		};

		return AWS.getField(AWS.request(''POST'', AWS.params.region, ''monitoring'', '''', payload), ''MetricDataResults'');
	}
};

try {
	AWS.setParams(JSON.parse(value));
	return JSON.stringify(AWS.getMetricsData());
}
catch (error) {
	error += (String(error).endsWith(''.'')) ? '''' : ''.'';
	Zabbix.log(3, ''[ AWS ELB Get metrics] ERROR: '' + error);

	return JSON.stringify({ ''error'': error });
}','','0','','','','','0',NULL,'Get ELB Application Load Balancer metrics.
Full 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,E'var AWS = {
	params: {},
	metadata: ''http://169.254.169.254/latest/'',

	getField: function (data, path) {
		var steps = path.split(''.'');
		for (var i = 0; i < steps.length; i++) {
			var step = steps[i];
			if (typeof data !== ''object'' || typeof data[step] === ''undefined'') {
				throw ''Required field was not found: '' + path;
			}

			data = data[step];
		}

		return data;
	},

	setParams: function (params) {
		AWS.params[''proxy''] = params.proxy;
		switch (AWS.getField(params, ''auth_type'')) {
			case ''role_base'':
				AWS.params[''auth_type''] = ''role_base'';
				var request = new HttpRequest();
				if (typeof AWS.params.proxy !== ''undefined'' && AWS.params.proxy !== '''') {
					request.setProxy(AWS.params.proxy);
				}
				request.addHeader(''X-aws-ec2-metadata-token-ttl-seconds: 21600'');
				var token = request.put(AWS.metadata + ''api/token'');

				if (request.getStatus() !== 200 || token === null || token === '''') {
					throw ''Error getting IMDSv2 session token.'';
				}
				request.addHeader(''X-aws-ec2-metadata-token: '' + token);
				var IamRoleName = request.get(AWS.metadata + ''meta-data/iam/security-credentials'');

				if (request.getStatus() !== 200 || IamRoleName === null || IamRoleName === '''') {
					throw ''Error getting security credentials from instance metadata. Role not found.'';
				}

				credentials = request.get(AWS.metadata + ''meta-data/iam/security-credentials/'' + encodeURI(IamRoleName));

				if (request.getStatus() !== 200 || credentials === null || credentials === '''') {
					throw ''Error getting security credentials from instance metadata.'';
				}

				try {
					credentials = JSON.parse(credentials);
				}
				catch (error) {
					throw ''Failed to parse response received from instance metadata. Check debug log for more information.'';
				}

				[''AccessKeyId'', ''SecretAccessKey'', ''Token''].forEach(function (field) {
					if (typeof credentials !== ''object'' || typeof credentials[field] === ''undefined'' || credentials[field] === '''') {
						throw ''Required credentials are not set: "'' + field + ''".'';
					};
					AWS.params[field] = credentials[field];
				});
				break;
			case ''assume_role'':
				AWS.params[''auth_type''] = ''assume_role'';

				[''AccessKeyId'', ''SecretAccessKey'', ''sts_region'', ''role_arn''].forEach(function (field) {
					if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
						throw ''Required param is not set: "'' + field + ''".'';
					}
					AWS.params[field] = params[field];
				});

				role_arn_regex = /role\\/(.+)$/;

				var payload = {
					''Action'': ''AssumeRole'',
					''Version'': ''2011-06-15'',
					''RoleArn'': AWS.params.role_arn,
					''RoleSessionName'': AWS.params.role_arn.match(role_arn_regex)[1] + ''Session'',
				};

				credentials = AWS.getField(AWS.request(''GET'', AWS.params.sts_region, ''sts'', AWS.prepareParams(payload), ''''), ''AssumeRoleResponse.AssumeRoleResult.Credentials'');

				[''AccessKeyId'', ''SecretAccessKey'', ''SessionToken''].forEach(function (field) {
					if (typeof credentials !== ''object'' || typeof credentials[field] === ''undefined'' || credentials[field] === '''') {
						throw ''Required credentials are not set: "'' + field + ''".'';
					};
					AWS.params[field] = credentials[field];
				});
				break;
			default:
				AWS.params[''auth_type''] = ''access_key'';
				[''AccessKeyId'', ''SecretAccessKey''].forEach(function (field) {
					if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
						throw ''Required param is not set: "'' + field + ''".'';
					}
					AWS.params[field] = params[field];
				});
		}
		[''region'', ''arn''].forEach(function (field) {
			if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
				throw ''Required param is not set: "'' + field + ''".'';
			}
			AWS.params[field] = params[field];
		});
	},

	sign: function (key, message) {
		var hex = hmac(''sha256'', key, message);

		if ((hex.length % 2) === 1) {
			throw ''Invalid length of a hex string!'';
		}

		var result = new Int8Array(hex.length / 2);
		for (var i = 0, b = 0; i < hex.length; i += 2, b++) {
			result[b] = parseInt(hex.substring(i, i + 2), 16);
		}

		return result;
	},

	prepareParams: function (params) {
		var result = [];

		Object.keys(params).sort().forEach(function (key) {
			if (typeof params[key] !== ''object'') {
				result.push(key + ''='' + encodeURIComponent(params[key]));
			}
			else {
				result.push(prepareObject(key, params[key]));
			}
		});

		return result.join(''&'');
	},

	request: function (method, region, service, params, data) {
		if (typeof data === ''undefined'' || data === null) {
			data = JSON.stringify([]);
		}
		var amzdate = (new Date()).toISOString().replace(/\\.\\d+Z/, ''Z'').replace(/[-:]/g, ''''),
			date = amzdate.replace(/T\\d+Z/, ''''),
			canonical_uri = ''/'',
			host = service + ''.'' + region + ''.amazonaws.com'',
			canonical_headers = ''content-encoding:amz-1.0\\n'' + ''host:'' + host + ''\\n'' + ''x-amz-date:'' + amzdate + ''\\n'',
			signed_headers = ''content-encoding;host;x-amz-date'',
			canonical_request = method + ''\\n'' + canonical_uri + ''\\n'' + params + ''\\n'' + canonical_headers + ''\\n'' + signed_headers + ''\\n'' + sha256(data),
			credential_scope = date + ''/'' + region + ''/'' + service + ''/'' + ''aws4_request'',
			request_string = ''AWS4-HMAC-SHA256'' + ''\\n'' + amzdate + ''\\n'' + credential_scope + ''\\n'' + sha256(canonical_request),
			key = AWS.sign(''AWS4'' + AWS.params.SecretAccessKey, date),
			key = AWS.sign(key, region),
			key = AWS.sign(key, service),
			key = AWS.sign(key, ''aws4_request''),
			request = new HttpRequest(),
			url = ''https://'' + host + canonical_uri + ''?'' + params;

		if (typeof AWS.params.proxy !== ''undefined'' && AWS.params.proxy !== '''') {
			request.setProxy(AWS.params.proxy);
		}
		request.addHeader(''x-amz-date: '' + amzdate);
		request.addHeader(''x-amz-content-sha256:'' + sha256(data));
		request.addHeader(''Accept: application/json'');
		request.addHeader(''Content-Type: application/json'');
		request.addHeader(''Content-Encoding: amz-1.0'');
		request.addHeader(''Authorization: '' + ''AWS4-HMAC-SHA256 Credential='' + AWS.params.AccessKeyId + ''/'' + credential_scope + '', '' + ''SignedHeaders='' + signed_headers + '', '' + ''Signature='' + hmac(''sha256'', key, request_string));
		if (AWS.params.auth_type === ''role_base'' || (AWS.params.auth_type === ''assume_role'' & !params.includes(''AssumeRole''))) {
			request.addHeader(''X-Amz-Security-Token: '' + (AWS.params.auth_type === ''role_base'' ? AWS.params.Token : AWS.params.SessionToken));
		}

		Zabbix.log(4, ''[ AWS ELB ] Sending request: '' + url);
		response = request.get(url);
		Zabbix.log(4, ''[ AWS ELB ] Received response with status code '' + request.getStatus() + '': '' + response);
		if (request.getStatus() !== 200) {
			throw ''Request failed with status code '' + request.getStatus() + '': '' + response;
		}

		return JSON.parse(response);
	},

	listTargetGroups: function () {
		var lld_array = [],
			regex = /targetgroup\\/(.+)$/,
			payload = {
				''Action'': ''DescribeTargetGroups'',
				''LoadBalancerArn'': AWS.params.arn,
				''Version'': ''2015-12-01''
			};
		targets = AWS.getField(AWS.request(''GET'', AWS.params.region, ''elasticloadbalancing'', AWS.prepareParams(payload), ''''), ''DescribeTargetGroupsResponse.DescribeTargetGroupsResult.TargetGroups'');

		if (!Array.isArray(targets))
			targets = [targets]

		targets.forEach(function (targets) {
			lld_array.push(
				{
					target_name: AWS.getField(targets, ''TargetGroupName''),
					target_arn: AWS.getField(targets, ''TargetGroupArn'').match(regex)[0],
					type: AWS.getField(targets, ''TargetType''),
					protocol: AWS.getField(targets, ''Protocol'')
				}
			)
		});

		return lld_array;
	}
};

try {
	AWS.setParams(JSON.parse(value));
	return JSON.stringify(AWS.listTargetGroups());
}
catch (error) {
	error += (String(error).endsWith(''.'')) ? '''' : ''.'';
	Zabbix.log(3, ''[ AWS ELB Target groups ] ERROR: '' + error);

	return JSON.stringify({ ''error'': error });
}','','0','','','','','0',NULL,'Get ELB target group.
`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,E'var AWS = {
	params: {},
	metadata: ''http://169.254.169.254/latest/'',
	request_period: 60,

	getField: function (data, path) {
		var steps = path.split(''.'');
		for (var i = 0; i < steps.length; i++) {
			var step = steps[i];
			if (typeof data !== ''object'' || typeof data[step] === ''undefined'') {
				throw ''Required field was not found: '' + path;
			}

			data = data[step];
		}

		return data;
	},

	setParams: function (params) {
		AWS.params[''proxy''] = params.proxy;
		switch (AWS.getField(params, ''auth_type'')) {
			case ''role_base'':
				AWS.params[''auth_type''] = ''role_base'';
				var request = new HttpRequest();
				if (typeof AWS.params.proxy !== ''undefined'' && AWS.params.proxy !== '''') {
					request.setProxy(AWS.params.proxy);
				}
				request.addHeader(''X-aws-ec2-metadata-token-ttl-seconds: 21600'');
				var token = request.put(AWS.metadata + ''api/token'');

				if (request.getStatus() !== 200 || token === null || token === '''') {
					throw ''Error getting IMDSv2 session token.'';
				}
				request.addHeader(''X-aws-ec2-metadata-token: '' + token);
				var IamRoleName = request.get(AWS.metadata + ''meta-data/iam/security-credentials'');

				if (request.getStatus() !== 200 || IamRoleName === null || IamRoleName === '''') {
					throw ''Error getting security credentials from instance metadata. Role not found.'';
				}

				credentials = request.get(AWS.metadata + ''meta-data/iam/security-credentials/'' + encodeURI(IamRoleName));

				if (request.getStatus() !== 200 || credentials === null || credentials === '''') {
					throw ''Error getting security credentials from instance metadata.'';
				}

				try {
					credentials = JSON.parse(credentials);
				}
				catch (error) {
					throw ''Failed to parse response received from instance metadata. Check debug log for more information.'';
				}

				[''AccessKeyId'', ''SecretAccessKey'', ''Token''].forEach(function (field) {
					if (typeof credentials !== ''object'' || typeof credentials[field] === ''undefined'' || credentials[field] === '''') {
						throw ''Required credentials are not set: "'' + field + ''".'';
					};
					AWS.params[field] = credentials[field];
				});
				break;
			case ''assume_role'':
				AWS.params[''auth_type''] = ''assume_role'';

				[''AccessKeyId'', ''SecretAccessKey'', ''sts_region'', ''role_arn''].forEach(function (field) {
					if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
						throw ''Required param is not set: "'' + field + ''".'';
					}
					AWS.params[field] = params[field];
				});

				role_arn_regex = /role\\/(.+)$/;

				var payload = {
					''Action'': ''AssumeRole'',
					''Version'': ''2011-06-15'',
					''RoleArn'': AWS.params.role_arn,
					''RoleSessionName'': AWS.params.role_arn.match(role_arn_regex)[1] + ''Session'',
				};

				credentials = AWS.getField(AWS.request(''POST'', AWS.params.sts_region, ''sts'', AWS.prepareParams(payload), ''''), ''AssumeRoleResponse.AssumeRoleResult.Credentials'');

				[''AccessKeyId'', ''SecretAccessKey'', ''SessionToken''].forEach(function (field) {
					if (typeof credentials !== ''object'' || typeof credentials[field] === ''undefined'' || credentials[field] === '''') {
						throw ''Required credentials are not set: "'' + field + ''".'';
					};
					AWS.params[field] = credentials[field];
				});
				break;
			default:
				AWS.params[''auth_type''] = ''access_key'';
				[''AccessKeyId'', ''SecretAccessKey''].forEach(function (field) {
					if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
						throw ''Required param is not set: "'' + field + ''".'';
					}
					AWS.params[field] = params[field];
				});
		}
		[''region'', ''arn'', ''target_arn''].forEach(function (field) {
			if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
				throw ''Required param is not set: "'' + field + ''".'';
			}
			AWS.params[field] = params[field];
		});
	},

	sign: function (key, message) {
		var hex = hmac(''sha256'', key, message);

		if ((hex.length % 2) === 1) {
			throw ''Invalid length of a hex string!'';
		}

		var result = new Int8Array(hex.length / 2);
		for (var i = 0, b = 0; i < hex.length; i += 2, b++) {
			result[b] = parseInt(hex.substring(i, i + 2), 16);
		}

		return result;
	},

	prepareParams: function (params) {
		var result = [];

		Object.keys(params).sort().forEach(function (key) {
			if (typeof params[key] !== ''object'') {
				result.push(key + ''='' + encodeURIComponent(params[key]));
			}
			else {
				result.push(prepareObject(key, params[key]));
			}
		});

		return result.join(''&'');
	},

	renderMetricQuery: function (period, arn, target_arn) {
		var metrics_list = [
			''HTTPCode_Target_2XX_Count:Sum'',
			''HTTPCode_Target_3XX_Count:Sum'',
			''HTTPCode_Target_4XX_Count:Sum'',
			''HTTPCode_Target_5XX_Count:Sum'',
			''HealthyHostCount:Average'',
			''UnHealthyHostCount:Average'',
			''HealthyStateRouting:Sum'',
			''UnhealthyStateRouting:Sum'',
			''UnhealthyRoutingRequestCount:Sum'',
			''HealthyStateDNS:Sum'',
			''UnhealthyStateDNS:Sum'',
			''RequestCountPerTarget:Sum'',
			''MitigatedHostCount:Average'',
			''AnomalousHostCount:Average'',
		],
			regex = /loadbalancer\\/(.+)$/;

		var metric_payload = [];
		metrics_list.forEach(function (metric, index) {
			var parts = metric.split('':'', 2);
			metric_payload.push({
				''Id'': ''m'' + index,
				''MetricStat'': {
					''Metric'': {
						''MetricName'': parts[0],
						''Namespace'': ''AWS/ApplicationELB'',
						''Dimensions'': [
							{
								''Name'': ''LoadBalancer'',
								''Value'': arn.match(regex)[1],
							},
							{
								''Name'': ''TargetGroup'',
								''Value'': target_arn
							}
						]
					},
					''Period'': period,
					''Stat'': parts[1],
				}
			});
		});

		return metric_payload;
	},

	request: function (method, region, service, params, data) {
		if (typeof data === ''undefined'' || data === null) {
			data = JSON.stringify([]);
		}
		else {
			data = JSON.stringify(data)
		}
		var amzdate = (new Date()).toISOString().replace(/\\.\\d+Z/, ''Z'').replace(/[-:]/g, ''''),
			date = amzdate.replace(/T\\d+Z/, ''''),
			canonical_uri = ''/'',
			host = service + ''.'' + region + ''.amazonaws.com'',
			canonical_headers = ''content-encoding:amz-1.0\\n'' + ''host:'' + host + ''\\n'' + ''x-amz-date:'' + amzdate + ''\\n'',
			signed_headers = ''content-encoding;host;x-amz-date'',
			canonical_request = method + ''\\n'' + canonical_uri + ''\\n'' + params + ''\\n'' + canonical_headers + ''\\n'' + signed_headers + ''\\n'' + sha256(data),
			credential_scope = date + ''/'' + region + ''/'' + service + ''/'' + ''aws4_request'',
			request_string = ''AWS4-HMAC-SHA256'' + ''\\n'' + amzdate + ''\\n'' + credential_scope + ''\\n'' + sha256(canonical_request),
			key = AWS.sign(''AWS4'' + AWS.params.SecretAccessKey, date),
			key = AWS.sign(key, region),
			key = AWS.sign(key, service),
			key = AWS.sign(key, ''aws4_request''),
			request = new HttpRequest(),
			url = ''https://'' + host + canonical_uri + ''?'' + params;

		if (typeof AWS.params.proxy !== ''undefined'' && AWS.params.proxy !== '''') {
			request.setProxy(AWS.params.proxy);
		}
		request.addHeader(''x-amz-date: '' + amzdate);
		request.addHeader(''x-amz-content-sha256:'' + sha256(data));
		request.addHeader(''X-Amz-Target: GraniteServiceVersion20100801.GetMetricData'')
		request.addHeader(''Accept: application/json'');
		request.addHeader(''Content-Type: application/json'');
		request.addHeader(''Content-Encoding: amz-1.0'');
		request.addHeader(''Authorization: '' + ''AWS4-HMAC-SHA256 Credential='' + AWS.params.AccessKeyId + ''/'' + credential_scope + '', '' + ''SignedHeaders='' + signed_headers + '', '' + ''Signature='' + hmac(''sha256'', key, request_string));
		if (AWS.params.auth_type === ''role_base'' || (AWS.params.auth_type === ''assume_role'' & !params.includes(''AssumeRole''))) {
			request.addHeader(''X-Amz-Security-Token: '' + (AWS.params.auth_type === ''role_base'' ? AWS.params.Token : AWS.params.SessionToken));
		}

		Zabbix.log(4, ''[ AWS ELB ] Sending request: '' + url);
		response = request.post(url, data);
		Zabbix.log(4, ''[ AWS ELB ] Received response with status code '' + request.getStatus() + '': '' + response);
		if (request.getStatus() !== 200) {
			throw ''Request failed with status code '' + request.getStatus() + '': '' + response;
		}

		return JSON.parse(response);
	},

	getMetricsData: function () {
		var end_time = Math.floor((new Date().getTime()) / 1000),
			start_time = end_time - AWS.request_period * 60;
		payload = {
			''StartTime'': start_time,
			''EndTime'': end_time,
			''ScanBy'': ''TimestampDescending'',
			''MetricDataQueries'': AWS.renderMetricQuery(AWS.request_period, AWS.params.arn, AWS.params.target_arn)
		};

		return AWS.getField(AWS.request(''POST'', AWS.params.region, ''monitoring'', '''', payload), ''MetricDataResults'');
	}
};

try {
	AWS.setParams(JSON.parse(value));
	return JSON.stringify(AWS.getMetricsData());
}
catch (error) {
	error += (String(error).endsWith(''.'')) ? '''' : ''.'';
	Zabbix.log(3, ''[ AWS ELB Get targets group metrics] ERROR: '' + error);

	return JSON.stringify({ ''error'': error });
}','','0','','','','','2',NULL,'Get the metrics of the ELB target group `{#AWS.ELB.TARGET.GROUP.NAME}`.
Full 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,E'var AWS = {
	params: {},
	metadata: ''http://169.254.169.254/latest/'',

	getField: function (data, path) {
		var steps = path.split(''.'');
		for (var i = 0; i < steps.length; i++) {
			var step = steps[i];
			if (typeof data !== ''object'' || typeof data[step] === ''undefined'') {
				throw ''Required field was not found: '' + path;
			}

			data = data[step];
		}

		return data;
	},

	setParams: function (params) {
		AWS.params[''proxy''] = params.proxy;
		switch (AWS.getField(params, ''auth_type'')) {
			case ''role_base'':
				AWS.params[''auth_type''] = ''role_base'';
				var request = new HttpRequest();
				if (typeof AWS.params.proxy !== ''undefined'' && AWS.params.proxy !== '''') {
					request.setProxy(AWS.params.proxy);
				}
				request.addHeader(''X-aws-ec2-metadata-token-ttl-seconds: 21600'');
				var token = request.put(AWS.metadata + ''api/token'');

				if (request.getStatus() !== 200 || token === null || token === '''') {
					throw ''Error getting IMDSv2 session token.'';
				}
				request.addHeader(''X-aws-ec2-metadata-token: '' + token);
				var IamRoleName = request.get(AWS.metadata + ''meta-data/iam/security-credentials'');

				if (request.getStatus() !== 200 || IamRoleName === null || IamRoleName === '''') {
					throw ''Error getting security credentials from instance metadata. Role not found.'';
				}

				credentials = request.get(AWS.metadata + ''meta-data/iam/security-credentials/'' + encodeURI(IamRoleName));

				if (request.getStatus() !== 200 || credentials === null || credentials === '''') {
					throw ''Error getting security credentials from instance metadata.'';
				}

				try {
					credentials = JSON.parse(credentials);
				}
				catch (error) {
					throw ''Failed to parse response received from instance metadata. Check debug log for more information.'';
				}

				[''AccessKeyId'', ''SecretAccessKey'', ''Token''].forEach(function (field) {
					if (typeof credentials !== ''object'' || typeof credentials[field] === ''undefined'' || credentials[field] === '''') {
						throw ''Required credentials are not set: "'' + field + ''".'';
					};
					AWS.params[field] = credentials[field];
				});
				break;
			case ''assume_role'':
				AWS.params[''auth_type''] = ''assume_role'';

				[''AccessKeyId'', ''SecretAccessKey'', ''sts_region'', ''role_arn''].forEach(function (field) {
					if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
						throw ''Required param is not set: "'' + field + ''".'';
					}
					AWS.params[field] = params[field];
				});

				role_arn_regex = /role\\/(.+)$/;

				var payload = {
					''Action'': ''AssumeRole'',
					''Version'': ''2011-06-15'',
					''RoleArn'': AWS.params.role_arn,
					''RoleSessionName'': AWS.params.role_arn.match(role_arn_regex)[1] + ''Session'',
				};

				credentials = AWS.getField(AWS.request(''GET'', AWS.params.sts_region, ''sts'', AWS.prepareParams(payload)), ''AssumeRoleResponse.AssumeRoleResult.Credentials'');

				[''AccessKeyId'', ''SecretAccessKey'', ''SessionToken''].forEach(function (field) {
					if (typeof credentials !== ''object'' || typeof credentials[field] === ''undefined'' || credentials[field] === '''') {
						throw ''Required credentials are not set: "'' + field + ''".'';
					};
					AWS.params[field] = credentials[field];
				});
				break;
			default:
				AWS.params[''auth_type''] = ''access_key'';
				[''AccessKeyId'', ''SecretAccessKey''].forEach(function (field) {
					if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
						throw ''Required param is not set: "'' + field + ''".'';
					}
					AWS.params[field] = params[field];
				});
		}
		[''describe_region'', ''region_match'', ''region_not_match''].forEach(function (field) {
			if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
				throw ''Required param is not set: "'' + field + ''".'';
			}
			AWS.params[field] = params[field];
		});
	},

	sign: function (key, message) {
		var hex = hmac(''sha256'', key, message);

		if ((hex.length % 2) === 1) {
			throw ''Invalid length of a hex string!'';
		}

		var result = new Int8Array(hex.length / 2);
		for (var i = 0, b = 0; i < hex.length; i += 2, b++) {
			result[b] = parseInt(hex.substring(i, i + 2), 16);
		}

		return result;
	},

	prepareParams: function (params) {
		var result = [];

		Object.keys(params).sort().forEach(function (key) {
			if (typeof params[key] !== ''object'') {
				result.push(key + ''='' + encodeURIComponent(params[key]));
			}
			else {
				result.push(prepareObject(key, params[key]));
			}
		});

		return result.join(''&'');
	},

	request: function (method, region, service, params, data) {
		if (typeof data === ''undefined'' || data === null) {
			data = '''';
		}

		var amzdate = (new Date()).toISOString().replace(/\\.\\d+Z/, ''Z'').replace(/[-:]/g, ''''),
			date = amzdate.replace(/T\\d+Z/, ''''),
			canonical_uri = ''/'',
			host = service + ''.'' + region + ''.amazonaws.com'',
			canonical_headers = ''content-encoding:amz-1.0\\n'' + ''host:'' + host + ''\\n'' + ''x-amz-date:'' + amzdate + ''\\n'',
			signed_headers = ''content-encoding;host;x-amz-date'',
			canonical_request = method + ''\\n'' + canonical_uri + ''\\n'' + params + ''\\n'' + canonical_headers + ''\\n'' + signed_headers + ''\\n'' + sha256(data),
			credential_scope = date + ''/'' + region + ''/'' + service + ''/'' + ''aws4_request'',
			request_string = ''AWS4-HMAC-SHA256'' + ''\\n'' + amzdate + ''\\n'' + credential_scope + ''\\n'' + sha256(canonical_request),
			key = AWS.sign(''AWS4'' + AWS.params.SecretAccessKey, date),
			key = AWS.sign(key, region),
			key = AWS.sign(key, service),
			key = AWS.sign(key, ''aws4_request''),
			request = new HttpRequest(),
			url = ''https://'' + host + canonical_uri + ''?'' + params;

		if (typeof AWS.params.proxy !== ''undefined'' && AWS.params.proxy !== '''') {
			request.setProxy(AWS.params.proxy);
		}
		request.addHeader(''x-amz-date: '' + amzdate);
		request.addHeader(''x-amz-content-sha256:'' + sha256(data));
		request.addHeader(''Accept: application/json'');
		request.addHeader(''Content-Type: application/json'');
		request.addHeader(''Content-Encoding: amz-1.0'');
		request.addHeader(''Authorization: '' + ''AWS4-HMAC-SHA256 Credential='' + AWS.params.AccessKeyId + ''/'' + credential_scope + '', '' + ''SignedHeaders='' + signed_headers + '', '' + ''Signature='' + hmac(''sha256'', key, request_string));
		if (AWS.params.auth_type === ''role_base'' || (AWS.params.auth_type === ''assume_role'' & !params.includes(''AssumeRole''))) {
			request.addHeader(''X-Amz-Security-Token: '' + (AWS.params.auth_type === ''role_base'' ? AWS.params.Token : AWS.params.SessionToken));
		}

		Zabbix.log(4, ''[ AWS ELB ] Sending request: '' + url);
		response = request.get(url);
		Zabbix.log(4, ''[ AWS ELB ] Received response with status code '' + request.getStatus() + '': '' + response);

		if (request.getStatus() !== 200) {
			throw ''Request failed with status code '' + request.getStatus() + '': '' + response;
		}

		try {
			response = JSON.parse(response);
		}
		catch (error) {
			try {
				response = JSON.parse(XML.toJson(response));
			}
			catch (error) {
				throw ''Failed to parse response received from AWS API. Check debug log for more information.'';
			}
		}

		return response;
	},

	listRegions: function () {
		var payload = {
			''Action'': ''DescribeRegions'',
			''Version'': ''2016-11-15''
		};

		regions = AWS.getField(AWS.request(''GET'', AWS.params.describe_region, ''ec2'', AWS.prepareParams(payload)), ''DescribeRegionsResponse.regionInfo.item'');

		if (!Array.isArray(regions))
			regions = [regions]
		return regions
	},

	listLoadBalancers: function () {
		var lld_array = [],
			regions = AWS.listRegions(),
			payload = {
				''Action'': ''DescribeLoadBalancers'',
				''Version'': ''2015-12-01''
			};

		regions.forEach(function (region) {
			var region_name = AWS.getField(region, ''regionName'');
			if (region_name.match(AWS.params.region_match) === null ||
				region_name.match(AWS.params.region_not_match) !== null)
				return;
			elb = AWS.getField(AWS.request(''GET'', region_name, ''elasticloadbalancing'', AWS.prepareParams(payload)), ''DescribeLoadBalancersResponse.DescribeLoadBalancersResult.LoadBalancers'');
			if (!Array.isArray(elb))
				elb = [elb]

			elb.forEach(function (elb) {
				lld_array.push(
					{
						name: AWS.getField(elb, ''LoadBalancerName''),
						arn: AWS.getField(elb, ''LoadBalancerArn''),
						type: AWS.getField(elb, ''Type''),
						state: AWS.getField(elb, ''State.Code''),
						dns_name: AWS.getField(elb, ''DNSName''),
						region: region_name
					}
				)
			});
		});

		return lld_array;
	}
};

try {
	AWS.setParams(JSON.parse(value));

	return JSON.stringify(AWS.listLoadBalancers());
}
catch (error) {
	error += (String(error).endsWith(''.'')) ? '''' : ''.'';
	Zabbix.log(3, ''[ AWS ELB ] ERROR: '' + error);
	return JSON.stringify({ ''error'': error });
}','','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)) /
(last(//mssql.average_latch_wait_time_base) - last(//mssql.average_latch_wait_time_base,#2) +
(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)) /
(last(//mssql.average_wait_time_base) - last(//mssql.average_wait_time_base,#2) +
(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 /
(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 /
(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 = {
	params: {},
	clusters: [],
	error_msg: '''',

	setParams: function (params) {
		[''account_id'', ''project_id'', ''token''].forEach(function (field) {
			if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
				throw ''Required param is not set: '' + field + ''.'';
			}
		});

		YugabyteDB.params = params;
	},


	request: function (url, data) {
		if (typeof data === ''undefined'' || data === null) {
			data = '''';
		}

		var response, request = new HttpRequest();
		if (typeof YugabyteDB.params.proxy !== ''undefined'' && YugabyteDB.params.proxy !== '''') {
			request.setProxy(YugabyteDB.params.proxy);
		}
		if (YugabyteDB.params.token) {
			request.addHeader(''Accept: application/json'');
			request.addHeader(''Authorization: Bearer '' + YugabyteDB.params.token);
		}

		Zabbix.log(4, ''[ YugabyteDB ] Sending request: '' + url);

		response = request.get(url);

		Zabbix.log(4, ''[ YugabyteDB ] Received response with status code '' + request.getStatus() + '': '' + response);

		if (request.getStatus() !== 200 || response === null) {
			throw ''Request failed with status code '' + request.getStatus() + '': '' + response;
		}

		try {
			return JSON.parse(response);
		}
		catch (error) {
			throw ''Failed to parse response received from API:'' + error;
		}
	}

};

try {
	YugabyteDB.setParams(JSON.parse(value));

	clusters = YugabyteDB.request(
		''https://cloud.yugabyte.com/api/public/v1/accounts/'' + YugabyteDB.params.account_id + ''/projects/'' + YugabyteDB.params.project_id + ''/clusters''
	)

	YugabyteDB.clusters = clusters.data;
}
catch (error) {
	Zabbix.log(3, ''[ YugabyteDB ] ERROR: '' + error);
	YugabyteDB.error_msg = ''Failed to get data from API:'' + error;
}

return 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 = {
	params: {},
	clusters: [],
	error_msg: '''',

	setParams: function (params) {
		[''account_id'', ''project_id'', ''token'', ''cluster_id''].forEach(function (field) {
			if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
				throw ''Required param is not set: '' + field + ''.'';
			}
		});

		YugabyteDB.params = params;
	},


	request: function (url, data) {
		if (typeof data === ''undefined'' || data === null) {
			data = '''';
		}

		var response, request = new HttpRequest();
		if (typeof YugabyteDB.params.proxy !== ''undefined'' && YugabyteDB.params.proxy !== '''') {
			request.setProxy(YugabyteDB.params.proxy);
		}
		if (YugabyteDB.params.token) {
			request.addHeader(''Accept: application/json'');
			request.addHeader(''Authorization: Bearer '' + YugabyteDB.params.token);
		}

		Zabbix.log(4, ''[ YugabyteDB ] Sending request: '' + url);

		response = request.get(url);

		Zabbix.log(4, ''[ YugabyteDB ] Received response with status code '' + request.getStatus() + '': '' + response);

		if (request.getStatus() !== 200 || response === null) {
			throw ''Request failed with status code '' + request.getStatus() + '': '' + response;
		}

		try {
			return JSON.parse(response);
		}
		catch (error) {
			throw ''Failed to parse response received from API:'' + error;
		}
	}

};

try {
	YugabyteDB.setParams(JSON.parse(value));

	cluster = YugabyteDB.request(
		''https://cloud.yugabyte.com/api/public/v1/accounts/'' + YugabyteDB.params.account_id + ''/projects/'' + YugabyteDB.params.project_id + ''/clusters/'' + YugabyteDB.params.cluster_id
	)

	YugabyteDB.clusters = cluster.data;
}
catch (error) {
	Zabbix.log(3, ''[ YugabyteDB ] ERROR: '' + error);
	YugabyteDB.error_msg = ''Failed to get data from API:'' + error;
}

return 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 = {
	params: {},
	metrics: {},
	error_msg: '''',

	setParams: function (params) {
		[''account_id'', ''project_id'', ''token'', ''cluster_id''].forEach(function (field) {
			if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
				throw ''Required param is not set: '' + field + ''.'';
			}
		});

		YugabyteDB.params = params;
	},


	request: function (url, data) {
		if (typeof data === ''undefined'' || data === null) {
			data = '''';
		}

		var response, request = new HttpRequest();
		if (typeof YugabyteDB.params.proxy !== ''undefined'' && YugabyteDB.params.proxy !== '''') {
			request.setProxy(YugabyteDB.params.proxy);
		}
		if (YugabyteDB.params.token) {
			request.addHeader(''Accept: application/json'');
			request.addHeader(''Authorization: Bearer '' + YugabyteDB.params.token);
		}

		Zabbix.log(4, ''[ YugabyteDB ] Sending request: '' + url);

		response = request.get(url);

		Zabbix.log(4, ''[ YugabyteDB ] Received response with status code '' + request.getStatus() + '': '' + response);

		if (request.getStatus() !== 200 || response === null) {
			throw ''Request failed with status code '' + request.getStatus() + '': '' + response;
		}

		try {
			return JSON.parse(response);
		}
		catch (error) {
			throw ''Failed to parse response received from API:'' + error;
		}
	},


	get_last_values: function (values) {
		var max_timestamp = 0;
		var last_value = 0;
		for (e in values) {
			if (values[e][0] > max_timestamp) {
				max_timestamp = values[e][0];
				last_value = values[e][1];
			};
		};
		return last_value;
	},


	get_start_time: function() {
		return Math.floor(Date.now() / 1000 - 300);
	}

};

metrics = [
	"CPU_USAGE",
	"DISK_USAGE_GB",
	"PROVISIONED_DISK_SPACE_GB",
	"READ_OPS_PER_SEC",
	"WRITE_OPS_PER_SEC",
	"AVERAGE_READ_LATENCY_MS",
	"AVERAGE_WRITE_LATENCY_MS",
	"YSQL_CONNECTION_LIMIT",
	"AVERAGE_YSQL_CONNECTION_COUNT",
	"NODE_CLOCK_SKEW",
	"DISK_BYTES_READ_MB_PER_SEC",
	"DISK_BYTES_WRITTEN_MB_PER_SEC",
	"FOLLOWER_LAG_MS",
	"MEMORY_TOTAL_GB",
	"MEMORY_USAGE_GB",
	"NETWORK_RECEIVE_BYTES_MB_PER_SEC",
	"NETWORK_TRANSMIT_BYTES_MB_PER_SEC",
	"NETWORK_RECEIVE_ERRORS_PER_SEC",
	"NETWORK_TRANSMIT_ERRORS_PER_SEC",
	"MASTER_UP_STATUS",
	"TSERVER_UP_STATUS",
	"YSQL_MAX_CONNECTION_COUNT"
]

try {
	YugabyteDB.setParams(JSON.parse(value));

	var size = 6

	for (var i = 0; i < Math.ceil(metrics.length/size); i++)  {
		var values = YugabyteDB.request(
			''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()
		);

		values.data.forEach(function (e) {
			YugabyteDB.metrics[e.name] = YugabyteDB.get_last_values(e.values)
		});
	};
}
catch (error) {
	Zabbix.log(3, ''[ YugabyteDB ] ERROR: '' + error);
	error_msg = ''Failed to get data from API:'' + error;
}

return 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 = {
	params: {},
	metrics: {},
	error_msg: '''',

	setParams: function (params) {
		[''account_id'', ''project_id'', ''token'', ''cluster_id''].forEach(function (field) {
			if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
				throw ''Required param is not set: '' + field + ''.'';
			}
		});

		YugabyteDB.params = params;
	},


	request: function (url, data) {
		if (typeof data === ''undefined'' || data === null) {
			data = '''';
		}

		var response, request = new HttpRequest();
		if (typeof YugabyteDB.params.proxy !== ''undefined'' && YugabyteDB.params.proxy !== '''') {
			request.setProxy(YugabyteDB.params.proxy);
		}
		if (YugabyteDB.params.token) {
			request.addHeader(''Accept: application/json'');
			request.addHeader(''Authorization: Bearer '' + YugabyteDB.params.token);
		}

		Zabbix.log(4, ''[ YugabyteDB ] Sending request: '' + url);

		response = request.get(url);

		Zabbix.log(4, ''[ YugabyteDB ] Received response with status code '' + request.getStatus() + '': '' + response);

		if (request.getStatus() !== 200 || response === null) {
			throw ''Request failed with status code '' + request.getStatus() + '': '' + response;
		}

		try {
			return JSON.parse(response);
		}
		catch (error) {
			throw ''Failed to parse response received from API:'' + error;
		}
	},


	get_last_values: function (values) {
		var max_timestamp = 0;
		var last_value = 0;
		for (e in values) {
			if (values[e][0] > max_timestamp) {
				max_timestamp = values[e][0];
				last_value = values[e][1];
			};
		};
		return last_value;
	},


	get_start_time: function() {
		return Math.floor(Date.now() / 1000 - 300);
	}

};

metrics = [
	"YSQL_SELECT_OPS_PER_SEC",
	"YSQL_DELETE_OPS_PER_SEC",
	"YSQL_INSERT_OPS_PER_SEC",
	"YSQL_UPDATE_OPS_PER_SEC",
	"YSQL_OTHER_OPS_PER_SEC",
	"YSQL_TRANSACTION_OPS_PER_SEC",
	"YSQL_SELECT_LATENCY_MS",
	"YSQL_DELETE_LATENCY_MS",
	"YSQL_INSERT_LATENCY_MS",
	"YSQL_UPDATE_LATENCY_MS",
	"YSQL_OTHER_LATENCY_MS",
	"YSQL_TRANSACTION_LATENCY_MS",
	"YCQL_SELECT_OPS_PER_SEC",
	"YCQL_DELETE_OPS_PER_SEC",
	"YCQL_INSERT_OPS_PER_SEC",
	"YCQL_OTHER_OPS_PER_SEC",
	"YCQL_UPDATE_OPS_PER_SEC",
	"YCQL_TRANSACTION_OPS_PER_SEC",
	"YCQL_SELECT_LATENCY_MS",
	"YCQL_DELETE_LATENCY_MS",
	"YCQL_INSERT_LATENCY_MS",
	"YCQL_OTHER_LATENCY_MS",
	"YCQL_UPDATE_LATENCY_MS",
	"YCQL_TRANSACTION_LATENCY_MS"
]

try {
	YugabyteDB.setParams(JSON.parse(value));

	var size = 6

	for (var i = 0; i < Math.ceil(metrics.length/size); i++)  {
		var values = YugabyteDB.request(
			''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()
		);

		values.data.forEach(function (e) {
			YugabyteDB.metrics[e.name] = YugabyteDB.get_last_values(e.values)
		});
	};
}
catch (error) {
	Zabbix.log(3, ''[ YugabyteDB ] ERROR: '' + error);
	error_msg = ''Failed to get data from API:'' + error;
	return JSON.stringify({''error'': error_msg});
}

return 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 = {
	params: {},
	keyspaces: {},
	error_msg: '''',

	setParams: function (params) {
		[''account_id'', ''project_id'', ''token''].forEach(function (field) {
			if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
				throw ''Required param is not set: '' + field + ''.'';
			}
		});

		YugabyteDB.params = params;
	},


	request: function (url, data) {
		if (typeof data === ''undefined'' || data === null) {
			data = '''';
		}

		var response, request = new HttpRequest();
		if (typeof YugabyteDB.params.proxy !== ''undefined'' && YugabyteDB.params.proxy !== '''') {
			request.setProxy(YugabyteDB.params.proxy);
		}
		if (YugabyteDB.params.token) {
			request.addHeader(''Accept: application/json'');
			request.addHeader(''Authorization: Bearer '' + YugabyteDB.params.token);
		}

		Zabbix.log(4, ''[ YugabyteDB ] Sending request: '' + url);

		response = request.get(url);

		Zabbix.log(4, ''[ YugabyteDB ] Received response with status code '' + request.getStatus() + '': '' + response);

		if (request.getStatus() !== 200 || response === null) {
			throw ''Request failed with status code '' + request.getStatus() + '': '' + response;
		}

		try {
			return JSON.parse(response);
		}
		catch (error) {
			throw ''Failed to parse response received from API:'' + error;
		}
	},


	get_keyspace: function (tables) {
		var table_info = {};
		var result = [];
		for (var table in tables[''data'']) {
			var table_name = tables[''data''][table][''keyspace''];
			if (typeof table_info[table_name] !== ''undefined'') {
				table_info[table_name][''size_bytes''] += tables[''data''][table][''size_bytes'']
				table_info[table_name][''wal_size_bytes''] += tables[''data''][table][''wal_size_bytes'']
			}
			else {
				table_info[table_name] = {
					''keyspace_name'': table_name,
					''size_bytes'': tables[''data''][table][''size_bytes''],
					''wal_size_bytes'': tables[''data''][table][''wal_size_bytes''],
					''type'': tables[''data''][table][''type'']}
			}
		}
		for (keyspace in table_info) {
			result.push(table_info[keyspace])
		}
		return result;
	}

};

try {
	YugabyteDB.setParams(JSON.parse(value));

	var tables = YugabyteDB.request(
		''https://cloud.yugabyte.com/api/public/v1/accounts/'' + YugabyteDB.params.account_id + ''/projects/'' + YugabyteDB.params.project_id + ''/clusters/'' + YugabyteDB.params.cluster_id + ''/tables''
	)
	
	YugabyteDB.keyspaces = YugabyteDB.get_keyspace(tables);
}
catch (error) {
	Zabbix.log(3, ''[ YugabyteDB ] ERROR: '' + error);
	error_msg = ''Failed to get data from API:'' + error;
}

return 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 = {
	params: {},
	nodes: {},
	error_msg: '''',

	setParams: function (params) {
		[''account_id'', ''project_id'', ''token''].forEach(function (field) {
			if (typeof params !== ''object'' || typeof params[field] === ''undefined'' || params[field] === '''') {
				throw ''Required param is not set: '' + field + ''.'';
			}
		});

		YugabyteDB.params = params;
	},


	request: function (url, data) {
		if (typeof data === ''undefined'' || data === null) {
			data = '''';
		}

		var response, request = new HttpRequest();
		if (typeof YugabyteDB.params.proxy !== ''undefined'' && YugabyteDB.params.proxy !== '''') {
			request.setProxy(YugabyteDB.params.proxy);
		}
		if (YugabyteDB.params.token) {
			request.addHeader(''Accept: application/json'');
			request.addHeader(''Authorization: Bearer '' + YugabyteDB.params.token);
		}

		Zabbix.log(4, ''[ YugabyteDB ] Sending request: '' + url);

		response = request.get(url);

		Zabbix.log(4, ''[ YugabyteDB ] Received response with status code '' + request.getStatus() + '': '' + response);

		if (request.getStatus() !== 200 || response === null) {
			throw ''Request failed with status code '' + request.getStatus() + '': '' + response;
		}

		try {
			return JSON.parse(response);
		}
		catch (error) {
			throw ''Failed to parse response received from API:'' + error;
		}
	}

};

try {
	YugabyteDB.setParams(JSON.parse(value));

	var node = YugabyteDB.request(
		''https://cloud.yugabyte.com/api/public/v1/accounts/'' + YugabyteDB.params.account_id + ''/projects/'' + YugabyteDB.params.project_id + ''/clusters/'' + YugabyteDB.params.cluster_id + ''/nodes''
	)
	YugabyteDB.nodes = node.data;
}
catch (error) {
	Zabbix.log(3, ''[ YugabyteDB ] ERROR: '' + error);
	error_msg = ''Failed to get data from API:'' + error;
}

return 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.
0 - ICMP ping fails.
1 - 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
Number 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
Name 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
Average 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
Number 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
Average 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
Average 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
Average 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
Number 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
Number 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
Average 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
Average 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
CPU 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
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','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
Appliance 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
Appliance 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
Appliance 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
Physical 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
An 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
The 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
Time 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
Active 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
Free 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
Total 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
Number 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
Number 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.

Possible values:
0 - not available
1 - available
2 - 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
Number 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
Peak 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
Number 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
Number 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
Last 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
Name 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
Number 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
Number 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
Firewall 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
Number 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
Current 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,E'function validateZabbixParams(requiredParams, allParams) {
	requiredParams.forEach(function (field) {
		if (typeof allParams !== ''object'' || typeof allParams[field] === ''undefined'' || allParams[field] === '''') {
			throw ''Required param is not set: '' + field + ''.'';
		}
	});
}

function OCI(service, action, params) {
	this.zabbixLogPrefix = ''[ OCI ] [ '' + service + '' ] [ '' + action + '' ]'';
	this.request = new HttpRequest();

	this.hash = function (string) {
		return sha256(string);
	};

	this.sign = function (string) {
		return sign(''sha256'', params[''private_key''], string);
	};

	this.encode = function (hash) {
		const hexArr = hash.match(/.{1,2}/g);
		var uInt8Array = new Uint8Array(hexArr.length);
		hexArr.forEach(function (hex, idx) {
			uInt8Array[idx] = parseInt(hex, 16);
		});
		return btoa(uInt8Array);
	};

	this.getDate = function () {
		const weekdayShortList = [''Sun'', ''Mon'', ''Tue'', ''Wed'', ''Thu'', ''Fri'', ''Sat''];
		const monthShortList = [''jan'', ''feb'', ''mar'', ''apr'', ''may'', ''jun'', ''jul'', ''aug'', ''sep'', ''oct'', ''nov'', ''dec''];
		const today = new Date();
		return weekdayShortList[today.getUTCDay()] + '', '' + today.getUTCDate() + '' '' + monthShortList[today.getUTCMonth()] + '' '' + today.getUTCFullYear() + '' '' + today.getUTCHours() + '':'' + today.getUTCMinutes() + '':'' + today.getUTCSeconds() + '' GMT'';
	};

	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {
		var headers = ''(request-target) date host'';
		const contentTypeHeader = ''content-type: application/json'';
		const dateHeader = ''date: '' + this.getDate();
		const hostHeader = ''host: '' + params[''api_host''];
		const requestTarget = ''(request-target): '' + httpMethod + '' '' + apiPath + apiParams;
		var signingString = requestTarget + ''\\n'' + dateHeader + ''\\n'' + hostHeader;
		var reqHeaders = [contentTypeHeader, dateHeader];

		if (httpMethod === ''post'') {
			var body = JSON.stringify({
				''namespace'': namespace,
				''query'': mql
			});
			headers = headers + '' x-content-sha256 content-type content-length'';
			const bodyHeader = ''x-content-sha256: '' + this.encode(this.hash(body));
			const bodyLengthHeader = ''content-length: '' + body.length;
			signingString = signingString + ''\\n'' + bodyHeader + ''\\n'' + contentTypeHeader + ''\\n'' + bodyLengthHeader;
			reqHeaders.push(bodyHeader, bodyLengthHeader);
		}

		const signature = this.encode(this.sign(signingString));

		reqHeaders.push(''Authorization: Signature version="1",keyId="'' + params[''tenancy_ocid''] + ''/'' + params[''user_ocid''] + ''/'' + params[''fingerprint''] + ''",algorithm="rsa-sha256",headers="'' + headers + ''",signature="'' + signature + ''"'');
		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {
			this.request.addHeader(reqHeaders[header]);
		}

		if (params[''http_proxy'']) {
			this.request.setProxy(params[''http_proxy'']);
			Zabbix.log(4, this.zabbixLogPrefix + '' Using http proxy: '' + params[''http_proxy'']);
		}

		if (httpMethod === ''post'') {
			var apiRateLimitExceeded = false;
			do {
				const response = this.request.post(''https://'' + params[''api_host''] + apiPath + apiParams, body);

				try {
					if (JSON.parse(response)[''code''] === ''TooManyRequests'') {

						apiRateLimitExceeded = true;
						Zabbix.sleep(1000);
					} else {
						apiRateLimitExceeded = false;
					}
				} catch (error) {
					Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the response: '' + JSON.stringify(response));
					throw ''Could not parse the response. See logs for more information.'';
				}
			} while (apiRateLimitExceeded);
		} else {
			const response = this.request.get(''https://'' + params[''api_host''] + apiPath + apiParams);
		}

		this.request.clearHeader();

		if (this.request.getStatus() === parseInt(params[''http_status_code''])) {
			return response;
		} else {
			Zabbix.log(3, this.zabbixLogPrefix + '' Unexpected HTTP response code: '' + this.request.getStatus());
			throw ''Unexpected HTTP response code: '' + this.request.getStatus();
		}
	};

	this.extractData = function (httpMethod, data, keys, compartment) {
		try {
			data = JSON.parse(data);
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the received JSON object: '' + data);
			throw ''Could not parse received JSON object. See logs for more information.'';
		}

		if (typeof keys == ''object'') {
			var returnBuffer = [];
			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {

				var objectBuffer = {};
				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {
					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {
						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];
					} else {
						Zabbix.log(3, this.zabbixLogPrefix + '' Received an unexpected JSON object. Could not get value for key "'' + keys[key] + ''" in JSON: '' + JSON.stringify(data[dataObj]));
						throw ''Received an unexpected JSON object. See logs for more information.'';
					}
				}
				if (typeof compartment != ''undefined'' && compartment != '''') objectBuffer[''compartment''] = compartment;
				returnBuffer.push(objectBuffer);
			}
			return returnBuffer;
		}

		try {
			if (httpMethod === ''get'') {
				return data[keys];
			} else {
				if (data.length === 0) {
					return 0;
				}
				data = data[0][keys];
				return data[data.length - 1][''value''];
			}
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not find key "'' + keys + ''" in JSON: '' + JSON.stringify(data));
			throw ''Could not find required key in JSON object. See logs for more information.'';
		}
	};
}

function buildMql(id, metrics, defaultStatistic, resourceType) {
	resourceType = resourceType === '''' || resourceType === undefined ? ''resourceId'' : resourceType;
	this.query = ''['' + params[''req_interval''] + ''m]{'' + resourceType + ''='' + id + ''}.'';

	for (var i = 0, metricsLength = metrics.length; i < metricsLength; i++) {
		const metric = ((Array.isArray(metrics[i]) ? metrics[i] : [metrics[i], defaultStatistic]));
		metrics[i] = [metric[0], this.query + metric[1]];
	}
}


const params = JSON.parse(value);
validateZabbixParams([''tenancy_ocid'', ''user_ocid'', ''private_key'', ''fingerprint'', ''api_host'', ''db_id'', ''http_status_code'', ''req_interval'', ''compartment_id''], params);
var oci = new OCI(''Autonomous DB'', ''Get metrics '' + params[''req_interval''] + ''m'', params);

const metrics = [
	[''CpuTime'', ''mean''],
	[''CpuUtilization'', ''mean''],
	[''CurrentLogons'', ''count''],
	''DBBlockChanges'',
	[''DBTime'', ''mean''],
	''ExecuteCount'',
	''FailedConnections'',
	[''FailedLogons'', ''mean''],
	''HardParseCount'',
	''LogicalReads'',
	''ParseCount'',
	''ParseFailureCount'',
	''PhysicalReads'',
	''PhysicalReadTotalBytes'',
	''PhysicalWrites'',
	''PhysicalWriteTotalBytes'',
	''QueuedStatements'',
	''RedoGenerated'',
	[''RunningStatements'', ''mean''],
	''Sessions'',
	''SQLNetBytesFromClient'',
	''SQLNetBytesFromDBLink'',
	''SQLNetBytesToClient'',
	''SQLNetBytesToDBLink'',
	''TransactionCount'',
	''UserCalls'',
	''UserCommits'',
	''UserRollbacks'',
	[''WaitTime'', ''mean'']
];
buildMql(params[''db_id''], metrics, ''sum'');

var result = {};
for (var i = 0, metricsLength = metrics.length; i < metricsLength; i++) {
	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'');
}
return 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,E'function validateZabbixParams(requiredParams, allParams) {
	requiredParams.forEach(function (field) {
		if (typeof allParams !== ''object'' || typeof allParams[field] === ''undefined'' || allParams[field] === '''') {
			throw ''Required param is not set: '' + field + ''.'';
		}
	});
}

function OCI(service, action, params) {
	this.zabbixLogPrefix = ''[ OCI ] [ '' + service + '' ] [ '' + action + '' ]'';
	this.request = new HttpRequest();

	this.hash = function (string) {
		return sha256(string);
	};

	this.sign = function (string) {
		return sign(''sha256'', params[''private_key''], string);
	};

	this.encode = function (hash) {
		const hexArr = hash.match(/.{1,2}/g);
		var uInt8Array = new Uint8Array(hexArr.length);
		hexArr.forEach(function (hex, idx) {
			uInt8Array[idx] = parseInt(hex, 16);
		});
		return btoa(uInt8Array);
	};

	this.getDate = function () {
		const weekdayShortList = [''Sun'', ''Mon'', ''Tue'', ''Wed'', ''Thu'', ''Fri'', ''Sat''];
		const monthShortList = [''jan'', ''feb'', ''mar'', ''apr'', ''may'', ''jun'', ''jul'', ''aug'', ''sep'', ''oct'', ''nov'', ''dec''];
		const today = new Date();
		return weekdayShortList[today.getUTCDay()] + '', '' + today.getUTCDate() + '' '' + monthShortList[today.getUTCMonth()] + '' '' + today.getUTCFullYear() + '' '' + today.getUTCHours() + '':'' + today.getUTCMinutes() + '':'' + today.getUTCSeconds() + '' GMT'';
	};

	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {
		var headers = ''(request-target) date host'';
		const contentTypeHeader = ''content-type: application/json'';
		const dateHeader = ''date: '' + this.getDate();
		const hostHeader = ''host: '' + params[''api_host''];
		const requestTarget = ''(request-target): '' + httpMethod + '' '' + apiPath + apiParams;
		var signingString = requestTarget + ''\\n'' + dateHeader + ''\\n'' + hostHeader;
		var reqHeaders = [contentTypeHeader, dateHeader];

		if (httpMethod === ''post'') {
			var body = JSON.stringify({
				''namespace'': namespace,
				''query'': mql
			});
			headers = headers + '' x-content-sha256 content-type content-length'';
			const bodyHeader = ''x-content-sha256: '' + this.encode(this.hash(body));
			const bodyLengthHeader = ''content-length: '' + body.length;
			signingString = signingString + ''\\n'' + bodyHeader + ''\\n'' + contentTypeHeader + ''\\n'' + bodyLengthHeader;
			reqHeaders.push(bodyHeader, bodyLengthHeader);
		}

		const signature = this.encode(this.sign(signingString));

		reqHeaders.push(''Authorization: Signature version="1",keyId="'' + params[''tenancy_ocid''] + ''/'' + params[''user_ocid''] + ''/'' + params[''fingerprint''] + ''",algorithm="rsa-sha256",headers="'' + headers + ''",signature="'' + signature + ''"'');
		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {
			this.request.addHeader(reqHeaders[header]);
		}

		if (params[''http_proxy'']) {
			this.request.setProxy(params[''http_proxy'']);
			Zabbix.log(4, this.zabbixLogPrefix + '' Using http proxy: '' + params[''http_proxy'']);
		}

		if (httpMethod === ''post'') {
			var apiRateLimitExceeded = false;
			do {
				const response = this.request.post(''https://'' + params[''api_host''] + apiPath + apiParams, body);

				try {
					if (JSON.parse(response)[''code''] === ''TooManyRequests'') {

						apiRateLimitExceeded = true;
						Zabbix.sleep(1000);
					} else {
						apiRateLimitExceeded = false;
					}
				} catch (error) {
					Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the response: '' + JSON.stringify(response));
					throw ''Could not parse the response. See logs for more information.'';
				}
			} while (apiRateLimitExceeded);
		} else {
			const response = this.request.get(''https://'' + params[''api_host''] + apiPath + apiParams);
		}

		this.request.clearHeader();

		if (this.request.getStatus() === parseInt(params[''http_status_code''])) {
			return response;
		} else {
			Zabbix.log(3, this.zabbixLogPrefix + '' Unexpected HTTP response code: '' + this.request.getStatus());
			throw ''Unexpected HTTP response code: '' + this.request.getStatus();
		}
	};

	this.extractData = function (httpMethod, data, keys, compartment) {
		try {
			data = JSON.parse(data);
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the received JSON object: '' + data);
			throw ''Could not parse received JSON object. See logs for more information.'';
		}

		if (typeof keys == ''object'') {
			var returnBuffer = [];
			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {

				var objectBuffer = {};
				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {
					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {
						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];
					} else {
						Zabbix.log(3, this.zabbixLogPrefix + '' Received an unexpected JSON object. Could not get value for key "'' + keys[key] + ''" in JSON: '' + JSON.stringify(data[dataObj]));
						throw ''Received an unexpected JSON object. See logs for more information.'';
					}
				}
				if (typeof compartment != ''undefined'' && compartment != '''') objectBuffer[''compartment''] = compartment;
				returnBuffer.push(objectBuffer);
			}
			return returnBuffer;
		}

		try {
			if (httpMethod === ''get'') {
				return data[keys];
			} else {
				if (data.length === 0) {
					return 0;
				}
				data = data[0][keys];
				return data[data.length - 1][''value''];
			}
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not find key "'' + keys + ''" in JSON: '' + JSON.stringify(data));
			throw ''Could not find required key in JSON object. See logs for more information.'';
		}
	};
}

function buildMql(id, metrics, defaultStatistic, resourceType) {
	resourceType = resourceType === '''' || resourceType === undefined ? ''resourceId'' : resourceType;
	this.query = ''['' + params[''req_interval''] + ''m]{'' + resourceType + ''='' + id + ''}.'';

	for (var i = 0, metricsLength = metrics.length; i < metricsLength; i++) {
		const metric = ((Array.isArray(metrics[i]) ? metrics[i] : [metrics[i], defaultStatistic]));
		metrics[i] = [metric[0], this.query + metric[1]];
	}
}


const params = JSON.parse(value);
validateZabbixParams([''tenancy_ocid'', ''user_ocid'', ''private_key'', ''fingerprint'', ''api_host'', ''db_id'', ''http_status_code'', ''req_interval'', ''compartment_id''], params);
var oci = new OCI(''Autonomous DB'', ''Get metrics '' + params[''req_interval''] + ''m'', params);

const metrics = [
	[''DatabaseAvailability'', ''last''],
	''ConnectionLatency'',
	''QueryLatency''
];
buildMql(params[''db_id''], metrics, ''max'');

var result = {};
for (var i = 0, metricsLength = metrics.length; i < metricsLength; i++) {
	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'');
}
return 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,E'function validateZabbixParams(requiredParams, allParams) {
	requiredParams.forEach(function (field) {
		if (typeof allParams !== ''object'' || typeof allParams[field] === ''undefined'' || allParams[field] === '''') {
			throw ''Required param is not set: '' + field + ''.'';
		}
	});
}

function OCI(service, action, params) {
	this.zabbixLogPrefix = ''[ OCI ] [ '' + service + '' ] [ '' + action + '' ]'';
	this.request = new HttpRequest();

	this.hash = function (string) {
		return sha256(string);
	};

	this.sign = function (string) {
		return sign(''sha256'', params[''private_key''], string);
	};

	this.encode = function (hash) {
		const hexArr = hash.match(/.{1,2}/g);
		var uInt8Array = new Uint8Array(hexArr.length);
		hexArr.forEach(function (hex, idx) {
			uInt8Array[idx] = parseInt(hex, 16);
		});
		return btoa(uInt8Array);
	};

	this.getDate = function () {
		const weekdayShortList = [''Sun'', ''Mon'', ''Tue'', ''Wed'', ''Thu'', ''Fri'', ''Sat''];
		const monthShortList = [''jan'', ''feb'', ''mar'', ''apr'', ''may'', ''jun'', ''jul'', ''aug'', ''sep'', ''oct'', ''nov'', ''dec''];
		const today = new Date();
		return weekdayShortList[today.getUTCDay()] + '', '' + today.getUTCDate() + '' '' + monthShortList[today.getUTCMonth()] + '' '' + today.getUTCFullYear() + '' '' + today.getUTCHours() + '':'' + today.getUTCMinutes() + '':'' + today.getUTCSeconds() + '' GMT'';
	};

	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {
		var headers = ''(request-target) date host'';
		const contentTypeHeader = ''content-type: application/json'';
		const dateHeader = ''date: '' + this.getDate();
		const hostHeader = ''host: '' + params[''api_host''];
		const requestTarget = ''(request-target): '' + httpMethod + '' '' + apiPath + apiParams;
		var signingString = requestTarget + ''\\n'' + dateHeader + ''\\n'' + hostHeader;
		var reqHeaders = [contentTypeHeader, dateHeader];

		if (httpMethod === ''post'') {
			var body = JSON.stringify({
				''namespace'': namespace,
				''query'': mql
			});
			headers = headers + '' x-content-sha256 content-type content-length'';
			const bodyHeader = ''x-content-sha256: '' + this.encode(this.hash(body));
			const bodyLengthHeader = ''content-length: '' + body.length;
			signingString = signingString + ''\\n'' + bodyHeader + ''\\n'' + contentTypeHeader + ''\\n'' + bodyLengthHeader;
			reqHeaders.push(bodyHeader, bodyLengthHeader);
		}

		const signature = this.encode(this.sign(signingString));

		reqHeaders.push(''Authorization: Signature version="1",keyId="'' + params[''tenancy_ocid''] + ''/'' + params[''user_ocid''] + ''/'' + params[''fingerprint''] + ''",algorithm="rsa-sha256",headers="'' + headers + ''",signature="'' + signature + ''"'');
		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {
			this.request.addHeader(reqHeaders[header]);
		}

		if (params[''http_proxy'']) {
			this.request.setProxy(params[''http_proxy'']);
			Zabbix.log(4, this.zabbixLogPrefix + '' Using http proxy: '' + params[''http_proxy'']);
		}

		if (httpMethod === ''post'') {
			var apiRateLimitExceeded = false;
			do {
				const response = this.request.post(''https://'' + params[''api_host''] + apiPath + apiParams, body);

				try {
					if (JSON.parse(response)[''code''] === ''TooManyRequests'') {

						apiRateLimitExceeded = true;
						Zabbix.sleep(1000);
					} else {
						apiRateLimitExceeded = false;
					}
				} catch (error) {
					Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the response: '' + JSON.stringify(response));
					throw ''Could not parse the response. See logs for more information.'';
				}
			} while (apiRateLimitExceeded);
		} else {
			const response = this.request.get(''https://'' + params[''api_host''] + apiPath + apiParams);
		}

		this.request.clearHeader();

		if (this.request.getStatus() === parseInt(params[''http_status_code''])) {
			return response;
		} else {
			Zabbix.log(3, this.zabbixLogPrefix + '' Unexpected HTTP response code: '' + this.request.getStatus());
			throw ''Unexpected HTTP response code: '' + this.request.getStatus();
		}
	};

	this.extractData = function (httpMethod, data, keys, compartment) {
		try {
			data = JSON.parse(data);
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the received JSON object: '' + data);
			throw ''Could not parse received JSON object. See logs for more information.'';
		}

		if (typeof keys == ''object'') {
			var returnBuffer = [];
			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {

				var objectBuffer = {};
				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {
					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {
						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];
					} else {
						Zabbix.log(3, this.zabbixLogPrefix + '' Received an unexpected JSON object. Could not get value for key "'' + keys[key] + ''" in JSON: '' + JSON.stringify(data[dataObj]));
						throw ''Received an unexpected JSON object. See logs for more information.'';
					}
				}
				if (typeof compartment != ''undefined'' && compartment != '''') objectBuffer[''compartment''] = compartment;
				returnBuffer.push(objectBuffer);
			}
			return returnBuffer;
		}

		try {
			if (httpMethod === ''get'') {
				return data[keys];
			} else {
				if (data.length === 0) {
					return 0;
				}
				data = data[0][keys];
				return data[data.length - 1][''value''];
			}
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not find key "'' + keys + ''" in JSON: '' + JSON.stringify(data));
			throw ''Could not find required key in JSON object. See logs for more information.'';
		}
	};
}

function buildMql(id, metrics, defaultStatistic, resourceType) {
	resourceType = resourceType === '''' || resourceType === undefined ? ''resourceId'' : resourceType;
	this.query = ''['' + params[''req_interval''] + ''m]{'' + resourceType + ''='' + id + ''}.'';

	for (var i = 0, metricsLength = metrics.length; i < metricsLength; i++) {
		const metric = ((Array.isArray(metrics[i]) ? metrics[i] : [metrics[i], defaultStatistic]));
		metrics[i] = [metric[0], this.query + metric[1]];
	}
}


const params = JSON.parse(value);
validateZabbixParams([''tenancy_ocid'', ''user_ocid'', ''private_key'', ''fingerprint'', ''api_host'', ''db_id'', ''http_status_code'', ''req_interval'', ''compartment_id''], params);
var oci = new OCI(''Autonomous DB'', ''Get metrics '' + params[''req_interval''] + ''m'', params);

const metrics = [
	''StorageAllocated'',
	''StorageMax'',
	''StorageUsed'',
	[''StorageUtilization'', ''mean'']
];
buildMql(params[''db_id''], metrics, ''max'');

var result = {};
for (var i = 0, metricsLength = metrics.length; i < metricsLength; i++) {
	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'');
}
return 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',E'function validateZabbixParams(requiredParams, allParams) {
	requiredParams.forEach(function (field) {
		if (typeof allParams !== ''object'' || typeof allParams[field] === ''undefined'' || allParams[field] === '''') {
			throw ''Required param is not set: '' + field + ''.'';
		}
	});
}

function OCI(service, action, params) {
	this.zabbixLogPrefix = ''[ OCI ] [ '' + service + '' ] [ '' + action + '' ]'';
	this.request = new HttpRequest();

	this.hash = function (string) {
		return sha256(string);
	};

	this.sign = function (string) {
		return sign(''sha256'', params[''private_key''], string);
	};

	this.encode = function (hash) {
		const hexArr = hash.match(/.{1,2}/g);
		var uInt8Array = new Uint8Array(hexArr.length);
		hexArr.forEach(function (hex, idx) {
			uInt8Array[idx] = parseInt(hex, 16);
		});
		return btoa(uInt8Array);
	};

	this.getDate = function () {
		const weekdayShortList = [''Sun'', ''Mon'', ''Tue'', ''Wed'', ''Thu'', ''Fri'', ''Sat''];
		const monthShortList = [''jan'', ''feb'', ''mar'', ''apr'', ''may'', ''jun'', ''jul'', ''aug'', ''sep'', ''oct'', ''nov'', ''dec''];
		const today = new Date();
		return weekdayShortList[today.getUTCDay()] + '', '' + today.getUTCDate() + '' '' + monthShortList[today.getUTCMonth()] + '' '' + today.getUTCFullYear() + '' '' + today.getUTCHours() + '':'' + today.getUTCMinutes() + '':'' + today.getUTCSeconds() + '' GMT'';
	};

	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {
		var headers = ''(request-target) date host'';
		const contentTypeHeader = ''content-type: application/json'';
		const dateHeader = ''date: '' + this.getDate();
		const hostHeader = ''host: '' + params[''api_host''];
		const requestTarget = ''(request-target): '' + httpMethod + '' '' + apiPath + apiParams;
		var signingString = requestTarget + ''\\n'' + dateHeader + ''\\n'' + hostHeader;
		var reqHeaders = [contentTypeHeader, dateHeader];

		if (httpMethod === ''post'') {
			var body = JSON.stringify({
				''namespace'': namespace,
				''query'': mql
			});
			headers = headers + '' x-content-sha256 content-type content-length'';
			const bodyHeader = ''x-content-sha256: '' + this.encode(this.hash(body));
			const bodyLengthHeader = ''content-length: '' + body.length;
			signingString = signingString + ''\\n'' + bodyHeader + ''\\n'' + contentTypeHeader + ''\\n'' + bodyLengthHeader;
			reqHeaders.push(bodyHeader, bodyLengthHeader);
		}

		const signature = this.encode(this.sign(signingString));

		reqHeaders.push(''Authorization: Signature version="1",keyId="'' + params[''tenancy_ocid''] + ''/'' + params[''user_ocid''] + ''/'' + params[''fingerprint''] + ''",algorithm="rsa-sha256",headers="'' + headers + ''",signature="'' + signature + ''"'');
		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {
			this.request.addHeader(reqHeaders[header]);
		}

		if (params[''http_proxy'']) {
			this.request.setProxy(params[''http_proxy'']);
			Zabbix.log(4, this.zabbixLogPrefix + '' Using http proxy: '' + params[''http_proxy'']);
		}

		if (httpMethod === ''post'') {
			var apiRateLimitExceeded = false;
			do {
				const response = this.request.post(''https://'' + params[''api_host''] + apiPath + apiParams, body);

				try {
					if (JSON.parse(response)[''code''] === ''TooManyRequests'') {

						apiRateLimitExceeded = true;
						Zabbix.sleep(1000);
					} else {
						apiRateLimitExceeded = false;
					}
				} catch (error) {
					Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the response: '' + JSON.stringify(response));
					throw ''Could not parse the response. See logs for more information.'';
				}
			} while (apiRateLimitExceeded);
		} else {
			const response = this.request.get(''https://'' + params[''api_host''] + apiPath + apiParams);
		}

		this.request.clearHeader();

		if (this.request.getStatus() === parseInt(params[''http_status_code''])) {
			return response;
		} else {
			Zabbix.log(3, this.zabbixLogPrefix + '' Unexpected HTTP response code: '' + this.request.getStatus());
			throw ''Unexpected HTTP response code: '' + this.request.getStatus();
		}
	};

	this.extractData = function (httpMethod, data, keys, compartment) {
		try {
			data = JSON.parse(data);
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the received JSON object: '' + data);
			throw ''Could not parse received JSON object. See logs for more information.'';
		}

		if (typeof keys == ''object'') {
			var returnBuffer = [];
			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {

				var objectBuffer = {};
				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {
					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {
						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];
					} else {
						Zabbix.log(3, this.zabbixLogPrefix + '' Received an unexpected JSON object. Could not get value for key "'' + keys[key] + ''" in JSON: '' + JSON.stringify(data[dataObj]));
						throw ''Received an unexpected JSON object. See logs for more information.'';
					}
				}
				if (typeof compartment != ''undefined'' && compartment != '''') objectBuffer[''compartment''] = compartment;
				returnBuffer.push(objectBuffer);
			}
			return returnBuffer;
		}

		try {
			if (httpMethod === ''get'') {
				return data[keys];
			} else {
				if (data.length === 0) {
					return 0;
				}
				data = data[0][keys];
				return data[data.length - 1][''value''];
			}
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not find key "'' + keys + ''" in JSON: '' + JSON.stringify(data));
			throw ''Could not find required key in JSON object. See logs for more information.'';
		}
	};
}


const params = JSON.parse(value);
validateZabbixParams([''tenancy_ocid'', ''user_ocid'', ''private_key'', ''fingerprint'', ''api_host'', ''db_id'', ''http_status_code''], params);
var oci = new OCI(''Autonomous DB'', ''Get state'', params);

return 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,E'function validateZabbixParams(requiredParams, allParams) {
	requiredParams.forEach(function (field) {
		if (typeof allParams !== ''object'' || typeof allParams[field] === ''undefined'' || allParams[field] === '''') {
			throw ''Required param is not set: '' + field + ''.'';
		}
	});
}

function OCI(service, action, params) {
	this.zabbixLogPrefix = ''[ OCI ] [ '' + service + '' ] [ '' + action + '' ]'';
	this.request = new HttpRequest();

	this.hash = function (string) {
		return sha256(string);
	};

	this.sign = function (string) {
		return sign(''sha256'', params[''private_key''], string);
	};

	this.encode = function (hash) {
		const hexArr = hash.match(/.{1,2}/g);
		var uInt8Array = new Uint8Array(hexArr.length);
		hexArr.forEach(function (hex, idx) {
			uInt8Array[idx] = parseInt(hex, 16);
		});
		return btoa(uInt8Array);
	};

	this.getDate = function () {
		const weekdayShortList = [''Sun'', ''Mon'', ''Tue'', ''Wed'', ''Thu'', ''Fri'', ''Sat''];
		const monthShortList = [''jan'', ''feb'', ''mar'', ''apr'', ''may'', ''jun'', ''jul'', ''aug'', ''sep'', ''oct'', ''nov'', ''dec''];
		const today = new Date();
		return weekdayShortList[today.getUTCDay()] + '', '' + today.getUTCDate() + '' '' + monthShortList[today.getUTCMonth()] + '' '' + today.getUTCFullYear() + '' '' + today.getUTCHours() + '':'' + today.getUTCMinutes() + '':'' + today.getUTCSeconds() + '' GMT'';
	};

	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {
		var headers = ''(request-target) date host'';
		const contentTypeHeader = ''content-type: application/json'';
		const dateHeader = ''date: '' + this.getDate();
		const hostHeader = ''host: '' + params[''api_host''];
		const requestTarget = ''(request-target): '' + httpMethod + '' '' + apiPath + apiParams;
		var signingString = requestTarget + ''\\n'' + dateHeader + ''\\n'' + hostHeader;
		var reqHeaders = [contentTypeHeader, dateHeader];

		if (httpMethod === ''post'') {
			var body = JSON.stringify({
				''namespace'': namespace,
				''query'': mql
			});
			headers = headers + '' x-content-sha256 content-type content-length'';
			const bodyHeader = ''x-content-sha256: '' + this.encode(this.hash(body));
			const bodyLengthHeader = ''content-length: '' + body.length;
			signingString = signingString + ''\\n'' + bodyHeader + ''\\n'' + contentTypeHeader + ''\\n'' + bodyLengthHeader;
			reqHeaders.push(bodyHeader, bodyLengthHeader);
		}

		const signature = this.encode(this.sign(signingString));

		reqHeaders.push(''Authorization: Signature version="1",keyId="'' + params[''tenancy_ocid''] + ''/'' + params[''user_ocid''] + ''/'' + params[''fingerprint''] + ''",algorithm="rsa-sha256",headers="'' + headers + ''",signature="'' + signature + ''"'');
		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {
			this.request.addHeader(reqHeaders[header]);
		}

		if (params[''http_proxy'']) {
			this.request.setProxy(params[''http_proxy'']);
			Zabbix.log(4, this.zabbixLogPrefix + '' Using http proxy: '' + params[''http_proxy'']);
		}

		if (httpMethod === ''post'') {
			var apiRateLimitExceeded = false;
			do {
				const response = this.request.post(''https://'' + params[''api_host''] + apiPath + apiParams, body);

				try {
					if (JSON.parse(response)[''code''] === ''TooManyRequests'') {

						apiRateLimitExceeded = true;
						Zabbix.sleep(1000);
					} else {
						apiRateLimitExceeded = false;
					}
				} catch (error) {
					Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the response: '' + JSON.stringify(response));
					throw ''Could not parse the response. See logs for more information.'';
				}
			} while (apiRateLimitExceeded);
		} else {
			const response = this.request.get(''https://'' + params[''api_host''] + apiPath + apiParams);
		}

		this.request.clearHeader();

		if (this.request.getStatus() === parseInt(params[''http_status_code''])) {
			return response;
		} else {
			Zabbix.log(3, this.zabbixLogPrefix + '' Unexpected HTTP response code: '' + this.request.getStatus());
			throw ''Unexpected HTTP response code: '' + this.request.getStatus();
		}
	};

	this.extractData = function (httpMethod, data, keys, compartment) {
		try {
			data = JSON.parse(data);
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the received JSON object: '' + data);
			throw ''Could not parse received JSON object. See logs for more information.'';
		}

		if (typeof keys == ''object'') {
			var returnBuffer = [];
			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {

				var objectBuffer = {};
				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {
					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {
						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];
					} else {
						Zabbix.log(3, this.zabbixLogPrefix + '' Received an unexpected JSON object. Could not get value for key "'' + keys[key] + ''" in JSON: '' + JSON.stringify(data[dataObj]));
						throw ''Received an unexpected JSON object. See logs for more information.'';
					}
				}
				if (typeof compartment != ''undefined'' && compartment != '''') objectBuffer[''compartment''] = compartment;
				returnBuffer.push(objectBuffer);
			}
			return returnBuffer;
		}

		try {
			if (httpMethod === ''get'') {
				return data[keys];
			} else {
				if (data.length === 0) {
					return 0;
				}
				data = data[0][keys];
				return data[data.length - 1][''value''];
			}
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not find key "'' + keys + ''" in JSON: '' + JSON.stringify(data));
			throw ''Could not find required key in JSON object. See logs for more information.'';
		}
	};
}

function buildMql(id, metrics, defaultStatistic, resourceType) {
	resourceType = resourceType === '''' || resourceType === undefined ? ''resourceId'' : resourceType;
	this.query = ''['' + params[''req_interval''] + ''m]{'' + resourceType + ''='' + id + ''}.'';

	for (var i = 0, metricsLength = metrics.length; i < metricsLength; i++) {
		const metric = ((Array.isArray(metrics[i]) ? metrics[i] : [metrics[i], defaultStatistic]));
		metrics[i] = [metric[0], this.query + metric[1]];
	}
}


const params = JSON.parse(value);
validateZabbixParams([''tenancy_ocid'', ''user_ocid'', ''private_key'', ''fingerprint'', ''api_host'', ''volume_id'', ''http_status_code'', ''req_interval'', ''compartment_id''], params);
var oci = new OCI(''Block volume'', ''Get metrics'', params);

const metrics = [
	''VolumeReadThroughput'',
	''VolumeWriteThroughput'',
	''VolumeReadOps'',
	''VolumeWriteOps'',
	[''VolumeThrottledIOs'', ''sum''],
	''VolumeGuaranteedVPUsPerGB'',
	''VolumeGuaranteedIOPS'',
	''VolumeGuaranteedThroughput''
];
buildMql(params[''volume_id''], metrics, ''mean'');

var result = {};
for (var i = 0, metricsLength = metrics.length; i < metricsLength; i++) {
	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'');
}
return 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',E'function validateZabbixParams(requiredParams, allParams) {
	requiredParams.forEach(function (field) {
		if (typeof allParams !== ''object'' || typeof allParams[field] === ''undefined'' || allParams[field] === '''') {
			throw ''Required param is not set: '' + field + ''.'';
		}
	});
}

function OCI(service, action, params) {
	this.zabbixLogPrefix = ''[ OCI ] [ '' + service + '' ] [ '' + action + '' ]'';
	this.request = new HttpRequest();

	this.hash = function (string) {
		return sha256(string);
	};

	this.sign = function (string) {
		return sign(''sha256'', params[''private_key''], string);
	};

	this.encode = function (hash) {
		const hexArr = hash.match(/.{1,2}/g);
		var uInt8Array = new Uint8Array(hexArr.length);
		hexArr.forEach(function (hex, idx) {
			uInt8Array[idx] = parseInt(hex, 16);
		});
		return btoa(uInt8Array);
	};

	this.getDate = function () {
		const weekdayShortList = [''Sun'', ''Mon'', ''Tue'', ''Wed'', ''Thu'', ''Fri'', ''Sat''];
		const monthShortList = [''jan'', ''feb'', ''mar'', ''apr'', ''may'', ''jun'', ''jul'', ''aug'', ''sep'', ''oct'', ''nov'', ''dec''];
		const today = new Date();
		return weekdayShortList[today.getUTCDay()] + '', '' + today.getUTCDate() + '' '' + monthShortList[today.getUTCMonth()] + '' '' + today.getUTCFullYear() + '' '' + today.getUTCHours() + '':'' + today.getUTCMinutes() + '':'' + today.getUTCSeconds() + '' GMT'';
	};

	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {
		var headers = ''(request-target) date host'';
		const contentTypeHeader = ''content-type: application/json'';
		const dateHeader = ''date: '' + this.getDate();
		const hostHeader = ''host: '' + params[''api_host''];
		const requestTarget = ''(request-target): '' + httpMethod + '' '' + apiPath + apiParams;
		var signingString = requestTarget + ''\\n'' + dateHeader + ''\\n'' + hostHeader;
		var reqHeaders = [contentTypeHeader, dateHeader];

		if (httpMethod === ''post'') {
			var body = JSON.stringify({
				''namespace'': namespace,
				''query'': mql
			});
			headers = headers + '' x-content-sha256 content-type content-length'';
			const bodyHeader = ''x-content-sha256: '' + this.encode(this.hash(body));
			const bodyLengthHeader = ''content-length: '' + body.length;
			signingString = signingString + ''\\n'' + bodyHeader + ''\\n'' + contentTypeHeader + ''\\n'' + bodyLengthHeader;
			reqHeaders.push(bodyHeader, bodyLengthHeader);
		}

		const signature = this.encode(this.sign(signingString));

		reqHeaders.push(''Authorization: Signature version="1",keyId="'' + params[''tenancy_ocid''] + ''/'' + params[''user_ocid''] + ''/'' + params[''fingerprint''] + ''",algorithm="rsa-sha256",headers="'' + headers + ''",signature="'' + signature + ''"'');
		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {
			this.request.addHeader(reqHeaders[header]);
		}

		if (params[''http_proxy'']) {
			this.request.setProxy(params[''http_proxy'']);
			Zabbix.log(4, this.zabbixLogPrefix + '' Using http proxy: '' + params[''http_proxy'']);
		}

		if (httpMethod === ''post'') {
			var apiRateLimitExceeded = false;
			do {
				const response = this.request.post(''https://'' + params[''api_host''] + apiPath + apiParams, body);

				try {
					if (JSON.parse(response)[''code''] === ''TooManyRequests'') {

						apiRateLimitExceeded = true;
						Zabbix.sleep(1000);
					} else {
						apiRateLimitExceeded = false;
					}
				} catch (error) {
					Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the response: '' + JSON.stringify(response));
					throw ''Could not parse the response. See logs for more information.'';
				}
			} while (apiRateLimitExceeded);
		} else {
			const response = this.request.get(''https://'' + params[''api_host''] + apiPath + apiParams);
		}

		this.request.clearHeader();

		if (this.request.getStatus() === parseInt(params[''http_status_code''])) {
			return response;
		} else {
			Zabbix.log(3, this.zabbixLogPrefix + '' Unexpected HTTP response code: '' + this.request.getStatus());
			throw ''Unexpected HTTP response code: '' + this.request.getStatus();
		}
	};

	this.extractData = function (httpMethod, data, keys, compartment) {
		try {
			data = JSON.parse(data);
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the received JSON object: '' + data);
			throw ''Could not parse received JSON object. See logs for more information.'';
		}

		if (typeof keys == ''object'') {
			var returnBuffer = [];
			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {

				var objectBuffer = {};
				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {
					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {
						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];
					} else {
						Zabbix.log(3, this.zabbixLogPrefix + '' Received an unexpected JSON object. Could not get value for key "'' + keys[key] + ''" in JSON: '' + JSON.stringify(data[dataObj]));
						throw ''Received an unexpected JSON object. See logs for more information.'';
					}
				}
				if (typeof compartment != ''undefined'' && compartment != '''') objectBuffer[''compartment''] = compartment;
				returnBuffer.push(objectBuffer);
			}
			return returnBuffer;
		}

		try {
			if (httpMethod === ''get'') {
				return data[keys];
			} else {
				if (data.length === 0) {
					return 0;
				}
				data = data[0][keys];
				return data[data.length - 1][''value''];
			}
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not find key "'' + keys + ''" in JSON: '' + JSON.stringify(data));
			throw ''Could not find required key in JSON object. See logs for more information.'';
		}
	};
}


const params = JSON.parse(value);
validateZabbixParams([''tenancy_ocid'', ''user_ocid'', ''private_key'', ''fingerprint'', ''api_host'', ''volume_id'', ''http_status_code''], params);
var oci = new OCI(''Block volume'', ''Get volume state'', params);

return 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,E'function validateZabbixParams(requiredParams, allParams) {
	requiredParams.forEach(function (field) {
		if (typeof allParams !== ''object'' || typeof allParams[field] === ''undefined'' || allParams[field] === '''') {
			throw ''Required param is not set: '' + field + ''.'';
		}
	});
}

function OCI(service, action, params) {
	this.zabbixLogPrefix = ''[ OCI ] [ '' + service + '' ] [ '' + action + '' ]'';
	this.request = new HttpRequest();

	this.hash = function (string) {
		return sha256(string);
	};

	this.sign = function (string) {
		return sign(''sha256'', params[''private_key''], string);
	};

	this.encode = function (hash) {
		const hexArr = hash.match(/.{1,2}/g);
		var uInt8Array = new Uint8Array(hexArr.length);
		hexArr.forEach(function (hex, idx) {
			uInt8Array[idx] = parseInt(hex, 16);
		});
		return btoa(uInt8Array);
	};

	this.getDate = function () {
		const weekdayShortList = [''Sun'', ''Mon'', ''Tue'', ''Wed'', ''Thu'', ''Fri'', ''Sat''];
		const monthShortList = [''jan'', ''feb'', ''mar'', ''apr'', ''may'', ''jun'', ''jul'', ''aug'', ''sep'', ''oct'', ''nov'', ''dec''];
		const today = new Date();
		return weekdayShortList[today.getUTCDay()] + '', '' + today.getUTCDate() + '' '' + monthShortList[today.getUTCMonth()] + '' '' + today.getUTCFullYear() + '' '' + today.getUTCHours() + '':'' + today.getUTCMinutes() + '':'' + today.getUTCSeconds() + '' GMT'';
	};

	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {
		var headers = ''(request-target) date host'';
		const contentTypeHeader = ''content-type: application/json'';
		const dateHeader = ''date: '' + this.getDate();
		const hostHeader = ''host: '' + params[''api_host''];
		const requestTarget = ''(request-target): '' + httpMethod + '' '' + apiPath + apiParams;
		var signingString = requestTarget + ''\\n'' + dateHeader + ''\\n'' + hostHeader;
		var reqHeaders = [contentTypeHeader, dateHeader];

		if (httpMethod === ''post'') {
			var body = JSON.stringify({
				''namespace'': namespace,
				''query'': mql
			});
			headers = headers + '' x-content-sha256 content-type content-length'';
			const bodyHeader = ''x-content-sha256: '' + this.encode(this.hash(body));
			const bodyLengthHeader = ''content-length: '' + body.length;
			signingString = signingString + ''\\n'' + bodyHeader + ''\\n'' + contentTypeHeader + ''\\n'' + bodyLengthHeader;
			reqHeaders.push(bodyHeader, bodyLengthHeader);
		}

		const signature = this.encode(this.sign(signingString));

		reqHeaders.push(''Authorization: Signature version="1",keyId="'' + params[''tenancy_ocid''] + ''/'' + params[''user_ocid''] + ''/'' + params[''fingerprint''] + ''",algorithm="rsa-sha256",headers="'' + headers + ''",signature="'' + signature + ''"'');
		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {
			this.request.addHeader(reqHeaders[header]);
		}

		if (params[''http_proxy'']) {
			this.request.setProxy(params[''http_proxy'']);
			Zabbix.log(4, this.zabbixLogPrefix + '' Using http proxy: '' + params[''http_proxy'']);
		}

		if (httpMethod === ''post'') {
			var apiRateLimitExceeded = false;
			do {
				const response = this.request.post(''https://'' + params[''api_host''] + apiPath + apiParams, body);

				try {
					if (JSON.parse(response)[''code''] === ''TooManyRequests'') {

						apiRateLimitExceeded = true;
						Zabbix.sleep(1000);
					} else {
						apiRateLimitExceeded = false;
					}
				} catch (error) {
					Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the response: '' + JSON.stringify(response));
					throw ''Could not parse the response. See logs for more information.'';
				}
			} while (apiRateLimitExceeded);
		} else {
			const response = this.request.get(''https://'' + params[''api_host''] + apiPath + apiParams);
		}

		this.request.clearHeader();

		if (this.request.getStatus() === parseInt(params[''http_status_code''])) {
			return response;
		} else {
			Zabbix.log(3, this.zabbixLogPrefix + '' Unexpected HTTP response code: '' + this.request.getStatus());
			throw ''Unexpected HTTP response code: '' + this.request.getStatus();
		}
	};

	this.extractData = function (httpMethod, data, keys, compartment) {
		try {
			data = JSON.parse(data);
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the received JSON object: '' + data);
			throw ''Could not parse received JSON object. See logs for more information.'';
		}

		if (typeof keys == ''object'') {
			var returnBuffer = [];
			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {

				var objectBuffer = {};
				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {
					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {
						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];
					} else {
						Zabbix.log(3, this.zabbixLogPrefix + '' Received an unexpected JSON object. Could not get value for key "'' + keys[key] + ''" in JSON: '' + JSON.stringify(data[dataObj]));
						throw ''Received an unexpected JSON object. See logs for more information.'';
					}
				}
				if (typeof compartment != ''undefined'' && compartment != '''') objectBuffer[''compartment''] = compartment;
				returnBuffer.push(objectBuffer);
			}
			return returnBuffer;
		}

		try {
			if (httpMethod === ''get'') {
				return data[keys];
			} else {
				if (data.length === 0) {
					return 0;
				}
				data = data[0][keys];
				return data[data.length - 1][''value''];
			}
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not find key "'' + keys + ''" in JSON: '' + JSON.stringify(data));
			throw ''Could not find required key in JSON object. See logs for more information.'';
		}
	};
}

function buildMql(id, metrics, defaultStatistic, resourceType) {
	resourceType = resourceType === '''' || resourceType === undefined ? ''resourceId'' : resourceType;
	this.query = ''['' + params[''req_interval''] + ''m]{'' + resourceType + ''='' + id + ''}.'';

	for (var i = 0, metricsLength = metrics.length; i < metricsLength; i++) {
		const metric = ((Array.isArray(metrics[i]) ? metrics[i] : [metrics[i], defaultStatistic]));
		metrics[i] = [metric[0], this.query + metric[1]];
	}
}


const params = JSON.parse(value);
validateZabbixParams([''tenancy_ocid'', ''user_ocid'', ''private_key'', ''fingerprint'', ''api_host'', ''volume_id'', ''http_status_code'', ''req_interval'', ''compartment_id''], params);
var oci = new OCI(''Boot volume'', ''Get metrics'', params);

const metrics = [
	''VolumeReadThroughput'',
	''VolumeWriteThroughput'',
	''VolumeReadOps'',
	''VolumeWriteOps'',
	[''VolumeThrottledIOs'', ''sum''],
	''VolumeGuaranteedVPUsPerGB'',
	''VolumeGuaranteedIOPS'',
	''VolumeGuaranteedThroughput''
];
buildMql(params[''volume_id''], metrics, ''mean'');

var result = {};
for (var i = 0, metricsLength = metrics.length; i < metricsLength; i++) {
	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'');
}
return 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',E'function validateZabbixParams(requiredParams, allParams) {
	requiredParams.forEach(function (field) {
		if (typeof allParams !== ''object'' || typeof allParams[field] === ''undefined'' || allParams[field] === '''') {
			throw ''Required param is not set: '' + field + ''.'';
		}
	});
}

function OCI(service, action, params) {
	this.zabbixLogPrefix = ''[ OCI ] [ '' + service + '' ] [ '' + action + '' ]'';
	this.request = new HttpRequest();

	this.hash = function (string) {
		return sha256(string);
	};

	this.sign = function (string) {
		return sign(''sha256'', params[''private_key''], string);
	};

	this.encode = function (hash) {
		const hexArr = hash.match(/.{1,2}/g);
		var uInt8Array = new Uint8Array(hexArr.length);
		hexArr.forEach(function (hex, idx) {
			uInt8Array[idx] = parseInt(hex, 16);
		});
		return btoa(uInt8Array);
	};

	this.getDate = function () {
		const weekdayShortList = [''Sun'', ''Mon'', ''Tue'', ''Wed'', ''Thu'', ''Fri'', ''Sat''];
		const monthShortList = [''jan'', ''feb'', ''mar'', ''apr'', ''may'', ''jun'', ''jul'', ''aug'', ''sep'', ''oct'', ''nov'', ''dec''];
		const today = new Date();
		return weekdayShortList[today.getUTCDay()] + '', '' + today.getUTCDate() + '' '' + monthShortList[today.getUTCMonth()] + '' '' + today.getUTCFullYear() + '' '' + today.getUTCHours() + '':'' + today.getUTCMinutes() + '':'' + today.getUTCSeconds() + '' GMT'';
	};

	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {
		var headers = ''(request-target) date host'';
		const contentTypeHeader = ''content-type: application/json'';
		const dateHeader = ''date: '' + this.getDate();
		const hostHeader = ''host: '' + params[''api_host''];
		const requestTarget = ''(request-target): '' + httpMethod + '' '' + apiPath + apiParams;
		var signingString = requestTarget + ''\\n'' + dateHeader + ''\\n'' + hostHeader;
		var reqHeaders = [contentTypeHeader, dateHeader];

		if (httpMethod === ''post'') {
			var body = JSON.stringify({
				''namespace'': namespace,
				''query'': mql
			});
			headers = headers + '' x-content-sha256 content-type content-length'';
			const bodyHeader = ''x-content-sha256: '' + this.encode(this.hash(body));
			const bodyLengthHeader = ''content-length: '' + body.length;
			signingString = signingString + ''\\n'' + bodyHeader + ''\\n'' + contentTypeHeader + ''\\n'' + bodyLengthHeader;
			reqHeaders.push(bodyHeader, bodyLengthHeader);
		}

		const signature = this.encode(this.sign(signingString));

		reqHeaders.push(''Authorization: Signature version="1",keyId="'' + params[''tenancy_ocid''] + ''/'' + params[''user_ocid''] + ''/'' + params[''fingerprint''] + ''",algorithm="rsa-sha256",headers="'' + headers + ''",signature="'' + signature + ''"'');
		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {
			this.request.addHeader(reqHeaders[header]);
		}

		if (params[''http_proxy'']) {
			this.request.setProxy(params[''http_proxy'']);
			Zabbix.log(4, this.zabbixLogPrefix + '' Using http proxy: '' + params[''http_proxy'']);
		}

		if (httpMethod === ''post'') {
			var apiRateLimitExceeded = false;
			do {
				const response = this.request.post(''https://'' + params[''api_host''] + apiPath + apiParams, body);

				try {
					if (JSON.parse(response)[''code''] === ''TooManyRequests'') {

						apiRateLimitExceeded = true;
						Zabbix.sleep(1000);
					} else {
						apiRateLimitExceeded = false;
					}
				} catch (error) {
					Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the response: '' + JSON.stringify(response));
					throw ''Could not parse the response. See logs for more information.'';
				}
			} while (apiRateLimitExceeded);
		} else {
			const response = this.request.get(''https://'' + params[''api_host''] + apiPath + apiParams);
		}

		this.request.clearHeader();

		if (this.request.getStatus() === parseInt(params[''http_status_code''])) {
			return response;
		} else {
			Zabbix.log(3, this.zabbixLogPrefix + '' Unexpected HTTP response code: '' + this.request.getStatus());
			throw ''Unexpected HTTP response code: '' + this.request.getStatus();
		}
	};

	this.extractData = function (httpMethod, data, keys, compartment) {
		try {
			data = JSON.parse(data);
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the received JSON object: '' + data);
			throw ''Could not parse received JSON object. See logs for more information.'';
		}

		if (typeof keys == ''object'') {
			var returnBuffer = [];
			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {

				var objectBuffer = {};
				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {
					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {
						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];
					} else {
						Zabbix.log(3, this.zabbixLogPrefix + '' Received an unexpected JSON object. Could not get value for key "'' + keys[key] + ''" in JSON: '' + JSON.stringify(data[dataObj]));
						throw ''Received an unexpected JSON object. See logs for more information.'';
					}
				}
				if (typeof compartment != ''undefined'' && compartment != '''') objectBuffer[''compartment''] = compartment;
				returnBuffer.push(objectBuffer);
			}
			return returnBuffer;
		}

		try {
			if (httpMethod === ''get'') {
				return data[keys];
			} else {
				if (data.length === 0) {
					return 0;
				}
				data = data[0][keys];
				return data[data.length - 1][''value''];
			}
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not find key "'' + keys + ''" in JSON: '' + JSON.stringify(data));
			throw ''Could not find required key in JSON object. See logs for more information.'';
		}
	};
}


const params = JSON.parse(value);
validateZabbixParams([''tenancy_ocid'', ''user_ocid'', ''private_key'', ''fingerprint'', ''api_host'', ''volume_id'', ''http_status_code''], params);
var oci = new OCI(''Boot volume'', ''Get volume state'', params);

return 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',E'function validateZabbixParams(requiredParams, allParams) {
	requiredParams.forEach(function (field) {
		if (typeof allParams !== ''object'' || typeof allParams[field] === ''undefined'' || allParams[field] === '''') {
			throw ''Required param is not set: '' + field + ''.'';
		}
	});
}

function OCI(service, action, params) {
	this.zabbixLogPrefix = ''[ OCI ] [ '' + service + '' ] [ '' + action + '' ]'';
	this.request = new HttpRequest();

	this.hash = function (string) {
		return sha256(string);
	};

	this.sign = function (string) {
		return sign(''sha256'', params[''private_key''], string);
	};

	this.encode = function (hash) {
		const hexArr = hash.match(/.{1,2}/g);
		var uInt8Array = new Uint8Array(hexArr.length);
		hexArr.forEach(function (hex, idx) {
			uInt8Array[idx] = parseInt(hex, 16);
		});
		return btoa(uInt8Array);
	};

	this.getDate = function () {
		const weekdayShortList = [''Sun'', ''Mon'', ''Tue'', ''Wed'', ''Thu'', ''Fri'', ''Sat''];
		const monthShortList = [''jan'', ''feb'', ''mar'', ''apr'', ''may'', ''jun'', ''jul'', ''aug'', ''sep'', ''oct'', ''nov'', ''dec''];
		const today = new Date();
		return weekdayShortList[today.getUTCDay()] + '', '' + today.getUTCDate() + '' '' + monthShortList[today.getUTCMonth()] + '' '' + today.getUTCFullYear() + '' '' + today.getUTCHours() + '':'' + today.getUTCMinutes() + '':'' + today.getUTCSeconds() + '' GMT'';
	};

	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {
		var headers = ''(request-target) date host'';
		const contentTypeHeader = ''content-type: application/json'';
		const dateHeader = ''date: '' + this.getDate();
		const hostHeader = ''host: '' + params[''api_host''];
		const requestTarget = ''(request-target): '' + httpMethod + '' '' + apiPath + apiParams;
		var signingString = requestTarget + ''\\n'' + dateHeader + ''\\n'' + hostHeader;
		var reqHeaders = [contentTypeHeader, dateHeader];

		if (httpMethod === ''post'') {
			var body = JSON.stringify({
				''namespace'': namespace,
				''query'': mql
			});
			headers = headers + '' x-content-sha256 content-type content-length'';
			const bodyHeader = ''x-content-sha256: '' + this.encode(this.hash(body));
			const bodyLengthHeader = ''content-length: '' + body.length;
			signingString = signingString + ''\\n'' + bodyHeader + ''\\n'' + contentTypeHeader + ''\\n'' + bodyLengthHeader;
			reqHeaders.push(bodyHeader, bodyLengthHeader);
		}

		const signature = this.encode(this.sign(signingString));

		reqHeaders.push(''Authorization: Signature version="1",keyId="'' + params[''tenancy_ocid''] + ''/'' + params[''user_ocid''] + ''/'' + params[''fingerprint''] + ''",algorithm="rsa-sha256",headers="'' + headers + ''",signature="'' + signature + ''"'');
		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {
			this.request.addHeader(reqHeaders[header]);
		}

		if (params[''http_proxy'']) {
			this.request.setProxy(params[''http_proxy'']);
			Zabbix.log(4, this.zabbixLogPrefix + '' Using http proxy: '' + params[''http_proxy'']);
		}

		if (httpMethod === ''post'') {
			var apiRateLimitExceeded = false;
			do {
				const response = this.request.post(''https://'' + params[''api_host''] + apiPath + apiParams, body);

				try {
					if (JSON.parse(response)[''code''] === ''TooManyRequests'') {

						apiRateLimitExceeded = true;
						Zabbix.sleep(1000);
					} else {
						apiRateLimitExceeded = false;
					}
				} catch (error) {
					Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the response: '' + JSON.stringify(response));
					throw ''Could not parse the response. See logs for more information.'';
				}
			} while (apiRateLimitExceeded);
		} else {
			const response = this.request.get(''https://'' + params[''api_host''] + apiPath + apiParams);
		}

		this.request.clearHeader();

		if (this.request.getStatus() === parseInt(params[''http_status_code''])) {
			return response;
		} else {
			Zabbix.log(3, this.zabbixLogPrefix + '' Unexpected HTTP response code: '' + this.request.getStatus());
			throw ''Unexpected HTTP response code: '' + this.request.getStatus();
		}
	};

	this.extractData = function (httpMethod, data, keys, compartment) {
		try {
			data = JSON.parse(data);
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the received JSON object: '' + data);
			throw ''Could not parse received JSON object. See logs for more information.'';
		}

		if (typeof keys == ''object'') {
			var returnBuffer = [];
			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {

				var objectBuffer = {};
				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {
					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {
						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];
					} else {
						Zabbix.log(3, this.zabbixLogPrefix + '' Received an unexpected JSON object. Could not get value for key "'' + keys[key] + ''" in JSON: '' + JSON.stringify(data[dataObj]));
						throw ''Received an unexpected JSON object. See logs for more information.'';
					}
				}
				if (typeof compartment != ''undefined'' && compartment != '''') objectBuffer[''compartment''] = compartment;
				returnBuffer.push(objectBuffer);
			}
			return returnBuffer;
		}

		try {
			if (httpMethod === ''get'') {
				return data[keys];
			} else {
				if (data.length === 0) {
					return 0;
				}
				data = data[0][keys];
				return data[data.length - 1][''value''];
			}
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not find key "'' + keys + ''" in JSON: '' + JSON.stringify(data));
			throw ''Could not find required key in JSON object. See logs for more information.'';
		}
	};
}


const params = JSON.parse(value);
validateZabbixParams([''tenancy_ocid'', ''user_ocid'', ''private_key'', ''fingerprint'', ''api_host'', ''instance_id'', ''http_status_code'', ''req_interval'', ''compartment_id''], params);
var oci = new OCI(''Compute'', ''Get health'', params);
const mql = ''InstanceAccessibilityStatus['' + params[''req_interval''] + ''m]{resourceId='' + params[''instance_id''] + ''}.max()'';

return 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. A value of "1" indicates that the instance is unresponsive due to an issue with the infrastructure or the instance itself. A value of "0" indicates that an accessibility issue has not been detected. If 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,E'function validateZabbixParams(requiredParams, allParams) {
	requiredParams.forEach(function (field) {
		if (typeof allParams !== ''object'' || typeof allParams[field] === ''undefined'' || allParams[field] === '''') {
			throw ''Required param is not set: '' + field + ''.'';
		}
	});
}

function OCI(service, action, params) {
	this.zabbixLogPrefix = ''[ OCI ] [ '' + service + '' ] [ '' + action + '' ]'';
	this.request = new HttpRequest();

	this.hash = function (string) {
		return sha256(string);
	};

	this.sign = function (string) {
		return sign(''sha256'', params[''private_key''], string);
	};

	this.encode = function (hash) {
		const hexArr = hash.match(/.{1,2}/g);
		var uInt8Array = new Uint8Array(hexArr.length);
		hexArr.forEach(function (hex, idx) {
			uInt8Array[idx] = parseInt(hex, 16);
		});
		return btoa(uInt8Array);
	};

	this.getDate = function () {
		const weekdayShortList = [''Sun'', ''Mon'', ''Tue'', ''Wed'', ''Thu'', ''Fri'', ''Sat''];
		const monthShortList = [''jan'', ''feb'', ''mar'', ''apr'', ''may'', ''jun'', ''jul'', ''aug'', ''sep'', ''oct'', ''nov'', ''dec''];
		const today = new Date();
		return weekdayShortList[today.getUTCDay()] + '', '' + today.getUTCDate() + '' '' + monthShortList[today.getUTCMonth()] + '' '' + today.getUTCFullYear() + '' '' + today.getUTCHours() + '':'' + today.getUTCMinutes() + '':'' + today.getUTCSeconds() + '' GMT'';
	};

	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {
		var headers = ''(request-target) date host'';
		const contentTypeHeader = ''content-type: application/json'';
		const dateHeader = ''date: '' + this.getDate();
		const hostHeader = ''host: '' + params[''api_host''];
		const requestTarget = ''(request-target): '' + httpMethod + '' '' + apiPath + apiParams;
		var signingString = requestTarget + ''\\n'' + dateHeader + ''\\n'' + hostHeader;
		var reqHeaders = [contentTypeHeader, dateHeader];

		if (httpMethod === ''post'') {
			var body = JSON.stringify({
				''namespace'': namespace,
				''query'': mql
			});
			headers = headers + '' x-content-sha256 content-type content-length'';
			const bodyHeader = ''x-content-sha256: '' + this.encode(this.hash(body));
			const bodyLengthHeader = ''content-length: '' + body.length;
			signingString = signingString + ''\\n'' + bodyHeader + ''\\n'' + contentTypeHeader + ''\\n'' + bodyLengthHeader;
			reqHeaders.push(bodyHeader, bodyLengthHeader);
		}

		const signature = this.encode(this.sign(signingString));

		reqHeaders.push(''Authorization: Signature version="1",keyId="'' + params[''tenancy_ocid''] + ''/'' + params[''user_ocid''] + ''/'' + params[''fingerprint''] + ''",algorithm="rsa-sha256",headers="'' + headers + ''",signature="'' + signature + ''"'');
		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {
			this.request.addHeader(reqHeaders[header]);
		}

		if (params[''http_proxy'']) {
			this.request.setProxy(params[''http_proxy'']);
			Zabbix.log(4, this.zabbixLogPrefix + '' Using http proxy: '' + params[''http_proxy'']);
		}

		if (httpMethod === ''post'') {
			var apiRateLimitExceeded = false;
			do {
				const response = this.request.post(''https://'' + params[''api_host''] + apiPath + apiParams, body);

				try {
					if (JSON.parse(response)[''code''] === ''TooManyRequests'') {

						apiRateLimitExceeded = true;
						Zabbix.sleep(1000);
					} else {
						apiRateLimitExceeded = false;
					}
				} catch (error) {
					Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the response: '' + JSON.stringify(response));
					throw ''Could not parse the response. See logs for more information.'';
				}
			} while (apiRateLimitExceeded);
		} else {
			const response = this.request.get(''https://'' + params[''api_host''] + apiPath + apiParams);
		}

		this.request.clearHeader();

		if (this.request.getStatus() === parseInt(params[''http_status_code''])) {
			return response;
		} else {
			Zabbix.log(3, this.zabbixLogPrefix + '' Unexpected HTTP response code: '' + this.request.getStatus());
			throw ''Unexpected HTTP response code: '' + this.request.getStatus();
		}
	};

	this.extractData = function (httpMethod, data, keys, compartment) {
		try {
			data = JSON.parse(data);
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the received JSON object: '' + data);
			throw ''Could not parse received JSON object. See logs for more information.'';
		}

		if (typeof keys == ''object'') {
			var returnBuffer = [];
			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {

				var objectBuffer = {};
				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {
					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {
						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];
					} else {
						Zabbix.log(3, this.zabbixLogPrefix + '' Received an unexpected JSON object. Could not get value for key "'' + keys[key] + ''" in JSON: '' + JSON.stringify(data[dataObj]));
						throw ''Received an unexpected JSON object. See logs for more information.'';
					}
				}
				if (typeof compartment != ''undefined'' && compartment != '''') objectBuffer[''compartment''] = compartment;
				returnBuffer.push(objectBuffer);
			}
			return returnBuffer;
		}

		try {
			if (httpMethod === ''get'') {
				return data[keys];
			} else {
				if (data.length === 0) {
					return 0;
				}
				data = data[0][keys];
				return data[data.length - 1][''value''];
			}
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not find key "'' + keys + ''" in JSON: '' + JSON.stringify(data));
			throw ''Could not find required key in JSON object. See logs for more information.'';
		}
	};
}

function buildMql(id, metrics, defaultStatistic, resourceType) {
	resourceType = resourceType === '''' || resourceType === undefined ? ''resourceId'' : resourceType;
	this.query = ''['' + params[''req_interval''] + ''m]{'' + resourceType + ''='' + id + ''}.'';

	for (var i = 0, metricsLength = metrics.length; i < metricsLength; i++) {
		const metric = ((Array.isArray(metrics[i]) ? metrics[i] : [metrics[i], defaultStatistic]));
		metrics[i] = [metric[0], this.query + metric[1]];
	}
}


const params = JSON.parse(value);
validateZabbixParams([''tenancy_ocid'', ''user_ocid'', ''private_key'', ''fingerprint'', ''api_host'', ''instance_id'', ''http_status_code'', ''req_interval'', ''compartment_id''], params);
var oci = new OCI(''Compute'', ''Get metrics'', params);

const metrics = [
	[''CpuUtilization'', ''mean''],
	[''MemoryUtilization'', ''mean''],
	[''LoadAverage'', ''mean''],
	[''MemoryAllocationStalls'', ''mean''],
	''DiskBytesRead'',
	''DiskBytesWritten'',
	''DiskIopsRead'',
	''DiskIopsWritten'',
	''NetworksBytesIn'',
	''NetworksBytesOut''
];
buildMql(params[''instance_id''], metrics, ''rate'');

var result = {};
for (var i = 0, metricsLength = metrics.length; i < metricsLength; i++) {
	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'');
}
return 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',E'function validateZabbixParams(requiredParams, allParams) {
	requiredParams.forEach(function (field) {
		if (typeof allParams !== ''object'' || typeof allParams[field] === ''undefined'' || allParams[field] === '''') {
			throw ''Required param is not set: '' + field + ''.'';
		}
	});
}

function OCI(service, action, params) {
	this.zabbixLogPrefix = ''[ OCI ] [ '' + service + '' ] [ '' + action + '' ]'';
	this.request = new HttpRequest();

	this.hash = function (string) {
		return sha256(string);
	};

	this.sign = function (string) {
		return sign(''sha256'', params[''private_key''], string);
	};

	this.encode = function (hash) {
		const hexArr = hash.match(/.{1,2}/g);
		var uInt8Array = new Uint8Array(hexArr.length);
		hexArr.forEach(function (hex, idx) {
			uInt8Array[idx] = parseInt(hex, 16);
		});
		return btoa(uInt8Array);
	};

	this.getDate = function () {
		const weekdayShortList = [''Sun'', ''Mon'', ''Tue'', ''Wed'', ''Thu'', ''Fri'', ''Sat''];
		const monthShortList = [''jan'', ''feb'', ''mar'', ''apr'', ''may'', ''jun'', ''jul'', ''aug'', ''sep'', ''oct'', ''nov'', ''dec''];
		const today = new Date();
		return weekdayShortList[today.getUTCDay()] + '', '' + today.getUTCDate() + '' '' + monthShortList[today.getUTCMonth()] + '' '' + today.getUTCFullYear() + '' '' + today.getUTCHours() + '':'' + today.getUTCMinutes() + '':'' + today.getUTCSeconds() + '' GMT'';
	};

	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {
		var headers = ''(request-target) date host'';
		const contentTypeHeader = ''content-type: application/json'';
		const dateHeader = ''date: '' + this.getDate();
		const hostHeader = ''host: '' + params[''api_host''];
		const requestTarget = ''(request-target): '' + httpMethod + '' '' + apiPath + apiParams;
		var signingString = requestTarget + ''\\n'' + dateHeader + ''\\n'' + hostHeader;
		var reqHeaders = [contentTypeHeader, dateHeader];

		if (httpMethod === ''post'') {
			var body = JSON.stringify({
				''namespace'': namespace,
				''query'': mql
			});
			headers = headers + '' x-content-sha256 content-type content-length'';
			const bodyHeader = ''x-content-sha256: '' + this.encode(this.hash(body));
			const bodyLengthHeader = ''content-length: '' + body.length;
			signingString = signingString + ''\\n'' + bodyHeader + ''\\n'' + contentTypeHeader + ''\\n'' + bodyLengthHeader;
			reqHeaders.push(bodyHeader, bodyLengthHeader);
		}

		const signature = this.encode(this.sign(signingString));

		reqHeaders.push(''Authorization: Signature version="1",keyId="'' + params[''tenancy_ocid''] + ''/'' + params[''user_ocid''] + ''/'' + params[''fingerprint''] + ''",algorithm="rsa-sha256",headers="'' + headers + ''",signature="'' + signature + ''"'');
		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {
			this.request.addHeader(reqHeaders[header]);
		}

		if (params[''http_proxy'']) {
			this.request.setProxy(params[''http_proxy'']);
			Zabbix.log(4, this.zabbixLogPrefix + '' Using http proxy: '' + params[''http_proxy'']);
		}

		if (httpMethod === ''post'') {
			var apiRateLimitExceeded = false;
			do {
				const response = this.request.post(''https://'' + params[''api_host''] + apiPath + apiParams, body);

				try {
					if (JSON.parse(response)[''code''] === ''TooManyRequests'') {

						apiRateLimitExceeded = true;
						Zabbix.sleep(1000);
					} else {
						apiRateLimitExceeded = false;
					}
				} catch (error) {
					Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the response: '' + JSON.stringify(response));
					throw ''Could not parse the response. See logs for more information.'';
				}
			} while (apiRateLimitExceeded);
		} else {
			const response = this.request.get(''https://'' + params[''api_host''] + apiPath + apiParams);
		}

		this.request.clearHeader();

		if (this.request.getStatus() === parseInt(params[''http_status_code''])) {
			return response;
		} else {
			Zabbix.log(3, this.zabbixLogPrefix + '' Unexpected HTTP response code: '' + this.request.getStatus());
			throw ''Unexpected HTTP response code: '' + this.request.getStatus();
		}
	};

	this.extractData = function (httpMethod, data, keys, compartment) {
		try {
			data = JSON.parse(data);
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the received JSON object: '' + data);
			throw ''Could not parse received JSON object. See logs for more information.'';
		}

		if (typeof keys == ''object'') {
			var returnBuffer = [];
			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {

				var objectBuffer = {};
				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {
					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {
						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];
					} else {
						Zabbix.log(3, this.zabbixLogPrefix + '' Received an unexpected JSON object. Could not get value for key "'' + keys[key] + ''" in JSON: '' + JSON.stringify(data[dataObj]));
						throw ''Received an unexpected JSON object. See logs for more information.'';
					}
				}
				if (typeof compartment != ''undefined'' && compartment != '''') objectBuffer[''compartment''] = compartment;
				returnBuffer.push(objectBuffer);
			}
			return returnBuffer;
		}

		try {
			if (httpMethod === ''get'') {
				return data[keys];
			} else {
				if (data.length === 0) {
					return 0;
				}
				data = data[0][keys];
				return data[data.length - 1][''value''];
			}
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not find key "'' + keys + ''" in JSON: '' + JSON.stringify(data));
			throw ''Could not find required key in JSON object. See logs for more information.'';
		}
	};
}


const params = JSON.parse(value);
validateZabbixParams([''tenancy_ocid'', ''user_ocid'', ''private_key'', ''fingerprint'', ''api_host'', ''instance_id'', ''http_status_code''], params);
var oci = new OCI(''Compute'', ''Get state'', params);

return 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,E'function validateZabbixParams(requiredParams, allParams) {
	requiredParams.forEach(function (field) {
		if (typeof allParams !== ''object'' || typeof allParams[field] === ''undefined'' || allParams[field] === '''') {
			throw ''Required param is not set: '' + field + ''.'';
		}
	});
}

function OCI(service, action, params) {
	this.zabbixLogPrefix = ''[ OCI ] [ '' + service + '' ] [ '' + action + '' ]'';
	this.request = new HttpRequest();

	this.hash = function (string) {
		return sha256(string);
	};

	this.sign = function (string) {
		return sign(''sha256'', params[''private_key''], string);
	};

	this.encode = function (hash) {
		const hexArr = hash.match(/.{1,2}/g);
		var uInt8Array = new Uint8Array(hexArr.length);
		hexArr.forEach(function (hex, idx) {
			uInt8Array[idx] = parseInt(hex, 16);
		});
		return btoa(uInt8Array);
	};

	this.getDate = function () {
		const weekdayShortList = [''Sun'', ''Mon'', ''Tue'', ''Wed'', ''Thu'', ''Fri'', ''Sat''];
		const monthShortList = [''jan'', ''feb'', ''mar'', ''apr'', ''may'', ''jun'', ''jul'', ''aug'', ''sep'', ''oct'', ''nov'', ''dec''];
		const today = new Date();
		return weekdayShortList[today.getUTCDay()] + '', '' + today.getUTCDate() + '' '' + monthShortList[today.getUTCMonth()] + '' '' + today.getUTCFullYear() + '' '' + today.getUTCHours() + '':'' + today.getUTCMinutes() + '':'' + today.getUTCSeconds() + '' GMT'';
	};

	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {
		var headers = ''(request-target) date host'';
		const contentTypeHeader = ''content-type: application/json'';
		const dateHeader = ''date: '' + this.getDate();
		const hostHeader = ''host: '' + params[''api_host''];
		const requestTarget = ''(request-target): '' + httpMethod + '' '' + apiPath + apiParams;
		var signingString = requestTarget + ''\\n'' + dateHeader + ''\\n'' + hostHeader;
		var reqHeaders = [contentTypeHeader, dateHeader];

		if (httpMethod === ''post'') {
			var body = JSON.stringify({
				''namespace'': namespace,
				''query'': mql
			});
			headers = headers + '' x-content-sha256 content-type content-length'';
			const bodyHeader = ''x-content-sha256: '' + this.encode(this.hash(body));
			const bodyLengthHeader = ''content-length: '' + body.length;
			signingString = signingString + ''\\n'' + bodyHeader + ''\\n'' + contentTypeHeader + ''\\n'' + bodyLengthHeader;
			reqHeaders.push(bodyHeader, bodyLengthHeader);
		}

		const signature = this.encode(this.sign(signingString));

		reqHeaders.push(''Authorization: Signature version="1",keyId="'' + params[''tenancy_ocid''] + ''/'' + params[''user_ocid''] + ''/'' + params[''fingerprint''] + ''",algorithm="rsa-sha256",headers="'' + headers + ''",signature="'' + signature + ''"'');
		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {
			this.request.addHeader(reqHeaders[header]);
		}

		if (params[''http_proxy'']) {
			this.request.setProxy(params[''http_proxy'']);
			Zabbix.log(4, this.zabbixLogPrefix + '' Using http proxy: '' + params[''http_proxy'']);
		}

		if (httpMethod === ''post'') {
			var apiRateLimitExceeded = false;
			do {
				const response = this.request.post(''https://'' + params[''api_host''] + apiPath + apiParams, body);

				try {
					if (JSON.parse(response)[''code''] === ''TooManyRequests'') {

						apiRateLimitExceeded = true;
						Zabbix.sleep(1000);
					} else {
						apiRateLimitExceeded = false;
					}
				} catch (error) {
					Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the response: '' + JSON.stringify(response));
					throw ''Could not parse the response. See logs for more information.'';
				}
			} while (apiRateLimitExceeded);
		} else {
			const response = this.request.get(''https://'' + params[''api_host''] + apiPath + apiParams);
		}

		this.request.clearHeader();

		if (this.request.getStatus() === parseInt(params[''http_status_code''])) {
			return response;
		} else {
			Zabbix.log(3, this.zabbixLogPrefix + '' Unexpected HTTP response code: '' + this.request.getStatus());
			throw ''Unexpected HTTP response code: '' + this.request.getStatus();
		}
	};

	this.extractData = function (httpMethod, data, keys, compartment) {
		try {
			data = JSON.parse(data);
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the received JSON object: '' + data);
			throw ''Could not parse received JSON object. See logs for more information.'';
		}

		if (typeof keys == ''object'') {
			var returnBuffer = [];
			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {

				var objectBuffer = {};
				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {
					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {
						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];
					} else {
						Zabbix.log(3, this.zabbixLogPrefix + '' Received an unexpected JSON object. Could not get value for key "'' + keys[key] + ''" in JSON: '' + JSON.stringify(data[dataObj]));
						throw ''Received an unexpected JSON object. See logs for more information.'';
					}
				}
				if (typeof compartment != ''undefined'' && compartment != '''') objectBuffer[''compartment''] = compartment;
				returnBuffer.push(objectBuffer);
			}
			return returnBuffer;
		}

		try {
			if (httpMethod === ''get'') {
				return data[keys];
			} else {
				if (data.length === 0) {
					return 0;
				}
				data = data[0][keys];
				return data[data.length - 1][''value''];
			}
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not find key "'' + keys + ''" in JSON: '' + JSON.stringify(data));
			throw ''Could not find required key in JSON object. See logs for more information.'';
		}
	};
}


const params = JSON.parse(value);
validateZabbixParams([''tenancy_ocid'', ''user_ocid'', ''private_key'', ''fingerprint'', ''api_host'', ''instance_id'', ''availability_domain'', ''http_status_code'', ''compartment_id''], params);
var oci = new OCI(''Compute'', ''Get VNICs'', params);

return 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',E'function validateZabbixParams(requiredParams, allParams) {
	requiredParams.forEach(function (field) {
		if (typeof allParams !== ''object'' || typeof allParams[field] === ''undefined'' || allParams[field] === '''') {
			throw ''Required param is not set: '' + field + ''.'';
		}
	});
}

function OCI(service, action, params) {
	this.zabbixLogPrefix = ''[ OCI ] [ '' + service + '' ] [ '' + action + '' ]'';
	this.request = new HttpRequest();

	this.hash = function (string) {
		return sha256(string);
	};

	this.sign = function (string) {
		return sign(''sha256'', params[''private_key''], string);
	};

	this.encode = function (hash) {
		const hexArr = hash.match(/.{1,2}/g);
		var uInt8Array = new Uint8Array(hexArr.length);
		hexArr.forEach(function (hex, idx) {
			uInt8Array[idx] = parseInt(hex, 16);
		});
		return btoa(uInt8Array);
	};

	this.getDate = function () {
		const weekdayShortList = [''Sun'', ''Mon'', ''Tue'', ''Wed'', ''Thu'', ''Fri'', ''Sat''];
		const monthShortList = [''jan'', ''feb'', ''mar'', ''apr'', ''may'', ''jun'', ''jul'', ''aug'', ''sep'', ''oct'', ''nov'', ''dec''];
		const today = new Date();
		return weekdayShortList[today.getUTCDay()] + '', '' + today.getUTCDate() + '' '' + monthShortList[today.getUTCMonth()] + '' '' + today.getUTCFullYear() + '' '' + today.getUTCHours() + '':'' + today.getUTCMinutes() + '':'' + today.getUTCSeconds() + '' GMT'';
	};

	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {
		var headers = ''(request-target) date host'';
		const contentTypeHeader = ''content-type: application/json'';
		const dateHeader = ''date: '' + this.getDate();
		const hostHeader = ''host: '' + params[''api_host''];
		const requestTarget = ''(request-target): '' + httpMethod + '' '' + apiPath + apiParams;
		var signingString = requestTarget + ''\\n'' + dateHeader + ''\\n'' + hostHeader;
		var reqHeaders = [contentTypeHeader, dateHeader];

		if (httpMethod === ''post'') {
			var body = JSON.stringify({
				''namespace'': namespace,
				''query'': mql
			});
			headers = headers + '' x-content-sha256 content-type content-length'';
			const bodyHeader = ''x-content-sha256: '' + this.encode(this.hash(body));
			const bodyLengthHeader = ''content-length: '' + body.length;
			signingString = signingString + ''\\n'' + bodyHeader + ''\\n'' + contentTypeHeader + ''\\n'' + bodyLengthHeader;
			reqHeaders.push(bodyHeader, bodyLengthHeader);
		}

		const signature = this.encode(this.sign(signingString));

		reqHeaders.push(''Authorization: Signature version="1",keyId="'' + params[''tenancy_ocid''] + ''/'' + params[''user_ocid''] + ''/'' + params[''fingerprint''] + ''",algorithm="rsa-sha256",headers="'' + headers + ''",signature="'' + signature + ''"'');
		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {
			this.request.addHeader(reqHeaders[header]);
		}

		if (params[''http_proxy'']) {
			this.request.setProxy(params[''http_proxy'']);
			Zabbix.log(4, this.zabbixLogPrefix + '' Using http proxy: '' + params[''http_proxy'']);
		}

		if (httpMethod === ''post'') {
			var apiRateLimitExceeded = false;
			do {
				const response = this.request.post(''https://'' + params[''api_host''] + apiPath + apiParams, body);

				try {
					if (JSON.parse(response)[''code''] === ''TooManyRequests'') {

						apiRateLimitExceeded = true;
						Zabbix.sleep(1000);
					} else {
						apiRateLimitExceeded = false;
					}
				} catch (error) {
					Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the response: '' + JSON.stringify(response));
					throw ''Could not parse the response. See logs for more information.'';
				}
			} while (apiRateLimitExceeded);
		} else {
			const response = this.request.get(''https://'' + params[''api_host''] + apiPath + apiParams);
		}

		this.request.clearHeader();

		if (this.request.getStatus() === parseInt(params[''http_status_code''])) {
			return response;
		} else {
			Zabbix.log(3, this.zabbixLogPrefix + '' Unexpected HTTP response code: '' + this.request.getStatus());
			throw ''Unexpected HTTP response code: '' + this.request.getStatus();
		}
	};

	this.extractData = function (httpMethod, data, keys, compartment) {
		try {
			data = JSON.parse(data);
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the received JSON object: '' + data);
			throw ''Could not parse received JSON object. See logs for more information.'';
		}

		if (typeof keys == ''object'') {
			var returnBuffer = [];
			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {

				var objectBuffer = {};
				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {
					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {
						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];
					} else {
						Zabbix.log(3, this.zabbixLogPrefix + '' Received an unexpected JSON object. Could not get value for key "'' + keys[key] + ''" in JSON: '' + JSON.stringify(data[dataObj]));
						throw ''Received an unexpected JSON object. See logs for more information.'';
					}
				}
				if (typeof compartment != ''undefined'' && compartment != '''') objectBuffer[''compartment''] = compartment;
				returnBuffer.push(objectBuffer);
			}
			return returnBuffer;
		}

		try {
			if (httpMethod === ''get'') {
				return data[keys];
			} else {
				if (data.length === 0) {
					return 0;
				}
				data = data[0][keys];
				return data[data.length - 1][''value''];
			}
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not find key "'' + keys + ''" in JSON: '' + JSON.stringify(data));
			throw ''Could not find required key in JSON object. See logs for more information.'';
		}
	};
}


const params = JSON.parse(value);
validateZabbixParams([''tenancy_ocid'', ''user_ocid'', ''private_key'', ''fingerprint'', ''api_host'', ''vcn_id'', ''http_status_code''], params);
var oci = new OCI(''VCN'', ''Get VCN status'', params);

return 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,E'function validateZabbixParams(requiredParams, allParams) {
	requiredParams.forEach(function (field) {
		if (typeof allParams !== ''object'' || typeof allParams[field] === ''undefined'' || allParams[field] === '''') {
			throw ''Required param is not set: '' + field + ''.'';
		}
	});
}

function OCI(service, action, params) {
	this.zabbixLogPrefix = ''[ OCI ] [ '' + service + '' ] [ '' + action + '' ]'';
	this.request = new HttpRequest();

	this.hash = function (string) {
		return sha256(string);
	};

	this.sign = function (string) {
		return sign(''sha256'', params[''private_key''], string);
	};

	this.encode = function (hash) {
		const hexArr = hash.match(/.{1,2}/g);
		var uInt8Array = new Uint8Array(hexArr.length);
		hexArr.forEach(function (hex, idx) {
			uInt8Array[idx] = parseInt(hex, 16);
		});
		return btoa(uInt8Array);
	};

	this.getDate = function () {
		const weekdayShortList = [''Sun'', ''Mon'', ''Tue'', ''Wed'', ''Thu'', ''Fri'', ''Sat''];
		const monthShortList = [''jan'', ''feb'', ''mar'', ''apr'', ''may'', ''jun'', ''jul'', ''aug'', ''sep'', ''oct'', ''nov'', ''dec''];
		const today = new Date();
		return weekdayShortList[today.getUTCDay()] + '', '' + today.getUTCDate() + '' '' + monthShortList[today.getUTCMonth()] + '' '' + today.getUTCFullYear() + '' '' + today.getUTCHours() + '':'' + today.getUTCMinutes() + '':'' + today.getUTCSeconds() + '' GMT'';
	};

	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {
		var headers = ''(request-target) date host'';
		const contentTypeHeader = ''content-type: application/json'';
		const dateHeader = ''date: '' + this.getDate();
		const hostHeader = ''host: '' + params[''api_host''];
		const requestTarget = ''(request-target): '' + httpMethod + '' '' + apiPath + apiParams;
		var signingString = requestTarget + ''\\n'' + dateHeader + ''\\n'' + hostHeader;
		var reqHeaders = [contentTypeHeader, dateHeader];

		if (httpMethod === ''post'') {
			var body = JSON.stringify({
				''namespace'': namespace,
				''query'': mql
			});
			headers = headers + '' x-content-sha256 content-type content-length'';
			const bodyHeader = ''x-content-sha256: '' + this.encode(this.hash(body));
			const bodyLengthHeader = ''content-length: '' + body.length;
			signingString = signingString + ''\\n'' + bodyHeader + ''\\n'' + contentTypeHeader + ''\\n'' + bodyLengthHeader;
			reqHeaders.push(bodyHeader, bodyLengthHeader);
		}

		const signature = this.encode(this.sign(signingString));

		reqHeaders.push(''Authorization: Signature version="1",keyId="'' + params[''tenancy_ocid''] + ''/'' + params[''user_ocid''] + ''/'' + params[''fingerprint''] + ''",algorithm="rsa-sha256",headers="'' + headers + ''",signature="'' + signature + ''"'');
		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {
			this.request.addHeader(reqHeaders[header]);
		}

		if (params[''http_proxy'']) {
			this.request.setProxy(params[''http_proxy'']);
			Zabbix.log(4, this.zabbixLogPrefix + '' Using http proxy: '' + params[''http_proxy'']);
		}

		if (httpMethod === ''post'') {
			var apiRateLimitExceeded = false;
			do {
				const response = this.request.post(''https://'' + params[''api_host''] + apiPath + apiParams, body);

				try {
					if (JSON.parse(response)[''code''] === ''TooManyRequests'') {

						apiRateLimitExceeded = true;
						Zabbix.sleep(1000);
					} else {
						apiRateLimitExceeded = false;
					}
				} catch (error) {
					Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the response: '' + JSON.stringify(response));
					throw ''Could not parse the response. See logs for more information.'';
				}
			} while (apiRateLimitExceeded);
		} else {
			const response = this.request.get(''https://'' + params[''api_host''] + apiPath + apiParams);
		}

		this.request.clearHeader();

		if (this.request.getStatus() === parseInt(params[''http_status_code''])) {
			return response;
		} else {
			Zabbix.log(3, this.zabbixLogPrefix + '' Unexpected HTTP response code: '' + this.request.getStatus());
			throw ''Unexpected HTTP response code: '' + this.request.getStatus();
		}
	};

	this.extractData = function (httpMethod, data, keys, compartment) {
		try {
			data = JSON.parse(data);
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the received JSON object: '' + data);
			throw ''Could not parse received JSON object. See logs for more information.'';
		}

		if (typeof keys == ''object'') {
			var returnBuffer = [];
			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {

				var objectBuffer = {};
				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {
					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {
						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];
					} else {
						Zabbix.log(3, this.zabbixLogPrefix + '' Received an unexpected JSON object. Could not get value for key "'' + keys[key] + ''" in JSON: '' + JSON.stringify(data[dataObj]));
						throw ''Received an unexpected JSON object. See logs for more information.'';
					}
				}
				if (typeof compartment != ''undefined'' && compartment != '''') objectBuffer[''compartment''] = compartment;
				returnBuffer.push(objectBuffer);
			}
			return returnBuffer;
		}

		try {
			if (httpMethod === ''get'') {
				return data[keys];
			} else {
				if (data.length === 0) {
					return 0;
				}
				data = data[0][keys];
				return data[data.length - 1][''value''];
			}
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not find key "'' + keys + ''" in JSON: '' + JSON.stringify(data));
			throw ''Could not find required key in JSON object. See logs for more information.'';
		}
	};
}


const params = JSON.parse(value);
validateZabbixParams([''tenancy_ocid'', ''user_ocid'', ''private_key'', ''fingerprint'', ''api_host'', ''vcn_id'', ''http_status_code'', ''compartment_id''], params);
var oci = new OCI(''VCN'', ''Get subnets'', params);

return 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,E'function validateZabbixParams(requiredParams, allParams) {
	requiredParams.forEach(function (field) {
		if (typeof allParams !== ''object'' || typeof allParams[field] === ''undefined'' || allParams[field] === '''') {
			throw ''Required param is not set: '' + field + ''.'';
		}
	});
}

function OCI(service, action, params) {
	this.zabbixLogPrefix = ''[ OCI ] [ '' + service + '' ] [ '' + action + '' ]'';
	this.request = new HttpRequest();

	this.hash = function (string) {
		return sha256(string);
	};

	this.sign = function (string) {
		return sign(''sha256'', params[''private_key''], string);
	};

	this.encode = function (hash) {
		const hexArr = hash.match(/.{1,2}/g);
		var uInt8Array = new Uint8Array(hexArr.length);
		hexArr.forEach(function (hex, idx) {
			uInt8Array[idx] = parseInt(hex, 16);
		});
		return btoa(uInt8Array);
	};

	this.getDate = function () {
		const weekdayShortList = [''Sun'', ''Mon'', ''Tue'', ''Wed'', ''Thu'', ''Fri'', ''Sat''];
		const monthShortList = [''jan'', ''feb'', ''mar'', ''apr'', ''may'', ''jun'', ''jul'', ''aug'', ''sep'', ''oct'', ''nov'', ''dec''];
		const today = new Date();
		return weekdayShortList[today.getUTCDay()] + '', '' + today.getUTCDate() + '' '' + monthShortList[today.getUTCMonth()] + '' '' + today.getUTCFullYear() + '' '' + today.getUTCHours() + '':'' + today.getUTCMinutes() + '':'' + today.getUTCSeconds() + '' GMT'';
	};

	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {
		var headers = ''(request-target) date host'';
		const contentTypeHeader = ''content-type: application/json'';
		const dateHeader = ''date: '' + this.getDate();
		const hostHeader = ''host: '' + params[''api_host''];
		const requestTarget = ''(request-target): '' + httpMethod + '' '' + apiPath + apiParams;
		var signingString = requestTarget + ''\\n'' + dateHeader + ''\\n'' + hostHeader;
		var reqHeaders = [contentTypeHeader, dateHeader];

		if (httpMethod === ''post'') {
			var body = JSON.stringify({
				''namespace'': namespace,
				''query'': mql
			});
			headers = headers + '' x-content-sha256 content-type content-length'';
			const bodyHeader = ''x-content-sha256: '' + this.encode(this.hash(body));
			const bodyLengthHeader = ''content-length: '' + body.length;
			signingString = signingString + ''\\n'' + bodyHeader + ''\\n'' + contentTypeHeader + ''\\n'' + bodyLengthHeader;
			reqHeaders.push(bodyHeader, bodyLengthHeader);
		}

		const signature = this.encode(this.sign(signingString));

		reqHeaders.push(''Authorization: Signature version="1",keyId="'' + params[''tenancy_ocid''] + ''/'' + params[''user_ocid''] + ''/'' + params[''fingerprint''] + ''",algorithm="rsa-sha256",headers="'' + headers + ''",signature="'' + signature + ''"'');
		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {
			this.request.addHeader(reqHeaders[header]);
		}

		if (params[''http_proxy'']) {
			this.request.setProxy(params[''http_proxy'']);
			Zabbix.log(4, this.zabbixLogPrefix + '' Using http proxy: '' + params[''http_proxy'']);
		}

		if (httpMethod === ''post'') {
			var apiRateLimitExceeded = false;
			do {
				const response = this.request.post(''https://'' + params[''api_host''] + apiPath + apiParams, body);

				try {
					if (JSON.parse(response)[''code''] === ''TooManyRequests'') {

						apiRateLimitExceeded = true;
						Zabbix.sleep(1000);
					} else {
						apiRateLimitExceeded = false;
					}
				} catch (error) {
					Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the response: '' + JSON.stringify(response));
					throw ''Could not parse the response. See logs for more information.'';
				}
			} while (apiRateLimitExceeded);
		} else {
			const response = this.request.get(''https://'' + params[''api_host''] + apiPath + apiParams);
		}

		this.request.clearHeader();

		if (this.request.getStatus() === parseInt(params[''http_status_code''])) {
			return response;
		} else {
			Zabbix.log(3, this.zabbixLogPrefix + '' Unexpected HTTP response code: '' + this.request.getStatus());
			throw ''Unexpected HTTP response code: '' + this.request.getStatus();
		}
	};

	this.extractData = function (httpMethod, data, keys, compartment) {
		try {
			data = JSON.parse(data);
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the received JSON object: '' + data);
			throw ''Could not parse received JSON object. See logs for more information.'';
		}

		if (typeof keys == ''object'') {
			var returnBuffer = [];
			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {

				var objectBuffer = {};
				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {
					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {
						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];
					} else {
						Zabbix.log(3, this.zabbixLogPrefix + '' Received an unexpected JSON object. Could not get value for key "'' + keys[key] + ''" in JSON: '' + JSON.stringify(data[dataObj]));
						throw ''Received an unexpected JSON object. See logs for more information.'';
					}
				}
				if (typeof compartment != ''undefined'' && compartment != '''') objectBuffer[''compartment''] = compartment;
				returnBuffer.push(objectBuffer);
			}
			return returnBuffer;
		}

		try {
			if (httpMethod === ''get'') {
				return data[keys];
			} else {
				if (data.length === 0) {
					return 0;
				}
				data = data[0][keys];
				return data[data.length - 1][''value''];
			}
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not find key "'' + keys + ''" in JSON: '' + JSON.stringify(data));
			throw ''Could not find required key in JSON object. See logs for more information.'';
		}
	};
}

function buildMql(id, metrics, defaultStatistic, resourceType) {
	resourceType = resourceType === '''' || resourceType === undefined ? ''resourceId'' : resourceType;
	this.query = ''['' + params[''req_interval''] + ''m]{'' + resourceType + ''='' + id + ''}.'';

	for (var i = 0, metricsLength = metrics.length; i < metricsLength; i++) {
		const metric = ((Array.isArray(metrics[i]) ? metrics[i] : [metrics[i], defaultStatistic]));
		metrics[i] = [metric[0], this.query + metric[1]];
	}
}


const params = JSON.parse(value);
validateZabbixParams([''tenancy_ocid'', ''user_ocid'', ''private_key'', ''fingerprint'', ''api_host'', ''bucket_name'', ''http_status_code'', ''req_interval'', ''compartment_id''], params);
var oci = new OCI(''Object storage'', ''Get metrics '' + params[''req_interval''] + ''m'', params);

const metrics = [
	''AllRequests'',
	''ClientErrors'',
	''FirstByteLatency'',
	''PostRequests'',
	''PutRequests'',
	''TotalRequestLatency''
];
buildMql(params[''bucket_name''], metrics, ''mean'', ''resourceDisplayName'');

var result = {};
for (var i = 0, metricsLength = metrics.length; i < metricsLength; i++) {
	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'');
}
return 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,E'function validateZabbixParams(requiredParams, allParams) {
	requiredParams.forEach(function (field) {
		if (typeof allParams !== ''object'' || typeof allParams[field] === ''undefined'' || allParams[field] === '''') {
			throw ''Required param is not set: '' + field + ''.'';
		}
	});
}

function OCI(service, action, params) {
	this.zabbixLogPrefix = ''[ OCI ] [ '' + service + '' ] [ '' + action + '' ]'';
	this.request = new HttpRequest();

	this.hash = function (string) {
		return sha256(string);
	};

	this.sign = function (string) {
		return sign(''sha256'', params[''private_key''], string);
	};

	this.encode = function (hash) {
		const hexArr = hash.match(/.{1,2}/g);
		var uInt8Array = new Uint8Array(hexArr.length);
		hexArr.forEach(function (hex, idx) {
			uInt8Array[idx] = parseInt(hex, 16);
		});
		return btoa(uInt8Array);
	};

	this.getDate = function () {
		const weekdayShortList = [''Sun'', ''Mon'', ''Tue'', ''Wed'', ''Thu'', ''Fri'', ''Sat''];
		const monthShortList = [''jan'', ''feb'', ''mar'', ''apr'', ''may'', ''jun'', ''jul'', ''aug'', ''sep'', ''oct'', ''nov'', ''dec''];
		const today = new Date();
		return weekdayShortList[today.getUTCDay()] + '', '' + today.getUTCDate() + '' '' + monthShortList[today.getUTCMonth()] + '' '' + today.getUTCFullYear() + '' '' + today.getUTCHours() + '':'' + today.getUTCMinutes() + '':'' + today.getUTCSeconds() + '' GMT'';
	};

	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {
		var headers = ''(request-target) date host'';
		const contentTypeHeader = ''content-type: application/json'';
		const dateHeader = ''date: '' + this.getDate();
		const hostHeader = ''host: '' + params[''api_host''];
		const requestTarget = ''(request-target): '' + httpMethod + '' '' + apiPath + apiParams;
		var signingString = requestTarget + ''\\n'' + dateHeader + ''\\n'' + hostHeader;
		var reqHeaders = [contentTypeHeader, dateHeader];

		if (httpMethod === ''post'') {
			var body = JSON.stringify({
				''namespace'': namespace,
				''query'': mql
			});
			headers = headers + '' x-content-sha256 content-type content-length'';
			const bodyHeader = ''x-content-sha256: '' + this.encode(this.hash(body));
			const bodyLengthHeader = ''content-length: '' + body.length;
			signingString = signingString + ''\\n'' + bodyHeader + ''\\n'' + contentTypeHeader + ''\\n'' + bodyLengthHeader;
			reqHeaders.push(bodyHeader, bodyLengthHeader);
		}

		const signature = this.encode(this.sign(signingString));

		reqHeaders.push(''Authorization: Signature version="1",keyId="'' + params[''tenancy_ocid''] + ''/'' + params[''user_ocid''] + ''/'' + params[''fingerprint''] + ''",algorithm="rsa-sha256",headers="'' + headers + ''",signature="'' + signature + ''"'');
		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {
			this.request.addHeader(reqHeaders[header]);
		}

		if (params[''http_proxy'']) {
			this.request.setProxy(params[''http_proxy'']);
			Zabbix.log(4, this.zabbixLogPrefix + '' Using http proxy: '' + params[''http_proxy'']);
		}

		if (httpMethod === ''post'') {
			var apiRateLimitExceeded = false;
			do {
				const response = this.request.post(''https://'' + params[''api_host''] + apiPath + apiParams, body);

				try {
					if (JSON.parse(response)[''code''] === ''TooManyRequests'') {

						apiRateLimitExceeded = true;
						Zabbix.sleep(1000);
					} else {
						apiRateLimitExceeded = false;
					}
				} catch (error) {
					Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the response: '' + JSON.stringify(response));
					throw ''Could not parse the response. See logs for more information.'';
				}
			} while (apiRateLimitExceeded);
		} else {
			const response = this.request.get(''https://'' + params[''api_host''] + apiPath + apiParams);
		}

		this.request.clearHeader();

		if (this.request.getStatus() === parseInt(params[''http_status_code''])) {
			return response;
		} else {
			Zabbix.log(3, this.zabbixLogPrefix + '' Unexpected HTTP response code: '' + this.request.getStatus());
			throw ''Unexpected HTTP response code: '' + this.request.getStatus();
		}
	};

	this.extractData = function (httpMethod, data, keys, compartment) {
		try {
			data = JSON.parse(data);
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the received JSON object: '' + data);
			throw ''Could not parse received JSON object. See logs for more information.'';
		}

		if (typeof keys == ''object'') {
			var returnBuffer = [];
			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {

				var objectBuffer = {};
				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {
					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {
						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];
					} else {
						Zabbix.log(3, this.zabbixLogPrefix + '' Received an unexpected JSON object. Could not get value for key "'' + keys[key] + ''" in JSON: '' + JSON.stringify(data[dataObj]));
						throw ''Received an unexpected JSON object. See logs for more information.'';
					}
				}
				if (typeof compartment != ''undefined'' && compartment != '''') objectBuffer[''compartment''] = compartment;
				returnBuffer.push(objectBuffer);
			}
			return returnBuffer;
		}

		try {
			if (httpMethod === ''get'') {
				return data[keys];
			} else {
				if (data.length === 0) {
					return 0;
				}
				data = data[0][keys];
				return data[data.length - 1][''value''];
			}
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not find key "'' + keys + ''" in JSON: '' + JSON.stringify(data));
			throw ''Could not find required key in JSON object. See logs for more information.'';
		}
	};
}

function buildMql(id, metrics, defaultStatistic, resourceType) {
	resourceType = resourceType === '''' || resourceType === undefined ? ''resourceId'' : resourceType;
	this.query = ''['' + params[''req_interval''] + ''m]{'' + resourceType + ''='' + id + ''}.'';

	for (var i = 0, metricsLength = metrics.length; i < metricsLength; i++) {
		const metric = ((Array.isArray(metrics[i]) ? metrics[i] : [metrics[i], defaultStatistic]));
		metrics[i] = [metric[0], this.query + metric[1]];
	}
}


const params = JSON.parse(value);
validateZabbixParams([''tenancy_ocid'', ''user_ocid'', ''private_key'', ''fingerprint'', ''api_host'', ''bucket_name'', ''http_status_code'', ''req_interval'', ''compartment_id''], params);
var oci = new OCI(''Object storage'', ''Get metrics '' + params[''req_interval''] + ''m'', params);

const metrics = [
	''ObjectCount'',
	''StoredBytes'',
	''UncommittedParts''
];
buildMql(params[''bucket_name''], metrics, ''mean'', ''resourceDisplayName'')

var result = {};
for (var i = 0, metricsLength = metrics.length; i < metricsLength; i++) {
	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'');
}
return 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,E'function validateZabbixParams(requiredParams, allParams) {
	requiredParams.forEach(function (field) {
		if (typeof allParams !== ''object'' || typeof allParams[field] === ''undefined'' || allParams[field] === '''') {
			throw ''Required param is not set: '' + field + ''.'';
		}
	});
}

function OCI(service, action, params) {
	this.zabbixLogPrefix = ''[ OCI ] [ '' + service + '' ] [ '' + action + '' ]'';
	this.request = new HttpRequest();

	this.hash = function (string) {
		return sha256(string);
	};

	this.sign = function (string) {
		return sign(''sha256'', params[''private_key''], string);
	};

	this.encode = function (hash) {
		const hexArr = hash.match(/.{1,2}/g);
		var uInt8Array = new Uint8Array(hexArr.length);
		hexArr.forEach(function (hex, idx) {
			uInt8Array[idx] = parseInt(hex, 16);
		});
		return btoa(uInt8Array);
	};

	this.getDate = function () {
		const weekdayShortList = [''Sun'', ''Mon'', ''Tue'', ''Wed'', ''Thu'', ''Fri'', ''Sat''];
		const monthShortList = [''jan'', ''feb'', ''mar'', ''apr'', ''may'', ''jun'', ''jul'', ''aug'', ''sep'', ''oct'', ''nov'', ''dec''];
		const today = new Date();
		return weekdayShortList[today.getUTCDay()] + '', '' + today.getUTCDate() + '' '' + monthShortList[today.getUTCMonth()] + '' '' + today.getUTCFullYear() + '' '' + today.getUTCHours() + '':'' + today.getUTCMinutes() + '':'' + today.getUTCSeconds() + '' GMT'';
	};

	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {
		var headers = ''(request-target) date host'';
		const contentTypeHeader = ''content-type: application/json'';
		const dateHeader = ''date: '' + this.getDate();
		const hostHeader = ''host: '' + params[''api_host''];
		const requestTarget = ''(request-target): '' + httpMethod + '' '' + apiPath + apiParams;
		var signingString = requestTarget + ''\\n'' + dateHeader + ''\\n'' + hostHeader;
		var reqHeaders = [contentTypeHeader, dateHeader];

		if (httpMethod === ''post'') {
			var body = JSON.stringify({
				''namespace'': namespace,
				''query'': mql
			});
			headers = headers + '' x-content-sha256 content-type content-length'';
			const bodyHeader = ''x-content-sha256: '' + this.encode(this.hash(body));
			const bodyLengthHeader = ''content-length: '' + body.length;
			signingString = signingString + ''\\n'' + bodyHeader + ''\\n'' + contentTypeHeader + ''\\n'' + bodyLengthHeader;
			reqHeaders.push(bodyHeader, bodyLengthHeader);
		}

		const signature = this.encode(this.sign(signingString));

		reqHeaders.push(''Authorization: Signature version="1",keyId="'' + params[''tenancy_ocid''] + ''/'' + params[''user_ocid''] + ''/'' + params[''fingerprint''] + ''",algorithm="rsa-sha256",headers="'' + headers + ''",signature="'' + signature + ''"'');
		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {
			this.request.addHeader(reqHeaders[header]);
		}

		if (params[''http_proxy'']) {
			this.request.setProxy(params[''http_proxy'']);
			Zabbix.log(4, this.zabbixLogPrefix + '' Using http proxy: '' + params[''http_proxy'']);
		}

		if (httpMethod === ''post'') {
			var apiRateLimitExceeded = false;
			do {
				const response = this.request.post(''https://'' + params[''api_host''] + apiPath + apiParams, body);

				try {
					if (JSON.parse(response)[''code''] === ''TooManyRequests'') {

						apiRateLimitExceeded = true;
						Zabbix.sleep(1000);
					} else {
						apiRateLimitExceeded = false;
					}
				} catch (error) {
					Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the response: '' + JSON.stringify(response));
					throw ''Could not parse the response. See logs for more information.'';
				}
			} while (apiRateLimitExceeded);
		} else {
			const response = this.request.get(''https://'' + params[''api_host''] + apiPath + apiParams);
		}

		this.request.clearHeader();

		if (this.request.getStatus() === parseInt(params[''http_status_code''])) {
			return response;
		} else {
			Zabbix.log(3, this.zabbixLogPrefix + '' Unexpected HTTP response code: '' + this.request.getStatus());
			throw ''Unexpected HTTP response code: '' + this.request.getStatus();
		}
	};

	this.extractData = function (httpMethod, data, keys, compartment) {
		try {
			data = JSON.parse(data);
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the received JSON object: '' + data);
			throw ''Could not parse received JSON object. See logs for more information.'';
		}

		if (typeof keys == ''object'') {
			var returnBuffer = [];
			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {

				var objectBuffer = {};
				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {
					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {
						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];
					} else {
						Zabbix.log(3, this.zabbixLogPrefix + '' Received an unexpected JSON object. Could not get value for key "'' + keys[key] + ''" in JSON: '' + JSON.stringify(data[dataObj]));
						throw ''Received an unexpected JSON object. See logs for more information.'';
					}
				}
				if (typeof compartment != ''undefined'' && compartment != '''') objectBuffer[''compartment''] = compartment;
				returnBuffer.push(objectBuffer);
			}
			return returnBuffer;
		}

		try {
			if (httpMethod === ''get'') {
				return data[keys];
			} else {
				if (data.length === 0) {
					return 0;
				}
				data = data[0][keys];
				return data[data.length - 1][''value''];
			}
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not find key "'' + keys + ''" in JSON: '' + JSON.stringify(data));
			throw ''Could not find required key in JSON object. See logs for more information.'';
		}
	};
}


const params = JSON.parse(value);
validateZabbixParams([''tenancy_ocid'', ''user_ocid'', ''private_key'', ''fingerprint'', ''api_host'', ''bucket_name'', ''http_status_code'', ''req_interval'', ''compartment_id''], params);
var oci = new OCI(''Object storage'', ''Get metrics '' + params[''req_interval''] + ''m'', params);
const mql = ''EnabledOLM['' + params[''req_interval''] + ''m]{resourceDisplayName='' + params[''bucket_name''] + ''}.mean()'';

return 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:

    1 - if policies are configured
    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,E'function validateZabbixParams(requiredParams, allParams) {
	requiredParams.forEach(function (field) {
		if (typeof allParams !== ''object'' || typeof allParams[field] === ''undefined'' || allParams[field] === '''') {
			throw ''Required param is not set: '' + field + ''.'';
		}
	});
}

function prepareCompartments(compartments, tenancy) {
	if (typeof compartments === ''undefined'' || compartments === '''') {
		return [tenancy];
	} else {
		return compartments.split('','')
	}
}

function OCI(service, action, params) {
	this.zabbixLogPrefix = ''[ OCI ] [ '' + service + '' ] [ '' + action + '' ]'';
	this.request = new HttpRequest();

	this.hash = function (string) {
		return sha256(string);
	};

	this.sign = function (string) {
		return sign(''sha256'', params[''private_key''], string);
	};

	this.encode = function (hash) {
		const hexArr = hash.match(/.{1,2}/g);
		var uInt8Array = new Uint8Array(hexArr.length);
		hexArr.forEach(function (hex, idx) {
			uInt8Array[idx] = parseInt(hex, 16);
		});
		return btoa(uInt8Array);
	};

	this.getDate = function () {
		const weekdayShortList = [''Sun'', ''Mon'', ''Tue'', ''Wed'', ''Thu'', ''Fri'', ''Sat''];
		const monthShortList = [''jan'', ''feb'', ''mar'', ''apr'', ''may'', ''jun'', ''jul'', ''aug'', ''sep'', ''oct'', ''nov'', ''dec''];
		const today = new Date();
		return weekdayShortList[today.getUTCDay()] + '', '' + today.getUTCDate() + '' '' + monthShortList[today.getUTCMonth()] + '' '' + today.getUTCFullYear() + '' '' + today.getUTCHours() + '':'' + today.getUTCMinutes() + '':'' + today.getUTCSeconds() + '' GMT'';
	};

	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {
		var headers = ''(request-target) date host'';
		const contentTypeHeader = ''content-type: application/json'';
		const dateHeader = ''date: '' + this.getDate();
		const hostHeader = ''host: '' + params[''api_host''];
		const requestTarget = ''(request-target): '' + httpMethod + '' '' + apiPath + apiParams;
		var signingString = requestTarget + ''\\n'' + dateHeader + ''\\n'' + hostHeader;
		var reqHeaders = [contentTypeHeader, dateHeader];

		if (httpMethod === ''post'') {
			var body = JSON.stringify({
				''namespace'': namespace,
				''query'': mql
			});
			headers = headers + '' x-content-sha256 content-type content-length'';
			const bodyHeader = ''x-content-sha256: '' + this.encode(this.hash(body));
			const bodyLengthHeader = ''content-length: '' + body.length;
			signingString = signingString + ''\\n'' + bodyHeader + ''\\n'' + contentTypeHeader + ''\\n'' + bodyLengthHeader;
			reqHeaders.push(bodyHeader, bodyLengthHeader);
		}

		const signature = this.encode(this.sign(signingString));

		reqHeaders.push(''Authorization: Signature version="1",keyId="'' + params[''tenancy_ocid''] + ''/'' + params[''user_ocid''] + ''/'' + params[''fingerprint''] + ''",algorithm="rsa-sha256",headers="'' + headers + ''",signature="'' + signature + ''"'');
		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {
			this.request.addHeader(reqHeaders[header]);
		}

		if (params[''http_proxy'']) {
			this.request.setProxy(params[''http_proxy'']);
			Zabbix.log(4, this.zabbixLogPrefix + '' Using http proxy: '' + params[''http_proxy'']);
		}

		if (httpMethod === ''post'') {
			var apiRateLimitExceeded = false;
			do {
				const response = this.request.post(''https://'' + params[''api_host''] + apiPath + apiParams, body);

				try {
					if (JSON.parse(response)[''code''] === ''TooManyRequests'') {

						apiRateLimitExceeded = true;
						Zabbix.sleep(1000);
					} else {
						apiRateLimitExceeded = false;
					}
				} catch (error) {
					Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the response: '' + JSON.stringify(response));
					throw ''Could not parse the response. See logs for more information.'';
				}
			} while (apiRateLimitExceeded);
		} else {
			const response = this.request.get(''https://'' + params[''api_host''] + apiPath + apiParams);
		}

		this.request.clearHeader();

		if (this.request.getStatus() === parseInt(params[''http_status_code''])) {
			return response;
		} else {
			Zabbix.log(3, this.zabbixLogPrefix + '' Unexpected HTTP response code: '' + this.request.getStatus());
			throw ''Unexpected HTTP response code: '' + this.request.getStatus();
		}
	};

	this.extractData = function (httpMethod, data, keys, compartment) {
		try {
			data = JSON.parse(data);
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the received JSON object: '' + data);
			throw ''Could not parse received JSON object. See logs for more information.'';
		}

		if (typeof keys == ''object'') {
			var returnBuffer = [];
			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {

				var objectBuffer = {};
				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {
					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {
						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];
					} else {
						Zabbix.log(3, this.zabbixLogPrefix + '' Received an unexpected JSON object. Could not get value for key "'' + keys[key] + ''" in JSON: '' + JSON.stringify(data[dataObj]));
						throw ''Received an unexpected JSON object. See logs for more information.'';
					}
				}
				if (typeof compartment != ''undefined'' && compartment != '''') objectBuffer[''compartment''] = compartment;
				returnBuffer.push(objectBuffer);
			}
			return returnBuffer;
		}

		try {
			if (httpMethod === ''get'') {
				return data[keys];
			} else {
				if (data.length === 0) {
					return 0;
				}
				data = data[0][keys];
				return data[data.length - 1][''value''];
			}
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not find key "'' + keys + ''" in JSON: '' + JSON.stringify(data));
			throw ''Could not find required key in JSON object. See logs for more information.'';
		}
	};
}


const params = JSON.parse(value);
validateZabbixParams([''tenancy_ocid'', ''user_ocid'', ''private_key'', ''fingerprint'', ''api_host'', ''http_status_code''], params);
var oci = new OCI(''Block volume'', ''Get volumes'', params);
var compartments = prepareCompartments(params[''compartment_ocid''], params[''tenancy_ocid'']);

var buffer = [];
compartments.forEach(function (compartment) {
	Array.prototype.push.apply(buffer, oci.extractData(''get'', oci.executeRequest(''get'', ''/20160918/volumes'', ''?compartmentId='' + encodeURIComponent(compartment)), [''id'', ''displayName'', ''lifecycleState'', ''freeformTags''], compartment));
})
return 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,E'function validateZabbixParams(requiredParams, allParams) {
	requiredParams.forEach(function (field) {
		if (typeof allParams !== ''object'' || typeof allParams[field] === ''undefined'' || allParams[field] === '''') {
			throw ''Required param is not set: '' + field + ''.'';
		}
	});
}

function prepareCompartments(compartments, tenancy) {
	if (typeof compartments === ''undefined'' || compartments === '''') {
		return [tenancy];
	} else {
		return compartments.split('','')
	}
}

function OCI(service, action, params) {
	this.zabbixLogPrefix = ''[ OCI ] [ '' + service + '' ] [ '' + action + '' ]'';
	this.request = new HttpRequest();

	this.hash = function (string) {
		return sha256(string);
	};

	this.sign = function (string) {
		return sign(''sha256'', params[''private_key''], string);
	};

	this.encode = function (hash) {
		const hexArr = hash.match(/.{1,2}/g);
		var uInt8Array = new Uint8Array(hexArr.length);
		hexArr.forEach(function (hex, idx) {
			uInt8Array[idx] = parseInt(hex, 16);
		});
		return btoa(uInt8Array);
	};

	this.getDate = function () {
		const weekdayShortList = [''Sun'', ''Mon'', ''Tue'', ''Wed'', ''Thu'', ''Fri'', ''Sat''];
		const monthShortList = [''jan'', ''feb'', ''mar'', ''apr'', ''may'', ''jun'', ''jul'', ''aug'', ''sep'', ''oct'', ''nov'', ''dec''];
		const today = new Date();
		return weekdayShortList[today.getUTCDay()] + '', '' + today.getUTCDate() + '' '' + monthShortList[today.getUTCMonth()] + '' '' + today.getUTCFullYear() + '' '' + today.getUTCHours() + '':'' + today.getUTCMinutes() + '':'' + today.getUTCSeconds() + '' GMT'';
	};

	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {
		var headers = ''(request-target) date host'';
		const contentTypeHeader = ''content-type: application/json'';
		const dateHeader = ''date: '' + this.getDate();
		const hostHeader = ''host: '' + params[''api_host''];
		const requestTarget = ''(request-target): '' + httpMethod + '' '' + apiPath + apiParams;
		var signingString = requestTarget + ''\\n'' + dateHeader + ''\\n'' + hostHeader;
		var reqHeaders = [contentTypeHeader, dateHeader];

		if (httpMethod === ''post'') {
			var body = JSON.stringify({
				''namespace'': namespace,
				''query'': mql
			});
			headers = headers + '' x-content-sha256 content-type content-length'';
			const bodyHeader = ''x-content-sha256: '' + this.encode(this.hash(body));
			const bodyLengthHeader = ''content-length: '' + body.length;
			signingString = signingString + ''\\n'' + bodyHeader + ''\\n'' + contentTypeHeader + ''\\n'' + bodyLengthHeader;
			reqHeaders.push(bodyHeader, bodyLengthHeader);
		}

		const signature = this.encode(this.sign(signingString));

		reqHeaders.push(''Authorization: Signature version="1",keyId="'' + params[''tenancy_ocid''] + ''/'' + params[''user_ocid''] + ''/'' + params[''fingerprint''] + ''",algorithm="rsa-sha256",headers="'' + headers + ''",signature="'' + signature + ''"'');
		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {
			this.request.addHeader(reqHeaders[header]);
		}

		if (params[''http_proxy'']) {
			this.request.setProxy(params[''http_proxy'']);
			Zabbix.log(4, this.zabbixLogPrefix + '' Using http proxy: '' + params[''http_proxy'']);
		}

		if (httpMethod === ''post'') {
			var apiRateLimitExceeded = false;
			do {
				const response = this.request.post(''https://'' + params[''api_host''] + apiPath + apiParams, body);

				try {
					if (JSON.parse(response)[''code''] === ''TooManyRequests'') {

						apiRateLimitExceeded = true;
						Zabbix.sleep(1000);
					} else {
						apiRateLimitExceeded = false;
					}
				} catch (error) {
					Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the response: '' + JSON.stringify(response));
					throw ''Could not parse the response. See logs for more information.'';
				}
			} while (apiRateLimitExceeded);
		} else {
			const response = this.request.get(''https://'' + params[''api_host''] + apiPath + apiParams);
		}

		this.request.clearHeader();

		if (this.request.getStatus() === parseInt(params[''http_status_code''])) {
			return response;
		} else {
			Zabbix.log(3, this.zabbixLogPrefix + '' Unexpected HTTP response code: '' + this.request.getStatus());
			throw ''Unexpected HTTP response code: '' + this.request.getStatus();
		}
	};

	this.extractData = function (httpMethod, data, keys, compartment) {
		try {
			data = JSON.parse(data);
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the received JSON object: '' + data);
			throw ''Could not parse received JSON object. See logs for more information.'';
		}

		if (typeof keys == ''object'') {
			var returnBuffer = [];
			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {

				var objectBuffer = {};
				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {
					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {
						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];
					} else {
						Zabbix.log(3, this.zabbixLogPrefix + '' Received an unexpected JSON object. Could not get value for key "'' + keys[key] + ''" in JSON: '' + JSON.stringify(data[dataObj]));
						throw ''Received an unexpected JSON object. See logs for more information.'';
					}
				}
				if (typeof compartment != ''undefined'' && compartment != '''') objectBuffer[''compartment''] = compartment;
				returnBuffer.push(objectBuffer);
			}
			return returnBuffer;
		}

		try {
			if (httpMethod === ''get'') {
				return data[keys];
			} else {
				if (data.length === 0) {
					return 0;
				}
				data = data[0][keys];
				return data[data.length - 1][''value''];
			}
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not find key "'' + keys + ''" in JSON: '' + JSON.stringify(data));
			throw ''Could not find required key in JSON object. See logs for more information.'';
		}
	};
}


const params = JSON.parse(value);
validateZabbixParams([''tenancy_ocid'', ''user_ocid'', ''private_key'', ''fingerprint'', ''api_host'', ''http_status_code''], params);
var oci = new OCI(''Boot volume'', ''Get volumes'', params);
var compartments = prepareCompartments(params[''compartment_ocid''], params[''tenancy_ocid'']);

var buffer = [];
compartments.forEach(function (compartment) {
	Array.prototype.push.apply(buffer, oci.extractData(''get'', oci.executeRequest(''get'', ''/20160918/bootVolumes'', ''?compartmentId='' + encodeURIComponent(compartment)), [''id'', ''displayName'', ''lifecycleState'', ''freeformTags''], compartment));
})
return 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,E'function validateZabbixParams(requiredParams, allParams) {
	requiredParams.forEach(function (field) {
		if (typeof allParams !== ''object'' || typeof allParams[field] === ''undefined'' || allParams[field] === '''') {
			throw ''Required param is not set: '' + field + ''.'';
		}
	});
}

function prepareCompartments(compartments, tenancy) {
	if (typeof compartments === ''undefined'' || compartments === '''') {
		return [tenancy];
	} else {
		return compartments.split('','')
	}
}

function OCI(service, action, params) {
	this.zabbixLogPrefix = ''[ OCI ] [ '' + service + '' ] [ '' + action + '' ]'';
	this.request = new HttpRequest();

	this.hash = function (string) {
		return sha256(string);
	};

	this.sign = function (string) {
		return sign(''sha256'', params[''private_key''], string);
	};

	this.encode = function (hash) {
		const hexArr = hash.match(/.{1,2}/g);
		var uInt8Array = new Uint8Array(hexArr.length);
		hexArr.forEach(function (hex, idx) {
			uInt8Array[idx] = parseInt(hex, 16);
		});
		return btoa(uInt8Array);
	};

	this.getDate = function () {
		const weekdayShortList = [''Sun'', ''Mon'', ''Tue'', ''Wed'', ''Thu'', ''Fri'', ''Sat''];
		const monthShortList = [''jan'', ''feb'', ''mar'', ''apr'', ''may'', ''jun'', ''jul'', ''aug'', ''sep'', ''oct'', ''nov'', ''dec''];
		const today = new Date();
		return weekdayShortList[today.getUTCDay()] + '', '' + today.getUTCDate() + '' '' + monthShortList[today.getUTCMonth()] + '' '' + today.getUTCFullYear() + '' '' + today.getUTCHours() + '':'' + today.getUTCMinutes() + '':'' + today.getUTCSeconds() + '' GMT'';
	};

	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {
		var headers = ''(request-target) date host'';
		const contentTypeHeader = ''content-type: application/json'';
		const dateHeader = ''date: '' + this.getDate();
		const hostHeader = ''host: '' + params[''api_host''];
		const requestTarget = ''(request-target): '' + httpMethod + '' '' + apiPath + apiParams;
		var signingString = requestTarget + ''\\n'' + dateHeader + ''\\n'' + hostHeader;
		var reqHeaders = [contentTypeHeader, dateHeader];

		if (httpMethod === ''post'') {
			var body = JSON.stringify({
				''namespace'': namespace,
				''query'': mql
			});
			headers = headers + '' x-content-sha256 content-type content-length'';
			const bodyHeader = ''x-content-sha256: '' + this.encode(this.hash(body));
			const bodyLengthHeader = ''content-length: '' + body.length;
			signingString = signingString + ''\\n'' + bodyHeader + ''\\n'' + contentTypeHeader + ''\\n'' + bodyLengthHeader;
			reqHeaders.push(bodyHeader, bodyLengthHeader);
		}

		const signature = this.encode(this.sign(signingString));

		reqHeaders.push(''Authorization: Signature version="1",keyId="'' + params[''tenancy_ocid''] + ''/'' + params[''user_ocid''] + ''/'' + params[''fingerprint''] + ''",algorithm="rsa-sha256",headers="'' + headers + ''",signature="'' + signature + ''"'');
		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {
			this.request.addHeader(reqHeaders[header]);
		}

		if (params[''http_proxy'']) {
			this.request.setProxy(params[''http_proxy'']);
			Zabbix.log(4, this.zabbixLogPrefix + '' Using http proxy: '' + params[''http_proxy'']);
		}

		if (httpMethod === ''post'') {
			var apiRateLimitExceeded = false;
			do {
				const response = this.request.post(''https://'' + params[''api_host''] + apiPath + apiParams, body);

				try {
					if (JSON.parse(response)[''code''] === ''TooManyRequests'') {

						apiRateLimitExceeded = true;
						Zabbix.sleep(1000);
					} else {
						apiRateLimitExceeded = false;
					}
				} catch (error) {
					Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the response: '' + JSON.stringify(response));
					throw ''Could not parse the response. See logs for more information.'';
				}
			} while (apiRateLimitExceeded);
		} else {
			const response = this.request.get(''https://'' + params[''api_host''] + apiPath + apiParams);
		}

		this.request.clearHeader();

		if (this.request.getStatus() === parseInt(params[''http_status_code''])) {
			return response;
		} else {
			Zabbix.log(3, this.zabbixLogPrefix + '' Unexpected HTTP response code: '' + this.request.getStatus());
			throw ''Unexpected HTTP response code: '' + this.request.getStatus();
		}
	};

	this.extractData = function (httpMethod, data, keys, compartment) {
		try {
			data = JSON.parse(data);
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the received JSON object: '' + data);
			throw ''Could not parse received JSON object. See logs for more information.'';
		}

		if (typeof keys == ''object'') {
			var returnBuffer = [];
			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {

				var objectBuffer = {};
				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {
					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {
						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];
					} else {
						Zabbix.log(3, this.zabbixLogPrefix + '' Received an unexpected JSON object. Could not get value for key "'' + keys[key] + ''" in JSON: '' + JSON.stringify(data[dataObj]));
						throw ''Received an unexpected JSON object. See logs for more information.'';
					}
				}
				if (typeof compartment != ''undefined'' && compartment != '''') objectBuffer[''compartment''] = compartment;
				returnBuffer.push(objectBuffer);
			}
			return returnBuffer;
		}

		try {
			if (httpMethod === ''get'') {
				return data[keys];
			} else {
				if (data.length === 0) {
					return 0;
				}
				data = data[0][keys];
				return data[data.length - 1][''value''];
			}
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not find key "'' + keys + ''" in JSON: '' + JSON.stringify(data));
			throw ''Could not find required key in JSON object. See logs for more information.'';
		}
	};
}


const params = JSON.parse(value);
validateZabbixParams([''tenancy_ocid'', ''user_ocid'', ''private_key'', ''fingerprint'', ''api_host'', ''http_status_code''], params);
var oci = new OCI(''Compute'', ''Get instances'', params);
var compartments = prepareCompartments(params[''compartment_ocid''], params[''tenancy_ocid'']);

var buffer = [];
compartments.forEach(function (compartment) {
	Array.prototype.push.apply(buffer, oci.extractData(''get'', oci.executeRequest(''get'', ''/20160918/instances'', ''?compartmentId='' + encodeURIComponent(compartment)), [''id'', ''displayName'', ''lifecycleState'', ''freeformTags'', ''availabilityDomain''], compartment));
})
return 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,E'function validateZabbixParams(requiredParams, allParams) {
	requiredParams.forEach(function (field) {
		if (typeof allParams !== ''object'' || typeof allParams[field] === ''undefined'' || allParams[field] === '''') {
			throw ''Required param is not set: '' + field + ''.'';
		}
	});
}

function prepareCompartments(compartments, tenancy) {
	if (typeof compartments === ''undefined'' || compartments === '''') {
		return [tenancy];
	} else {
		return compartments.split('','')
	}
}

function OCI(service, action, params) {
	this.zabbixLogPrefix = ''[ OCI ] [ '' + service + '' ] [ '' + action + '' ]'';
	this.request = new HttpRequest();

	this.hash = function (string) {
		return sha256(string);
	};

	this.sign = function (string) {
		return sign(''sha256'', params[''private_key''], string);
	};

	this.encode = function (hash) {
		const hexArr = hash.match(/.{1,2}/g);
		var uInt8Array = new Uint8Array(hexArr.length);
		hexArr.forEach(function (hex, idx) {
			uInt8Array[idx] = parseInt(hex, 16);
		});
		return btoa(uInt8Array);
	};

	this.getDate = function () {
		const weekdayShortList = [''Sun'', ''Mon'', ''Tue'', ''Wed'', ''Thu'', ''Fri'', ''Sat''];
		const monthShortList = [''jan'', ''feb'', ''mar'', ''apr'', ''may'', ''jun'', ''jul'', ''aug'', ''sep'', ''oct'', ''nov'', ''dec''];
		const today = new Date();
		return weekdayShortList[today.getUTCDay()] + '', '' + today.getUTCDate() + '' '' + monthShortList[today.getUTCMonth()] + '' '' + today.getUTCFullYear() + '' '' + today.getUTCHours() + '':'' + today.getUTCMinutes() + '':'' + today.getUTCSeconds() + '' GMT'';
	};

	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {
		var headers = ''(request-target) date host'';
		const contentTypeHeader = ''content-type: application/json'';
		const dateHeader = ''date: '' + this.getDate();
		const hostHeader = ''host: '' + params[''api_host''];
		const requestTarget = ''(request-target): '' + httpMethod + '' '' + apiPath + apiParams;
		var signingString = requestTarget + ''\\n'' + dateHeader + ''\\n'' + hostHeader;
		var reqHeaders = [contentTypeHeader, dateHeader];

		if (httpMethod === ''post'') {
			var body = JSON.stringify({
				''namespace'': namespace,
				''query'': mql
			});
			headers = headers + '' x-content-sha256 content-type content-length'';
			const bodyHeader = ''x-content-sha256: '' + this.encode(this.hash(body));
			const bodyLengthHeader = ''content-length: '' + body.length;
			signingString = signingString + ''\\n'' + bodyHeader + ''\\n'' + contentTypeHeader + ''\\n'' + bodyLengthHeader;
			reqHeaders.push(bodyHeader, bodyLengthHeader);
		}

		const signature = this.encode(this.sign(signingString));

		reqHeaders.push(''Authorization: Signature version="1",keyId="'' + params[''tenancy_ocid''] + ''/'' + params[''user_ocid''] + ''/'' + params[''fingerprint''] + ''",algorithm="rsa-sha256",headers="'' + headers + ''",signature="'' + signature + ''"'');
		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {
			this.request.addHeader(reqHeaders[header]);
		}

		if (params[''http_proxy'']) {
			this.request.setProxy(params[''http_proxy'']);
			Zabbix.log(4, this.zabbixLogPrefix + '' Using http proxy: '' + params[''http_proxy'']);
		}

		if (httpMethod === ''post'') {
			var apiRateLimitExceeded = false;
			do {
				const response = this.request.post(''https://'' + params[''api_host''] + apiPath + apiParams, body);

				try {
					if (JSON.parse(response)[''code''] === ''TooManyRequests'') {

						apiRateLimitExceeded = true;
						Zabbix.sleep(1000);
					} else {
						apiRateLimitExceeded = false;
					}
				} catch (error) {
					Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the response: '' + JSON.stringify(response));
					throw ''Could not parse the response. See logs for more information.'';
				}
			} while (apiRateLimitExceeded);
		} else {
			const response = this.request.get(''https://'' + params[''api_host''] + apiPath + apiParams);
		}

		this.request.clearHeader();

		if (this.request.getStatus() === parseInt(params[''http_status_code''])) {
			return response;
		} else {
			Zabbix.log(3, this.zabbixLogPrefix + '' Unexpected HTTP response code: '' + this.request.getStatus());
			throw ''Unexpected HTTP response code: '' + this.request.getStatus();
		}
	};

	this.extractData = function (httpMethod, data, keys, compartment) {
		try {
			data = JSON.parse(data);
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the received JSON object: '' + data);
			throw ''Could not parse received JSON object. See logs for more information.'';
		}

		if (typeof keys == ''object'') {
			var returnBuffer = [];
			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {

				var objectBuffer = {};
				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {
					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {
						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];
					} else {
						Zabbix.log(3, this.zabbixLogPrefix + '' Received an unexpected JSON object. Could not get value for key "'' + keys[key] + ''" in JSON: '' + JSON.stringify(data[dataObj]));
						throw ''Received an unexpected JSON object. See logs for more information.'';
					}
				}
				if (typeof compartment != ''undefined'' && compartment != '''') objectBuffer[''compartment''] = compartment;
				returnBuffer.push(objectBuffer);
			}
			return returnBuffer;
		}

		try {
			if (httpMethod === ''get'') {
				return data[keys];
			} else {
				if (data.length === 0) {
					return 0;
				}
				data = data[0][keys];
				return data[data.length - 1][''value''];
			}
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not find key "'' + keys + ''" in JSON: '' + JSON.stringify(data));
			throw ''Could not find required key in JSON object. See logs for more information.'';
		}
	};
}


const params = JSON.parse(value);
validateZabbixParams([''tenancy_ocid'', ''user_ocid'', ''private_key'', ''fingerprint'', ''api_host'', ''http_status_code''], params);
var oci = new OCI(''Autonomous DB'', ''Get DBs'', params);
var compartments = prepareCompartments(params[''compartment_ocid''], params[''tenancy_ocid'']);

var buffer = [];
compartments.forEach(function (compartment) {
	Array.prototype.push.apply(buffer, oci.extractData(''get'', oci.executeRequest(''get'', ''/20160918/autonomousDatabases'', ''?compartmentId='' + encodeURIComponent(compartment)), [''id'', ''dbName'', ''lifecycleState'', ''freeformTags''], compartment));
})
return 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'),
('46937','21','','10617','Object storage discovery','oci.object.storage.discovery','1h','31d','365d','0','4','','','','',NULL,NULL,E'function validateZabbixParams(requiredParams, allParams) {
	requiredParams.forEach(function (field) {
		if (typeof allParams !== ''object'' || typeof allParams[field] === ''undefined'' || allParams[field] === '''') {
			throw ''Required param is not set: '' + field + ''.'';
		}
	});
}

function prepareCompartments(compartments, tenancy) {
	if (typeof compartments === ''undefined'' || compartments === '''') {
		return [tenancy];
	} else {
		return compartments.split('','')
	}
}

function OCI(service, action, params) {
	this.zabbixLogPrefix = ''[ OCI ] [ '' + service + '' ] [ '' + action + '' ]'';
	this.request = new HttpRequest();

	this.hash = function (string) {
		return sha256(string);
	};

	this.sign = function (string) {
		return sign(''sha256'', params[''private_key''], string);
	};

	this.encode = function (hash) {
		const hexArr = hash.match(/.{1,2}/g);
		var uInt8Array = new Uint8Array(hexArr.length);
		hexArr.forEach(function (hex, idx) {
			uInt8Array[idx] = parseInt(hex, 16);
		});
		return btoa(uInt8Array);
	};

	this.getDate = function () {
		const weekdayShortList = [''Sun'', ''Mon'', ''Tue'', ''Wed'', ''Thu'', ''Fri'', ''Sat''];
		const monthShortList = [''jan'', ''feb'', ''mar'', ''apr'', ''may'', ''jun'', ''jul'', ''aug'', ''sep'', ''oct'', ''nov'', ''dec''];
		const today = new Date();
		return weekdayShortList[today.getUTCDay()] + '', '' + today.getUTCDate() + '' '' + monthShortList[today.getUTCMonth()] + '' '' + today.getUTCFullYear() + '' '' + today.getUTCHours() + '':'' + today.getUTCMinutes() + '':'' + today.getUTCSeconds() + '' GMT'';
	};

	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {
		var headers = ''(request-target) date host'';
		const contentTypeHeader = ''content-type: application/json'';
		const dateHeader = ''date: '' + this.getDate();
		const hostHeader = ''host: '' + params[''api_host''];
		const requestTarget = ''(request-target): '' + httpMethod + '' '' + apiPath + apiParams;
		var signingString = requestTarget + ''\\n'' + dateHeader + ''\\n'' + hostHeader;
		var reqHeaders = [contentTypeHeader, dateHeader];

		if (httpMethod === ''post'') {
			var body = JSON.stringify({
				''namespace'': namespace,
				''query'': mql
			});
			headers = headers + '' x-content-sha256 content-type content-length'';
			const bodyHeader = ''x-content-sha256: '' + this.encode(this.hash(body));
			const bodyLengthHeader = ''content-length: '' + body.length;
			signingString = signingString + ''\\n'' + bodyHeader + ''\\n'' + contentTypeHeader + ''\\n'' + bodyLengthHeader;
			reqHeaders.push(bodyHeader, bodyLengthHeader);
		}

		const signature = this.encode(this.sign(signingString));

		reqHeaders.push(''Authorization: Signature version="1",keyId="'' + params[''tenancy_ocid''] + ''/'' + params[''user_ocid''] + ''/'' + params[''fingerprint''] + ''",algorithm="rsa-sha256",headers="'' + headers + ''",signature="'' + signature + ''"'');
		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {
			this.request.addHeader(reqHeaders[header]);
		}

		if (params[''http_proxy'']) {
			this.request.setProxy(params[''http_proxy'']);
			Zabbix.log(4, this.zabbixLogPrefix + '' Using http proxy: '' + params[''http_proxy'']);
		}

		if (httpMethod === ''post'') {
			var apiRateLimitExceeded = false;
			do {
				const response = this.request.post(''https://'' + params[''api_host''] + apiPath + apiParams, body);

				try {
					if (JSON.parse(response)[''code''] === ''TooManyRequests'') {

						apiRateLimitExceeded = true;
						Zabbix.sleep(1000);
					} else {
						apiRateLimitExceeded = false;
					}
				} catch (error) {
					Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the response: '' + JSON.stringify(response));
					throw ''Could not parse the response. See logs for more information.'';
				}
			} while (apiRateLimitExceeded);
		} else {
			const response = this.request.get(''https://'' + params[''api_host''] + apiPath + apiParams);
		}

		this.request.clearHeader();

		if (this.request.getStatus() === parseInt(params[''http_status_code''])) {
			return response;
		} else {
			Zabbix.log(3, this.zabbixLogPrefix + '' Unexpected HTTP response code: '' + this.request.getStatus());
			throw ''Unexpected HTTP response code: '' + this.request.getStatus();
		}
	};

	this.extractData = function (httpMethod, data, keys, compartment) {
		try {
			data = JSON.parse(data);
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the received JSON object: '' + data);
			throw ''Could not parse received JSON object. See logs for more information.'';
		}

		if (typeof keys == ''object'') {
			var returnBuffer = [];
			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {

				var objectBuffer = {};
				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {
					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {
						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];
					} else {
						Zabbix.log(3, this.zabbixLogPrefix + '' Received an unexpected JSON object. Could not get value for key "'' + keys[key] + ''" in JSON: '' + JSON.stringify(data[dataObj]));
						throw ''Received an unexpected JSON object. See logs for more information.'';
					}
				}
				if (typeof compartment != ''undefined'' && compartment != '''') objectBuffer[''compartment''] = compartment;
				returnBuffer.push(objectBuffer);
			}
			return returnBuffer;
		}

		try {
			if (httpMethod === ''get'') {
				return data[keys];
			} else {
				if (data.length === 0) {
					return 0;
				}
				data = data[0][keys];
				return data[data.length - 1][''value''];
			}
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not find key "'' + keys + ''" in JSON: '' + JSON.stringify(data));
			throw ''Could not find required key in JSON object. See logs for more information.'';
		}
	};
}


const params = JSON.parse(value);
validateZabbixParams([''tenancy_ocid'', ''user_ocid'', ''private_key'', ''fingerprint'', ''api_host'', ''http_status_code''], params);
var oci = new OCI(''Object storage'', ''Get buckets'', params);
var compartments = prepareCompartments(params[''compartment_ocid''], params[''tenancy_ocid'']);
const namespace = JSON.parse(oci.executeRequest(''get'', ''/n'', ''''));

var buffer = [];
compartments.forEach(function (compartment) {
	Array.prototype.push.apply(buffer, oci.extractData(''get'', oci.executeRequest(''get'', ''/n/'' + encodeURIComponent(namespace) + ''/b/'', ''?compartmentId='' + encodeURIComponent(compartment) + ''&fields=tags''), [''name'', ''freeformTags''], compartment));
})
return JSON.stringify(buffer);','','0','','','','','1',NULL,'Discover object storage.','0','7d','1','',NULL,'10s','','','','200','1','0','','','0','0','0','0','0','0','0','e1949f127af04efeb8c192f23e45b58a','0','2','0'),
('46938','21','','10617','Virtual cloud networks discovery','oci.vcn.discovery','1h','31d','365d','0','4','','','','',NULL,NULL,E'function validateZabbixParams(requiredParams, allParams) {
	requiredParams.forEach(function (field) {
		if (typeof allParams !== ''object'' || typeof allParams[field] === ''undefined'' || allParams[field] === '''') {
			throw ''Required param is not set: '' + field + ''.'';
		}
	});
}

function prepareCompartments(compartments, tenancy) {
	if (typeof compartments === ''undefined'' || compartments === '''') {
		return [tenancy];
	} else {
		return compartments.split('','')
	}
}

function OCI(service, action, params) {
	this.zabbixLogPrefix = ''[ OCI ] [ '' + service + '' ] [ '' + action + '' ]'';
	this.request = new HttpRequest();

	this.hash = function (string) {
		return sha256(string);
	};

	this.sign = function (string) {
		return sign(''sha256'', params[''private_key''], string);
	};

	this.encode = function (hash) {
		const hexArr = hash.match(/.{1,2}/g);
		var uInt8Array = new Uint8Array(hexArr.length);
		hexArr.forEach(function (hex, idx) {
			uInt8Array[idx] = parseInt(hex, 16);
		});
		return btoa(uInt8Array);
	};

	this.getDate = function () {
		const weekdayShortList = [''Sun'', ''Mon'', ''Tue'', ''Wed'', ''Thu'', ''Fri'', ''Sat''];
		const monthShortList = [''jan'', ''feb'', ''mar'', ''apr'', ''may'', ''jun'', ''jul'', ''aug'', ''sep'', ''oct'', ''nov'', ''dec''];
		const today = new Date();
		return weekdayShortList[today.getUTCDay()] + '', '' + today.getUTCDate() + '' '' + monthShortList[today.getUTCMonth()] + '' '' + today.getUTCFullYear() + '' '' + today.getUTCHours() + '':'' + today.getUTCMinutes() + '':'' + today.getUTCSeconds() + '' GMT'';
	};

	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {
		var headers = ''(request-target) date host'';
		const contentTypeHeader = ''content-type: application/json'';
		const dateHeader = ''date: '' + this.getDate();
		const hostHeader = ''host: '' + params[''api_host''];
		const requestTarget = ''(request-target): '' + httpMethod + '' '' + apiPath + apiParams;
		var signingString = requestTarget + ''\\n'' + dateHeader + ''\\n'' + hostHeader;
		var reqHeaders = [contentTypeHeader, dateHeader];

		if (httpMethod === ''post'') {
			var body = JSON.stringify({
				''namespace'': namespace,
				''query'': mql
			});
			headers = headers + '' x-content-sha256 content-type content-length'';
			const bodyHeader = ''x-content-sha256: '' + this.encode(this.hash(body));
			const bodyLengthHeader = ''content-length: '' + body.length;
			signingString = signingString + ''\\n'' + bodyHeader + ''\\n'' + contentTypeHeader + ''\\n'' + bodyLengthHeader;
			reqHeaders.push(bodyHeader, bodyLengthHeader);
		}

		const signature = this.encode(this.sign(signingString));

		reqHeaders.push(''Authorization: Signature version="1",keyId="'' + params[''tenancy_ocid''] + ''/'' + params[''user_ocid''] + ''/'' + params[''fingerprint''] + ''",algorithm="rsa-sha256",headers="'' + headers + ''",signature="'' + signature + ''"'');
		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {
			this.request.addHeader(reqHeaders[header]);
		}

		if (params[''http_proxy'']) {
			this.request.setProxy(params[''http_proxy'']);
			Zabbix.log(4, this.zabbixLogPrefix + '' Using http proxy: '' + params[''http_proxy'']);
		}

		if (httpMethod === ''post'') {
			var apiRateLimitExceeded = false;
			do {
				const response = this.request.post(''https://'' + params[''api_host''] + apiPath + apiParams, body);

				try {
					if (JSON.parse(response)[''code''] === ''TooManyRequests'') {

						apiRateLimitExceeded = true;
						Zabbix.sleep(1000);
					} else {
						apiRateLimitExceeded = false;
					}
				} catch (error) {
					Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the response: '' + JSON.stringify(response));
					throw ''Could not parse the response. See logs for more information.'';
				}
			} while (apiRateLimitExceeded);
		} else {
			const response = this.request.get(''https://'' + params[''api_host''] + apiPath + apiParams);
		}

		this.request.clearHeader();

		if (this.request.getStatus() === parseInt(params[''http_status_code''])) {
			return response;
		} else {
			Zabbix.log(3, this.zabbixLogPrefix + '' Unexpected HTTP response code: '' + this.request.getStatus());
			throw ''Unexpected HTTP response code: '' + this.request.getStatus();
		}
	};

	this.extractData = function (httpMethod, data, keys, compartment) {
		try {
			data = JSON.parse(data);
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the received JSON object: '' + data);
			throw ''Could not parse received JSON object. See logs for more information.'';
		}

		if (typeof keys == ''object'') {
			var returnBuffer = [];
			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {

				var objectBuffer = {};
				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {
					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {
						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];
					} else {
						Zabbix.log(3, this.zabbixLogPrefix + '' Received an unexpected JSON object. Could not get value for key "'' + keys[key] + ''" in JSON: '' + JSON.stringify(data[dataObj]));
						throw ''Received an unexpected JSON object. See logs for more information.'';
					}
				}
				if (typeof compartment != ''undefined'' && compartment != '''') objectBuffer[''compartment''] = compartment;
				returnBuffer.push(objectBuffer);
			}
			return returnBuffer;
		}

		try {
			if (httpMethod === ''get'') {
				return data[keys];
			} else {
				if (data.length === 0) {
					return 0;
				}
				data = data[0][keys];
				return data[data.length - 1][''value''];
			}
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not find key "'' + keys + ''" in JSON: '' + JSON.stringify(data));
			throw ''Could not find required key in JSON object. See logs for more information.'';
		}
	};
}


const params = JSON.parse(value);
validateZabbixParams([''tenancy_ocid'', ''user_ocid'', ''private_key'', ''fingerprint'', ''api_host'', ''http_status_code''], params);
var oci = new OCI(''VCN'', ''Get VCNs'', params);
var compartments = prepareCompartments(params[''compartment_ocid''], params[''tenancy_ocid'']);

var buffer = [];
compartments.forEach(function (compartment) {
	Array.prototype.push.apply(buffer, oci.extractData(''get'', oci.executeRequest(''get'', ''/20160918/vcns'', ''?compartmentId='' + encodeURIComponent(compartment)), [''id'', ''displayName'', ''lifecycleState'', ''freeformTags''], compartment));
})
return JSON.stringify(buffer);','','0','','','','','1',NULL,'Discover virtual cloud networks (VCNs).','0','7d','1','',NULL,'10s','','','','200','1','0','','','0','0','0','0','0','0','0','378d760173924bf48fbc25c74a520a8b','0','2','0'),
('46941','21','','10618','VNIC [{#NAME}]: Get metrics','oci.compute.vnic.metrics.get[{#ID}]','1m','0','0','0','4','','','','',NULL,NULL,E'function validateZabbixParams(requiredParams, allParams) {
	requiredParams.forEach(function (field) {
		if (typeof allParams !== ''object'' || typeof allParams[field] === ''undefined'' || allParams[field] === '''') {
			throw ''Required param is not set: '' + field + ''.'';
		}
	});
}

function OCI(service, action, params) {
	this.zabbixLogPrefix = ''[ OCI ] [ '' + service + '' ] [ '' + action + '' ]'';
	this.request = new HttpRequest();

	this.hash = function (string) {
		return sha256(string);
	};

	this.sign = function (string) {
		return sign(''sha256'', params[''private_key''], string);
	};

	this.encode = function (hash) {
		const hexArr = hash.match(/.{1,2}/g);
		var uInt8Array = new Uint8Array(hexArr.length);
		hexArr.forEach(function (hex, idx) {
			uInt8Array[idx] = parseInt(hex, 16);
		});
		return btoa(uInt8Array);
	};

	this.getDate = function () {
		const weekdayShortList = [''Sun'', ''Mon'', ''Tue'', ''Wed'', ''Thu'', ''Fri'', ''Sat''];
		const monthShortList = [''jan'', ''feb'', ''mar'', ''apr'', ''may'', ''jun'', ''jul'', ''aug'', ''sep'', ''oct'', ''nov'', ''dec''];
		const today = new Date();
		return weekdayShortList[today.getUTCDay()] + '', '' + today.getUTCDate() + '' '' + monthShortList[today.getUTCMonth()] + '' '' + today.getUTCFullYear() + '' '' + today.getUTCHours() + '':'' + today.getUTCMinutes() + '':'' + today.getUTCSeconds() + '' GMT'';
	};

	this.executeRequest = function (httpMethod, apiPath, apiParams, mql, namespace) {
		var headers = ''(request-target) date host'';
		const contentTypeHeader = ''content-type: application/json'';
		const dateHeader = ''date: '' + this.getDate();
		const hostHeader = ''host: '' + params[''api_host''];
		const requestTarget = ''(request-target): '' + httpMethod + '' '' + apiPath + apiParams;
		var signingString = requestTarget + ''\\n'' + dateHeader + ''\\n'' + hostHeader;
		var reqHeaders = [contentTypeHeader, dateHeader];

		if (httpMethod === ''post'') {
			var body = JSON.stringify({
				''namespace'': namespace,
				''query'': mql
			});
			headers = headers + '' x-content-sha256 content-type content-length'';
			const bodyHeader = ''x-content-sha256: '' + this.encode(this.hash(body));
			const bodyLengthHeader = ''content-length: '' + body.length;
			signingString = signingString + ''\\n'' + bodyHeader + ''\\n'' + contentTypeHeader + ''\\n'' + bodyLengthHeader;
			reqHeaders.push(bodyHeader, bodyLengthHeader);
		}

		const signature = this.encode(this.sign(signingString));

		reqHeaders.push(''Authorization: Signature version="1",keyId="'' + params[''tenancy_ocid''] + ''/'' + params[''user_ocid''] + ''/'' + params[''fingerprint''] + ''",algorithm="rsa-sha256",headers="'' + headers + ''",signature="'' + signature + ''"'');
		for (var header = 0, headerLength = reqHeaders.length; header < headerLength; header++) {
			this.request.addHeader(reqHeaders[header]);
		}

		if (params[''http_proxy'']) {
			this.request.setProxy(params[''http_proxy'']);
			Zabbix.log(4, this.zabbixLogPrefix + '' Using http proxy: '' + params[''http_proxy'']);
		}

		if (httpMethod === ''post'') {
			var apiRateLimitExceeded = false;
			do {
				const response = this.request.post(''https://'' + params[''api_host''] + apiPath + apiParams, body);

				try {
					if (JSON.parse(response)[''code''] === ''TooManyRequests'') {

						apiRateLimitExceeded = true;
						Zabbix.sleep(1000);
					} else {
						apiRateLimitExceeded = false;
					}
				} catch (error) {
					Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the response: '' + JSON.stringify(response));
					throw ''Could not parse the response. See logs for more information.'';
				}
			} while (apiRateLimitExceeded);
		} else {
			const response = this.request.get(''https://'' + params[''api_host''] + apiPath + apiParams);
		}

		this.request.clearHeader();

		if (this.request.getStatus() === parseInt(params[''http_status_code''])) {
			return response;
		} else {
			Zabbix.log(3, this.zabbixLogPrefix + '' Unexpected HTTP response code: '' + this.request.getStatus());
			throw ''Unexpected HTTP response code: '' + this.request.getStatus();
		}
	};

	this.extractData = function (httpMethod, data, keys, compartment) {
		try {
			data = JSON.parse(data);
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not parse the received JSON object: '' + data);
			throw ''Could not parse received JSON object. See logs for more information.'';
		}

		if (typeof keys == ''object'') {
			var returnBuffer = [];
			for (var dataObj = 0, dataLength = data.length; dataObj < dataLength; dataObj++) {

				var objectBuffer = {};
				for (var key = 0, keysLength = keys.length; key < keysLength; key++) {
					if (data[dataObj][keys[key]] || data[dataObj][keys[key]] == null) {
						objectBuffer[keys[key].match(/^[a-z]+$|[A-Z][a-z]+$/)[0].toLowerCase()] = data[dataObj][keys[key]];
					} else {
						Zabbix.log(3, this.zabbixLogPrefix + '' Received an unexpected JSON object. Could not get value for key "'' + keys[key] + ''" in JSON: '' + JSON.stringify(data[dataObj]));
						throw ''Received an unexpected JSON object. See logs for more information.'';
					}
				}
				if (typeof compartment != ''undefined'' && compartment != '''') objectBuffer[''compartment''] = compartment;
				returnBuffer.push(objectBuffer);
			}
			return returnBuffer;
		}

		try {
			if (httpMethod === ''get'') {
				return data[keys];
			} else {
				if (data.length === 0) {
					return 0;
				}
				data = data[0][keys];
				return data[data.length - 1][''value''];
			}
		} catch (error) {
			Zabbix.log(3, this.zabbixLogPrefix + '' Could not find key "'' + keys + ''" in JSON: '' + JSON.stringify(data));
			throw ''Could not find required key in JSON object. See logs for more information.'';
		}
	};
}

function buildMql(id, metrics, defaultStatistic, resourceType) {
	resourceType = resourceType === '''' || resourceType === undefined ? ''resourceId'' : resourceType;
	this.query = ''['' + params[''req_interval''] + ''m]{'' + resourceType + ''='' + id + ''}.'';

	for (var i = 0, metricsLength = metrics.length; i < metricsLength; i++) {
		const metric = ((Array.isArray(metrics[i]) ? metrics[i] : [metrics[i], defaultStatistic]));
		metrics[i] = [metric[0], this.query + metric[1]];
	}
}


const params = JSON.parse(value);
validateZabbixParams([''tenancy_ocid'', ''user_ocid'', ''private_key'', ''fingerprint'', ''api_host'', ''vnic_id'', ''http_status_code'', ''req_interval'', ''compartment_id''], params);
var oci = new OCI(''Compute - VNIC'', ''Get metrics'', params);

const metrics = [
	''VnicEgressDropsSecurityList'',
	''VnicIngressDropsSecurityList'',
	''VnicFromNetworkBytes'',
	''VnicFromNetworkPackets'',
	''VnicToNetworkBytes'',
	''VnicToNetworkPackets'',
	''VnicIngressDropsThrottle'',
	''VnicEgressDropsThrottle'',
	''VnicIngressDropsConntrackFull'',
	''VnicEgressDropsConntrackFull'',
	''VnicConntrackUtilPercent'',
	[''VnicConntrackIsFull'', ''last''],
	''SmartnicBufferDropsFromNetwork'',
	''SmartnicBufferDropsFromHost''
];
buildMql(params[''vnic_id''], metrics, ''sum'');

var result = {};
for (var i = 0, metricsLength = metrics.length; i < metricsLength; i++) {
	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_vcn''), ''aggregatedDatapoints'');
}
return JSON.stringify(result);','','0','','','','','2',NULL,'Gets virtual network interface card metrics.','0','7d','0','',NULL,'30s','','','','200','1','0','','','0','0','0','0','0','0','0','eb79782153524452ba4ba8506fb207a5','0','2','0'),
('46958','11','','10317','Get database','db.odbc.get[get_database,"{$MYSQL.DSN}"]','1h','0','0','0','4','','','','',NULL,NULL,'show databases','','0','{$MYSQL.USER}','{$MYSQL.PASSWORD}','','','0',NULL,'Used for scanning databases in DBMS.','0','7d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','70491bf6b6af401c9dfb10c0cbfddee1','0','2','0'),
('46959','11','','10317','Get replication','db.odbc.get[get_replication,"{$MYSQL.DSN}"]','1m','0','0','0','4','','','','',NULL,NULL,'show slave status','','0','{$MYSQL.USER}','{$MYSQL.PASSWORD}','','','0',NULL,'Gets replication status information.','0','7d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','e389af9f1d134e028e3b637544c8a265','0','2','0'),
('46960','11','','10328','Get archive log','db.odbc.get[get_archivelog,,"Driver={$ORACLE.DRIVER};DBQ=//{$ORACLE.HOST}:{$ORACLE.PORT}/{$ORACLE.SERVICE};"]','1h','0','0','0','4','','','','',NULL,NULL,'SELECT d.dest_name
FROM v$archive_dest d , v$database db WHERE d.status != ''INACTIVE'' AND db.log_mode = ''ARCHIVELOG'';','','0','{$ORACLE.USER}','{$ORACLE.PASSWORD}','','','0',NULL,'Gets the destinations of the log archive.','0','7d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','76591a03cf684d30ae15eca8519ce1dd','0','2','0'),
('46961','11','','10328','Get ASM disk groups','db.odbc.get[get_asm,,"Driver={$ORACLE.DRIVER};DBQ=//{$ORACLE.HOST}:{$ORACLE.PORT}/{$ORACLE.SERVICE};"]','1h','0','0','0','4','','','','',NULL,NULL,'SELECT name AS dgname FROM v$asm_diskgroup;','','0','{$ORACLE.USER}','{$ORACLE.PASSWORD}','','','0',NULL,'Gets the ASM disk groups.','0','7d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','10f3da9afb674ff18956aa99229de8dd','0','2','0'),
('46962','11','','10328','Get database','db.odbc.get[get_db,,"Driver={$ORACLE.DRIVER};DBQ=//{$ORACLE.HOST}:{$ORACLE.PORT}/{$ORACLE.SERVICE};"]','1h','0','0','0','4','','','','',NULL,NULL,'SELECT name as DBNAME, DECODE(CDB, ''YES'', ''CDB'', ''No-CDB'') AS TYPE  FROM V$DATABASE;','','0','{$ORACLE.USER}','{$ORACLE.PASSWORD}','','','0',NULL,'Gets the databases in the database management system (DBMS).','0','7d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','7ca479f46bb2435f9f9cb62d404fa37c','0','2','0'),
('46963','11','','10328','Get PDB','db.odbc.get[get_pdb,,"Driver={$ORACLE.DRIVER};DBQ=//{$ORACLE.HOST}:{$ORACLE.PORT}/{$ORACLE.SERVICE};"]','1h','0','0','0','4','','','','',NULL,NULL,'SELECT name as DBNAME FROM V$PDBS;','','0','{$ORACLE.USER}','{$ORACLE.PASSWORD}','','','0',NULL,'Gets the pluggable database (PDB) in DBMS.','0','7d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','de5aa291b7da4733ad26d517e8ff55cf','0','2','0'),
('46964','11','','10328','Get tablespace','db.odbc.get[get_tablespace,,"Driver={$ORACLE.DRIVER};DBQ=//{$ORACLE.HOST}:{$ORACLE.PORT}/{$ORACLE.SERVICE};"]','1h','0','0','0','4','','','','',NULL,NULL,'SELECT NVL(CON$NAME, ''DB'') CON_NAME,
TABLESPACE_NAME TABLESPACE,
CONTENTS
FROM CDB_TABLESPACES;','','0','{$ORACLE.USER}','{$ORACLE.PASSWORD}','','','0',NULL,'Gets tablespaces in DBMS.','0','7d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','2310462a8936465c8a62d8586ab0ba65','0','2','0'),
('46965','20','1.3.6.1.4.1.12356.101.13.1.5.0','10604','HA config sync','ha.auto.sync[fgHaAutoSync.0]','1h','31d','365d','0','3','','','','',NULL,'1206','','','0','','','','','0',NULL,'MIB: FORTINET-FORTIGATE-MIB
Configuration of an automatic configuration synchronization (enabled or disabled).','0','7d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','ea59bff13fd44c37aa5bd711146fe3d9','0','2','0'),
('46966','20','1.3.6.1.4.1.12356.101.13.1.2.0','10604','HA cluster group ID','ha.cluster.group_id[fgHaGroupId.0]','1h','31d','0','0','3','','','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: FORTINET-FORTIGATE-MIB
HA cluster group ID device is configured for.','0','7d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','dbc47cff3e60401d9a52f590e1ed6281','0','2','0'),
('46967','20','1.3.6.1.4.1.12356.101.13.1.7.0','10604','HA cluster group name','ha.cluster.group_name[fgHaGroupName.0]','1h','31d','0','0','1','','','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: FORTINET-FORTIGATE-MIB
HA cluster group name.','0','7d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','4e2b57a68243445e87ca0e23277bafd6','0','2','0'),
('46968','20','1.3.6.1.4.1.12356.101.13.1.4.0','10604','HA cluster primary override','ha.cluster.override[fgHaOverride.0]','1h','31d','365d','0','3','','','','',NULL,'1206','','','0','','','','','0',NULL,'MIB: FORTINET-FORTIGATE-MIB
Status of the primary override flag.','0','7d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','b6bdf8c8d09140ffa4087d0204a0711d','0','2','0'),
('46969','20','1.3.6.1.4.1.12356.101.13.1.3.0','10604','HA cluster priority','ha.cluster.priority[fgHaPriority.0]','1h','31d','365d','0','3','','','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: FORTINET-FORTIGATE-MIB
HA clustering priority of the device (default = 128).','0','7d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','3f1d2dfb8fd74e80aedb6fa0b7ff7215','0','2','0'),
('46970','20','walk[1.3.6.1.4.1.12356.101.13.2.1.1]','10604','SNMP walk HA members','ha.members.walk','1m','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Used for discovering HA members from FORTINET-FORTIGATE-MIB.','0','7d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','ff27aa75a1d84aa5a472fbf114f8dec0','0','2','0'),
('46971','20','1.3.6.1.4.1.12356.101.13.1.1.0','10604','HA mode','ha.mode[fgHaSystemMode.0]','1h','31d','0','0','3','','','','',NULL,'1208','','','0','','','','','0',NULL,'MIB: FORTINET-FORTIGATE-MIB
High-availability mode (Standalone, A-A or A-P).','0','7d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','3d9bb1ddb4924d5ba4dc75fb4103cc10','0','2','0'),
('46972','20','1.3.6.1.4.1.12356.101.13.1.6.0','10604','HA load-balancing schedule','ha.schedule[fgHaSchedule.0]','1h','31d','365d','0','3','','','','',NULL,'1205','','','0','','','','','0',NULL,'MIB: FORTINET-FORTIGATE-MIB
Load-balancing schedule of cluster (in A-A mode).','0','7d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','bd3dc8fdcb8e41569f1f81b2624e1462','0','2','0'),
('46973','20','walk[1.3.6.1.4.1.12356.101.4.3.2.1]','10604','SNMP walk hardware sensors','hw.sensor.walk','1m','0','0','0','4','','','','',NULL,NULL,'','','0','','','','','0',NULL,'Used for discovering hardware sensors from FORTINET-FORTIGATE-MIB.','0','7d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','bb422f92e3ad4eafb9f43f0167a250ee','0','2','0'),
('46974','20','1.3.6.1.4.1.12356.101.9.2.1.1.2.1','10604','Blocked intrusions','ips.blocked[fgIpsIntrusionsBlocked.0]','1m','31d','365d','0','0','','','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: FORTINET-FORTIGATE-MIB
Number of intrusions blocked per second.','0','7d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','04f58b6b63b945a08a27799bee741702','0','2','0'),
('46975','20','1.3.6.1.4.1.12356.101.4.2.2.0','10604','IPS database version','ips.database.version[fgSysVersionIps.0]','1h','31d','0','0','1','','','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: FORTINET-FORTIGATE-MIB
IPS signature database version installed on the device.','0','7d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','9a42006208224b94a64ecc13437516b6','0','2','0'),
('46976','20','1.3.6.1.4.1.12356.101.9.2.1.1.9.1','10604','Detected anomaly based intrusions','ips.detected.anomaly[fgIpsAnomalyDetections.0]','1m','31d','365d','0','0','','','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: FORTINET-FORTIGATE-MIB
Number of intrusions detected as anomalies per second.','0','7d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','afa9709de4c34d0c82aaf87c5b4f4572','0','2','0'),
('46977','20','1.3.6.1.4.1.12356.101.9.2.1.1.3.1','10604','Detected critical intrusions','ips.detected.crit[fgIpsCritSevDetections.0]','1m','31d','365d','0','0','','','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: FORTINET-FORTIGATE-MIB
Number of critical severity intrusions detected per second.','0','7d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','20ceeb0c520d454bba3d032d10a5db11','0','2','0'),
('46978','20','1.3.6.1.4.1.12356.101.9.2.1.1.4.1','10604','Detected high intrusions','ips.detected.high[fgIpsHighSevDetections.0]','1m','31d','365d','0','0','','','','',NULL,NULL,'','','0','','','','','0',NULL,'MIB: FORTINET-FORTIGATE-MIB
Number of high severity intrusions detected per second.','0','7d','0','',NULL,'','','','','200','1','0','','','0','0','0','0','0','0','0','badcc4a4fe3d4b219a2c67cda182ff4c','0','2','0'),
