chef-handler-sns 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +94 -45
- data/lib/chef/handler/sns.rb +23 -37
- data/lib/chef/handler/sns/templates/body.erb +36 -0
- data/lib/chef/handler/sns/version.rb +1 -1
- metadata +19 -2
data/README.md
CHANGED
@@ -1,18 +1,20 @@
|
|
1
|
-
|
2
|
-
===========
|
1
|
+
# Chef Handler SNS
|
3
2
|
|
4
3
|
A simple Chef report handler that reports status of a Chef run through Amazon SNS.
|
5
4
|
|
5
|
+
This Chef Handler is heavily based on [Joshua Timberman](https://github.com/jtimberman) examples.
|
6
|
+
|
6
7
|
* http://wiki.opscode.com/display/chef/Exception+and+Report+Handlers
|
7
8
|
|
8
|
-
|
9
|
-
|
9
|
+
[![Gem Version](https://badge.fury.io/rb/chef-handler-sns.png)](http://badge.fury.io/rb/chef-handler-sns)
|
10
|
+
[![Dependency Status](https://gemnasium.com/onddo/chef-handler-sns.png)](https://gemnasium.com/onddo/chef-handler-sns)
|
11
|
+
|
12
|
+
## Requirements
|
10
13
|
|
11
14
|
* Amazon AWS: uses Amazon SNS service.
|
12
15
|
* Uses the `right_aws` library.
|
13
16
|
|
14
|
-
Usage
|
15
|
-
=====
|
17
|
+
## Usage
|
16
18
|
|
17
19
|
You can install this handler in two ways:
|
18
20
|
|
@@ -24,55 +26,102 @@ You can install the RubyGem and configure Chef to use it:
|
|
24
26
|
|
25
27
|
Then add to the configuration (`/etc/chef/solo.rb` for chef-solo or `/etc/chef/client.rb` for chef-client):
|
26
28
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
29
|
+
```ruby
|
30
|
+
require "chef/handler/sns"
|
31
|
+
|
32
|
+
# Create the handler
|
33
|
+
sns_handler = Chef::Handler::Sns.new
|
34
|
+
|
35
|
+
# Your Amazon AWS credentials
|
36
|
+
sns_handler.access_key = "***AMAZON-KEY***"
|
37
|
+
sns_handler.secret_key = "***AMAZON-SECRET***"
|
38
|
+
|
39
|
+
# Some Amazon SNS configurations
|
40
|
+
sns_handler.topic_arn = "arn:aws:sns:***"
|
41
|
+
sns_handler.region = "us-east-1" # optional
|
42
|
+
|
43
|
+
# Add your handler
|
44
|
+
exception_handlers << sns_handler
|
45
|
+
```
|
42
46
|
|
43
47
|
### Method 2: In a recipe with the chef_handler LWRP
|
44
48
|
|
45
49
|
Use the [chef_handler LWRP](http://community.opscode.com/cookbooks/chef_handler), creating a recipe with the following:
|
46
50
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
51
|
+
```ruby
|
52
|
+
# Handler configuration options
|
53
|
+
argument_array = [
|
54
|
+
:access_key => "***AMAZON-KEY***",
|
55
|
+
:secret_key => "***AMAZON-SECRET***",
|
56
|
+
:topic_arn => "arn:aws:sns:***",
|
57
|
+
]
|
58
|
+
|
59
|
+
# Install the `chef-handler-sns` RubyGem during the compile phase
|
60
|
+
chef_gem "chef-handler-sns"
|
61
|
+
|
62
|
+
# Then activate the handler with the `chef_handler` LWRP
|
63
|
+
chef_handler "Chef::Handler::Sns" do
|
64
|
+
source "#{Gem::Specification.find_by_name("chef-handler-sns").lib_dirs_glob}/chef/handler/sns"
|
65
|
+
arguments argument_array
|
66
|
+
supports :exception => true
|
67
|
+
action :enable
|
68
|
+
end
|
69
|
+
```
|
70
|
+
|
71
|
+
If you have an old version of gem package (< 1.8.6) without `find_by_name` or old chef-client (< 0.10.10) without `chef_gem`, you can try creating a recipe similar to the following:
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
# Handler configuration options
|
75
|
+
argument_array = [
|
76
|
+
:access_key => "***AMAZON-KEY***",
|
77
|
+
:secret_key => "***AMAZON-SECRET***",
|
78
|
+
:topic_arn => "arn:aws:sns:***",
|
79
|
+
]
|
80
|
+
|
81
|
+
# Install the `chef-handler-sns` RubyGem during the compile phase
|
82
|
+
if defined?(Chef::Resource::ChefGem)
|
83
|
+
chef_gem "chef-handler-sns"
|
84
|
+
else
|
85
|
+
gem_package("chef-handler-sns") do
|
86
|
+
action :nothing
|
87
|
+
end.run_action(:install)
|
88
|
+
end
|
89
|
+
|
90
|
+
# Get the installed `chef-handler-sns` gem path
|
91
|
+
sns_handler_path = Gem::Specification.respond_to?("find_by_name") ?
|
92
|
+
Gem::Specification.find_by_name("chef-handler-sns").lib_dirs_glob :
|
93
|
+
Gem.all_load_paths.grep(/chef-handler-sns/).first
|
94
|
+
|
95
|
+
# Then activate the handler with the `chef_handler` LWRP
|
96
|
+
chef_handler "Chef::Handler::Sns" do
|
97
|
+
source "#{sns_handler_path}/chef/handler/sns"
|
98
|
+
arguments argument_array
|
99
|
+
supports :exception => true
|
100
|
+
action :enable
|
101
|
+
end
|
102
|
+
```
|
103
|
+
|
104
|
+
## Handler Configuration Options
|
105
|
+
|
106
|
+
The following options are available to configure the handler:
|
107
|
+
|
108
|
+
* `access_key` - AWS access key (required).
|
109
|
+
* `secret_key` - AWS secret key (required).
|
110
|
+
* `topic_arn` - AWS topic ARN name (required).
|
111
|
+
* `region` - AWS region (optional).
|
112
|
+
* `subject` - Message subject string in erubis format (optional). Example:
|
113
|
+
```
|
114
|
+
sns_handler.subject: "Chef-run: <%= node.name %> - <%= run_status.success? ? 'ok' : 'error' %>"
|
115
|
+
```
|
116
|
+
* `body_template` - Full path of an erubis template file to use for the message body (optional).
|
117
|
+
|
118
|
+
## Roadmap
|
69
119
|
|
70
120
|
* rspec tests.
|
71
121
|
|
72
122
|
Pull requests are welcome.
|
73
123
|
|
74
|
-
License and Author
|
75
|
-
==================
|
124
|
+
## License and Author
|
76
125
|
|
77
126
|
| | |
|
78
127
|
|:---------------------|:-----------------------------------------|
|
data/lib/chef/handler/sns.rb
CHANGED
@@ -18,11 +18,12 @@
|
|
18
18
|
|
19
19
|
require 'chef/handler'
|
20
20
|
require 'right_aws'
|
21
|
+
require 'erubis'
|
21
22
|
|
22
23
|
class Chef
|
23
24
|
class Handler
|
24
25
|
class Sns < ::Chef::Handler
|
25
|
-
attr_writer :access_key, :secret_key, :region, :token, :topic_arn
|
26
|
+
attr_writer :access_key, :secret_key, :region, :token, :topic_arn, :subject, :body_template
|
26
27
|
|
27
28
|
def initialize(config={})
|
28
29
|
Chef::Log.debug("#{self.class.to_s} initialized.")
|
@@ -31,6 +32,8 @@ class Chef
|
|
31
32
|
@region = config[:region] if config.has_key?(:region)
|
32
33
|
@token = config[:token] if config.has_key?(:token)
|
33
34
|
@topic_arn = config[:topic_arn]
|
35
|
+
@subject = config[:subject] if config.has_key?(:subject)
|
36
|
+
@body_template = config[:body_template] if config.has_key?(:body_template)
|
34
37
|
end
|
35
38
|
|
36
39
|
def report
|
@@ -46,8 +49,13 @@ class Chef
|
|
46
49
|
raise "access_key not properly set" unless @access_key.kind_of?(String)
|
47
50
|
raise "secret_key not properly set" unless @secret_key.kind_of?(String)
|
48
51
|
raise "region not properly set" unless @region.kind_of?(String) or @region.nil?
|
49
|
-
raise "topic_arn not properly set" unless @topic_arn.kind_of?(String)
|
50
52
|
raise "token not properly set" unless @token.kind_of?(String) or @token.nil?
|
53
|
+
raise "topic_arn not properly set" unless @topic_arn.kind_of?(String)
|
54
|
+
raise "subject not properly set" unless @subject.kind_of?(String) or @subject.nil?
|
55
|
+
unless @body_template.nil?
|
56
|
+
raise "body_template not properly set" unless @body_template.kind_of?(String)
|
57
|
+
raise "body_template file not found: #{@body_template}" unless ::File.exists?(@body_template)
|
58
|
+
end
|
51
59
|
end
|
52
60
|
|
53
61
|
def sns
|
@@ -62,44 +70,22 @@ class Chef
|
|
62
70
|
end
|
63
71
|
|
64
72
|
def sns_subject
|
65
|
-
|
66
|
-
|
67
|
-
|
73
|
+
if @subject
|
74
|
+
context = self
|
75
|
+
eruby = Erubis::Eruby.new(@subject)
|
76
|
+
eruby.evaluate(context)
|
77
|
+
else
|
78
|
+
chef_client = Chef::Config[:solo] ? 'Chef Solo' : 'Chef Client'
|
79
|
+
status = run_status.success? ? 'success' : 'failure'
|
80
|
+
"#{chef_client} #{status} in #{node.name}"
|
81
|
+
end
|
68
82
|
end
|
69
83
|
|
70
84
|
def sns_body
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
message << "\n"
|
76
|
-
|
77
|
-
message << "Chef Run List: #{node.run_list.to_s}\n"
|
78
|
-
message << "Chef Environment: #{node.chef_environment}\n"
|
79
|
-
message << "\n"
|
80
|
-
|
81
|
-
if node.attribute?('ec2')
|
82
|
-
message << "Instance Id: #{node.ec2.instance_id}\n"
|
83
|
-
message << "Instance Public Hostname: #{node.ec2.public_hostname}\n"
|
84
|
-
message << "Instance Hostname: #{node.ec2.hostname}\n"
|
85
|
-
message << "Instance Public IPv4: #{node.ec2.public_ipv4}\n"
|
86
|
-
message << "Instance Local IPv4: #{node.ec2.local_ipv4}\n"
|
87
|
-
end
|
88
|
-
message << "\n"
|
89
|
-
|
90
|
-
message << "Chef Client Elapsed Time: #{elapsed_time.to_s}\n"
|
91
|
-
message << "Chef Client Start Time: #{start_time.to_s}\n"
|
92
|
-
message << "Chef Client Start Time: #{end_time.to_s}\n"
|
93
|
-
message << "\n"
|
94
|
-
|
95
|
-
if exception
|
96
|
-
message << "Exception: #{run_status.formatted_exception}\n"
|
97
|
-
message << "Stacktrace:\n"
|
98
|
-
message << Array(backtrace).join("\n")
|
99
|
-
message << "\n"
|
100
|
-
end
|
101
|
-
|
102
|
-
message
|
85
|
+
template = IO.read(@body_template || "#{File.dirname(__FILE__)}/sns/templates/body.erb")
|
86
|
+
context = self
|
87
|
+
eruby = Erubis::Eruby.new(template)
|
88
|
+
eruby.evaluate(context)
|
103
89
|
end
|
104
90
|
|
105
91
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
Node Name: <%= node.name %>
|
2
|
+
<% if node.attribute?('fqdn') -%>
|
3
|
+
Hostname: <%= node.fqdn %>
|
4
|
+
<% end -%>
|
5
|
+
|
6
|
+
Chef Run List: <%= node.run_list.to_s %>
|
7
|
+
Chef Environment: <%= node.chef_environment %>
|
8
|
+
|
9
|
+
<% if node.attribute?('ec2') -%>
|
10
|
+
<% if node.ec2.attribute?('instance_id') -%>
|
11
|
+
Instance Id: <%= node.ec2.instance_id %>
|
12
|
+
<% end -%>
|
13
|
+
<% if node.ec2.attribute?('public_hostname') -%>
|
14
|
+
Instance Public Hostname: <%= node.ec2.public_hostname %>
|
15
|
+
<% end -%>
|
16
|
+
<% if node.ec2.attribute?('hostname') -%>
|
17
|
+
Instance Hostname: <%= node.ec2.hostname %>
|
18
|
+
<% end -%>
|
19
|
+
<% if node.ec2.attribute?('public_ipv4') -%>
|
20
|
+
Instance Public IPv4: <%= node.ec2.public_ipv4 %>
|
21
|
+
<% end -%>
|
22
|
+
<% if node.ec2.attribute?('local_ipv4') -%>
|
23
|
+
Instance Local IPv4: <%= node.ec2.local_ipv4 %>
|
24
|
+
<% end -%>
|
25
|
+
<% end -%>
|
26
|
+
|
27
|
+
Chef Client Elapsed Time: <%= elapsed_time.to_s %>
|
28
|
+
Chef Client Start Time: <%= start_time.to_s %>
|
29
|
+
Chef Client Start Time: <%= end_time.to_s %>
|
30
|
+
|
31
|
+
<% if exception -%>
|
32
|
+
Exception: <%= run_status.formatted_exception %>
|
33
|
+
Stacktrace:
|
34
|
+
<%= Array(backtrace).join("\n") %>
|
35
|
+
|
36
|
+
<% end -%>
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chef-handler-sns
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-02
|
12
|
+
date: 2013-03-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: right_aws
|
@@ -27,6 +27,22 @@ dependencies:
|
|
27
27
|
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: '3.0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: erubis
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
30
46
|
description: Chef report handler to send SNS notifications on failures or changes
|
31
47
|
email: team@onddo.com
|
32
48
|
executables: []
|
@@ -35,6 +51,7 @@ extra_rdoc_files: []
|
|
35
51
|
files:
|
36
52
|
- LICENSE
|
37
53
|
- README.md
|
54
|
+
- lib/chef/handler/sns/templates/body.erb
|
38
55
|
- lib/chef/handler/sns/version.rb
|
39
56
|
- lib/chef/handler/sns.rb
|
40
57
|
homepage: http://github.com/onddo/chef-handler-sns
|