|
| 1 | +#! /usr/bin/env ruby |
| 2 | +# |
| 3 | +# metrics-waf |
| 4 | +# |
| 5 | +# DESCRIPTION: |
| 6 | +# Gets latency metrics from CloudWatch and puts them in Graphite for longer term storage |
| 7 | +# |
| 8 | +# OUTPUT: |
| 9 | +# metric-data |
| 10 | +# |
| 11 | +# PLATFORMS: |
| 12 | +# Linux |
| 13 | +# |
| 14 | +# DEPENDENCIES: |
| 15 | +# gem: aws-sdk |
| 16 | +# gem: sensu-plugin |
| 17 | +# gem: sensu-plugin-aws |
| 18 | +# gem: time |
| 19 | +# |
| 20 | +# USAGE: |
| 21 | +# |
| 22 | +# |
| 23 | +# NOTES: |
| 24 | +# |
| 25 | +# LICENSE: |
| 26 | +# Zubov Yuri <[email protected]> sponsored by Actility, https://www.actility.com |
| 27 | +# Released under the same terms as Sensu (the MIT license); see LICENSE |
| 28 | +# for details. |
| 29 | +# |
| 30 | + |
| 31 | +require 'sensu-plugin/metric/cli' |
| 32 | +require 'aws-sdk' |
| 33 | +require 'sensu-plugins-aws' |
| 34 | +require 'time' |
| 35 | + |
| 36 | +class WafMetrics < Sensu::Plugin::Metric::CLI::Generic |
| 37 | + include CloudwatchCommon |
| 38 | + |
| 39 | + option :scheme, |
| 40 | + description: 'Metric naming scheme, text to prepend to metric', |
| 41 | + short: '-s SCHEME', |
| 42 | + long: '--scheme SCHEME', |
| 43 | + default: 'aws.waf' |
| 44 | + |
| 45 | + option :aws_region, |
| 46 | + short: '-r AWS_REGION', |
| 47 | + long: '--aws-region REGION', |
| 48 | + description: 'AWS Region (defaults to us-east-1).', |
| 49 | + default: 'us-east-1' |
| 50 | + |
| 51 | + option :metric, |
| 52 | + description: 'Metric to fetch', |
| 53 | + short: '-m METRIC', |
| 54 | + long: '--metric', |
| 55 | + required: false, |
| 56 | + in: %w[AllowedRequests BlockedRequests CountedRequests PassedRequests] |
| 57 | + |
| 58 | + option :end_time, |
| 59 | + short: '-t T', |
| 60 | + long: '--end-time TIME', |
| 61 | + default: Time.now, |
| 62 | + proc: proc { |a| Time.parse a }, |
| 63 | + description: 'CloudWatch metric statistics end time' |
| 64 | + |
| 65 | + option :period, |
| 66 | + short: '-p N', |
| 67 | + long: '--period SECONDS', |
| 68 | + default: 60, |
| 69 | + proc: proc(&:to_i), |
| 70 | + description: 'CloudWatch metric statistics period' |
| 71 | + |
| 72 | + def print_statistics(statistics, config) |
| 73 | + statistics.each do |key, stats| |
| 74 | + r = client.get_metric_statistics(metrics_request(config).merge(metric_name: key, statistics: [stats])) |
| 75 | + keys = [config[:scheme]] |
| 76 | + keys.concat([key, stats]) |
| 77 | + unless r[:datapoints].first.nil? |
| 78 | + output metric_name: keys.join('.'), value: r[:datapoints].first[stats.downcase] |
| 79 | + end |
| 80 | + end |
| 81 | + end |
| 82 | + |
| 83 | + def run |
| 84 | + statistic = { |
| 85 | + 'AllowedRequests' => 'Sum', |
| 86 | + 'BlockedRequests' => 'Sum', |
| 87 | + 'CountedRequests' => 'Sum', |
| 88 | + 'PassedRequests' => 'Sum' |
| 89 | + } |
| 90 | + |
| 91 | + unless config[:metric].nil? |
| 92 | + statistic.select! { |key, _| key == config[:metric] } |
| 93 | + end |
| 94 | + |
| 95 | + new_config = config.clone |
| 96 | + new_config[:namespace] = 'WAF' |
| 97 | + new_config[:dimensions] = [ |
| 98 | + { |
| 99 | + name: 'WebACL', |
| 100 | + value: 'SecurityAutomationsMaliciousRequesters' |
| 101 | + }, |
| 102 | + { |
| 103 | + name: 'Rule', |
| 104 | + value: 'ALL' |
| 105 | + } |
| 106 | + ] |
| 107 | + |
| 108 | + print_statistics(statistic, new_config) |
| 109 | + ok |
| 110 | + end |
| 111 | +end |
0 commit comments