chef_ec2_node_rm 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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f65051bb01a78f95fcb647917c531790e0b0c2cd188273f082371c6cf4c13425
4
+ data.tar.gz: dcc336aaf1e627f84f09632fa7923732be51be35aa9a42e83b40db281a87f620
5
+ SHA512:
6
+ metadata.gz: 7ef29f3f5a0f1fd4d6cc526f3467434cdedee818e6de1d13f592e9374f40a76d6ad9877c4ffaf252b5375f25b0dd8979c01f18f7b14278ee8b6d1ecdefb5dafd
7
+ data.tar.gz: caad41eedbacdefb78f38b1ad564f65e3162df9ea91366146fb31faac312613dc36cf3ee83003164e309d9cd1cf7fc43d50bd4fe57e5e907ba7b221ba5841f1f
@@ -0,0 +1,9 @@
1
+ *.gem
2
+ /.bundle/
3
+ /.yardoc
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
@@ -0,0 +1 @@
1
+ ruby 2.5.0
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.4.2
5
+ before_install: gem install bundler -v 1.16.1
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in chef_ec2_node_rm.gemspec
6
+ gemspec
@@ -0,0 +1,56 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ chef_ec2_node_rm (0.1.0)
5
+ aws-sdk-sqs (~> 1.3)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ ast (2.4.0)
11
+ aws-partitions (1.63.0)
12
+ aws-sdk-core (3.15.0)
13
+ aws-partitions (~> 1.0)
14
+ aws-sigv4 (~> 1.0)
15
+ jmespath (~> 1.0)
16
+ aws-sdk-sqs (1.3.0)
17
+ aws-sdk-core (~> 3)
18
+ aws-sigv4 (~> 1.0)
19
+ aws-sigv4 (1.0.2)
20
+ jmespath (1.3.1)
21
+ minitest (5.11.3)
22
+ minitest-autotest (1.0.3)
23
+ minitest-server (~> 1.0)
24
+ minitest-server (1.0.5)
25
+ minitest (~> 5.0)
26
+ parallel (1.12.1)
27
+ parser (2.5.0.0)
28
+ ast (~> 2.4.0)
29
+ powerpack (0.1.1)
30
+ rainbow (3.0.0)
31
+ rake (10.5.0)
32
+ rubocop (0.52.1)
33
+ parallel (~> 1.10)
34
+ parser (>= 2.4.0.2, < 3.0)
35
+ powerpack (~> 0.1)
36
+ rainbow (>= 2.2.2, < 4.0)
37
+ ruby-progressbar (~> 1.7)
38
+ unicode-display_width (~> 1.0, >= 1.0.1)
39
+ ruby-progressbar (1.9.0)
40
+ unicode-display_width (1.3.0)
41
+ yard (0.9.12)
42
+
43
+ PLATFORMS
44
+ ruby
45
+
46
+ DEPENDENCIES
47
+ bundler (~> 1.16)
48
+ chef_ec2_node_rm!
49
+ minitest (~> 5.0)
50
+ minitest-autotest (~> 1.0)
51
+ rake (~> 10.0)
52
+ rubocop (~> 0.45)
53
+ yard (~> 0.9)
54
+
55
+ BUNDLED WITH
56
+ 1.16.1
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 Mike Conigliaro
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,97 @@
1
+ # chef_ec2_node_rm
2
+
3
+ If you're managing EC2 instances with a Chef server, this gem can help prevent your server from becoming polluted with stale node/client data by automatically deleting it whenever instances are destroyed.
4
+
5
+ ## AWS Credentials
6
+
7
+ This gem relies on [aws-sdk](https://aws.amazon.com/sdk-for-ruby/), so AWS credentials will automatically be read from the usual places (credential files under `~/.aws`, environment variables, IAM roles, etc.).
8
+
9
+ ## Installation
10
+
11
+ 1. Create an SQS queue for your EC2 termination events.
12
+
13
+ 1. Create a CloudWatch event rule to send termination events to the SQS queue:
14
+
15
+ ```
16
+ {
17
+ "source": [
18
+ "aws.ec2"
19
+ ],
20
+ "detail-type": [
21
+ "EC2 Instance State-change Notification"
22
+ ],
23
+ "detail": {
24
+ "state": [
25
+ "terminated"
26
+ ]
27
+ }
28
+ }
29
+ ```
30
+
31
+ 1. [Configure knife](https://docs.chef.io/knife_setup.html) on your Chef server.
32
+
33
+ 1. Install `chef_ec2_node_rm` on your Chef server:
34
+
35
+ ```
36
+ gem install chef_ec2_node_rm
37
+ ```
38
+
39
+ 1. Run the application in the foreground to make sure everything is working (run it with `--help` to see a list of available options):
40
+
41
+ ```
42
+ chef_ec2_node_rm <options>
43
+ ```
44
+
45
+ 1. Using the command above, create an Upstart job on your Chef server (e.g. `/etc/systemd/system/chef_ec2_node_rm.service`) to keep the application running in the background:
46
+
47
+ ```
48
+ [Unit]
49
+ Description=chef_ec2_node_rm
50
+
51
+ [Service]
52
+ Type=simple
53
+ Environment=HOME=/root
54
+ ExecStart=/path/to/chef_ec2_node_rm <options>
55
+ Restart=always
56
+
57
+ [Install]
58
+ WantedBy=multi-user.target
59
+ ```
60
+
61
+ 1. Start the service:
62
+
63
+ ```
64
+ systemctl daemon-reload
65
+ systemctl restart chef_ec2_node_rm
66
+ ```
67
+
68
+ ## Development
69
+
70
+ ### Getting Started
71
+
72
+ ./bin/setup
73
+
74
+ ### Testing
75
+
76
+ #### Running Tests
77
+
78
+ rake test
79
+ rake rubocop
80
+
81
+ #### Example SQS Message
82
+
83
+ {
84
+ "detail": {
85
+ "instance-id": "foo",
86
+ "state": "bar"
87
+ }
88
+ }
89
+
90
+ ### Releases
91
+
92
+ gem build chef_ec2_node_rm.gemspec
93
+ gem install chef_ec2_node_rm-*.gem
94
+
95
+ ## Credits
96
+
97
+ - Inspired by [Matt Revell's script](http://blog.mattrevell.net/2014/02/19/automatically-remove-dead-autoscale-nodes-from-chef-server/)
@@ -0,0 +1,14 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+ require 'rubocop/rake_task'
4
+
5
+ Rake::TestTask.new(:test) do |t|
6
+ t.libs << 'test'
7
+ t.libs << 'lib'
8
+ t.test_files = FileList['test/**/*_test.rb']
9
+ t.warning = false
10
+ end
11
+
12
+ RuboCop::RakeTask.new
13
+
14
+ task default: %i[test rubocop]
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'chef_ec2_node_rm'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require 'irb'
14
+ IRB.start(__FILE__)
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ gem install bundler --conservative
7
+ bundle install
@@ -0,0 +1,30 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'chef_ec2_node_rm/meta'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = ChefEc2NodeRm::NAME
7
+ spec.version = ChefEc2NodeRm::VERSION
8
+ spec.authors = ChefEc2NodeRm::AUTHORS
9
+ spec.email = ChefEc2NodeRm::AUTHORS.map { |obj| obj.match(/<(.*?)>/)[1] }
10
+
11
+ spec.summary = 'Automatically delete chef node/client data on EC2'
12
+ spec.description = 'Automatically delete chef node/client data on EC2'
13
+ spec.homepage = ChefEc2NodeRm::URL
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ end
19
+ spec.bindir = 'exe'
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ['lib']
22
+
23
+ spec.add_development_dependency 'bundler', '~> 1.16'
24
+ spec.add_development_dependency 'minitest', '~> 5.0'
25
+ spec.add_development_dependency 'minitest-autotest', '~> 1.0'
26
+ spec.add_development_dependency 'rake', '~> 10.0'
27
+ spec.add_development_dependency 'rubocop', '~> 0.45'
28
+
29
+ spec.add_dependency 'aws-sdk-sqs', '~> 1.3'
30
+ end
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+
5
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
6
+ require 'chef_ec2_node_rm'
7
+
8
+ options = {
9
+ aws_sqs_instance_states: %w[terminated],
10
+ knife_search_attribute: 'ec2_instance_id',
11
+ log_level: 'info',
12
+ dry_run: false
13
+ }
14
+ OptionParser.new do |opts|
15
+ opts.version = ChefEc2NodeRm::VERSION
16
+ opts.banner = "Usage: #{File.basename($PROGRAM_NAME)} [options] <AWS SQS URL(s)>\n\n"
17
+
18
+ opts.on_tail('-s', '--aws-sqs-instance-states <state>[,<state>,...]', Array, "Deletes will be triggered for these instance states (default: #{options[:aws_sqs_instance_states].join(', ')})") do |opt|
19
+ options[:aws_sqs_instance_states] = opt
20
+ end
21
+
22
+ opts.on_tail('-d', '--dry-run', FalseClass, 'Show what will happen without actually deleting anything') do
23
+ options[:dry_run] = true
24
+ end
25
+
26
+ opts.on_tail('-h', '--help', 'Show this message') do
27
+ puts opts.help
28
+ exit
29
+ end
30
+
31
+ opts.on_tail('-a', '--knife-search-attribute <attribute>', String, "Instance ID attribute to use in knife search (default: #{options[:knife_search_attribute]})") do |opt|
32
+ options[:knife_search_attribute] = opt
33
+ end
34
+
35
+ opts.on_tail('-l', '--log-level <level>', String, "Log level (default: #{options[:log_level]})") do |opt|
36
+ options[:log_level] = opt
37
+ end
38
+
39
+ opts.on_tail('-v', '--version', 'Show version') do
40
+ puts format("#{opts.program_name} v#{opts.version}\n#{ChefEc2NodeRm::URL}\n#{ChefEc2NodeRm::AUTHORS.join("\n")}\n")
41
+ exit
42
+ end
43
+
44
+ if ARGV.length.zero?
45
+ puts opts.help
46
+ exit(1)
47
+ end
48
+ end.parse!
49
+
50
+ include ChefEc2NodeRm::Logging
51
+ logger.level = Logger.const_get(options[:log_level].upcase)
52
+
53
+ ChefEc2NodeRm::SqsPollers.new(ARGV).start do |poller, msg|
54
+ msg_parsed = ChefEc2NodeRm::SqsMessage.new(msg.body)
55
+ logger.info(Thread.current.name) { "Message received: id='#{msg.message_id}' instance_id='#{msg_parsed.instance_id}' state='#{msg_parsed.state}'" }
56
+
57
+ if options[:aws_sqs_instance_states].include?(msg_parsed.state)
58
+ search_results = ChefEc2NodeRm::Knife.new("search node '#{options[:knife_search_attribute]}:#{msg_parsed.instance_id}' --id-only").run
59
+ if search_results['results'].is_a?(Numeric) && search_results['rows'].respond_to?(:each)
60
+ logger.info("Found #{search_results['results']} Chef node(s) with instance_id: #{msg_parsed.instance_id}")
61
+ search_results['rows'].each do |name|
62
+ %w[node client].each do |type|
63
+ logger.info("Deleting #{type}: #{name}#{' (dry-run)' if options[:dry_run]}")
64
+ ChefEc2NodeRm::Knife.new("#{type} delete #{name} -y").run unless options[:dry_run]
65
+ end
66
+ end
67
+ else
68
+ logger.error("Knife search results are malformed: #{search_results}")
69
+ end
70
+ end
71
+
72
+ logger.info(Thread.current.name) { "Deleting message: id='#{msg.message_id}'#{' (dry-run)' if options[:dry_run]}" }
73
+ poller.delete_message(msg) unless options[:dry_run]
74
+ end
@@ -0,0 +1,11 @@
1
+ require 'aws-sdk-sqs'
2
+ require 'json'
3
+ require 'logger'
4
+
5
+ require 'chef_ec2_node_rm/logging'
6
+
7
+ require 'chef_ec2_node_rm/error'
8
+ require 'chef_ec2_node_rm/knife'
9
+ require 'chef_ec2_node_rm/meta'
10
+ require 'chef_ec2_node_rm/sqs_message'
11
+ require 'chef_ec2_node_rm/sqs_pollers'
@@ -0,0 +1,8 @@
1
+ module ChefEc2NodeRm
2
+ class Error < StandardError; end
3
+
4
+ class SqsMessageError < Error; end
5
+ class SqsMessageMalformedJson < SqsMessageError; end
6
+ class SqsMessageNotHash < SqsMessageError; end
7
+ class SqsMessageMissingAttribute < SqsMessageError; end
8
+ end
@@ -0,0 +1,21 @@
1
+ module ChefEc2NodeRm
2
+ class Knife
3
+ include Logging
4
+
5
+ def initialize(command)
6
+ @command = "knife #{command} --format json"
7
+ end
8
+
9
+ def run
10
+ logger.debug("Knife command: #{@command}")
11
+ result = `#{@command}`
12
+ result_parsed = begin
13
+ JSON.parse(result)
14
+ rescue JSON::ParserError
15
+ result
16
+ end
17
+ logger.debug("Knife output: #{result_parsed}")
18
+ result_parsed
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,19 @@
1
+ module ChefEc2NodeRm
2
+ module Logging
3
+ def logger
4
+ Logging.logger
5
+ end
6
+
7
+ def self.logger
8
+ @logger ||= Logger.new(@device || STDOUT)
9
+ end
10
+
11
+ def logger_device(device)
12
+ Logging.logger_device(device)
13
+ end
14
+
15
+ def self.logger_device(device)
16
+ @device = device
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,8 @@
1
+ module ChefEc2NodeRm
2
+ NAME = 'chef_ec2_node_rm'.freeze
3
+ VERSION = '0.1.0'.freeze
4
+ AUTHORS = [
5
+ 'Mike Conigliaro <mike@conigliaro.org>'
6
+ ].freeze
7
+ URL = 'https://github.com/mconigliaro/chef_ec2_node_rm'.freeze
8
+ end
@@ -0,0 +1,22 @@
1
+ module ChefEc2NodeRm
2
+ class SqsMessage
3
+ attr_reader :instance_id, :state
4
+
5
+ def initialize(msg)
6
+ msg_parsed = JSON.parse(msg)
7
+ raise SqsMessageNotHash, "Expected a Hash but got a #{msg_parsed.class}" unless msg_parsed.is_a?(Hash)
8
+
9
+ attr_map = {
10
+ instance_id: ['detail', 'instance-id'],
11
+ state: %w[detail state]
12
+ }
13
+ attr_map.each do |name, path|
14
+ value = msg_parsed.dig(*path)
15
+ raise ChefEc2NodeRm::SqsMessageMissingAttribute, "Missing value for #{name} (msg='#{msg}', path='#{path.join('.')}')" if value.nil?
16
+ instance_variable_set("@#{name}", value)
17
+ end
18
+ rescue JSON::ParserError => e
19
+ raise ChefEc2NodeRm::SqsMessageMalformedJson, "Malformed JSON: #{e}"
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,38 @@
1
+ module ChefEc2NodeRm
2
+ class SqsPollers
3
+ include Logging
4
+
5
+ attr_reader :pollers
6
+
7
+ def initialize(urls)
8
+ @pollers = urls.map do |url|
9
+ begin
10
+ logger.debug(url) { 'Verifying queue' }
11
+ # Each queue is verified by making a request for its attributes. An
12
+ # exception should get raised for any queue that is non-existent or
13
+ # otherwise unavailable.
14
+ Aws::SQS::Queue.new(url).attributes
15
+ Aws::SQS::QueuePoller.new(url)
16
+ rescue Aws::Errors::ServiceError => e
17
+ logger.error(url) { e.message }
18
+ nil
19
+ end
20
+ end.compact
21
+ end
22
+
23
+ def start
24
+ trap('SIGINT') { Thread.new { exit } }
25
+ @pollers.map do |poller|
26
+ Thread.new do
27
+ Thread.current.name = poller.queue_url
28
+ logger.info(Thread.current.name) { 'Starting poller' }
29
+ poller.poll(skip_delete: true) do |msg|
30
+ logger.debug(Thread.current.name) { %(Message received: id='#{msg.message_id}' body='#{msg.body.delete("\n")}') }
31
+ yield(poller, msg)
32
+ end
33
+ end
34
+ end.each(&:join)
35
+ logger.info('No queues left to poll')
36
+ end
37
+ end
38
+ end
metadata ADDED
@@ -0,0 +1,148 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: chef_ec2_node_rm
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Mike Conigliaro <mike@conigliaro.org>
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-02-21 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.16'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.16'
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '5.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '5.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest-autotest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '10.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.45'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.45'
83
+ - !ruby/object:Gem::Dependency
84
+ name: aws-sdk-sqs
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.3'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.3'
97
+ description: Automatically delete chef node/client data on EC2
98
+ email:
99
+ - mike@conigliaro.org
100
+ executables:
101
+ - chef_ec2_node_rm
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - ".gitignore"
106
+ - ".tool-versions"
107
+ - ".travis.yml"
108
+ - Gemfile
109
+ - Gemfile.lock
110
+ - LICENSE.txt
111
+ - README.md
112
+ - Rakefile
113
+ - bin/console
114
+ - bin/setup
115
+ - chef_ec2_node_rm.gemspec
116
+ - exe/chef_ec2_node_rm
117
+ - lib/chef_ec2_node_rm.rb
118
+ - lib/chef_ec2_node_rm/error.rb
119
+ - lib/chef_ec2_node_rm/knife.rb
120
+ - lib/chef_ec2_node_rm/logging.rb
121
+ - lib/chef_ec2_node_rm/meta.rb
122
+ - lib/chef_ec2_node_rm/sqs_message.rb
123
+ - lib/chef_ec2_node_rm/sqs_pollers.rb
124
+ homepage: https://github.com/mconigliaro/chef_ec2_node_rm
125
+ licenses:
126
+ - MIT
127
+ metadata: {}
128
+ post_install_message:
129
+ rdoc_options: []
130
+ require_paths:
131
+ - lib
132
+ required_ruby_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ required_rubygems_version: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - ">="
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ requirements: []
143
+ rubyforge_project:
144
+ rubygems_version: 2.7.3
145
+ signing_key:
146
+ specification_version: 4
147
+ summary: Automatically delete chef node/client data on EC2
148
+ test_files: []