You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

923 lines
42 KiB

zabbix_export:
version: '7.0'
template_groups:
- uuid: c2c162144c2d4c5491c8801193af4945
name: Templates/Cloud
host_groups:
- uuid: a571c0d144b14fd4a87a9d9b2aa9fcd6
name: Applications
- uuid: 748ad4d098d447d492bb935c907f652f
name: Databases
- uuid: 137f19e6e2dc4219b33553b812627bc2
name: 'Virtual machines'
templates:
- uuid: c60e5929ab474f67bbe67dc6b04e709d
template: 'AWS by HTTP'
name: 'AWS by HTTP'
description: |
Get AWS EC2, RDS and S3 instances, AWS ECS clusters. Don't forget to read the README.md for the correct setup of the template.
You can discuss this template or leave feedback on our forum https://www.zabbix.com/forum/zabbix-suggestions-and-feedback
Generated by official Zabbix template tool "Templator" 2.0.0
vendor:
name: Zabbix
version: 7.0-0
groups:
- name: Templates/Cloud
discovery_rules:
- uuid: c651911bad9244ad9c8d2dad5b0d70e4
name: 'EC2 instances discovery'
type: SCRIPT
key: aws.ec2.discovery
delay: 12h
params: |
var AwsEC2 = {
params: {},
setParams: function (params) {
['access_key', 'region', 'secret_key'].forEach(function (field) {
if (typeof params !== 'object' || typeof params[field] === 'undefined' || params[field] === '') {
throw 'Required param is not set: "' + field + '".';
}
});
AwsEC2.params = params;
},
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, host, params, data, uri) {
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 = '/' + 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 = AwsEC2.sign('AWS4' + AwsEC2.params.secret_key, date);
key = AwsEC2.sign(key, region);
key = AwsEC2.sign(key, service);
key = AwsEC2.sign(key, 'aws4_request');
var request = new HttpRequest(),
url = 'https://' + host + canonical_uri + '?' + params;
if (typeof AwsEC2.params.proxy !== 'undefined' && AwsEC2.params.proxy !== '') {
request.setProxy(AwsEC2.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=' + AwsEC2.params.access_key + '/' + credential_scope + ', ' + 'SignedHeaders=' + signed_headers + ', ' + 'Signature=' + hmac('sha256', key, request_string));
Zabbix.log(4, '[ AWS EC2 ] Sending request: ' + url);
response = request.post(url, data);
Zabbix.log(4, '[ AWS EC2 ] Received response with status code ' + request.getStatus() + ': ' + response);
if (request.getStatus() !== 200) {
throw 'Request failed with status code ' + request.getStatus() + ': ' + response;
}
if (response !== null) {
try {
response = XML.toJson(response);
}
catch (error) {
throw 'Failed to parse response received from AWS CloudWatch API. Check debug log for more information.';
}
}
return JSON.parse(response);
},
tagToNameInstances: function (instance) {
if (!Array.isArray(instance))
instance = [instance];
instance.forEach(function (item, index, instance_array) {
if (typeof item !== 'object'
|| typeof item.instancesSet !== 'object'
|| typeof item.instancesSet.item !== 'object'
|| item.instancesSet.item.hasOwnProperty('instanceId') === false)
throw 'Failed response parse. Check debug log for more information.';
var instanceName = item.instancesSet.item.instanceId
if (typeof item.instancesSet.item.tagSet === 'object'
&& typeof item.instancesSet.item.tagSet.item === 'object') {
if (!Array.isArray(item.instancesSet.item.tagSet.item))
item.instancesSet.item.tagSet.item = [item.instancesSet.item.tagSet.item];
item.instancesSet.item.tagSet.item.forEach(
function (tag) {
if (tag.hasOwnProperty('key') && tag.key === 'Name') {
instanceName = tag.value;
}
}
);
}
instance_array[index]['instanceName'] = instanceName;
});
return instance;
},
listInstances: function () {
var payload = {};
payload['Action'] = 'DescribeInstances',
payload['Version'] = '2016-11-15'
result = AwsEC2.request('POST', AwsEC2.params.region, 'ec2', 'ec2.' + AwsEC2.params.region + '.amazonaws.com', AwsEC2.prepareParams(payload), '', '');
if (typeof result !== 'object'
|| typeof result.DescribeInstancesResponse !== 'object'
|| typeof result.DescribeInstancesResponse.reservationSet !== 'object') {
throw 'Cannot get EC2 instance list from AWS API. Check debug log for more information.';
}
if (result.DescribeInstancesResponse.reservationSet === null)
return [];
if (typeof result.DescribeInstancesResponse.reservationSet.item !== 'object')
throw 'Cannot get EC2 instance list from AWS API. Check debug log for more information.';
return AwsEC2.tagToNameInstances(result.DescribeInstancesResponse.reservationSet.item);
}
};
try {
AwsEC2.setParams(JSON.parse(value));
return JSON.stringify(AwsEC2.listInstances());
}
catch (error) {
error += (String(error).endsWith('.')) ? '' : '.';
Zabbix.log(3, '[ AWS EC2 ] ERROR: ' + error);
return JSON.stringify({ 'error': error });
}
filter:
evaltype: AND
conditions:
- macro: '{#AWS.EC2.INSTANCE.NAME}'
value: '{$AWS.EC2.LLD.FILTER.NAME.MATCHES}'
formulaid: A
- macro: '{#AWS.EC2.INSTANCE.NAME}'
value: '{$AWS.EC2.LLD.FILTER.NAME.NOT_MATCHES}'
operator: NOT_MATCHES_REGEX
formulaid: B
description: 'Get EC2 instances.'
host_prototypes:
- uuid: c4c830c727294b07926c39b00cf19046
host: '{#AWS.EC2.INSTANCE.ID}'
name: '{#AWS.EC2.INSTANCE.NAME}'
group_links:
- group:
name: 'Virtual machines'
templates:
- name: 'AWS EC2 by HTTP'
macros:
- macro: '{$AWS.EC2.INSTANCE.ID}'
value: '{#AWS.EC2.INSTANCE.ID}'
description: 'EC2 instance ID.'
custom_interfaces: 'YES'
interfaces:
- ip: '{#AWS.EC2.INSTANCE.ID}'
timeout: 15s
parameters:
- name: access_key
value: '{$AWS.ACCESS.KEY.ID}'
- name: secret_key
value: '{$AWS.SECRET.ACCESS.KEY}'
- name: region
value: '{$AWS.REGION}'
- name: proxy
value: '{$AWS.PROXY}'
lld_macro_paths:
- lld_macro: '{#AWS.EC2.INSTANCE.ID}'
path: $.instancesSet.item.instanceId
- lld_macro: '{#AWS.EC2.INSTANCE.NAME}'
path: $.instanceName
- uuid: 44b68894d68c45ec9a5ea787c975ae16
name: 'ECS clusters discovery'
type: SCRIPT
key: aws.ecs.discovery
delay: 12h
params: |
var AwsECS = {
params: {},
setParams: function (params) {
['access_key', 'region', 'secret_key'].forEach(function (field) {
if (typeof params !== 'object' || typeof params[field] === 'undefined' || params[field] === '') {
throw 'Required param is not set: "' + field + '".';
}
});
AwsECS.params = params;
},
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, host, params, data, uri) {
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 = '/' + 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 = AwsECS.sign('AWS4' + AwsECS.params.secret_key, date);
key = AwsECS.sign(key, region);
key = AwsECS.sign(key, service);
key = AwsECS.sign(key, 'aws4_request');
var request = new HttpRequest(),
url = 'https://' + host + canonical_uri + '?' + params;
if (typeof AwsECS.params.proxy !== 'undefined' && AwsECS.params.proxy !== '') {
request.setProxy(AwsECS.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=' + AwsECS.params.access_key + '/' + credential_scope + ', ' + 'SignedHeaders=' + signed_headers + ', ' + 'Signature=' + hmac('sha256', key, request_string));
Zabbix.log(4, '[ AWS ECS ] Sending request: ' + url);
response = request.post(url, data);
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) {
throw 'Failed to parse response received from AWS API. Check debug log for more information.';
}
return response;
},
listClusters: function () {
var payload = {},
result,
ECSClusters,
data = [];
payload['Action'] = 'ListClusters';
payload['Version'] = '2014-11-13';
result = AwsECS.request('POST', AwsECS.params.region, 'ecs', 'ecs.' + AwsECS.params.region + '.amazonaws.com', AwsECS.prepareParams(payload), '', '');
ECSClusters = AwsECS.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],
});
}
if (Array.isArray(data))
return data;
else
return [data];
},
decribeClusters: function (cluster_name) {
var payload = {},
result;
payload['Action'] = 'DescribeClusters';
payload['Version'] = '2014-11-13';
payload['clusters.clusterName'] = cluster_name;
payload['include.statistics'] = 'STATISTICS';
result = AwsECS.request('POST', AwsECS.params.region, 'ecs', 'ecs.' + AwsECS.params.region + '.amazonaws.com', AwsECS.prepareParams(payload), '', '');
return result;
}
};
try {
AwsECS.setParams(JSON.parse(value));
var clusters = AwsECS.listClusters(),
infrastructure = [],
metrics = ['runningEC2TasksCount', 'pendingEC2TasksCount', 'activeEC2ServiceCount', 'drainingEC2ServiceCount'],
ECSClusters = [],
DescribeClusters = [];
DescribeClusters = clusters.map(function (cluster) {
ECSClusters = AwsECS.getField(AwsECS.decribeClusters(cluster.clusters_name), 'DescribeClustersResponse.DescribeClustersResult.clusters')
for (k in ECSClusters) {
var ECS2 = 0;
statistic = AwsECS.getField(ECSClusters[k], 'statistics');
statistic.forEach(function (id) {
for (i in metrics) {
if (AwsECS.getField(id, 'name') === metrics[i]) {
ECS2 += Number(AwsECS.getField(id, 'value'));
}
}
})
infrastructure = (ECS2 > 0) ? 'use_ecs2' : 'serverless';
return {
'clusterName': ECSClusters[k].clusterName,
'status': ECSClusters[k].status,
'infrastructure': infrastructure
}
}
})
return JSON.stringify(DescribeClusters);
}
catch (error) {
error += (String(error).endsWith('.')) ? '' : '.';
Zabbix.log(3, '[ AWS ECS ] ERROR: ' + error);
return JSON.stringify({ 'error': error });
}
filter:
evaltype: AND
conditions:
- macro: '{#AWS.ECS.CLUSTER.NAME}'
value: '{$AWS.ECS.LLD.FILTER.NAME.MATCHES}'
formulaid: A
- macro: '{#AWS.ECS.CLUSTER.NAME}'
value: '{$AWS.ECS.LLD.FILTER.NAME.NOT_MATCHES}'
operator: NOT_MATCHES_REGEX
formulaid: B
- macro: '{#AWS.ECS.CLUSTER.STATUS}'
value: '{$AWS.ECS.LLD.FILTER.STATUS.MATCHES}'
formulaid: C
- macro: '{#AWS.ECS.CLUSTER.STATUS}'
value: '{$AWS.ECS.LLD.FILTER.STATUS.NOT_MATCHES}'
operator: NOT_MATCHES_REGEX
formulaid: D
description: 'Get ECS clusters.'
host_prototypes:
- uuid: 71072e5a149e45b293946866f8220c07
host: '{#AWS.ECS.CLUSTER.NAME}'
name: '{#AWS.ECS.CLUSTER.NAME}'
group_links:
- group:
name: Applications
macros:
- macro: '{$AWS.ECS.CLUSTER.NAME}'
value: '{#AWS.ECS.CLUSTER.NAME}'
description: 'ECS cluster name.'
timeout: 15s
parameters:
- name: access_key
value: '{$AWS.ACCESS.KEY.ID}'
- name: secret_key
value: '{$AWS.SECRET.ACCESS.KEY}'
- name: region
value: '{$AWS.REGION}'
- name: proxy
value: '{$AWS.PROXY}'
lld_macro_paths:
- lld_macro: '{#AWS.ECS.CLUSTER.NAME}'
path: $.clusterName
- lld_macro: '{#AWS.ECS.CLUSTER.STATUS}'
path: $.status
- lld_macro: '{#AWS.ECS.CLUSTER.INFRASTRUCTURE}'
path: $.infrastructure
overrides:
- name: Serverless
step: '1'
filter:
conditions:
- macro: '{#AWS.ECS.CLUSTER.INFRASTRUCTURE}'
value: ^serverless$
formulaid: A
operations:
- operationobject: HOST_PROTOTYPE
operator: REGEXP
templates:
- name: 'AWS ECS Serverless Cluster by HTTP'
- name: 'Use EC2 Infrastructure'
step: '2'
filter:
conditions:
- macro: '{#AWS.ECS.CLUSTER.INFRASTRUCTURE}'
value: ^use_ecs2$
formulaid: A
operations:
- operationobject: HOST_PROTOTYPE
operator: REGEXP
templates:
- name: 'AWS ECS Cluster by HTTP'
- uuid: c1127e674b7548b2802cd8771f3a4768
name: 'RDS instances discovery'
type: SCRIPT
key: aws.rds.discovery
delay: 12h
params: |
var AwsRDS = {
params: {},
setParams: function (params) {
['access_key', 'region', 'secret_key'].forEach(function (field) {
if (typeof params !== 'object' || typeof params[field] === 'undefined' || params[field] === '') {
throw 'Required param is not set: "' + field + '".';
}
});
AwsRDS.params = params;
},
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, host, params, data, uri) {
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 = '/' + 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 = AwsRDS.sign('AWS4' + AwsRDS.params.secret_key, date);
key = AwsRDS.sign(key, region);
key = AwsRDS.sign(key, service);
key = AwsRDS.sign(key, 'aws4_request');
var request = new HttpRequest(),
url = 'https://' + host + canonical_uri + '?' + params;
if (typeof AwsRDS.params.proxy !== 'undefined' && AwsRDS.params.proxy !== '') {
request.setProxy(AwsRDS.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=' + AwsRDS.params.access_key + '/' + credential_scope + ', ' + 'SignedHeaders=' + signed_headers + ', ' + 'Signature=' + hmac('sha256', key, request_string));
Zabbix.log(4, '[ AWS RDS ] Sending request: ' + url);
response = request.post(url, data);
Zabbix.log(4, '[ AWS RDS ] 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) {
throw 'Failed to parse response received from AWS API. Check debug log for more information.';
}
return response;
},
listInstances: function () {
var payload = {};
payload['Action'] = 'DescribeDBInstances',
payload['Version'] = '2014-10-31'
result = AwsRDS.request('POST', AwsRDS.params.region, 'rds', 'rds.' + AwsRDS.params.region + '.amazonaws.com', AwsRDS.prepareParams(payload), '', '');
if (typeof result !== 'object'
|| typeof result.DescribeDBInstancesResponse !== 'object'
|| typeof result.DescribeDBInstancesResponse.DescribeDBInstancesResult !== 'object'
|| typeof result.DescribeDBInstancesResponse.DescribeDBInstancesResult.DBInstances !== 'object') {
throw 'Cannot get DB instance list from AWS RDS API. Check debug log for more information.';
}
if (Array.isArray(result.DescribeDBInstancesResponse.DescribeDBInstancesResult.DBInstances))
return result.DescribeDBInstancesResponse.DescribeDBInstancesResult.DBInstances;
else
return [result.DescribeDBInstancesResponse.DescribeDBInstancesResult.DBInstances];
}
};
try {
AwsRDS.setParams(JSON.parse(value));
return JSON.stringify(AwsRDS.listInstances());
}
catch (error) {
error += (String(error).endsWith('.')) ? '' : '.';
Zabbix.log(3, '[ AWS RDS ] ERROR: ' + error);
return JSON.stringify({ 'error': error });
}
filter:
evaltype: AND
conditions:
- macro: '{#AWS.RDS.INSTANCE.ID}'
value: '{$AWS.RDS.LLD.FILTER.NAME.MATCHES}'
formulaid: A
- macro: '{#AWS.RDS.INSTANCE.ID}'
value: '{$AWS.RDS.LLD.FILTER.NAME.NOT_MATCHES}'
operator: NOT_MATCHES_REGEX
formulaid: B
description: 'Get RDS instances.'
host_prototypes:
- uuid: 799663c52a644f78aa3b3c14d4cc7235
host: '{#AWS.RDS.INSTANCE.ID}'
name: '{#AWS.RDS.INSTANCE.ID}'
group_links:
- group:
name: Databases
templates:
- name: 'AWS RDS instance by HTTP'
macros:
- macro: '{$AWS.RDS.INSTANCE.ID}'
value: '{#AWS.RDS.INSTANCE.ID}'
description: 'RDS instance ID.'
custom_interfaces: 'YES'
interfaces:
- ip: '{#AWS.RDS.INSTANCE.ID}'
timeout: 15s
parameters:
- name: access_key
value: '{$AWS.ACCESS.KEY.ID}'
- name: secret_key
value: '{$AWS.SECRET.ACCESS.KEY}'
- name: region
value: '{$AWS.REGION}'
- name: proxy
value: '{$AWS.PROXY}'
lld_macro_paths:
- lld_macro: '{#AWS.RDS.INSTANCE.ID}'
path: $.DBInstanceIdentifier
- uuid: ab6a97a108fb4dbc9fd1e07378721ffe
name: 'S3 buckets discovery'
type: SCRIPT
key: aws.s3.discovery
delay: 12h
params: |
var AwsS3 = {
params: {},
setParams: function (params) {
['access_key', 'secret_key'].forEach(function (field) {
if (typeof params !== 'object' || typeof params[field] === 'undefined' || params[field] === '') {
throw 'Required param is not set: "' + field + '".';
}
});
AwsS3.params = params;
},
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, host, params, data, uri) {
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 = '/' + 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 = AwsS3.sign('AWS4' + AwsS3.params.secret_key, date);
key = AwsS3.sign(key, region);
key = AwsS3.sign(key, service);
key = AwsS3.sign(key, 'aws4_request');
var request = new HttpRequest(),
url = 'https://' + host + canonical_uri + '?' + params;
if (typeof AwsS3.params.proxy !== 'undefined' && AwsS3.params.proxy !== '') {
request.setProxy(AwsS3.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=' + AwsS3.params.access_key + '/' + credential_scope + ', ' + 'SignedHeaders=' + signed_headers + ', ' + 'Signature=' + hmac('sha256', key, request_string));
Zabbix.log(4, '[ AWS S3 ] Sending request: ' + url);
response = request.get(url);
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;
}
if (response !== null) {
try {
response = XML.toJson(response);
}
catch (error) {
throw 'Failed to parse response received from AWS CloudWatch API. Check debug log for more information.';
}
}
return JSON.parse(response);
},
getBucketLocation: function (bucket_name) {
var payload = {};
payload['location'] = '',
result = AwsS3.request('GET', 'us-east-1', 's3', 's3.amazonaws.com', AwsS3.prepareParams(payload), '', bucket_name);
if (typeof result !== 'object'
|| result.hasOwnProperty('LocationConstraint') === false
) {
throw 'Cannot get buckets region location data from AWS S3 API. Check debug log for more information.';
}
return result.LocationConstraint !== null ? result.LocationConstraint : 'us-east-1';
},
listBuckets: function () {
var payload = {};
payload['Action'] = 'ListBuckets',
payload['Version'] = '2006-03-01',
result = AwsS3.request('GET', 'us-east-1', 's3', 's3.us-east-1.amazonaws.com', AwsS3.prepareParams(payload), '', '');
if (typeof result !== 'object'
|| typeof result.ListAllMyBucketsResult !== 'object'
|| typeof result.ListAllMyBucketsResult.Buckets !== 'object') {
throw 'Cannot get buckets list from AWS S3 API. Check debug log for more information.';
}
if (result.ListAllMyBucketsResult.Buckets === null)
return []
if (typeof result.ListAllMyBucketsResult.Buckets.Bucket !== 'object') {
throw 'Cannot get buckets list from AWS S3 API. Check debug log for more information.';
}
var buckets = [];
if (!Array.isArray(result.ListAllMyBucketsResult.Buckets.Bucket))
buckets = [result.ListAllMyBucketsResult.Buckets.Bucket]
else
buckets = result.ListAllMyBucketsResult.Buckets.Bucket
buckets.forEach(
function (bucket, index, buckets_array) {
if (!bucket.hasOwnProperty('Name'))
throw 'Cannot get location for bucket. Check debug log for more information.';
buckets_array[index]['location'] = AwsS3.getBucketLocation(bucket['Name']);
});
return buckets;
}
};
try {
AwsS3.setParams(JSON.parse(value));
return JSON.stringify(AwsS3.listBuckets());
}
catch (error) {
error += (String(error).endsWith('.')) ? '' : '.';
Zabbix.log(3, '[ AWS S3 ] ERROR: ' + error);
return JSON.stringify({ 'error': error });
}
filter:
evaltype: AND
conditions:
- macro: '{#AWS.S3.NAME}'
value: '{$AWS.S3.LLD.FILTER.NAME.MATCHES}'
formulaid: A
- macro: '{#AWS.S3.NAME}'
value: '{$AWS.S3.LLD.FILTER.NAME.NOT_MATCHES}'
operator: NOT_MATCHES_REGEX
formulaid: B
description: 'Get S3 bucket instances.'
host_prototypes:
- uuid: e45bd9810ea14718b17b875aad3fc544
host: '{#AWS.S3.NAME}'
name: '{#AWS.S3.NAME}'
group_links:
- group:
name: Applications
group_prototypes:
- name: '{#AWS.S3.REGION}'
templates:
- name: 'AWS S3 bucket by HTTP'
macros:
- macro: '{$AWS.REGION}'
value: '{#AWS.S3.REGION}'
description: 'Amazon S3 region code.'
- macro: '{$AWS.S3.BUCKET.NAME}'
value: '{#AWS.S3.NAME}'
description: 'S3 bucket name.'
- macro: '{$AWS.S3.FILTER.ID}'
value: '1'
description: 'S3 bucket requests filter identifier.'
custom_interfaces: 'YES'
interfaces:
- ip: '{#AWS.S3.NAME}'
timeout: 15s
parameters:
- name: access_key
value: '{$AWS.ACCESS.KEY.ID}'
- name: secret_key
value: '{$AWS.SECRET.ACCESS.KEY}'
- name: proxy
value: '{$AWS.PROXY}'
lld_macro_paths:
- lld_macro: '{#AWS.S3.NAME}'
path: $.Name
- lld_macro: '{#AWS.S3.REGION}'
path: $.location
tags:
- tag: class
value: software
- tag: target
value: aws
macros:
- macro: '{$AWS.ACCESS.KEY.ID}'
description: 'Access key ID.'
- macro: '{$AWS.EC2.LLD.FILTER.NAME.MATCHES}'
value: '.*'
description: 'Filter of discoverable EC2 instances by namespace.'
- macro: '{$AWS.EC2.LLD.FILTER.NAME.NOT_MATCHES}'
value: CHANGE_IF_NEEDED
description: 'Filter to exclude discovered EC2 instances by namespace.'
- macro: '{$AWS.ECS.LLD.FILTER.NAME.MATCHES}'
value: '.*'
description: 'Filter of discoverable ECS clusters by name.'
- macro: '{$AWS.ECS.LLD.FILTER.NAME.NOT_MATCHES}'
value: CHANGE_IF_NEEDED
description: 'Filter to exclude discovered ECS clusters by name.'
- macro: '{$AWS.ECS.LLD.FILTER.STATUS.MATCHES}'
value: ACTIVE
description: 'Filter of discoverable ECS clusters by status.'
- macro: '{$AWS.ECS.LLD.FILTER.STATUS.NOT_MATCHES}'
value: CHANGE_IF_NEEDED
description: 'Filter to exclude discovered ECS clusters by status.'
- macro: '{$AWS.PROXY}'
description: 'Sets HTTP proxy value. If this macro is empty then no proxy is used.'
- macro: '{$AWS.RDS.LLD.FILTER.NAME.MATCHES}'
value: '.*'
description: 'Filter of discoverable RDS instances by namespace.'
- macro: '{$AWS.RDS.LLD.FILTER.NAME.NOT_MATCHES}'
value: CHANGE_IF_NEEDED
description: 'Filter to exclude discovered RDS instances by namespace.'
- macro: '{$AWS.REGION}'
value: us-west-1
description: 'Amazon EC2 region code.'
- macro: '{$AWS.S3.LLD.FILTER.NAME.MATCHES}'
value: '.*'
description: 'Filter of discoverable S3 buckets by namespace.'
- macro: '{$AWS.S3.LLD.FILTER.NAME.NOT_MATCHES}'
value: CHANGE_IF_NEEDED
description: 'Filter to exclude discovered S3 buckets by namespace.'
- macro: '{$AWS.SECRET.ACCESS.KEY}'
type: SECRET_TEXT
description: 'Secret access key.'