cookbook_sdk 1.2.0 → 2.0.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 +4 -4
- data/.rubocop.yml +8 -0
- data/.travis.yml +2 -2
- data/README.md +2 -0
- data/cookbook_sdk.gemspec +7 -1
- data/lib/cookbook_sdk/handlers/slack.rb +29 -27
- data/lib/cookbook_sdk/rake_tasks.rb +2 -0
- data/lib/cookbook_sdk/rake_tasks/go_tasks.rb +56 -0
- data/lib/cookbook_sdk/rake_tasks/jenkins_tasks.rb +43 -0
- data/lib/cookbook_sdk/rake_tasks/provisioning_tasks.rb +15 -10
- data/lib/cookbook_sdk/rake_tasks/test_tasks.rb +4 -4
- data/lib/cookbook_sdk/version.rb +1 -1
- data/test/unit/handlers/test_slack.rb +249 -0
- data/test/unit/helpers.rb +9 -0
- metadata +82 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: db20953f625842a05cb9c9b4052ba82f6130ddbe
|
4
|
+
data.tar.gz: c7959d2a228be21d3bb71005afa87728d582f061
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e59c713b5aeddaa4cef7563a45ea2b87184d936e1bd17771dcee3c25250de2c624ea91d21c75cc9e031d80c4238da0f5100f675b4de9fb176c353c47941c09c1
|
7
|
+
data.tar.gz: a5175b5ff37fd4e5bca2a7788c5ed9e01598d31dcad145be7450bd8768ef7d27daad5d287bf28e8d7558a82ed6e238c67c6483fecf882bc3c68bbf1d01cbd235
|
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
@@ -14,5 +14,5 @@ script:
|
|
14
14
|
- /opt/chefdk/embedded/bin/chef --version
|
15
15
|
- /opt/chefdk/embedded/bin/rubocop --version
|
16
16
|
- /opt/chefdk/embedded/bin/foodcritic --version
|
17
|
-
- chef exec bundle
|
18
|
-
- chef exec rake test:
|
17
|
+
- chef exec bundle install
|
18
|
+
- chef exec rake test:ci
|
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# cookbook_sdk
|
2
2
|
|
3
|
+
[](https://badge.fury.io/rb/cookbook_sdk)
|
3
4
|
[](https://travis-ci.org/Mindera/cookbook_sdk)
|
5
|
+
[](https://coveralls.io/github/Mindera/cookbook_sdk?branch=master)
|
4
6
|
|
5
7
|
Helpers for chef cookbook development and provisioning.
|
data/cookbook_sdk.gemspec
CHANGED
@@ -21,5 +21,11 @@ Gem::Specification.new do |spec|
|
|
21
21
|
|
22
22
|
spec.add_dependency 'bundler', '~> 1.9'
|
23
23
|
spec.add_dependency 'rake', '~> 10.4'
|
24
|
-
spec.add_dependency 'highline', '~> 1.
|
24
|
+
spec.add_dependency 'highline', '~> 1.7.8'
|
25
|
+
|
26
|
+
spec.add_development_dependency 'chef'
|
27
|
+
spec.add_development_dependency 'minitest'
|
28
|
+
spec.add_development_dependency 'mocha'
|
29
|
+
spec.add_development_dependency 'simplecov'
|
30
|
+
spec.add_development_dependency 'coveralls'
|
25
31
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'chef/exceptions'
|
1
2
|
require 'chef/handler'
|
2
3
|
require 'net/http'
|
3
4
|
require 'uri'
|
@@ -8,18 +9,19 @@ class Chef
|
|
8
9
|
# Slack Handler goal is send messages to a Slack channel with Chef run status.
|
9
10
|
# It can be used as a start, failure or success handler.
|
10
11
|
class Slack < Chef::Handler
|
12
|
+
attr_reader :token, :channel, :username, :on_start, :on_success, :on_failure
|
13
|
+
|
11
14
|
def initialize(options = {})
|
12
|
-
@token = options
|
13
|
-
@channel = options
|
14
|
-
@username = options
|
15
|
-
@on_start = options
|
16
|
-
@on_success = options
|
17
|
-
@on_failure = options
|
15
|
+
@token = options.fetch(:token) { raise Exceptions::ConfigurationError, "Slack 'token' should be provided!" }
|
16
|
+
@channel = options.fetch(:channel, '#chef')
|
17
|
+
@username = options.fetch(:username, 'Chef')
|
18
|
+
@on_start = options.fetch(:on_start, true)
|
19
|
+
@on_success = options.fetch(:on_success, true)
|
20
|
+
@on_failure = options.fetch(:on_failure, true)
|
18
21
|
end
|
19
22
|
|
20
23
|
def report
|
21
|
-
options = {}
|
22
|
-
options[:pretext] = "Run at #{run_status.node.name}"
|
24
|
+
options = { :pretext => "Run at #{run_status.node.name}" }
|
23
25
|
|
24
26
|
if !run_status.is_a?(Chef::RunStatus) || elapsed_time.nil?
|
25
27
|
report_start(options)
|
@@ -30,6 +32,8 @@ class Chef
|
|
30
32
|
end
|
31
33
|
end
|
32
34
|
|
35
|
+
private
|
36
|
+
|
33
37
|
def report_start(options)
|
34
38
|
return exit_without_sending('start') unless @on_start
|
35
39
|
options[:title] = 'Chef run started!'
|
@@ -51,34 +55,32 @@ class Chef
|
|
51
55
|
def report_failure(options)
|
52
56
|
return exit_without_sending('failure') unless @on_failure
|
53
57
|
|
54
|
-
options[:title] = 'Chef FAILED!'
|
58
|
+
options[:title] = 'Chef run FAILED!'
|
55
59
|
options[:color] = 'danger'
|
56
60
|
options[:body] = "Running #{node.run_list} failed in #{run_status.elapsed_time} seconds."
|
57
|
-
options[:fallback] = "Chef FAILED! #{run_status.node.name} failed to run #{node.run_list}
|
61
|
+
options[:fallback] = "Chef FAILED! #{run_status.node.name} failed to run #{node.run_list}" \
|
58
62
|
" in #{run_status.elapsed_time.to_i} seconds."
|
59
63
|
send_attachment(options)
|
60
64
|
|
61
65
|
return if run_status.exception.nil?
|
62
|
-
|
63
|
-
text = '```' + run_status.formatted_exception.encode(
|
66
|
+
options[:text] = '```' + run_status.formatted_exception.encode(
|
64
67
|
'UTF-8',
|
65
|
-
invalid:
|
68
|
+
:invalid => :replace, :undef => :replace, :replace => '?'
|
66
69
|
) + '```'
|
67
|
-
options[:text] = text
|
68
70
|
send_text(options)
|
69
71
|
end
|
70
72
|
|
71
73
|
def send_attachment(options)
|
72
|
-
|
74
|
+
raise 'No message defined to be send to slack' if options[:body].nil?
|
73
75
|
params = {
|
74
|
-
color
|
75
|
-
attachments
|
76
|
-
pretext
|
77
|
-
title
|
78
|
-
title_link
|
79
|
-
color
|
80
|
-
text
|
81
|
-
fallback
|
76
|
+
:color => options[:color],
|
77
|
+
:attachments => [{
|
78
|
+
:pretext => options[:pretext],
|
79
|
+
:title => options[:title],
|
80
|
+
:title_link => options[:title_link],
|
81
|
+
:color => options[:color],
|
82
|
+
:text => options[:body],
|
83
|
+
:fallback => options[:fallback]
|
82
84
|
}]
|
83
85
|
}
|
84
86
|
send_slack_message(params)
|
@@ -89,15 +91,15 @@ class Chef
|
|
89
91
|
end
|
90
92
|
|
91
93
|
def send_text(options)
|
92
|
-
|
94
|
+
raise 'No message defined to be send to slack' if options[:text].nil?
|
93
95
|
params = {
|
94
|
-
text
|
96
|
+
:text => options[:text]
|
95
97
|
}
|
96
98
|
send_slack_message(params)
|
97
99
|
end
|
98
100
|
|
99
101
|
def send_slack_message(specif_params)
|
100
|
-
params = { username
|
102
|
+
params = { :username => @username, :channel => @channel, :token => @token }.merge(specif_params)
|
101
103
|
|
102
104
|
uri = URI("https://hooks.slack.com/services/#{@token}")
|
103
105
|
http = Net::HTTP.new(uri.host, uri.port)
|
@@ -105,7 +107,7 @@ class Chef
|
|
105
107
|
|
106
108
|
begin
|
107
109
|
req = Net::HTTP::Post.new("#{uri.path}?#{uri.query}")
|
108
|
-
req.set_form_data(payload
|
110
|
+
req.set_form_data(:payload => params.to_json)
|
109
111
|
res = http.request(req)
|
110
112
|
if res.code != '200'
|
111
113
|
Chef::Log.error("We got an error while posting a message to Slack: #{res.code} - #{res.msg}")
|
@@ -2,6 +2,8 @@ require 'cookbook_sdk/ext/string'
|
|
2
2
|
require 'cookbook_sdk/rake_tasks/test_tasks'
|
3
3
|
require 'cookbook_sdk/rake_tasks/helper_tasks'
|
4
4
|
require 'cookbook_sdk/rake_tasks/provisioning_tasks'
|
5
|
+
require 'cookbook_sdk/rake_tasks/jenkins_tasks'
|
6
|
+
require 'cookbook_sdk/rake_tasks/go_tasks'
|
5
7
|
require 'English'
|
6
8
|
|
7
9
|
# Runs a shell command.
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'cookbook_sdk/rake_tasks'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
namespace :go do
|
5
|
+
desc 'Generate attribute json file for image creation'
|
6
|
+
task :image_attr_json do
|
7
|
+
rpm_version_file = File.join('../rpm_version')
|
8
|
+
|
9
|
+
base_dir = Dir.pwd
|
10
|
+
base_dir += '/provision' if File.directory?('provision')
|
11
|
+
attributes_file = File.join(base_dir, 'attributes.json')
|
12
|
+
|
13
|
+
version = nil
|
14
|
+
File.open(rpm_version_file, 'r') do |output|
|
15
|
+
version = output.read.strip
|
16
|
+
end
|
17
|
+
|
18
|
+
raise "'rpm_version' file should have a valid rpm version" if version.nil? || version.empty?
|
19
|
+
|
20
|
+
attributes = { 'pipeline' => { 'app_version' => version } }
|
21
|
+
|
22
|
+
File.open(attributes_file, 'w') do |f|
|
23
|
+
f.write(attributes.to_json)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
desc 'Create attribute json file for cluster deployment'
|
28
|
+
task :cluster_attr_json do
|
29
|
+
begin
|
30
|
+
image_output_file = File.read('../_aws_image.output.json')
|
31
|
+
image_output = JSON.parse(image_output_file)
|
32
|
+
rescue StandardError => err
|
33
|
+
raise err
|
34
|
+
end
|
35
|
+
|
36
|
+
environment = ENV['ENVIRONMENT']
|
37
|
+
environment = 'test' if environment.nil? || environment.empty?
|
38
|
+
|
39
|
+
action = ENV['ACTION'] || nil
|
40
|
+
actions = %w(create destroy update)
|
41
|
+
raise "'ACTION' should be one of #{actions}" unless actions.include? action
|
42
|
+
|
43
|
+
attributes_file = File.join('provision', 'attributes.json')
|
44
|
+
attributes = {
|
45
|
+
'pipeline' => {
|
46
|
+
'ami_id' => image_output['ami_id'],
|
47
|
+
'environment' => environment,
|
48
|
+
'action' => action
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
File.open(attributes_file, 'w') do |f|
|
53
|
+
f.write(attributes.to_json)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'cookbook_sdk/rake_tasks'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
namespace :jenkins do
|
5
|
+
desc 'Generate attribute json file for image creation'
|
6
|
+
task :pipeline_version do
|
7
|
+
attributes_file = File.join('provision', 'attributes.json')
|
8
|
+
pipeline_version = ENV['PIPELINE_VERSION']
|
9
|
+
|
10
|
+
raise '$PIPELINE_VERSION cannot be null or empty' if pipeline_version.nil? || pipeline_version.empty?
|
11
|
+
|
12
|
+
attributes = {
|
13
|
+
'pipeline_version' => pipeline_version
|
14
|
+
}
|
15
|
+
|
16
|
+
File.open(attributes_file, 'w') do |f|
|
17
|
+
f.write(attributes.to_json)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
desc 'Create attribute json file for cluster deployment'
|
22
|
+
task :attributes do
|
23
|
+
begin
|
24
|
+
image_output_file = File.read(File.join('.', '_aws_image.output.json'))
|
25
|
+
image_output = JSON.parse(image_output_file)
|
26
|
+
rescue StandardError => err
|
27
|
+
raise err
|
28
|
+
end
|
29
|
+
|
30
|
+
environment = ENV['ENVIRONMENT']
|
31
|
+
environment = 'test' if environment.nil? || environment.empty?
|
32
|
+
|
33
|
+
attributes_file = File.join('provision', 'attributes.json')
|
34
|
+
attributes = {
|
35
|
+
'image_id' => image_output['ami_id'],
|
36
|
+
'environment' => environment
|
37
|
+
}
|
38
|
+
|
39
|
+
File.open(attributes_file, 'w') do |f|
|
40
|
+
f.write(attributes.to_json)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -9,14 +9,14 @@ module CookbookSDK
|
|
9
9
|
base_dir = Dir.pwd
|
10
10
|
base_dir += '/provision' if File.directory?('provision')
|
11
11
|
TARGET_FOLDER = File.join(base_dir, '.target')
|
12
|
-
SDK_CONFIGURATION = 'cookbook_sdk.json'
|
12
|
+
SDK_CONFIGURATION = 'cookbook_sdk.json'.freeze
|
13
13
|
CUSTOM_NAMED_LIST = ENV['NAMED_RUN_LIST']
|
14
14
|
RUN_LIST = ENV['RUN_LIST']
|
15
15
|
DEBUG = ENV['DEBUG']
|
16
|
-
BERKS = ENV['BERKS'] ||
|
16
|
+
BERKS = ENV['BERKS'] || true
|
17
17
|
|
18
18
|
desc 'Prepare chef-zero environment, and run it.'
|
19
|
-
task all
|
19
|
+
task :all => ['chef:prepare', 'chef:run', 'chef:clean']
|
20
20
|
|
21
21
|
namespace :chef do
|
22
22
|
desc 'Prepare chef-zero environment to run.'
|
@@ -81,7 +81,7 @@ def read_configuration(configuration_file)
|
|
81
81
|
end
|
82
82
|
return nil if file.nil?
|
83
83
|
|
84
|
-
data_hash = JSON.parse(file, symbolize_names
|
84
|
+
data_hash = JSON.parse(file, :symbolize_names => true)
|
85
85
|
data_hash
|
86
86
|
rescue Errno::ENOENT, Errno::EACCES, JSON::ParserError => e
|
87
87
|
puts "Problem reading #{configuration_file} - #{e}"
|
@@ -162,22 +162,27 @@ def run_chef_zero(target_folder, custom_named_run_list = nil, run_list = nil, de
|
|
162
162
|
named_run_list = custom_named_run_list.nil? ? '' : "-n #{custom_named_run_list}"
|
163
163
|
run_list = run_list.nil? ? '' : "-o #{run_list}"
|
164
164
|
debug = !debug ? '' : '-l debug'
|
165
|
+
log_format = '--force-formatter'
|
165
166
|
|
166
|
-
|
167
|
-
|
167
|
+
attributes_file_path = File.join(target_folder, 'attributes.json')
|
168
|
+
attributes_flag = File.exist?(attributes_file_path) ? '-j attributes.json' : ''
|
168
169
|
|
169
170
|
timestamp = Time.now.to_i
|
170
171
|
cache_pid_file = "#{target_folder}/.chef/cache/chef-client-running_#{timestamp}.pid"
|
171
172
|
lockfile = "--lockfile=#{cache_pid_file}"
|
172
173
|
|
173
174
|
cmd = 'chef exec chef-client -c custom_client.rb -z '
|
174
|
-
cmd += "#{named_run_list} #{run_list} #{debug} #{
|
175
|
+
cmd += "#{named_run_list} #{run_list} #{debug} #{attributes_flag} #{lockfile} #{log_format}"
|
175
176
|
|
176
|
-
|
177
|
+
if attributes_flag != ''
|
178
|
+
file = File.read(attributes_file_path)
|
179
|
+
data_hash = JSON.pretty_generate(JSON.parse(file))
|
177
180
|
|
178
|
-
|
179
|
-
|
181
|
+
banner('Attributes are:')
|
182
|
+
banner(data_hash)
|
180
183
|
end
|
184
|
+
|
185
|
+
_run_command(cmd, target_folder)
|
181
186
|
end
|
182
187
|
|
183
188
|
def clean(target_folder)
|
@@ -5,7 +5,7 @@ module CookbookSdk
|
|
5
5
|
extend Rake::DSL
|
6
6
|
|
7
7
|
desc 'Run all fast tests.'
|
8
|
-
task test
|
8
|
+
task :test => ['test:foodcritic', 'test:rubocop', 'test:rspec']
|
9
9
|
|
10
10
|
namespace :test do
|
11
11
|
desc 'Runs Foodcritic linting'
|
@@ -24,7 +24,7 @@ module CookbookSdk
|
|
24
24
|
end
|
25
25
|
|
26
26
|
### Continous Integration
|
27
|
-
desc 'Runs all tests
|
27
|
+
desc 'Runs all tests when run in a CI environment'
|
28
28
|
task :ci do
|
29
29
|
error = false
|
30
30
|
error = foodcritic(false) || error
|
@@ -44,8 +44,8 @@ def foodcritic(exit_on_error = true)
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def rspec(exit_on_error = true)
|
47
|
-
files = FileList[File.join(Dir.pwd, '
|
48
|
-
cmd = "chef exec rspec #{files}"
|
47
|
+
files = FileList[File.join(Dir.pwd, 'test', 'unit', '**/test_*.rb')]
|
48
|
+
cmd = "chef exec rspec #{files} --format doc"
|
49
49
|
banner("Running '#{cmd}' ...")
|
50
50
|
run_command(cmd, exit_on_error)
|
51
51
|
end
|
data/lib/cookbook_sdk/version.rb
CHANGED
@@ -0,0 +1,249 @@
|
|
1
|
+
require_relative '../helpers'
|
2
|
+
|
3
|
+
require 'webmock/rspec'
|
4
|
+
require 'cookbook_sdk/handlers/slack'
|
5
|
+
|
6
|
+
WebMock.disable_net_connect!(:allow_localhost => true)
|
7
|
+
|
8
|
+
describe Chef::Handler::Slack do
|
9
|
+
let(:node) do
|
10
|
+
node = Chef::Node.new
|
11
|
+
node.name('test')
|
12
|
+
node.run_list('recipe[fake_cookbook::fake_recipe]')
|
13
|
+
node
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:url) do
|
17
|
+
"https://hooks.slack.com/services/#{config[:token]}"
|
18
|
+
end
|
19
|
+
|
20
|
+
let(:config) do
|
21
|
+
{
|
22
|
+
:token => 'fake_token',
|
23
|
+
:channel => '#fake_channel',
|
24
|
+
:username => 'fake_user',
|
25
|
+
:on_start => true,
|
26
|
+
:on_success => true,
|
27
|
+
:on_failure => true
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
before do
|
32
|
+
Chef::Handler::Slack.any_instance.stubs(:node).returns(node)
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should read the configuration options on initialization' do
|
36
|
+
@slack_handler = Chef::Handler::Slack.new(config)
|
37
|
+
expect(@slack_handler.token).to eq(config[:token])
|
38
|
+
expect(@slack_handler.channel).to eq(config[:channel])
|
39
|
+
expect(@slack_handler.username).to eq(config[:username])
|
40
|
+
expect(@slack_handler.on_start).to eq(config[:on_start])
|
41
|
+
expect(@slack_handler.on_success).to eq(config[:on_success])
|
42
|
+
expect(@slack_handler.on_failure).to eq(config[:on_failure])
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should set configuration defaults when not provide on initialization' do
|
46
|
+
@slack_handler = Chef::Handler::Slack.new(:token => 'fake_token')
|
47
|
+
expect(@slack_handler.token).to eq('fake_token')
|
48
|
+
expect(@slack_handler.channel).to eq('#chef')
|
49
|
+
expect(@slack_handler.username).to eq('Chef')
|
50
|
+
expect(@slack_handler.on_start).to eq(true)
|
51
|
+
expect(@slack_handler.on_success).to eq(true)
|
52
|
+
expect(@slack_handler.on_failure).to eq(true)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should throw an exception when the slack token is not provided on initialization' do
|
56
|
+
expect { Chef::Handler::Slack.new({}) }.to raise_error(ChefConfig::ConfigurationError)
|
57
|
+
end
|
58
|
+
|
59
|
+
describe '#report' do
|
60
|
+
before do
|
61
|
+
@slack_handler = Chef::Handler::Slack.new(config)
|
62
|
+
@run_status = Chef::RunStatus.new(node, {})
|
63
|
+
end
|
64
|
+
|
65
|
+
describe 'when chef run is not over' do
|
66
|
+
before do
|
67
|
+
@run_status.start_clock
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should call report_start function at start of the run' do
|
71
|
+
@slack_handler.stubs(:report_start)
|
72
|
+
|
73
|
+
expect(@slack_handler).to receive(:report_start)
|
74
|
+
expect(@slack_handler).not_to receive(:report_success)
|
75
|
+
expect(@slack_handler).not_to receive(:report_failure)
|
76
|
+
|
77
|
+
@slack_handler.run_report_unsafe(@run_status)
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'should skip the sending of the starting message when on_start option is false' do
|
81
|
+
new_config = config
|
82
|
+
new_config[:on_start] = false
|
83
|
+
@slack_handler = Chef::Handler::Slack.new(new_config)
|
84
|
+
expect(Chef::Log).to receive(:debug).with("Slack 'start' handler is not active.")
|
85
|
+
expect(@slack_handler).not_to receive(:send_attachment)
|
86
|
+
expect(@slack_handler).not_to receive(:send_slack_message)
|
87
|
+
|
88
|
+
@slack_handler.run_report_unsafe(@run_status)
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'should send the starting message when on_start option is true' do
|
92
|
+
stub_request(:post, url).to_return(:status => 200, :headers => {})
|
93
|
+
|
94
|
+
expect(@slack_handler).not_to receive(:exit_without_sending)
|
95
|
+
expect(Chef::Log).to receive(:debug).with("Slack handler sent a message to channel '#{config[:channel]}'")
|
96
|
+
|
97
|
+
@slack_handler.run_report_unsafe(@run_status)
|
98
|
+
|
99
|
+
payload = {
|
100
|
+
:username => config[:username],
|
101
|
+
:channel => config[:channel],
|
102
|
+
:token => config[:token],
|
103
|
+
:color => nil,
|
104
|
+
:attachments => [{
|
105
|
+
:pretext => 'Run at test',
|
106
|
+
:title => 'Chef run started!',
|
107
|
+
:title_link => nil,
|
108
|
+
:color => nil,
|
109
|
+
:text => "Will run #{node.run_list}",
|
110
|
+
:fallback => "Chef run started! test will run #{node.run_list}."
|
111
|
+
}]
|
112
|
+
}
|
113
|
+
expect(WebMock).to have_requested(:post, url).with(:body => { :payload => payload.to_json })
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe 'when chef is over' do
|
118
|
+
before do
|
119
|
+
@run_status.start_clock
|
120
|
+
@run_status.stop_clock
|
121
|
+
end
|
122
|
+
|
123
|
+
describe 'and run successfully' do
|
124
|
+
it 'should call report_success function at end of the run' do
|
125
|
+
expect(@slack_handler).not_to receive(:report_start)
|
126
|
+
expect(@slack_handler).to receive(:report_success)
|
127
|
+
expect(@slack_handler).not_to receive(:report_failure)
|
128
|
+
|
129
|
+
@slack_handler.run_report_unsafe(@run_status)
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'should skip the sending of the success message when on_success option is false' do
|
133
|
+
new_config = config
|
134
|
+
new_config[:on_success] = false
|
135
|
+
@slack_handler = Chef::Handler::Slack.new(new_config)
|
136
|
+
expect(Chef::Log).to receive(:debug).with("Slack 'success' handler is not active.")
|
137
|
+
expect(@slack_handler).not_to receive(:send_attachment)
|
138
|
+
expect(@slack_handler).not_to receive(:send_slack_message)
|
139
|
+
|
140
|
+
@slack_handler.run_report_unsafe(@run_status)
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'should send the success message when on_success option is true' do
|
144
|
+
stub_request(:post, url).to_return(:status => 200)
|
145
|
+
|
146
|
+
expect(@slack_handler).not_to receive(:exit_without_sending)
|
147
|
+
expect(Chef::Log).to receive(:debug).with("Slack handler sent a message to channel '#{config[:channel]}'")
|
148
|
+
|
149
|
+
@slack_handler.run_report_unsafe(@run_status)
|
150
|
+
payload = {
|
151
|
+
:username => config[:username],
|
152
|
+
:channel => config[:channel],
|
153
|
+
:token => config[:token],
|
154
|
+
:color => 'good',
|
155
|
+
:attachments => [{
|
156
|
+
:pretext => 'Run at test',
|
157
|
+
:title => 'Chef run successfully!',
|
158
|
+
:title_link => nil,
|
159
|
+
:color => 'good',
|
160
|
+
:text => "Just run #{node.run_list} successfully in #{@run_status.elapsed_time} seconds.",
|
161
|
+
:fallback => "Chef run successfully! test run #{node.run_list} successfully "\
|
162
|
+
"in #{@run_status.elapsed_time.to_i} seconds."
|
163
|
+
}]
|
164
|
+
}
|
165
|
+
expect(WebMock).to have_requested(:post, url).with(:body => { :payload => payload.to_json })
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
describe 'and failed' do
|
170
|
+
before do
|
171
|
+
@run_status.start_clock
|
172
|
+
@run_status.stop_clock
|
173
|
+
@run_status.exception = ChefConfig::ConfigurationError.new('A fake error.')
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'should call report_failed function at end of the run' do
|
177
|
+
expect(@slack_handler).not_to receive(:report_start)
|
178
|
+
expect(@slack_handler).not_to receive(:report_success)
|
179
|
+
expect(@slack_handler).to receive(:report_failure)
|
180
|
+
|
181
|
+
@slack_handler.run_report_unsafe(@run_status)
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'should skip the sending of the failed message when on_failure option is false' do
|
185
|
+
new_config = config
|
186
|
+
new_config[:on_failure] = false
|
187
|
+
@slack_handler = Chef::Handler::Slack.new(new_config)
|
188
|
+
expect(Chef::Log).to receive(:debug).with("Slack 'failure' handler is not active.")
|
189
|
+
expect(@slack_handler).not_to receive(:send_attachment)
|
190
|
+
expect(@slack_handler).not_to receive(:send_slack_message)
|
191
|
+
|
192
|
+
@slack_handler.run_report_unsafe(@run_status)
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'should send the failure message when on_failure option is true' do
|
196
|
+
stub_request(:post, url).to_return(:status => 200, :headers => {})
|
197
|
+
|
198
|
+
expect(@slack_handler).not_to receive(:exit_without_sending)
|
199
|
+
expect(Chef::Log).to receive(:debug)
|
200
|
+
.with("Slack handler sent a message to channel '#{config[:channel]}'").twice
|
201
|
+
|
202
|
+
@slack_handler.run_report_unsafe(@run_status)
|
203
|
+
|
204
|
+
# Message as attachment
|
205
|
+
payload = {
|
206
|
+
:username => config[:username],
|
207
|
+
:channel => config[:channel],
|
208
|
+
:token => config[:token],
|
209
|
+
:color => 'danger',
|
210
|
+
:attachments => [{
|
211
|
+
:pretext => 'Run at test',
|
212
|
+
:title => 'Chef run FAILED!',
|
213
|
+
:title_link => nil,
|
214
|
+
:color => 'danger',
|
215
|
+
:text => "Running #{node.run_list} failed in #{@run_status.elapsed_time} seconds.",
|
216
|
+
:fallback => "Chef FAILED! #{@run_status.node.name} failed to run #{node.run_list}" \
|
217
|
+
" in #{@run_status.elapsed_time.to_i} seconds."
|
218
|
+
}]
|
219
|
+
}
|
220
|
+
expect(WebMock).to have_requested(:post, url).with(:body => { :payload => payload.to_json })
|
221
|
+
|
222
|
+
# Exception
|
223
|
+
payload = {
|
224
|
+
:username => config[:username],
|
225
|
+
:channel => config[:channel],
|
226
|
+
:token => config[:token],
|
227
|
+
:text => '```ChefConfig::ConfigurationError: A fake error.```'
|
228
|
+
}
|
229
|
+
expect(WebMock).to have_requested(:post, url).with(:body => { :payload => payload.to_json })
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
describe 'when tries to send an http request but it fails' do
|
235
|
+
it 'should log a error when receive a http response different than 200 OK' do
|
236
|
+
stub_request(:post, url).to_return(:status => 400)
|
237
|
+
expect(Chef::Log).to receive(:error).with('We got an error while posting a message to Slack: 400 - ')
|
238
|
+
@slack_handler.run_report_unsafe(@run_status)
|
239
|
+
end
|
240
|
+
|
241
|
+
it 'should log a error when got any exception related with the request' do
|
242
|
+
stub_request(:post, url).to_return(:should_timeout => true)
|
243
|
+
expect(Chef::Log).to receive(:error)
|
244
|
+
.with('An unhandled exception occurred while posting a message to Slack: execution expired')
|
245
|
+
@slack_handler.run_report_unsafe(@run_status)
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cookbook_sdk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mindera
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-04-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -44,24 +44,90 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
48
|
-
- - ">="
|
49
|
-
- !ruby/object:Gem::Version
|
50
|
-
version: 1.6.9
|
47
|
+
version: 1.7.8
|
51
48
|
type: :runtime
|
52
49
|
prerelease: false
|
53
50
|
version_requirements: !ruby/object:Gem::Requirement
|
54
51
|
requirements:
|
55
52
|
- - "~>"
|
56
53
|
- !ruby/object:Gem::Version
|
57
|
-
version:
|
54
|
+
version: 1.7.8
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: chef
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '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'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: minitest
|
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: mocha
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: simplecov
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: coveralls
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
58
122
|
- - ">="
|
59
123
|
- !ruby/object:Gem::Version
|
60
|
-
version:
|
124
|
+
version: '0'
|
61
125
|
description: |
|
62
126
|
# cookbook_sdk
|
63
127
|
|
128
|
+
[](https://badge.fury.io/rb/cookbook_sdk)
|
64
129
|
[](https://travis-ci.org/Mindera/cookbook_sdk)
|
130
|
+
[](https://coveralls.io/github/Mindera/cookbook_sdk?branch=master)
|
65
131
|
|
66
132
|
Helpers for chef cookbook development and provisioning.
|
67
133
|
email:
|
@@ -81,11 +147,15 @@ files:
|
|
81
147
|
- lib/cookbook_sdk/ext/string.rb
|
82
148
|
- lib/cookbook_sdk/handlers/slack.rb
|
83
149
|
- lib/cookbook_sdk/rake_tasks.rb
|
150
|
+
- lib/cookbook_sdk/rake_tasks/go_tasks.rb
|
84
151
|
- lib/cookbook_sdk/rake_tasks/helper_tasks.rb
|
152
|
+
- lib/cookbook_sdk/rake_tasks/jenkins_tasks.rb
|
85
153
|
- lib/cookbook_sdk/rake_tasks/provisioning_tasks.rb
|
86
154
|
- lib/cookbook_sdk/rake_tasks/test_tasks.rb
|
87
155
|
- lib/cookbook_sdk/version.rb
|
88
156
|
- lib/foodcritic/rules/etsy.rb
|
157
|
+
- test/unit/handlers/test_slack.rb
|
158
|
+
- test/unit/helpers.rb
|
89
159
|
homepage: https://github.com/mindera/cookbook_sdk
|
90
160
|
licenses:
|
91
161
|
- MIT
|
@@ -106,9 +176,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
106
176
|
version: '0'
|
107
177
|
requirements: []
|
108
178
|
rubyforge_project:
|
109
|
-
rubygems_version: 2.
|
179
|
+
rubygems_version: 2.5.2
|
110
180
|
signing_key:
|
111
181
|
specification_version: 4
|
112
182
|
summary: cookbook sdk
|
113
|
-
test_files:
|
183
|
+
test_files:
|
184
|
+
- test/unit/handlers/test_slack.rb
|
185
|
+
- test/unit/helpers.rb
|
114
186
|
has_rdoc:
|