cheftacular 2.9.1 → 2.10.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0fe23950f4d89fd436f8f7123dc8c8f97a37142c
4
- data.tar.gz: b51e27e4ccfff017252831899bb337807cb880e5
3
+ metadata.gz: 8949fa37858773111202176ac29af437fcbb10b4
4
+ data.tar.gz: 672dfda5a31ed376cbd1f73ad486af1e3f9f1407
5
5
  SHA512:
6
- metadata.gz: 4b4e7adec32f861223b857e4854e4a31ed3bcfb0bd3ecd2a3f59f6e60891f7a83dfddbb7417764250bf87038622f825fdeffb9cbb2707ef3ebc0837b9e0eb758
7
- data.tar.gz: 58f52b6c9c6f1a551086e4cce607f6e673107f8d2582fc661c0978b1b40cf8e837b83c8279bf49ee1c2ba5c592a9343a73bef763694a9313ff8a8a28e4257634
6
+ metadata.gz: 983c929c9118974e86668048b1e4d67b5f53fc6903355e7abc668b6a69b46e7e34c35e2a74f76f5e28dcaedfa1cca12ab182b999321844344603e87778f5a8f8
7
+ data.tar.gz: c0aead1166459633e9fa03dbfd08f80ee2d23b65e78ea90a014474f34c1ae3db8c7d5af91ad4e0a96a0757ee8aab6744ea762ebbd90d361c7af7325cea8bfabb
@@ -35,7 +35,7 @@ class Cheftacular
35
35
  options, locs, ridley, logs_bag_hash, pass_bag_hash, bundle_command, cheftacular, passwords = @config['helper'].set_local_instance_vars
36
36
 
37
37
  #on is namespaced to SSHKit::Backend::Netssh.on
38
- on ( nodes.map { |n| @config['cheftacular']['deploy_user'] + "@" + n.public_ipaddress } ), in: :groups, limit: 10, wait: 5 do |host|
38
+ on ( nodes.map { |n| @config['cheftacular']['deploy_user'] + "@" + n.public_ipaddress } ), in: :groups, limit: 6, wait: 5 do |host|
39
39
  n = get_node_from_address(nodes, host.hostname)
40
40
 
41
41
  puts("Beginning chef client run for #{ n.name } (#{ n.public_ipaddress }) on role #{ options['role'] }") unless options['quiet']
@@ -54,13 +54,13 @@ class Cheftacular
54
54
  def migrate_wordpress nodes=[]
55
55
  puts "Method #{ __method__ } is not yet implemented"
56
56
 
57
- exit
57
+ return false
58
58
  end
59
59
 
60
60
  def migrate_nodejs nodes=[]
61
61
  puts "Method #{ __method__ } is not yet implemented"
62
62
 
63
- exit
63
+ return false
64
64
  end
65
65
 
66
66
  def migrate_all nodes=[]
@@ -9,19 +9,20 @@ class Cheftacular
9
9
  current_day = Time.now.strftime('%Y%m%d')
10
10
  current_time = Time.now.strftime('%H:%M')
11
11
 
12
+ audit_data = audit_run_as_hash
13
+
12
14
  @config[@options['env']]['audit_bag_hash']['audit_log'][current_day] ||= {}
13
15
  @config[@options['env']]['audit_bag_hash']['audit_log'][current_day][current_time] ||= []
14
- @config[@options['env']]['audit_bag_hash']['audit_log'][current_day][current_time] << read_audit_cache_file_to_hash
16
+ @config[@options['env']]['audit_bag_hash']['audit_log'][current_day][current_time] << audit_data
15
17
 
16
18
  @config['ChefDataBag'].save_audit_bag
17
- end
18
19
 
19
- def write_audit_cache_file
20
- File.open( @config['filesystem'].current_audit_file_path, "w") { |f| f.write( fetch_audit_data_hash ) }
20
+ audit_command_to_slack_queue(audit_data) unless @config['cheftacular']['slack']['notify_on_command_execute'].blank?
21
21
  end
22
22
 
23
- def read_audit_cache_file_to_hash ret_hash={}, options_to_ignore=[]
24
- ret_hash = Hash.class_eval( File.read( @config['filesystem'].current_audit_file_path ))
23
+ def audit_run_as_hash ret_hash={}, options_to_ignore=[]
24
+ ret_hash['hostname'] = Socket.gethostname
25
+ ret_hash['directory'] = @config['locs']['root']
25
26
  ret_hash['command'] = @options['command']
26
27
 
27
28
  options_to_ignore << :preferred_cloud if @options['preferred_cloud'] == @config['cheftacular']['preferred_cloud']
@@ -29,6 +30,8 @@ class Cheftacular
29
30
  options_to_ignore << :preferred_cloud_region if @options['preferred_cloud_region'] == @config['cheftacular']['preferred_cloud_region']
30
31
  options_to_ignore << :virtualization_mode if @options['virtualization_mode'] == @config['cheftacular']['virtualization_mode']
31
32
  options_to_ignore << :route_dns_changes_via if @options['route_dns_changes_via'] == @config['cheftacular']['route_dns_changes_via']
33
+ options_to_ignore << :sub_env
34
+ options_to_ignore << :command
32
35
 
33
36
  ret_hash['options'] = @options.dup.delete_if { |key, value| options_to_ignore.include?(key.to_sym) }
34
37
 
@@ -37,14 +40,24 @@ class Cheftacular
37
40
  ret_hash
38
41
  end
39
42
 
40
- def fetch_audit_data_hash ret_hash={}, ip=""
41
- ret_hash['hostname'] = Socket.gethostname
43
+ def compile_audit_hash_entry_as_array audit_hash, entry_number=0, ret_array=[]
44
+ ret_array << "#{ (entry_number.to_s + '. ') unless entry_number == 0 }#{ audit_hash['command'] }"
45
+ ret_array << " Hostname: #{ audit_hash['hostname'] }"
46
+ ret_array << " Directory: #{ audit_hash['directory'] }" if audit_hash.has_key?('directory')
47
+ ret_array << " Arguments: #{ audit_hash['arguments'] }" if !audit_hash['arguments'].nil? && !audit_hash['arguments'].empty?
48
+ ret_array << " Options: #{ audit_hash['options'].to_hash }" unless audit_hash['options'].empty?
49
+
50
+ ret_array = ret_array.map { |entry| entry.prepend(' ')} unless entry_number == 0
42
51
 
43
- ret_hash
44
- rescue StandardError => exception
45
- @config['filesystem'].cleanup_file_caches('current-audit-only')
52
+ ret_array
53
+ end
54
+
55
+ private
56
+
57
+ def audit_command_to_slack_queue audit_hash, msg=''
58
+ msg << compile_audit_hash_entry_as_array(audit_hash).join("\n")
46
59
 
47
- @config['error'].exception_output "Unable to finish parsing auditing hash", exception
60
+ @config['slack_queue'] << { message: msg.prepend('```').insert(-1, '```'), channel: @config['cheftacular']['slack']['notify_on_command_execute'] }
48
61
  end
49
62
  end
50
63
  end
@@ -39,8 +39,6 @@ class Cheftacular
39
39
  if @config['helper'].is_initialization_command?(ARGV[0])
40
40
  @options['command'] = ARGV[0] #this is normally set by parse_context but that is not run for initialization commands
41
41
  else
42
- #@config['stateless_action'].cheftacular_config('sync') unless @config['helper'].running_on_chef_node?
43
-
44
42
  @config['stateless_action'].initialize_data_bag_contents(@options['env']) #ensure basic structure are always maintained before each run
45
43
 
46
44
  @config['parser'].parse_application_context if @config['helper'].running_in_mode?('application')
@@ -50,6 +48,8 @@ class Cheftacular
50
48
  puts("Preparing to run command \"#{ @options['command'] }\"...") if @options['verbose']
51
49
 
52
50
  @config['auditor'].audit_run if @config['cheftacular']['auditing']
51
+
52
+ @config['queue_master'].work_off_slack_queue #this occurs twice so commands that don't "end" can be queued
53
53
  end
54
54
 
55
55
  @config['stateless_action'].check_cheftacular_yml_keys unless @config['helper'].is_initialization_command?(ARGV[0])
@@ -177,7 +177,7 @@ class Cheftacular
177
177
  chef_repo_cookbooks
178
178
  end
179
179
 
180
- def parse_version_from_berkshelf_cookbook berkshelf_cookbook
180
+ def parse_version_from_berkshelf_cookbook berkshelf_cookbook
181
181
  if File.exists?(File.expand_path("#{ @config['locs']['berks'] }/#{ berkshelf_cookbook }/metadata.rb"))
182
182
  File.read(File.expand_path("#{ @config['locs']['berks'] }/#{ berkshelf_cookbook }/metadata.rb")).gsub('"',"'").gsub(/^version[\s]*('\d[.\d]+')/).peek[/('\d[.\d]+')/].gsub("'",'')
183
183
  else
@@ -185,6 +185,10 @@ class Cheftacular
185
185
  end
186
186
  end
187
187
 
188
+ def parse_gemfile_gem_version gem_name
189
+ File.read(File.expand_path("#{ @config['locs']['root'] }/Gemfile"))[/#{ gem_name }.*([\d\.]+)/][/([\d\.]+)/]
190
+ end
191
+
188
192
  private
189
193
  def current_file_path file_name, use_timestamp=true
190
194
  File.join( @config['locs']['app-root'], 'tmp', @config['helper'].declassify, ( use_timestamp ? "#{ Time.now.strftime("%Y%m%d") }-#{ file_name }" : file_name ))
@@ -48,7 +48,7 @@ class Cheftacular
48
48
  def fetch_remote_version
49
49
  puts "Checking remote #{ declassify } version..."
50
50
 
51
- `gem list #{ declassify } --remote`[/(\d+\.\d+\.\d+)/]
51
+ `gem list #{ declassify } --remote`[/([\d\.]+)/]
52
52
  end
53
53
 
54
54
  def completion_rate? percent, mode
@@ -274,7 +274,7 @@ class Cheftacular
274
274
  next unless key.include?(method.to_s)
275
275
 
276
276
  if hash['exit_status'] && hash['exit_status'] == 1
277
- @config['stateless_action'].slack(hash['text'].prepend('```').insert(-1, '```'))
277
+ @config['slack_queue'] << { message: hash['text'].prepend('```').insert(-1, '```') }
278
278
 
279
279
  @config['error'].exception_output(on_failing_exit_status_message) if !on_failing_exit_status_message.blank?
280
280
  end
@@ -285,9 +285,22 @@ class Cheftacular
285
285
  def slack_current_deploy_arguments
286
286
  msg = "#{ Socket.gethostname } just set for the repository #{ @config['getter'].get_repository_from_role_name(@options['role']) }:\n"
287
287
  msg << "the organization to #{ @options['deploy_organization'] }\n" if @options['deploy_organization']
288
- msg << "the revision to #{ @options['target_revision'] }" if @options['target_revision']
288
+ msg << "the revision to #{ @options['target_revision'] }\n" if @options['target_revision']
289
+ msg << "In the environment: #{ @options['env'] }"
289
290
 
290
- @config['stateless_action'].slack(msg.prepend('```').insert(-1, '```'), @config['cheftacular']['slack']['notify_on_deployment_args'])
291
+ @config['slack_queue'] << { message: msg.prepend('```').insert(-1, '```'), channel: @config['cheftacular']['slack']['notify_on_deployment_args'] }
292
+ end
293
+
294
+ def display_currently_installed_version
295
+ puts "The current version of cheftacular is #{ Cheftacular::VERSION }"
296
+ end
297
+
298
+ def set_detected_cheftacular_version
299
+ @config['detected_cheftacular_version'] ||= if File.exists?( @config['filesystem'].current_version_file_path )
300
+ File.read( @config['filesystem'].current_version_file_path )
301
+ else
302
+ @config['helper'].fetch_remote_version
303
+ end
291
304
  end
292
305
  end
293
306
  end
@@ -55,9 +55,7 @@ class Cheftacular
55
55
 
56
56
  @config['helper'].completion_rate? 100, 'initializer'
57
57
 
58
- initialize_version_check if @config['cheftacular']['strict_version_checks']
59
-
60
- initialize_auditing_checks if @config['cheftacular']['auditing']
58
+ initialize_version_check if @config['cheftacular']['strict_version_checks']
61
59
 
62
60
  initialize_chef_repo_up_to_date if @config['cheftacular']['keep_chef_repo_cheftacular_yml_up_to_date']
63
61
  end
@@ -133,6 +131,12 @@ class Cheftacular
133
131
  @options['verbose'] = true
134
132
  end
135
133
 
134
+ opts.on('-V', '--version', "Displays the current version of cheftacular") do
135
+ @config['helper'].display_currently_installed_version
136
+
137
+ exit
138
+ end
139
+
136
140
  opts.on('--no-logs', "Do not make logs for any command") do
137
141
  @options['no_logs'] = true
138
142
  end
@@ -426,38 +430,30 @@ class Cheftacular
426
430
  end
427
431
  end
428
432
 
429
- def initialize_version_check detected_version=""
433
+ def initialize_version_check
430
434
  current_version = Cheftacular::VERSION
431
435
 
432
- detected_version = File.exists?( @config['filesystem'].current_version_file_path ) ? File.read( @config['filesystem'].current_version_file_path ) : @config['helper'].fetch_remote_version
436
+ @config['helper'].set_detected_cheftacular_version
433
437
 
434
- if @config['helper'].is_higher_version? detected_version, current_version
435
- puts "\n Your Cheftacular is out of date. Currently #{ current_version } and remote version is #{ detected_version }.\n"
438
+ if @config['helper'].is_higher_version? @config['detected_cheftacular_version'], current_version
439
+ puts "\n Your Cheftacular is out of date. Currently #{ current_version } and remote version is #{ @config['detected_cheftacular_version'] }.\n"
436
440
 
437
441
  if @config['internal_ruby_config'].include?('@global')
438
442
  puts "Please run rvm #{ @config['internal_ruby_config'] } do gem update cheftacular to update to the latest version"
439
443
  else
440
- puts "Please update the gemfile to #{ detected_version }, bundle install and then restart this process.\n"
444
+ @config['stateless_action'].update_cheftacular
441
445
  end
442
446
 
443
447
  exit
444
448
  else
445
449
  unless File.exists?( @config['filesystem'].current_version_file_path )
446
- puts "Creating file cache for #{ Time.now.strftime("%Y%m%d") } (#{ detected_version }). No new version detected."
450
+ puts "Creating file cache for #{ Time.now.strftime("%Y%m%d") } (#{ @config['detected_cheftacular_version'] }). No new version detected."
447
451
 
448
- @config['filesystem'].write_version_file detected_version
452
+ @config['filesystem'].write_version_file @config['detected_cheftacular_version']
449
453
  end
450
454
  end
451
455
  end
452
456
 
453
- def initialize_auditing_checks
454
- unless File.exists? @config['filesystem'].current_audit_file_path
455
- puts "Creating file cache for #{ Time.now.strftime("%Y%m%d") } audit data..."
456
-
457
- @config['auditor'].write_audit_cache_file
458
- end
459
- end
460
-
461
457
  def initialize_classes
462
458
  @config['auditor'] = Cheftacular::Auditor.new(@options, @config)
463
459
  @config['parser'] = Cheftacular::Parser.new(@options, @config)
@@ -8,9 +8,11 @@ class Cheftacular
8
8
  def work_off_slack_queue
9
9
  return true if @config['slack_queue'].empty?
10
10
 
11
- @config['slack_queue'].each do |message|
12
- @config['stateless_action'].slack(message)
11
+ @config['slack_queue'].each do |slack_hash|
12
+ @config['stateless_action'].slack(slack_hash[:message], slack_hash[:channel])
13
13
  end
14
+
15
+ @config['slack_queue'] = []
14
16
  end
15
17
  end
16
18
  end
@@ -72,5 +72,7 @@ class Cheftacular
72
72
 
73
73
  puts @config['documentation']['arguments']
74
74
  end
75
+
76
+ alias_method :flags, :arguments
75
77
  end
76
78
  end
@@ -16,13 +16,32 @@ class Cheftacular
16
16
  def check_cheftacular_yml_keys out=[], exit_on_missing=false, warn_on_missing=false
17
17
  base_message = "Your cheftacular.yml is missing the key KEY, its default value is being set to DEFAULT for this run."
18
18
 
19
+ #############################2.10.0################################################
20
+
21
+ unless @config['cheftacular'].has_key?('self_update_repository')
22
+ puts base_message.gsub('KEY', 'self_update_repository').gsub('DEFAULT', 'blank')
23
+
24
+ @config['cheftacular']['self_update_repository'] = ''
25
+
26
+ warn_on_missing = true
27
+ end
28
+
29
+ #############################2.9.2################################################
30
+
31
+ unless @config['cheftacular']['slack'].has_key?('notify_on_command_execute')
32
+ puts base_message.gsub('KEY', 'slack:notify_on_command_execute').gsub('DEFAULT', 'blank')
33
+
34
+ @config['cheftacular']['slack']['notify_command_execute'] = ''
35
+
36
+ warn_on_missing = true
37
+ end
38
+
19
39
  #############################2.9.0################################################
20
40
 
21
41
  unless @config['cheftacular']['slack'].has_key?('notify_on_deployment_args')
22
- #backup_config:global_backup_role_name
23
- base_message.gsub('KEY', 'notify_on_deployment_args').gsub('DEFAULT', 'false')
42
+ puts base_message.gsub('KEY', 'slack:notify_on_deployment_args').gsub('DEFAULT', 'blank')
24
43
 
25
- @config['cheftacular']['slack']['notify_on_deployment_args'] = false
44
+ @config['cheftacular']['slack']['notify_on_deployment_args'] = ''
26
45
 
27
46
  warn_on_missing = true
28
47
  end
@@ -30,8 +49,7 @@ class Cheftacular
30
49
  #############################2.7.0################################################
31
50
 
32
51
  unless @config['cheftacular'].has_key?('backup_config')
33
- #backup_config:global_backup_role_name
34
- base_message.gsub('KEY', 'backup_config').gsub('DEFAULT', 'nil')
52
+ puts base_message.gsub('KEY', 'backup_config').gsub('DEFAULT', 'nil')
35
53
 
36
54
  warn_on_missing = true
37
55
  end
@@ -4,7 +4,7 @@ class Cheftacular
4
4
  def cheftacular_config
5
5
  @config['documentation']['stateless_action'][__method__] ||= {}
6
6
  @config['documentation']['stateless_action'][__method__]['long_description'] = [
7
- "`cft cheftacular_config [display|sync|overwrite]` this command " +
7
+ "`cft cheftacular_config [diff|display|sync|overwrite]` this command " +
8
8
  "Allows you to interact with your complete cheftacular configuration, the union of all repository's cheftacular.ymls. ",
9
9
 
10
10
  [
@@ -27,7 +27,7 @@ class Cheftacular
27
27
  def cheftacular_config command=''
28
28
  command = ARGV[1] if command.blank?
29
29
 
30
- raise "Unsupported command (#{ command }) for cft cheftacular_config" unless command =~ /display|sync|overwrite/
30
+ raise "Unsupported command (#{ command }) for cft cheftacular_config" unless command =~ /diff|display|sync|overwrite/
31
31
 
32
32
  self.send("cheftacular_config_#{ command }")
33
33
  end
@@ -42,11 +42,7 @@ class Cheftacular
42
42
 
43
43
  compiled_audit_hash[day][time].each do |log_arr|
44
44
  log_arr.each do |log_hash|
45
- out << " #{ log_array_entry_count }. #{ log_hash['command'] }"
46
- out << " 1. Hostname: #{ log_hash['hostname'] }"
47
- out << " 3. Arguments: #{ log_hash['arguments'] }"
48
- out << " 4. Options: #{ log_hash['options'].to_hash }"
49
- out << ""
45
+ out << @config['auditor'].compile_audit_hash_entry_as_array(log_hash, log_array_entry_count)
50
46
 
51
47
  log_array_entry_count += 1
52
48
  end
@@ -56,7 +52,7 @@ class Cheftacular
56
52
  end
57
53
  end
58
54
 
59
- File.open("#{ @config['locs']['chef-log'] }/audit-log-#{ Time.now.strftime("%Y%m%d%H%M%S") }.md", "w") { |f| f.write(out.join("\n")) }
55
+ File.open("#{ @config['locs']['chef-log'] }/audit-log-#{ Time.now.strftime("%Y%m%d%H%M%S") }.md", "w") { |f| f.write(out.flatten.join("\n")) }
60
56
  end
61
57
  end
62
58
  end
@@ -20,10 +20,12 @@ class Cheftacular
20
20
 
21
21
  class StatelessAction
22
22
  def slack message='', channel=''
23
+ return false if @config['cheftacular']['slack']['webhook'].nil?
24
+
23
25
  @slack_notifier ||= Slack::Notifier.new @config['cheftacular']['slack']['webhook'], username: 'Cheftacular'
24
26
 
25
- message = ARGV[1] if message.blank?
26
- channel = ARGV[2] if channel.blank?
27
+ message = ARGV[1] if !message.nil? && message.blank?
28
+ channel = ARGV[2] if !channel.nil? && channel.blank?
27
29
 
28
30
  @slack_notifier.channel = channel.nil? ? @config['cheftacular']['slack']['default_channel'] : channel
29
31
  @slack_notifier.ping message
@@ -0,0 +1,85 @@
1
+
2
+ class Cheftacular
3
+ class StatelessActionDocumentation
4
+ def update_cheftacular
5
+ @config['documentation']['stateless_action'][__method__] ||= {}
6
+ @config['documentation']['stateless_action'][__method__]['long_description'] = [
7
+ "`cft #{ __method__ }` this command attempts to update cheftacular to the latest version."
8
+ ]
9
+
10
+ @config['documentation']['stateless_action'][__method__]['short_description'] = 'Update cheftacular to the latest version'
11
+
12
+ @config['documentation']['application'][__method__] = @config['documentation']['stateless_action'][__method__]
13
+ end
14
+ end
15
+
16
+ class StatelessAction
17
+ def update_cheftacular status_hash={}
18
+ update_cheftacular_not_configured_to_update if @config['cheftacular']['self_update_repository'] != @config['locs']['root']
19
+
20
+ @config['helper'].set_detected_cheftacular_version
21
+
22
+ puts "Attempting to update cheftacular from #{ Cheftacular::VERSION } to #{ @config['detected_cheftacular_version'] }..."
23
+
24
+ status_hash['gemfile_is_latest_version'] = update_cheftacular_from_git
25
+ status_hash['gemfile_is_latest_version'] = update_cheftacular_gemfile unless status_hash['gemfile_is_latest_version']
26
+ status_hash['bundled_latest_version'] = update_cheftacular_bundle if status_hash['gemfile_is_latest_version']
27
+
28
+ if !status_hash['gemfile_is_latest_version'] || !status_hash['bundled_latest_version']
29
+ puts(
30
+ "Issues occured in automatically updating your cheftacular " +
31
+ "to #{ @config['detected_cheftacular_version'] }, please send " +
32
+ "the output of this command to your DevOps administrator or add " +
33
+ "it as an issue at this gem's github page."
34
+ )
35
+ else
36
+ puts "Successfully installed version #{ @config['detected_cheftacular_version'] }, please re-run your command."
37
+ end
38
+ end
39
+
40
+ private
41
+ def update_cheftacular_from_git out=[]
42
+ out << `git reset --hard origin/master && git pull origin master`
43
+
44
+ parsed_gemfile_version = @config['filesystem'].parse_gemfile_gem_version('cheftacular')
45
+
46
+ puts "After git update, Gemfile lists version #{ parsed_gemfile_version } versus latest version: #{ @config['detected_cheftacular_version'] }"
47
+
48
+ return parsed_gemfile_version == @config['detected_cheftacular_version']
49
+ end
50
+
51
+ def update_cheftacular_gemfile
52
+ puts "Forcing gemfile update to the latest version of cheftacular..."
53
+
54
+ gemfile_path = File.expand_path("#{ @config['locs']['root'] }/Gemfile")
55
+ parsed_gemfile_version = @config['filesystem'].parse_gemfile_gem_version('cheftacular')
56
+ new_file_content = File.read(gemfile_path).gsub(parsed_gemfile_version, @config['detected_cheftacular_version'])
57
+
58
+ File.open( gemfile_path, "w") { |f| f.write(new_file_content) }
59
+
60
+ new_parsed_gemfile_version = @config['filesystem'].parse_gemfile_gem_version('cheftacular')
61
+
62
+ puts "After forced gemfile update, Gemfile lists version #{ new_parsed_gemfile_version } versus latest version: #{ @config['detected_cheftacular_version'] }"
63
+
64
+ return new_parsed_gemfile_version == @config['detected_cheftacular_version']
65
+ end
66
+
67
+ def update_cheftacular_bundle out=[]
68
+ puts "Running bundle install..."
69
+
70
+ out << `bundle install`
71
+
72
+ cheftacular_bundle_version = out.first[/cheftacular.*([\d\.]+)/][/([\d\.]+)/]
73
+
74
+ puts "After bundle install, version is #{ cheftacular_bundle_version } versus latest version: #{ @config['detected_cheftacular_version'] }"
75
+
76
+ return cheftacular_bundle_version == @config['detected_cheftacular_version']
77
+ end
78
+
79
+ def update_cheftacular_not_configured_to_update
80
+ puts "Please update the gemfile to #{ @config['detected_cheftacular_version'] }, bundle install and then restart this process.\n"
81
+
82
+ exit
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,27 @@
1
+
2
+ class Cheftacular
3
+ class StatelessActionDocumentation
4
+ def version
5
+ @config['documentation']['stateless_action'][__method__] ||= {}
6
+ @config['documentation']['stateless_action'][__method__]['long_description'] = [
7
+ "`cft version` this command prints out the current version of cheftacular.",
8
+ ]
9
+
10
+ @config['documentation']['stateless_action'][__method__]['short_description'] = 'Displays the current version of cheftacular'
11
+
12
+ @config['documentation']['application'][__method__] = @config['documentation']['stateless_action'][__method__]
13
+ end
14
+ end
15
+
16
+ class InitializationAction
17
+ def version
18
+
19
+ end
20
+ end
21
+
22
+ class StatelessAction
23
+ def version
24
+ @config['helper'].display_currently_installed_version
25
+ end
26
+ end
27
+ end
@@ -1,5 +1,5 @@
1
1
  class Cheftacular
2
2
  #major_version.minor_version.bugfixes
3
- VERSION = "2.9.1"
3
+ VERSION = "2.10.0"
4
4
  RUBY_VERSION = "2.2.2"
5
5
  end
@@ -36,11 +36,13 @@ module SSHKit
36
36
  end
37
37
 
38
38
  def get_true_environment run_list, chef_env_roles, default_env
39
- chef_env_roles.each_pair do |role, env|
40
- if run_list.include?("role[#{ role }]")
41
- default_env = env
39
+ unless chef_env_roles.nil?
40
+ chef_env_roles.each_pair do |role, env|
41
+ if run_list.include?("role[#{ role }]")
42
+ default_env = env
42
43
 
43
- break
44
+ break
45
+ end
44
46
  end
45
47
  end
46
48
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cheftacular
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.9.1
4
+ version: 2.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Louis Alridge
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-06 00:00:00.000000000 Z
11
+ date: 2015-11-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hashie
@@ -303,12 +303,14 @@ files:
303
303
  - lib/cheftacular/stateless_actions/slack.rb
304
304
  - lib/cheftacular/stateless_actions/test_env.rb
305
305
  - lib/cheftacular/stateless_actions/update_chef_client.rb
306
+ - lib/cheftacular/stateless_actions/update_cheftacular.rb
306
307
  - lib/cheftacular/stateless_actions/update_cloudflare_dns_from_cloud.rb
307
308
  - lib/cheftacular/stateless_actions/update_split_branches.rb
308
309
  - lib/cheftacular/stateless_actions/update_thecheftacularcookbook.rb
309
310
  - lib/cheftacular/stateless_actions/update_tld.rb
310
311
  - lib/cheftacular/stateless_actions/upload_nodes.rb
311
312
  - lib/cheftacular/stateless_actions/upload_roles.rb
313
+ - lib/cheftacular/stateless_actions/version.rb
312
314
  - lib/cheftacular/version.rb
313
315
  - lib/cloud_interactor/authentication.rb
314
316
  - lib/cloud_interactor/cloud_interactor.rb