radiosonde 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +72 -0
- data/Rakefile +5 -0
- data/bin/radiosonde +110 -0
- data/lib/radiosonde/client.rb +66 -0
- data/lib/radiosonde/dsl/comparison_operator.rb +22 -0
- data/lib/radiosonde/dsl/context/alarm.rb +124 -0
- data/lib/radiosonde/dsl/context.rb +45 -0
- data/lib/radiosonde/dsl/converter.rb +119 -0
- data/lib/radiosonde/dsl/statistic.rb +23 -0
- data/lib/radiosonde/dsl/unit.rb +44 -0
- data/lib/radiosonde/dsl/validator.rb +46 -0
- data/lib/radiosonde/dsl.rb +11 -0
- data/lib/radiosonde/exporter.rb +60 -0
- data/lib/radiosonde/ext/cloud_watch_ext.rb +9 -0
- data/lib/radiosonde/ext/string_ext.rb +25 -0
- data/lib/radiosonde/logger.rb +27 -0
- data/lib/radiosonde/utils.rb +25 -0
- data/lib/radiosonde/version.rb +3 -0
- data/lib/radiosonde/wrapper/alarm.rb +109 -0
- data/lib/radiosonde/wrapper/alarm_collection.rb +29 -0
- data/lib/radiosonde/wrapper/cloud_watch.rb +14 -0
- data/lib/radiosonde/wrapper.rb +7 -0
- data/lib/radiosonde.rb +29 -0
- data/radiosonde.gemspec +27 -0
- data/spec/radiosonde_spec.rb +5 -0
- data/spec/spec_helper.rb +1 -0
- metadata +162 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 75143e75e9fad051bdae8993ad6d67d583b3873f
|
4
|
+
data.tar.gz: d0c7c4e7fee046cd4d644702aab4b406200f126c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b1bf53f56c20e10b82bed5cbf3926335acaaa1603a5ddf0de7cf2dfbcfb2fa82f048bc3050663054f5c68c776e42cfbf193502246a1e0f7ceb70316b72238f5c
|
7
|
+
data.tar.gz: a0fc622cfc46c04b57b63771d07010ea98e50bbb005e2387482b6dcaf1d4ad46090a02cb6ec9b8435a947350736b6c55f2afdbbe5e74069f2c351c9739ae26be
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Genki Sugawara
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
# Radiosonde
|
2
|
+
|
3
|
+
Radiosonde is a tool to manage CloudWatch Alarm.
|
4
|
+
|
5
|
+
It defines the state of CloudWatch Alarm using DSL, and updates CloudWatch Alarm according to DSL.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'radiosonde'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install radiosonde
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
```sh
|
24
|
+
export AWS_ACCESS_KEY_ID='...'
|
25
|
+
export AWS_SECRET_ACCESS_KEY='...'
|
26
|
+
export AWS_REGION='us-east-1'
|
27
|
+
radiosonde -e -o Alarmfile # export CloudWatch Alarm
|
28
|
+
vi Alarmfile
|
29
|
+
radiosonde -a --dry-run
|
30
|
+
radiosonde -a # apply `Alarmfile` to CloudWatch
|
31
|
+
```
|
32
|
+
|
33
|
+
## Help
|
34
|
+
|
35
|
+
```
|
36
|
+
Usage: radiosonde [options]
|
37
|
+
-p, --profile PROFILE_NAME
|
38
|
+
-k, --access-key ACCESS_KEY
|
39
|
+
-s, --secret-key SECRET_KEY
|
40
|
+
-r, --region REGION
|
41
|
+
-a, --apply
|
42
|
+
-f, --file FILE
|
43
|
+
--dry-run
|
44
|
+
-e, --export
|
45
|
+
-o, --output FILE
|
46
|
+
--no-color
|
47
|
+
--debug
|
48
|
+
```
|
49
|
+
|
50
|
+
## Alarmfile example
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
require 'other/alarmfile'
|
54
|
+
|
55
|
+
alarm "alarm1" do
|
56
|
+
namespace "AWS/EC2"
|
57
|
+
metric_name "CPUUtilization"
|
58
|
+
dimensions "InstanceId"=>"i-XXXXXXXX"
|
59
|
+
period 300
|
60
|
+
statistic :average
|
61
|
+
threshold ">=", 50.0
|
62
|
+
evaluation_periods 1
|
63
|
+
actions_enabled true
|
64
|
+
alarm_actions []
|
65
|
+
ok_actions []
|
66
|
+
insufficient_data_actions ["arn:aws:sns:us-east-1:123456789012:my_topic"]
|
67
|
+
end
|
68
|
+
|
69
|
+
alarm "alarm2" do
|
70
|
+
...
|
71
|
+
end
|
72
|
+
```
|
data/Rakefile
ADDED
data/bin/radiosonde
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$: << File.expand_path("#{File.dirname __FILE__}/../lib")
|
3
|
+
require 'rubygems'
|
4
|
+
require 'radiosonde'
|
5
|
+
require 'optparse'
|
6
|
+
|
7
|
+
Version = Radiosonde::VERSION
|
8
|
+
DEFAULT_FILENAME = 'Alarmfile'
|
9
|
+
|
10
|
+
mode = nil
|
11
|
+
file = DEFAULT_FILENAME
|
12
|
+
output_file = '-'
|
13
|
+
|
14
|
+
options = {
|
15
|
+
:dry_run => false,
|
16
|
+
:color => true,
|
17
|
+
:debug => false,
|
18
|
+
}
|
19
|
+
|
20
|
+
ARGV.options do |opt|
|
21
|
+
begin
|
22
|
+
access_key = nil
|
23
|
+
secret_key = nil
|
24
|
+
region = nil
|
25
|
+
profile_name = nil
|
26
|
+
|
27
|
+
opt.on('-p', '--profile PROFILE_NAME') {|v| profile_name = v }
|
28
|
+
opt.on('-k', '--access-key ACCESS_KEY') {|v| access_key = v }
|
29
|
+
opt.on('-s', '--secret-key SECRET_KEY') {|v| secret_key = v }
|
30
|
+
opt.on('-r', '--region REGION') {|v| region = v }
|
31
|
+
opt.on('-a', '--apply') { mode = :apply }
|
32
|
+
opt.on('-f', '--file FILE') {|v| file = v }
|
33
|
+
opt.on('', '--dry-run') { options[:dry_run] = true }
|
34
|
+
opt.on('-e', '--export') { mode = :export }
|
35
|
+
opt.on('-o', '--output FILE') {|v| output_file = v }
|
36
|
+
opt.on('' , '--no-color') { options[:color] = false }
|
37
|
+
opt.on('' , '--debug') { options[:debug] = true }
|
38
|
+
opt.parse!
|
39
|
+
|
40
|
+
aws_opts = {}
|
41
|
+
|
42
|
+
if access_key and secret_key
|
43
|
+
aws_opts = {
|
44
|
+
:access_key_id => access_key,
|
45
|
+
:secret_access_key => secret_key,
|
46
|
+
}
|
47
|
+
elsif profile_name
|
48
|
+
provider = AWS::Core::CredentialProviders::SharedCredentialFileProvider.new(
|
49
|
+
:profile_name => profile_name
|
50
|
+
)
|
51
|
+
aws_opts[:credential_provider] = provider
|
52
|
+
elsif (access_key and !secret_key) or (!access_key and secret_key) or mode.nil?
|
53
|
+
puts opt.help
|
54
|
+
exit 1
|
55
|
+
end
|
56
|
+
|
57
|
+
aws_opts[:region] = region if region
|
58
|
+
AWS.config(aws_opts)
|
59
|
+
rescue => e
|
60
|
+
$stderr.puts("[ERROR] #{e.message}")
|
61
|
+
exit 1
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
String.colorize = options[:color]
|
66
|
+
|
67
|
+
if options[:debug]
|
68
|
+
AWS.config({
|
69
|
+
:http_wire_trace => true,
|
70
|
+
:logger => Radiosonde::Logger.instance,
|
71
|
+
})
|
72
|
+
end
|
73
|
+
|
74
|
+
begin
|
75
|
+
logger = Radiosonde::Logger.instance
|
76
|
+
logger.set_debug(options[:debug])
|
77
|
+
client = Radiosonde::Client.new(options)
|
78
|
+
|
79
|
+
case mode
|
80
|
+
when :export
|
81
|
+
if output_file == '-'
|
82
|
+
logger.info('# Export Alarm')
|
83
|
+
puts client.export(options)
|
84
|
+
else
|
85
|
+
logger.info("Export Alarm to `#{output_file}`")
|
86
|
+
open(output_file, 'wb') {|f| f.puts client.export(options) }
|
87
|
+
end
|
88
|
+
when :apply
|
89
|
+
unless File.exist?(file)
|
90
|
+
raise "No Alarmfile found (looking for: #{file})"
|
91
|
+
end
|
92
|
+
|
93
|
+
msg = "Apply `#{file}` to CloudWatch"
|
94
|
+
msg << ' (dry-run)' if options[:dry_run]
|
95
|
+
logger.info(msg)
|
96
|
+
|
97
|
+
updated = client.apply(file)
|
98
|
+
|
99
|
+
logger.info('No change'.intense_blue) unless updated
|
100
|
+
else
|
101
|
+
raise 'must not happen'
|
102
|
+
end
|
103
|
+
rescue => e
|
104
|
+
if options[:debug]
|
105
|
+
raise e
|
106
|
+
else
|
107
|
+
$stderr.puts("[ERROR] #{e.message}".red)
|
108
|
+
exit 1
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
class Radiosonde::Client
|
2
|
+
include Radiosonde::Logger::Helper
|
3
|
+
include Radiosonde::Utils
|
4
|
+
|
5
|
+
def initialize(options = {})
|
6
|
+
@options = options
|
7
|
+
@cloud_watch = AWS::CloudWatch.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def export(opts = {})
|
11
|
+
exported = nil
|
12
|
+
|
13
|
+
AWS.memoize do
|
14
|
+
exported = Radiosonde::Exporter.export(@cloud_watch, @options.merge(opts))
|
15
|
+
end
|
16
|
+
|
17
|
+
Radiosonde::DSL.convert(exported, @options.merge(opts))
|
18
|
+
end
|
19
|
+
|
20
|
+
def apply(file)
|
21
|
+
AWS.memoize { walk(file) }
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def walk(file)
|
27
|
+
dsl = load_file(file)
|
28
|
+
dsl_alarms = collect_to_hash(dsl.alarms, :alarm_name)
|
29
|
+
aws = Radiosonde::Wrapper.wrap(@cloud_watch, @options)
|
30
|
+
aws_alarms = collect_to_hash(aws.alarms, :alarm_name)
|
31
|
+
|
32
|
+
dsl_alarms.each do |alarm_name, dsl_alarm|
|
33
|
+
aws_alarm = aws_alarms.delete(alarm_name)
|
34
|
+
|
35
|
+
if aws_alarm
|
36
|
+
walk_alarm(dsl_alarm, aws_alarm)
|
37
|
+
else
|
38
|
+
aws.alarms.create(alarm_name, dsl_alarm)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
aws_alarms.each do |alarm_name, aws_alarm|
|
43
|
+
aws_alarm.delete
|
44
|
+
end
|
45
|
+
|
46
|
+
@cloud_watch.modified?
|
47
|
+
end
|
48
|
+
|
49
|
+
def walk_alarm(dsl_alarm, aws_alarm)
|
50
|
+
unless aws_alarm.eql?(dsl_alarm)
|
51
|
+
aws_alarm.update(dsl_alarm)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def load_file(file)
|
56
|
+
if file.kind_of?(String)
|
57
|
+
open(file) do |f|
|
58
|
+
Radiosonde::DSL.parse(f.read, file)
|
59
|
+
end
|
60
|
+
elsif file.respond_to?(:read)
|
61
|
+
Radiosonde::DSL.parse(file.read, file.path)
|
62
|
+
else
|
63
|
+
raise TypeError, "can't convert #{file} into File"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class Radiosonde::DSL::ComparisonOperator
|
2
|
+
ALIASES = {
|
3
|
+
'GreaterThanOrEqualToThreshold' => '>=',
|
4
|
+
'GreaterThanThreshold' => '>',
|
5
|
+
'LessThanThreshold' => '<',
|
6
|
+
'LessThanOrEqualToThreshold' => '<=',
|
7
|
+
}
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def conv_to_alias(operator)
|
11
|
+
ALIASES[operator] || operator
|
12
|
+
end
|
13
|
+
|
14
|
+
def valid?(operator)
|
15
|
+
ALIASES.keys.include?(operator) or ALIASES.values.include?(operator)
|
16
|
+
end
|
17
|
+
|
18
|
+
def normalize(operator)
|
19
|
+
(ALIASES.respond_to?(:key) ? ALIASES.key(operator) : ALIASES.index(operator)) || operator
|
20
|
+
end
|
21
|
+
end # of class methods
|
22
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
class Radiosonde::DSL::Context::Alarm
|
2
|
+
include Radiosonde::DSL::Validator
|
3
|
+
|
4
|
+
def initialize(name, &block)
|
5
|
+
@error_identifier = "Alarm `#{name}`"
|
6
|
+
@result = OpenStruct.new(
|
7
|
+
:alarm_name => name,
|
8
|
+
:alarm_actions => [],
|
9
|
+
:ok_actions => [],
|
10
|
+
:insufficient_data_actions => []
|
11
|
+
)
|
12
|
+
instance_eval(&block)
|
13
|
+
end
|
14
|
+
|
15
|
+
def result
|
16
|
+
[
|
17
|
+
:metric_name,
|
18
|
+
:period,
|
19
|
+
:statistic,
|
20
|
+
:threshold,
|
21
|
+
:comparison_operator,
|
22
|
+
:actions_enabled,
|
23
|
+
].each do |name|
|
24
|
+
_required(name, @result[name])
|
25
|
+
end
|
26
|
+
|
27
|
+
@result
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def description(value)
|
33
|
+
_call_once(:alarm_description)
|
34
|
+
@result.alarm_description = value.nil? ? nil : value.to_s
|
35
|
+
end
|
36
|
+
|
37
|
+
def namespace(value)
|
38
|
+
_call_once(:namespace)
|
39
|
+
@result.namespace = value.nil? ? nil : value.to_s
|
40
|
+
end
|
41
|
+
|
42
|
+
def metric_name(value)
|
43
|
+
_call_once(:metric_name)
|
44
|
+
_required(:metric_name, value)
|
45
|
+
@result.metric_name = value.to_s
|
46
|
+
end
|
47
|
+
|
48
|
+
def dimensions(value)
|
49
|
+
_call_once(:dimensions)
|
50
|
+
_expected_type(value, Hash, Array)
|
51
|
+
|
52
|
+
if value.kind_of?(Hash)
|
53
|
+
value = value.map do |name, value|
|
54
|
+
{:name => name, :value => value}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
@result.dimensions = value
|
59
|
+
end
|
60
|
+
|
61
|
+
def period(value)
|
62
|
+
_call_once(:period)
|
63
|
+
@result.period = value.to_i
|
64
|
+
end
|
65
|
+
|
66
|
+
def statistic(value)
|
67
|
+
_call_once(:statistic)
|
68
|
+
_validate("Invalid value: #{value}") do
|
69
|
+
Radiosonde::DSL::Statistic.valid?(value)
|
70
|
+
end
|
71
|
+
|
72
|
+
@result.statistic = Radiosonde::DSL::Statistic.normalize(value)
|
73
|
+
end
|
74
|
+
|
75
|
+
def threshold(operator, value)
|
76
|
+
_call_once(:threshold)
|
77
|
+
_required(:threshold, value)
|
78
|
+
operator = operator.to_s
|
79
|
+
_validate("Invalid operator: #{operator}") do
|
80
|
+
Radiosonde::DSL::ComparisonOperator.valid?(operator)
|
81
|
+
end
|
82
|
+
|
83
|
+
@result.threshold = value.to_f
|
84
|
+
@result.comparison_operator = Radiosonde::DSL::ComparisonOperator.normalize(operator)
|
85
|
+
end
|
86
|
+
|
87
|
+
def evaluation_periods(value)
|
88
|
+
_call_once(:evaluation_periods)
|
89
|
+
@result.evaluation_periods = value.to_i
|
90
|
+
end
|
91
|
+
|
92
|
+
def unit(value)
|
93
|
+
_call_once(:unit)
|
94
|
+
_validate("Invalid value: #{value}") do
|
95
|
+
Radiosonde::DSL::Unit.valid?(value)
|
96
|
+
end
|
97
|
+
|
98
|
+
@result.unit = Radiosonde::DSL::Unit.normalize(value)
|
99
|
+
end
|
100
|
+
|
101
|
+
def actions_enabled(value)
|
102
|
+
_call_once(:actions_enabled)
|
103
|
+
_expected_type(value, TrueClass, FalseClass)
|
104
|
+
@result.actions_enabled = value
|
105
|
+
end
|
106
|
+
|
107
|
+
def alarm_actions(*actions)
|
108
|
+
_call_once(:alarm_actions)
|
109
|
+
_expected_type(actions, Array)
|
110
|
+
@result.alarm_actions = [(actions || [])].flatten
|
111
|
+
end
|
112
|
+
|
113
|
+
def ok_actions(*actions)
|
114
|
+
_call_once(:ok_actions)
|
115
|
+
_expected_type(actions, Array)
|
116
|
+
@result.ok_actions = [(actions || [])].flatten
|
117
|
+
end
|
118
|
+
|
119
|
+
def insufficient_data_actions(*actions)
|
120
|
+
_call_once(:insufficient_data_actions)
|
121
|
+
_expected_type(actions, Array)
|
122
|
+
@result.insufficient_data_actions = [(actions || [])].flatten
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class Radiosonde::DSL::Context
|
2
|
+
include Radiosonde::DSL::Validator
|
3
|
+
|
4
|
+
class << self
|
5
|
+
def eval(dsl, path, opts = {})
|
6
|
+
self.new(path, opts) {
|
7
|
+
eval(dsl, binding, path)
|
8
|
+
}
|
9
|
+
end
|
10
|
+
end # of class methods
|
11
|
+
|
12
|
+
attr_reader :result
|
13
|
+
|
14
|
+
def initialize(path, options = {}, &block)
|
15
|
+
@path = path
|
16
|
+
@options = options
|
17
|
+
@result = OpenStruct.new(:alarms => [])
|
18
|
+
@alarm_names = []
|
19
|
+
instance_eval(&block)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def require(file)
|
25
|
+
alarmfile = File.expand_path(File.join(File.dirname(@path), file))
|
26
|
+
|
27
|
+
if File.exist?(alarmfile)
|
28
|
+
instance_eval(File.read(alarmfile), alarmfile)
|
29
|
+
elsif File.exist?(alarmfile + '.rb')
|
30
|
+
instance_eval(File.read(alarmfile + '.rb'), alarmfile + '.rb')
|
31
|
+
else
|
32
|
+
Kernel.require(file)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def alarm(name, &block)
|
37
|
+
_required(:alarm_name, name)
|
38
|
+
_validate("Alarm `#{name}` is already defined") do
|
39
|
+
not @alarm_names.include?(name)
|
40
|
+
end
|
41
|
+
|
42
|
+
@result.alarms << Radiosonde::DSL::Context::Alarm.new(name, &block).result
|
43
|
+
@alarm_names << name
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
class Radiosonde::DSL::Converter
|
2
|
+
class << self
|
3
|
+
def convert(exported, opts = {})
|
4
|
+
self.new(exported, opts).convert
|
5
|
+
end
|
6
|
+
end # of class methods
|
7
|
+
|
8
|
+
def initialize(exported, options = {})
|
9
|
+
@exported = exported
|
10
|
+
@options = options
|
11
|
+
end
|
12
|
+
|
13
|
+
def convert
|
14
|
+
@exported.each.map {|alarm_name, alarm_attrs|
|
15
|
+
output_alarm(alarm_name, alarm_attrs)
|
16
|
+
}.join("\n")
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def output_alarm(name, attrs)
|
22
|
+
name = name.inspect
|
23
|
+
description = attrs[:description]
|
24
|
+
description = "description #{description.inspect}\n " if description
|
25
|
+
namespace = attrs[:namespace].inspect
|
26
|
+
metric_name = attrs[:metric_name].inspect
|
27
|
+
dimensions = format_dimensions(attrs)
|
28
|
+
dimensions = "dimensions #{dimensions}\n " if dimensions
|
29
|
+
period = attrs[:period].inspect
|
30
|
+
statistic = Radiosonde::DSL::Statistic.conv_to_alias(attrs[:statistic]).inspect
|
31
|
+
threshold = format_threshold(attrs)
|
32
|
+
evaluation_periods = attrs[:evaluation_periods].inspect
|
33
|
+
actions_enabled = attrs[:actions_enabled].inspect
|
34
|
+
alarm_actions = attrs[:alarm_actions].inspect
|
35
|
+
ok_actions = attrs[:ok_actions].inspect
|
36
|
+
insufficient_data_actions = attrs[:insufficient_data_actions].inspect
|
37
|
+
|
38
|
+
if unit = attrs[:unit]
|
39
|
+
unit = Radiosonde::DSL::Unit.conv_to_alias(unit).inspect
|
40
|
+
unit = "unit #{unit}"
|
41
|
+
end
|
42
|
+
|
43
|
+
<<-EOS
|
44
|
+
alarm #{name} do
|
45
|
+
#{description
|
46
|
+
}namespace #{namespace}
|
47
|
+
metric_name #{metric_name}
|
48
|
+
#{dimensions
|
49
|
+
}period #{period}
|
50
|
+
statistic #{statistic}
|
51
|
+
threshold #{threshold}
|
52
|
+
evaluation_periods #{evaluation_periods}
|
53
|
+
#{unit
|
54
|
+
}actions_enabled #{actions_enabled}
|
55
|
+
alarm_actions #{alarm_actions}
|
56
|
+
ok_actions #{ok_actions}
|
57
|
+
insufficient_data_actions #{insufficient_data_actions}
|
58
|
+
end
|
59
|
+
EOS
|
60
|
+
end
|
61
|
+
|
62
|
+
def format_dimensions(attrs)
|
63
|
+
dimensions = attrs[:dimensions] || []
|
64
|
+
return nil if dimensions.empty?
|
65
|
+
names = dimensions.map {|i| i[:name] }
|
66
|
+
|
67
|
+
if duplicated?(names)
|
68
|
+
dimensions.inspect
|
69
|
+
else
|
70
|
+
dimension_hash = {}
|
71
|
+
|
72
|
+
dimensions.each do |dimension|
|
73
|
+
name = dimension[:name]
|
74
|
+
value = dimension[:value]
|
75
|
+
dimension_hash[name] = value
|
76
|
+
end
|
77
|
+
|
78
|
+
unbrace(dimension_hash.inspect)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def format_threshold(attrs)
|
83
|
+
threshold = attrs[:threshold]
|
84
|
+
operator = attrs[:comparison_operator]
|
85
|
+
operator = Radiosonde::DSL::ComparisonOperator.conv_to_alias(operator)
|
86
|
+
|
87
|
+
[
|
88
|
+
operator.inspect,
|
89
|
+
threshold.inspect,
|
90
|
+
].join(', ')
|
91
|
+
end
|
92
|
+
|
93
|
+
def output_actions(attrs, opts = {})
|
94
|
+
prefix = opts[:prefix]
|
95
|
+
enabled = attrs[:actions_enabled].inspect
|
96
|
+
alarm_actions = attrs[:alarm_actions].inspect
|
97
|
+
ok_actions = attrs[:ok_actions].inspect
|
98
|
+
insufficient_data_actions = attrs[:insufficient_data_actions].inspect
|
99
|
+
|
100
|
+
[
|
101
|
+
'actions {',
|
102
|
+
" :enabled => #{enabled},",
|
103
|
+
" :alarm => #{alarm_actions},",
|
104
|
+
" :ok => #{ok_actions},",
|
105
|
+
" :insufficient => #{insufficient_data_actions},",
|
106
|
+
'}',
|
107
|
+
].join("\n#{prefix}")
|
108
|
+
end
|
109
|
+
|
110
|
+
private
|
111
|
+
|
112
|
+
def unbrace(str)
|
113
|
+
str.sub(/\A\s*\{/, '').sub(/\}\s*\z/, '')
|
114
|
+
end
|
115
|
+
|
116
|
+
def duplicated?(list)
|
117
|
+
list.length != list.uniq.length
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class Radiosonde::DSL::Statistic
|
2
|
+
ALIASES = {
|
3
|
+
'SampleCount' => :sample_count,
|
4
|
+
'Average' => :average,
|
5
|
+
'Sum' => :sum,
|
6
|
+
'Minimum' => :minimum,
|
7
|
+
'Maximum' => :maximum,
|
8
|
+
}
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def conv_to_alias(statistic)
|
12
|
+
ALIASES[statistic] || statistic
|
13
|
+
end
|
14
|
+
|
15
|
+
def valid?(statistic)
|
16
|
+
ALIASES.keys.include?(statistic) or ALIASES.values.include?(statistic)
|
17
|
+
end
|
18
|
+
|
19
|
+
def normalize(statistic)
|
20
|
+
(ALIASES.respond_to?(:key) ? ALIASES.key(statistic) : ALIASES.index(statistic)) || statistic
|
21
|
+
end
|
22
|
+
end # of class methods
|
23
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
class Radiosonde::DSL::Unit
|
2
|
+
ALIASES = {
|
3
|
+
'Seconds' => :seconds,
|
4
|
+
'Microseconds' => :microseconds,
|
5
|
+
'Milliseconds' => :milliseconds,
|
6
|
+
'Bytes' => :bytes,
|
7
|
+
'Kilobytes' => :kilobytes,
|
8
|
+
'Megabytes' => :megabytes,
|
9
|
+
'Gigabytes' => :gigabytes,
|
10
|
+
'Terabytes' => :terabytes,
|
11
|
+
'Bits' => :bits,
|
12
|
+
'Kilobits' => :kilobits,
|
13
|
+
'Megabits' => :megabits,
|
14
|
+
'Gigabits' => :gigabits,
|
15
|
+
'Terabits' => :terabits,
|
16
|
+
'Percent' => :percent,
|
17
|
+
'Count' => :count,
|
18
|
+
'Bytes/Second' => :bytes_per_second,
|
19
|
+
'Kilobytes/Second' => :kilobytes_per_second,
|
20
|
+
'Megabytes/Second' => :megabytes_per_second,
|
21
|
+
'Gigabytes/Second' => :gigabytes_per_second,
|
22
|
+
'Terabytes/Second' => :terabytes_per_second,
|
23
|
+
'Bits/Second' => :bits_per_second,
|
24
|
+
'Kilobits/Second' => :kilobits_per_second,
|
25
|
+
'Megabits/Second' => :megabits_per_second,
|
26
|
+
'Gigabits/Second' => :gigabits_per_second,
|
27
|
+
'Terabits/Second' => :terabits_per_second,
|
28
|
+
'Count/Second' => :count_per_second,
|
29
|
+
'None' => :none,
|
30
|
+
}
|
31
|
+
class << self
|
32
|
+
def conv_to_alias(unit)
|
33
|
+
ALIASES[unit] || unit
|
34
|
+
end
|
35
|
+
|
36
|
+
def valid?(unit)
|
37
|
+
ALIASES.keys.include?(unit) or ALIASES.values.include?(unit)
|
38
|
+
end
|
39
|
+
|
40
|
+
def normalize(unit)
|
41
|
+
(ALIASES.respond_to?(:key) ? ALIASES.key(unit) : ALIASES.index(unit)) || unit
|
42
|
+
end
|
43
|
+
end # of class methods
|
44
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Radiosonde::DSL::Validator
|
2
|
+
def _required(name, value)
|
3
|
+
invalid = false
|
4
|
+
|
5
|
+
if value
|
6
|
+
case value
|
7
|
+
when String
|
8
|
+
invalid = value.strip.empty?
|
9
|
+
when Array, Hash
|
10
|
+
invalid = value.empty?
|
11
|
+
end
|
12
|
+
elsif value.nil?
|
13
|
+
invalid = true
|
14
|
+
end
|
15
|
+
|
16
|
+
raise _identify("`#{name}` is required") if invalid
|
17
|
+
end
|
18
|
+
|
19
|
+
def _call_once(method_name)
|
20
|
+
@called ||= []
|
21
|
+
|
22
|
+
if @called.include?(method_name)
|
23
|
+
raise _identify("`#{method_name}` is already defined")
|
24
|
+
end
|
25
|
+
|
26
|
+
@called << method_name
|
27
|
+
end
|
28
|
+
|
29
|
+
def _expected_type(value, *types)
|
30
|
+
unless types.any? {|t| value.kind_of?(t) }
|
31
|
+
raise _identify("Invalid type: #{value}")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def _validate(errmsg)
|
36
|
+
raise _identify(errmsg) unless yield
|
37
|
+
end
|
38
|
+
|
39
|
+
def _identify(errmsg)
|
40
|
+
if @error_identifier
|
41
|
+
errmsg = "#{@error_identifier}: #{errmsg}"
|
42
|
+
end
|
43
|
+
|
44
|
+
return errmsg
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class Radiosonde::DSL
|
2
|
+
class << self
|
3
|
+
def convert(exported, opts = {})
|
4
|
+
Radiosonde::DSL::Converter.convert(exported, opts)
|
5
|
+
end
|
6
|
+
|
7
|
+
def parse(dsl, path, opts = {})
|
8
|
+
Radiosonde::DSL::Context.eval(dsl, path, opts).result
|
9
|
+
end
|
10
|
+
end # of class methods
|
11
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
class Radiosonde::Exporter
|
2
|
+
class << self
|
3
|
+
def export(clowd_watch, opts = {})
|
4
|
+
self.new(clowd_watch, opts).export
|
5
|
+
end
|
6
|
+
end # of class methods
|
7
|
+
|
8
|
+
def initialize(clowd_watch, options = {})
|
9
|
+
@clowd_watch = clowd_watch
|
10
|
+
@options = options
|
11
|
+
end
|
12
|
+
|
13
|
+
def export
|
14
|
+
result = {}
|
15
|
+
|
16
|
+
@clowd_watch.alarms.each do |alarm|
|
17
|
+
export_alarm(alarm, result)
|
18
|
+
end
|
19
|
+
|
20
|
+
return result
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def export_alarm(alarm, result)
|
26
|
+
alarm_attrs = {
|
27
|
+
:description => alarm.alarm_description,
|
28
|
+
:metric_name => alarm.metric_name,
|
29
|
+
:namespace => alarm.namespace,
|
30
|
+
:dimensions => alarm.dimensions,
|
31
|
+
:period => alarm.period,
|
32
|
+
:statistic => alarm.statistic,
|
33
|
+
:threshold => alarm.threshold,
|
34
|
+
:comparison_operator => alarm.comparison_operator,
|
35
|
+
:evaluation_periods => alarm.evaluation_periods,
|
36
|
+
:actions_enabled => alarm.actions_enabled,
|
37
|
+
:alarm_actions => alarm.alarm_actions,
|
38
|
+
:ok_actions => alarm.ok_actions,
|
39
|
+
:insufficient_data_actions => alarm.insufficient_data_actions,
|
40
|
+
:unit => alarm.unit,
|
41
|
+
}
|
42
|
+
|
43
|
+
if @options[:with_status]
|
44
|
+
alarm_attrs[:status] = export_alarm_status(alarm)
|
45
|
+
end
|
46
|
+
|
47
|
+
result[alarm.alarm_name] = alarm_attrs
|
48
|
+
end
|
49
|
+
|
50
|
+
def export_alarm_status(alarm)
|
51
|
+
{
|
52
|
+
:alarm_arn => alarm.alarm_arn,
|
53
|
+
:state_value => alarm.state_value,
|
54
|
+
:state_reason => alarm.state_reason,
|
55
|
+
:state_reason_data => alarm.state_reason_data ? JSON.parse(alarm.state_reason_data) : nil,
|
56
|
+
:state_updated_timestamp => alarm.state_updated_timestamp,
|
57
|
+
:alarm_configuration_updated_timestamp => alarm.alarm_configuration_updated_timestamp,
|
58
|
+
}
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class String
|
2
|
+
@@colorize = false
|
3
|
+
|
4
|
+
class << self
|
5
|
+
def colorize=(value)
|
6
|
+
@@colorize = value
|
7
|
+
end
|
8
|
+
|
9
|
+
def colorize
|
10
|
+
@@colorize
|
11
|
+
end
|
12
|
+
end # of class methods
|
13
|
+
|
14
|
+
Term::ANSIColor::Attribute.named_attributes.map do |attribute|
|
15
|
+
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
16
|
+
def #{attribute.name}
|
17
|
+
if @@colorize
|
18
|
+
Term::ANSIColor.send(#{attribute.name.inspect}, self)
|
19
|
+
else
|
20
|
+
self
|
21
|
+
end
|
22
|
+
end
|
23
|
+
EOS
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class Radiosonde::Logger < ::Logger
|
2
|
+
include Singleton
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
super($stdout)
|
6
|
+
|
7
|
+
self.formatter = proc do |severity, datetime, progname, msg|
|
8
|
+
"#{msg}\n"
|
9
|
+
end
|
10
|
+
|
11
|
+
self.level = Logger::INFO
|
12
|
+
end
|
13
|
+
|
14
|
+
def set_debug(value)
|
15
|
+
self.level = value ? Logger::DEBUG : Logger::INFO
|
16
|
+
end
|
17
|
+
|
18
|
+
module Helper
|
19
|
+
def log(level, message, color, log_id = nil)
|
20
|
+
message = "[#{level.to_s.upcase}] #{message}" unless level == :info
|
21
|
+
message << ": #{log_id}" if log_id
|
22
|
+
message << ' (dry-run)' if @options && @options[:dry_run]
|
23
|
+
logger = (@options && @options[:logger]) || Radiosonde::Logger.instance
|
24
|
+
logger.send(level, message.send(color))
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Radiosonde::Utils
|
2
|
+
def collect_to_hash(collection, *key_attrs)
|
3
|
+
opts = key_attrs.last.kind_of?(Hash) ? key_attrs.pop : {}
|
4
|
+
hash = {}
|
5
|
+
|
6
|
+
collection.each do |item|
|
7
|
+
if block_given?
|
8
|
+
key = yield(item)
|
9
|
+
else
|
10
|
+
key = key_attrs.map {|k| item.send(k) }
|
11
|
+
key = key.first if key_attrs.length == 1
|
12
|
+
end
|
13
|
+
|
14
|
+
if opts[:has_many]
|
15
|
+
hash[key] ||= []
|
16
|
+
hash[key] << item
|
17
|
+
else
|
18
|
+
hash[key] = item
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
return hash
|
23
|
+
end
|
24
|
+
module_function :collect_to_hash
|
25
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
class Radiosonde::Wrapper::Alarm
|
2
|
+
extend Forwardable
|
3
|
+
include Radiosonde::Logger::Helper
|
4
|
+
|
5
|
+
ATTRIBUTES_WITHOUT_NAME = [
|
6
|
+
:alarm_description,
|
7
|
+
:namespace,
|
8
|
+
:metric_name,
|
9
|
+
:dimensions,
|
10
|
+
:period,
|
11
|
+
:statistic,
|
12
|
+
:threshold,
|
13
|
+
:comparison_operator,
|
14
|
+
:evaluation_periods,
|
15
|
+
:actions_enabled,
|
16
|
+
:unit,
|
17
|
+
:alarm_actions,
|
18
|
+
:ok_actions,
|
19
|
+
:insufficient_data_actions,
|
20
|
+
:actions_enabled,
|
21
|
+
]
|
22
|
+
|
23
|
+
ATTRIBUTES = [:alarm_name] + ATTRIBUTES_WITHOUT_NAME
|
24
|
+
|
25
|
+
DEFAULT_VALUES = {
|
26
|
+
:dimensions => []
|
27
|
+
}
|
28
|
+
|
29
|
+
ATTRIBUTES.each do |name|
|
30
|
+
def_delegator :@alarm, name
|
31
|
+
end
|
32
|
+
|
33
|
+
class << self
|
34
|
+
def normalize_attrs(attrs)
|
35
|
+
normalized = {}
|
36
|
+
|
37
|
+
Radiosonde::Wrapper::Alarm::ATTRIBUTES_WITHOUT_NAME.each do |name|
|
38
|
+
unless (value = attrs[name]).nil?
|
39
|
+
normalized[name] = value
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
return normalized
|
44
|
+
end
|
45
|
+
end # of class methods
|
46
|
+
|
47
|
+
def initialize(clowd_watch, alarm, options = {})
|
48
|
+
@clowd_watch = clowd_watch
|
49
|
+
@alarm = alarm
|
50
|
+
@options = options
|
51
|
+
end
|
52
|
+
|
53
|
+
def eql?(dsl)
|
54
|
+
diff(dsl).empty?
|
55
|
+
end
|
56
|
+
|
57
|
+
def update(dsl)
|
58
|
+
delta = diff(dsl)
|
59
|
+
log(:info, 'Update Alarm', :green, "#{self.alarm_name} > #{format_delta(delta)}")
|
60
|
+
|
61
|
+
unless @options[:dry_run]
|
62
|
+
opts = self.class.normalize_attrs(dsl)
|
63
|
+
@alarm.update(opts)
|
64
|
+
@clowd_watch.modify!
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def delete
|
69
|
+
log(:info, 'Delete Alarm', :red, self.alarm_name)
|
70
|
+
|
71
|
+
unless @options[:dry_run]
|
72
|
+
@alarm.delete
|
73
|
+
@clowd_watch.modify!
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def diff(dsl)
|
80
|
+
delta = {}
|
81
|
+
|
82
|
+
ATTRIBUTES.each do |name|
|
83
|
+
self_value = self.send(name)
|
84
|
+
dsl_value = dsl[name]
|
85
|
+
|
86
|
+
if normalize(name, self_value) != normalize(name, dsl_value)
|
87
|
+
delta[name] = {:old => self_value, :new => dsl_value}
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
return delta
|
92
|
+
end
|
93
|
+
|
94
|
+
def format_delta(delta)
|
95
|
+
delta.map {|name, values|
|
96
|
+
"#{name}(#{values[:old]}=>#{values[:new]})"
|
97
|
+
}.join(', ')
|
98
|
+
end
|
99
|
+
|
100
|
+
def normalize(name, value)
|
101
|
+
if [Array, Hash].any? {|c| value.kind_of?(c) }
|
102
|
+
value.sort
|
103
|
+
elsif DEFAULT_VALUES.has_key?(name) and value.nil?
|
104
|
+
DEFAULT_VALUES[name]
|
105
|
+
else
|
106
|
+
value
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class Radiosonde::Wrapper::AlarmCollection
|
2
|
+
include Radiosonde::Logger::Helper
|
3
|
+
|
4
|
+
def initialize(clowd_watch, alarms, options = {})
|
5
|
+
@clowd_watch = clowd_watch
|
6
|
+
@alarms = alarms
|
7
|
+
@options = options
|
8
|
+
end
|
9
|
+
|
10
|
+
def each
|
11
|
+
@alarms.each do |alarm|
|
12
|
+
yield(Radiosonde::Wrapper::Alarm.new(@clowd_watch, alarm, @options))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def create(name, dsl)
|
17
|
+
log(:info, 'Create Alarm', :cyan, name)
|
18
|
+
opts = Radiosonde::Wrapper::Alarm.normalize_attrs(dsl)
|
19
|
+
|
20
|
+
if @options[:dry_run]
|
21
|
+
alarm = OpenStruct.new(opts.merge(:alarm_name => name))
|
22
|
+
else
|
23
|
+
alarm = @alarms.create(name, opts)
|
24
|
+
@clowd_watch.modify!
|
25
|
+
end
|
26
|
+
|
27
|
+
Radiosonde::Wrapper::Alarm.new(@clowd_watch, alarm, @options)
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class Radiosonde::Wrapper::CloudWatch
|
2
|
+
def initialize(clowd_watch, options = {})
|
3
|
+
@clowd_watch = clowd_watch
|
4
|
+
@options = options
|
5
|
+
end
|
6
|
+
|
7
|
+
def alarms
|
8
|
+
Radiosonde::Wrapper::AlarmCollection.new(@clowd_watch, @clowd_watch.alarms, @options)
|
9
|
+
end
|
10
|
+
|
11
|
+
def modified?
|
12
|
+
@clowd_watch.modified?
|
13
|
+
end
|
14
|
+
end
|
data/lib/radiosonde.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
module Radiosonde; end
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
require 'json'
|
5
|
+
require 'logger'
|
6
|
+
require 'ostruct'
|
7
|
+
require 'singleton'
|
8
|
+
|
9
|
+
require 'aws-sdk'
|
10
|
+
require 'term/ansicolor'
|
11
|
+
|
12
|
+
require 'radiosonde/logger'
|
13
|
+
require 'radiosonde/utils'
|
14
|
+
require 'radiosonde/client'
|
15
|
+
require 'radiosonde/dsl'
|
16
|
+
require 'radiosonde/dsl/validator'
|
17
|
+
require 'radiosonde/dsl/comparison_operator'
|
18
|
+
require 'radiosonde/dsl/context'
|
19
|
+
require 'radiosonde/dsl/context/alarm'
|
20
|
+
require 'radiosonde/dsl/converter'
|
21
|
+
require 'radiosonde/dsl/statistic'
|
22
|
+
require 'radiosonde/exporter'
|
23
|
+
require 'radiosonde/ext/cloud_watch_ext'
|
24
|
+
require 'radiosonde/ext/string_ext'
|
25
|
+
require 'radiosonde/version'
|
26
|
+
require 'radiosonde/wrapper'
|
27
|
+
require 'radiosonde/wrapper/alarm'
|
28
|
+
require 'radiosonde/wrapper/alarm_collection'
|
29
|
+
require 'radiosonde/wrapper/cloud_watch'
|
data/radiosonde.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'radiosonde/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'radiosonde'
|
8
|
+
spec.version = Radiosonde::VERSION
|
9
|
+
spec.authors = ['Genki Sugawara']
|
10
|
+
spec.email = ['sgwr_dts@yahoo.co.jp']
|
11
|
+
spec.description = "Radiosonde is a tool to manage CloudWatch Alarm. It defines the state of CloudWatch Alarm using DSL, and updates CloudWatch Alarm according to DSL."
|
12
|
+
spec.summary = "Radiosonde is a tool to manage CloudWatch Alarm."
|
13
|
+
spec.homepage = ''
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_dependency 'aws-sdk', '>= 1.50.0'
|
22
|
+
spec.add_dependency "json"
|
23
|
+
spec.add_dependency "term-ansicolor"
|
24
|
+
spec.add_development_dependency 'bundler', '~> 1.5'
|
25
|
+
spec.add_development_dependency 'rake'
|
26
|
+
spec.add_development_dependency 'rspec', '>= 3.0.0'
|
27
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'radiosonde'
|
metadata
ADDED
@@ -0,0 +1,162 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: radiosonde
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Genki Sugawara
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-08-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: aws-sdk
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.50.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.50.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: json
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: term-ansicolor
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.5'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.5'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 3.0.0
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 3.0.0
|
97
|
+
description: Radiosonde is a tool to manage CloudWatch Alarm. It defines the state
|
98
|
+
of CloudWatch Alarm using DSL, and updates CloudWatch Alarm according to DSL.
|
99
|
+
email:
|
100
|
+
- sgwr_dts@yahoo.co.jp
|
101
|
+
executables:
|
102
|
+
- radiosonde
|
103
|
+
extensions: []
|
104
|
+
extra_rdoc_files: []
|
105
|
+
files:
|
106
|
+
- .gitignore
|
107
|
+
- .rspec
|
108
|
+
- Gemfile
|
109
|
+
- LICENSE.txt
|
110
|
+
- README.md
|
111
|
+
- Rakefile
|
112
|
+
- bin/radiosonde
|
113
|
+
- lib/radiosonde.rb
|
114
|
+
- lib/radiosonde/client.rb
|
115
|
+
- lib/radiosonde/dsl.rb
|
116
|
+
- lib/radiosonde/dsl/comparison_operator.rb
|
117
|
+
- lib/radiosonde/dsl/context.rb
|
118
|
+
- lib/radiosonde/dsl/context/alarm.rb
|
119
|
+
- lib/radiosonde/dsl/converter.rb
|
120
|
+
- lib/radiosonde/dsl/statistic.rb
|
121
|
+
- lib/radiosonde/dsl/unit.rb
|
122
|
+
- lib/radiosonde/dsl/validator.rb
|
123
|
+
- lib/radiosonde/exporter.rb
|
124
|
+
- lib/radiosonde/ext/cloud_watch_ext.rb
|
125
|
+
- lib/radiosonde/ext/string_ext.rb
|
126
|
+
- lib/radiosonde/logger.rb
|
127
|
+
- lib/radiosonde/utils.rb
|
128
|
+
- lib/radiosonde/version.rb
|
129
|
+
- lib/radiosonde/wrapper.rb
|
130
|
+
- lib/radiosonde/wrapper/alarm.rb
|
131
|
+
- lib/radiosonde/wrapper/alarm_collection.rb
|
132
|
+
- lib/radiosonde/wrapper/cloud_watch.rb
|
133
|
+
- radiosonde.gemspec
|
134
|
+
- spec/radiosonde_spec.rb
|
135
|
+
- spec/spec_helper.rb
|
136
|
+
homepage: ''
|
137
|
+
licenses:
|
138
|
+
- MIT
|
139
|
+
metadata: {}
|
140
|
+
post_install_message:
|
141
|
+
rdoc_options: []
|
142
|
+
require_paths:
|
143
|
+
- lib
|
144
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
145
|
+
requirements:
|
146
|
+
- - '>='
|
147
|
+
- !ruby/object:Gem::Version
|
148
|
+
version: '0'
|
149
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
150
|
+
requirements:
|
151
|
+
- - '>='
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '0'
|
154
|
+
requirements: []
|
155
|
+
rubyforge_project:
|
156
|
+
rubygems_version: 2.0.14
|
157
|
+
signing_key:
|
158
|
+
specification_version: 4
|
159
|
+
summary: Radiosonde is a tool to manage CloudWatch Alarm.
|
160
|
+
test_files:
|
161
|
+
- spec/radiosonde_spec.rb
|
162
|
+
- spec/spec_helper.rb
|