aws-watcher 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/aws_watcher.rb +106 -0
- data/lib/aws-watcher.rb +35 -0
- metadata +216 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: f28f50f0ca7431183991d62d6ace837e3cc4c99b
|
|
4
|
+
data.tar.gz: 06704407b72737f799420afd04406926fa945052
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 4aa9aae62d9199e876121220d4321aaa17c13d87986c26ae24fa167388e620f8587eb1054855b8eccc24cee8e3bf0a431d2817438ee55abaf87fa807d899ef2b
|
|
7
|
+
data.tar.gz: beb7e55a6c11aa2c6a09a48ea3f83b07b7d0519ce05ebbf55620c5ebfaf0b21b28d3c1215961b799905a4c9742b5a703489db434900fcbfad8c25e5ba0ae1d23
|
data/bin/aws_watcher.rb
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
#
|
|
3
|
+
# Listen for AWS CloudWatch Events EC2 running events delivered via SQS
|
|
4
|
+
# and removes events after nodes have sucessfully bootstrapped to Chef.
|
|
5
|
+
# Copyright (c) 2017 Ben Abrams
|
|
6
|
+
# Licensed under The MIT License
|
|
7
|
+
#
|
|
8
|
+
|
|
9
|
+
# ensure gems are present
|
|
10
|
+
begin
|
|
11
|
+
# aws-cleaner deps
|
|
12
|
+
require 'json'
|
|
13
|
+
require 'yaml'
|
|
14
|
+
require 'aws-sdk-core'
|
|
15
|
+
require 'chef-api'
|
|
16
|
+
require 'chronic'
|
|
17
|
+
require 'hipchat'
|
|
18
|
+
require 'rest-client'
|
|
19
|
+
require 'time'
|
|
20
|
+
require 'trollop'
|
|
21
|
+
require 'slack/poster'
|
|
22
|
+
require 'aws_cleaner/aws_cleaner.rb'
|
|
23
|
+
# aws_watcher deps
|
|
24
|
+
rescue LoadError => e
|
|
25
|
+
raise "Missing Gems: #{e}"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
require_relative '../lib/aws-watcher.rb'
|
|
29
|
+
|
|
30
|
+
# config file
|
|
31
|
+
def config(file)
|
|
32
|
+
YAML.safe_load(File.read(file), [Symbol])
|
|
33
|
+
rescue StandardError => e
|
|
34
|
+
raise "Failed to open config file: #{e}"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# get options
|
|
38
|
+
opts = Trollop.options do
|
|
39
|
+
opt :config, 'Path to config file', type: :string, default: 'config.yml'
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
@config = config(opts[:config])
|
|
43
|
+
|
|
44
|
+
# initialize clients
|
|
45
|
+
@sqs_client = AwsCleaner::SQS.client(@config)
|
|
46
|
+
@chef_client = AwsCleaner::Chef.client(@config)
|
|
47
|
+
|
|
48
|
+
# start program in infinate loop
|
|
49
|
+
loop do
|
|
50
|
+
messages = @sqs_client.receive_message(
|
|
51
|
+
queue_url: @config[:sqs][:queue],
|
|
52
|
+
max_number_of_messages: 10,
|
|
53
|
+
visibility_timeout: 3
|
|
54
|
+
).messages
|
|
55
|
+
|
|
56
|
+
puts "Got #{messages.size} messages"
|
|
57
|
+
messages.each_with_index do |message, index|
|
|
58
|
+
puts "Looking at message number #{index}"
|
|
59
|
+
body = AwsCleaner.new.parse(message.body)
|
|
60
|
+
id = message.receipt_handle
|
|
61
|
+
now = Time.now.utc
|
|
62
|
+
launch_time = Chronic.parse(body['time'])
|
|
63
|
+
|
|
64
|
+
unless body
|
|
65
|
+
AwsCleaner.new.delete_message(id, @config)
|
|
66
|
+
next
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
@instance_id = AwsCleaner.new.process_message(body)
|
|
70
|
+
chef_node = AwsCleaner::Chef.get_chef_node_name(@instance_id, @config)
|
|
71
|
+
elapsed_time = now - launch_time
|
|
72
|
+
p "launch_time: #{launch_time}"
|
|
73
|
+
p "now: #{now}"
|
|
74
|
+
# if the node exists in chef it hass bootstrapped
|
|
75
|
+
# so we can delete the message
|
|
76
|
+
if chef_node || !AwsWatcher::EC2.instance_alive?(@instance_id, @config)
|
|
77
|
+
p "instance: #{@instance_id} has bootstrapped, removing message from queue"
|
|
78
|
+
AwsCleaner.new.delete_message(id, @config)
|
|
79
|
+
|
|
80
|
+
end
|
|
81
|
+
p "instance: #{@instance_id}, launched: #{launch_time}, elapsed: #{elapsed_time}"
|
|
82
|
+
# if the elapsed time is less than how long we consider
|
|
83
|
+
# a 'normal' converge time that's ok we just move on and
|
|
84
|
+
# wait for another pass
|
|
85
|
+
if elapsed_time < @config[:bootstrap][:converged_by]
|
|
86
|
+
if ENV['LOG_LEVEL'] == 'DEBUG'
|
|
87
|
+
'node elaspsed time is normal'
|
|
88
|
+
end
|
|
89
|
+
next
|
|
90
|
+
# if the elapsed time is greater than or equal then we need
|
|
91
|
+
# to do something although I am not sure what yet.
|
|
92
|
+
elsif elapsed_time >= @config[:bootstrap][:converged_by]
|
|
93
|
+
# we want to validate that the machine is still in aws
|
|
94
|
+
# and did not get terminated by something like an auto scale
|
|
95
|
+
# group or someone messing around in console
|
|
96
|
+
p 'node elaspsed time is too high'
|
|
97
|
+
notification = "node: #{@instance_id} has not checked in, "
|
|
98
|
+
notification += 'it should have converged by: '
|
|
99
|
+
notification += "#{@config[:bootstrap][:converged_by]} "
|
|
100
|
+
notification += 'and has been running since:and has been '
|
|
101
|
+
notification += "running since: #{elapsed_time}"
|
|
102
|
+
AwsCleaner::Notify.notify_chat(notification, @config)
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
sleep @config[:poll_time]
|
|
106
|
+
end
|
data/lib/aws-watcher.rb
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# main aws_watcher lib
|
|
2
|
+
class AwsWatcher
|
|
3
|
+
require 'aws_cleaner/aws_cleaner.rb'
|
|
4
|
+
module Chef
|
|
5
|
+
include AwsCleaner::Chef
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
module SQS
|
|
9
|
+
include AwsCleaner::SQS
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
module EC2
|
|
13
|
+
def self.client(config)
|
|
14
|
+
Aws::EC2::Client.new(config[:aws])
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.instance_alive?(id, config)
|
|
18
|
+
AwsWatcher::EC2.client(config).describe_instance_attribute(
|
|
19
|
+
attribute: 'instanceType',
|
|
20
|
+
instance_id: id.to_s
|
|
21
|
+
)
|
|
22
|
+
true
|
|
23
|
+
rescue Aws::EC2::Errors::InvalidInstanceIDNotFound => e
|
|
24
|
+
p "instance: #{id} was not found."
|
|
25
|
+
if ENV['LOG_LEVEL'] == 'DEBUG'
|
|
26
|
+
p e
|
|
27
|
+
end
|
|
28
|
+
false
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
module Notify
|
|
33
|
+
include AwsCleaner::Notify
|
|
34
|
+
end
|
|
35
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: aws-watcher
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Ben Abrams
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2017-04-14 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: bundler
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '1.12'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '1.12'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: rake
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '12.0'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '12.0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rspec
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '3.5'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '3.5'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: rubocop
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: 0.46.0
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: 0.46.0
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: aws-sdk-core
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - "~>"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '2.0'
|
|
76
|
+
type: :runtime
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - "~>"
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '2.0'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: chef-api
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - "~>"
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '0.5'
|
|
90
|
+
type: :runtime
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - "~>"
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '0.5'
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: chronic
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - "~>"
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '0.10'
|
|
104
|
+
type: :runtime
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - "~>"
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '0.10'
|
|
111
|
+
- !ruby/object:Gem::Dependency
|
|
112
|
+
name: hipchat
|
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
|
114
|
+
requirements:
|
|
115
|
+
- - "~>"
|
|
116
|
+
- !ruby/object:Gem::Version
|
|
117
|
+
version: '1.5'
|
|
118
|
+
type: :runtime
|
|
119
|
+
prerelease: false
|
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
+
requirements:
|
|
122
|
+
- - "~>"
|
|
123
|
+
- !ruby/object:Gem::Version
|
|
124
|
+
version: '1.5'
|
|
125
|
+
- !ruby/object:Gem::Dependency
|
|
126
|
+
name: rest-client
|
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - "~>"
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '2'
|
|
132
|
+
type: :runtime
|
|
133
|
+
prerelease: false
|
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
+
requirements:
|
|
136
|
+
- - "~>"
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: '2'
|
|
139
|
+
- !ruby/object:Gem::Dependency
|
|
140
|
+
name: slack-poster
|
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
|
142
|
+
requirements:
|
|
143
|
+
- - "~>"
|
|
144
|
+
- !ruby/object:Gem::Version
|
|
145
|
+
version: '2.2'
|
|
146
|
+
type: :runtime
|
|
147
|
+
prerelease: false
|
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
149
|
+
requirements:
|
|
150
|
+
- - "~>"
|
|
151
|
+
- !ruby/object:Gem::Version
|
|
152
|
+
version: '2.2'
|
|
153
|
+
- !ruby/object:Gem::Dependency
|
|
154
|
+
name: trollop
|
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
|
156
|
+
requirements:
|
|
157
|
+
- - "~>"
|
|
158
|
+
- !ruby/object:Gem::Version
|
|
159
|
+
version: '2.1'
|
|
160
|
+
type: :runtime
|
|
161
|
+
prerelease: false
|
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
163
|
+
requirements:
|
|
164
|
+
- - "~>"
|
|
165
|
+
- !ruby/object:Gem::Version
|
|
166
|
+
version: '2.1'
|
|
167
|
+
- !ruby/object:Gem::Dependency
|
|
168
|
+
name: aws-cleaner
|
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
|
170
|
+
requirements:
|
|
171
|
+
- - "~>"
|
|
172
|
+
- !ruby/object:Gem::Version
|
|
173
|
+
version: '2'
|
|
174
|
+
type: :runtime
|
|
175
|
+
prerelease: false
|
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
177
|
+
requirements:
|
|
178
|
+
- - "~>"
|
|
179
|
+
- !ruby/object:Gem::Version
|
|
180
|
+
version: '2'
|
|
181
|
+
description: AWS Watcher tracks EC2 instances being started to ensure they bootstrap
|
|
182
|
+
to chef
|
|
183
|
+
email: me@benabrams.it
|
|
184
|
+
executables:
|
|
185
|
+
- aws_watcher.rb
|
|
186
|
+
extensions: []
|
|
187
|
+
extra_rdoc_files: []
|
|
188
|
+
files:
|
|
189
|
+
- bin/aws_watcher.rb
|
|
190
|
+
- lib/aws-watcher.rb
|
|
191
|
+
homepage: https://github.com/majormoses/aws-watcher
|
|
192
|
+
licenses:
|
|
193
|
+
- MIT
|
|
194
|
+
metadata: {}
|
|
195
|
+
post_install_message:
|
|
196
|
+
rdoc_options: []
|
|
197
|
+
require_paths:
|
|
198
|
+
- lib
|
|
199
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
200
|
+
requirements:
|
|
201
|
+
- - ">="
|
|
202
|
+
- !ruby/object:Gem::Version
|
|
203
|
+
version: '0'
|
|
204
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
205
|
+
requirements:
|
|
206
|
+
- - ">="
|
|
207
|
+
- !ruby/object:Gem::Version
|
|
208
|
+
version: '0'
|
|
209
|
+
requirements: []
|
|
210
|
+
rubyforge_project:
|
|
211
|
+
rubygems_version: 2.4.5.1
|
|
212
|
+
signing_key:
|
|
213
|
+
specification_version: 4
|
|
214
|
+
summary: AWS Watcher tracks EC2 instances being started to ensure they bootstrap to
|
|
215
|
+
chef
|
|
216
|
+
test_files: []
|