cheftacular 2.10.2 → 2.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/lib/cheftacular/README.md +119 -77
  3. data/lib/cheftacular/actions/check.rb +58 -24
  4. data/lib/cheftacular/actions/deploy.rb +5 -3
  5. data/lib/cheftacular/auditor.rb +4 -3
  6. data/lib/cheftacular/cheftacular.rb +1 -0
  7. data/lib/cheftacular/cloud_provider.rb +17 -12
  8. data/lib/cheftacular/file_system.rb +20 -0
  9. data/lib/cheftacular/getter.rb +1 -1
  10. data/lib/cheftacular/helper.rb +41 -28
  11. data/lib/cheftacular/initializer.rb +5 -3
  12. data/lib/cheftacular/parser.rb +10 -6
  13. data/lib/cheftacular/queue_master.rb +24 -0
  14. data/lib/cheftacular/stateless_actions/backups.rb +2 -2
  15. data/lib/cheftacular/stateless_actions/bootstrappers/{centos_bootstrap.rb → centos_bootstrap_from_queue.rb} +1 -1
  16. data/lib/cheftacular/stateless_actions/bootstrappers/{coreos_bootstrap.rb → coreos_bootstrap_from_queue.rb} +1 -1
  17. data/lib/cheftacular/stateless_actions/bootstrappers/{fedora_bootstrap.rb → fedora_bootstrap_from_queue.rb} +1 -1
  18. data/lib/cheftacular/stateless_actions/bootstrappers/{redhat_bootstrap.rb → redhat_bootstrap_from_queue.rb} +1 -1
  19. data/lib/cheftacular/stateless_actions/bootstrappers/ubuntu_bootstrap_from_queue.rb +203 -0
  20. data/lib/cheftacular/stateless_actions/bootstrappers/vyatta_bootstrap_from_queue.rb +7 -0
  21. data/lib/cheftacular/stateless_actions/check_cheftacular_yml_keys.rb +30 -0
  22. data/lib/cheftacular/stateless_actions/chef_bootstrap_from_queue.rb +89 -0
  23. data/lib/cheftacular/stateless_actions/cheftacular_yml_help.rb +55 -6
  24. data/lib/cheftacular/stateless_actions/client_list.rb +1 -3
  25. data/lib/cheftacular/stateless_actions/cloud_bootstrap.rb +24 -15
  26. data/lib/cheftacular/stateless_actions/cloud_bootstrap_from_queue.rb +37 -0
  27. data/lib/cheftacular/stateless_actions/environment.rb +80 -31
  28. data/lib/cheftacular/stateless_actions/fix_known_hosts.rb +1 -22
  29. data/lib/cheftacular/stateless_actions/{full_bootstrap.rb → full_bootstrap_from_queue.rb} +8 -15
  30. data/lib/cheftacular/stateless_actions/knife_upload.rb +14 -3
  31. data/lib/cheftacular/stateless_actions/reinitialize.rb +1 -1
  32. data/lib/cheftacular/stateless_actions/remove_client.rb +3 -3
  33. data/lib/cheftacular/stateless_actions/restart_swap.rb +0 -1
  34. data/lib/cheftacular/stateless_actions/test_env.rb +24 -18
  35. data/lib/cheftacular/stateless_actions/update_thecheftacularcookbook.rb +1 -1
  36. data/lib/cheftacular/stateless_actions/upload_nodes.rb +2 -2
  37. data/lib/cheftacular/version.rb +1 -1
  38. data/lib/cloud_interactor/domain/create.rb +2 -2
  39. data/lib/cloud_interactor/domain/create_record.rb +1 -1
  40. data/lib/cloud_interactor/domain/destroy.rb +2 -2
  41. data/lib/cloud_interactor/domain/destroy_record.rb +1 -1
  42. data/lib/cloud_interactor/domain/list_records.rb +1 -1
  43. data/lib/cloud_interactor/domain/read.rb +1 -1
  44. data/lib/cloud_interactor/domain/read_record.rb +1 -1
  45. data/lib/cloud_interactor/domain/update.rb +2 -2
  46. data/lib/cloud_interactor/domain/update_record.rb +2 -2
  47. data/lib/cloud_interactor/helpers.rb +11 -6
  48. data/lib/cloud_interactor/server/attach_volume.rb +1 -1
  49. data/lib/cloud_interactor/server/create.rb +4 -4
  50. data/lib/cloud_interactor/server/detach_volume.rb +2 -2
  51. data/lib/cloud_interactor/server/list_volumes.rb +1 -1
  52. data/lib/cloud_interactor/server/poll.rb +2 -2
  53. data/lib/cloud_interactor/server/read_volume.rb +1 -1
  54. data/lib/cloud_interactor/version.rb +1 -1
  55. data/lib/cloud_interactor/volume/create.rb +1 -1
  56. data/lib/sshkit/getters.rb +9 -1
  57. metadata +25 -10
  58. data/lib/cheftacular/stateless_actions/bootstrappers/ubuntu_bootstrap.rb +0 -116
  59. data/lib/cheftacular/stateless_actions/bootstrappers/vyatta_bootstrap.rb +0 -7
  60. data/lib/cheftacular/stateless_actions/chef_bootstrap.rb +0 -63
@@ -3,11 +3,13 @@ class Cheftacular
3
3
  def check
4
4
  @config['documentation']['action'][__method__] ||= {}
5
5
  @config['documentation']['action'][__method__]['long_description'] = [
6
- "`cft check` Checks the commits for all servers for a repository (for an environment) and returns them in a simple chart. " +
6
+ "`cft check [all]` Checks the commits for all servers for a repository (for an environment) and returns them in a simple chart. " +
7
7
  "Also shows when these commits were deployed to the server.",
8
8
  [
9
9
  " 1. If the node has special repository based keys from TheCheftacularCookbook, this command will also display information " +
10
- "about the branch and organization currently deployed to the node(s)."
10
+ "about the branch and organization currently deployed to the node(s).",
11
+
12
+ " 2. If the all argument is provided, all repositories will be checked for the current environment"
11
13
  ]
12
14
  ]
13
15
  @config['documentation']['action'][__method__]['short_description'] = "Checks the branches currently deployed to an env for your repo"
@@ -15,41 +17,71 @@ class Cheftacular
15
17
  end
16
18
 
17
19
  class Action
18
- def check commit_hash={}, have_revisions=false, have_changed_orgs=false
20
+ def check commit_hash={}, have_revisions=false, have_changed_orgs=false, fetch_all_repository_data=false, headers=[], deployment_args={ in: :parallel }
19
21
  @config['filesystem'].cleanup_file_caches('current-nodes')
22
+
23
+ fetch_all_repository_data = ARGV[1] == 'all'
20
24
 
21
- nodes = @config['getter'].get_true_node_objects
25
+ nodes = @config['getter'].get_true_node_objects(fetch_all_repository_data)
26
+
27
+ nodes = @config['parser'].exclude_nodes(nodes, [{ if: { not_env: @options['env'] } }])
28
+
29
+ repositories_to_check = @config['getter'].get_repo_names_for_repositories
30
+ repositories_to_check = repositories_to_check.reject { |key,val| key != @options['repository'] } unless fetch_all_repository_data
31
+
32
+ deployment_args = { in: :groups, limit: 2, wait: 5 } if fetch_all_repository_data
22
33
 
23
34
  #this must always precede on () calls so they have the instance variables they need
24
35
  options, locs, ridley, logs_bag_hash, pass_bag_hash, bundle_command, cheftacular, passwords = @config['helper'].set_local_instance_vars
25
36
 
26
- on ( nodes.map { |n| @config['cheftacular']['deploy_user'] + "@" + n.public_ipaddress } ), in: :parallel do |host|
37
+ on ( nodes.map { |n| @config['cheftacular']['deploy_user'] + "@" + n.public_ipaddress } ), deployment_args do |host|
27
38
  n = get_node_from_address(nodes, host.hostname)
28
39
 
29
- puts("Beginning commit check run for #{ n.name } (#{ n.public_ipaddress }) on role #{ options['role'] }") unless options['quiet']
40
+ puts("Beginning commit check run for #{ n.name } (#{ n.public_ipaddress })...") unless options['quiet']
30
41
 
31
- commit_hash[n.name] = start_commit_check( n.name, n.public_ipaddress, options, locs, cheftacular)
42
+ repositories_to_check.each_pair do |repo, repo_hash|
43
+ next unless n.run_list.include?("role[#{ repo_hash['role'] }]")
32
44
 
33
- if n.normal_attributes.has_key?(options['repository'])
34
- commit_hash[n.name]['branch'] = n.normal_attributes[options['repository']]['repo_branch'] if n.normal_attributes[options['repository']].has_key?('repo_branch')
35
- commit_hash[n.name]['organization'] = n.normal_attributes[options['repository']]['repo_group'] if n.normal_attributes[options['repository']].has_key?('repo_group')
36
- end
45
+ options['repository'] = repo
46
+ commit_hash[n.name] ||= {}
47
+
48
+ commit_hash[n.name][repo] = start_commit_check( n.name, n.public_ipaddress, options, locs, cheftacular, passwords)
49
+
50
+ next if commit_hash[n.name][repo].nil?
37
51
 
38
- have_revisions = true if commit_hash[n.name].has_key?('branch')
39
- have_changed_orgs = true if commit_hash[n.name].has_key?('organization')
52
+ if n.normal_attributes.has_key?(options['repository'])
53
+ commit_hash[n.name][repo]['branch'] = n.normal_attributes[options['repository']]['repo_branch'] if n.normal_attributes[options['repository']].has_key?('repo_branch')
54
+ commit_hash[n.name][repo]['organization'] = n.normal_attributes[options['repository']]['repo_group'] if n.normal_attributes[options['repository']].has_key?('repo_group')
55
+ end
56
+
57
+ have_revisions = true if commit_hash[n.name].has_key?(repo) && commit_hash[n.name][repo].has_key?('branch')
58
+ have_changed_orgs = true if commit_hash[n.name].has_key?(repo) && commit_hash[n.name][repo].has_key?('organization')
59
+
60
+ sleep 5
61
+ end
40
62
  end
41
63
 
42
- puts "\n#{ 'name'.ljust(21) }#{ 'deployed_on'.ljust(22) } #{ 'commit'.ljust(40) } #{'revision'.ljust(29) if have_revisions } #{'organization'.ljust(30) if have_changed_orgs }"
64
+ headers << "\n#{ 'name'.ljust(20) }"
65
+ headers << 'repository'.ljust(30,'_') if repositories_to_check.length > 1
66
+ headers << "#{ 'deployed_on'.ljust(22) } #{ 'commit'.ljust(40) }"
67
+ headers << 'revision'.ljust(21) if have_revisions
68
+ headers << 'organization'.ljust(30) if have_changed_orgs
69
+
70
+ puts headers.join(' ')
43
71
  nodes.each do |n|
44
- unless commit_hash[n.name]['name'].blank?
45
- out = []
46
- out << n.name.ljust(20, '_')
47
- out << commit_hash[n.name]['time'].ljust(21)
48
- out << commit_hash[n.name]['name'].ljust(39)
49
- out << commit_hash[n.name]['branch'].ljust(29) if commit_hash[n.name].has_key?('branch')
50
- out << commit_hash[n.name]['organization'].ljust(30) if commit_hash[n.name].has_key?('organization')
51
-
52
- puts out.join(' ')
72
+ next if commit_hash[n.name].nil?
73
+ repositories_to_check.each_pair do |repo, repo_hash|
74
+ if commit_hash[n.name].has_key?(repo) && !commit_hash[n.name][repo].nil?
75
+ out = []
76
+ out << n.name.ljust(20, '_')
77
+ out << repo.ljust(30) if repositories_to_check.length > 1
78
+ out << commit_hash[n.name][repo]['time'].ljust(22)
79
+ out << commit_hash[n.name][repo]['name'].ljust(40)
80
+ out << commit_hash[n.name][repo]['branch'].ljust(21, '_') if commit_hash[n.name][repo].has_key?('branch')
81
+ out << commit_hash[n.name][repo]['organization'].ljust(30) if commit_hash[n.name][repo].has_key?('organization')
82
+
83
+ puts out.join(' ')
84
+ end
53
85
  end
54
86
  end
55
87
  end
@@ -59,7 +91,7 @@ end
59
91
  module SSHKit
60
92
  module Backend
61
93
  class Netssh
62
- def start_commit_check name, ip_address, options, locs, cheftacular, out={'name'=>'', 'time'=> ''}
94
+ def start_commit_check name, ip_address, options, locs, cheftacular, passwords, out={'name'=>'', 'time'=> ''}
63
95
  app_loc = "#{ cheftacular['base_file_path'] }/#{ options['repository'] }/releases"
64
96
 
65
97
  if test("[ -d #{ app_loc } ]") #true if file exists
@@ -68,6 +100,8 @@ module SSHKit
68
100
 
69
101
  out['time'] = Time.parse(capture( :stat, out['name'], '--printf=%y' )).strftime('%Y-%m-%d %I:%M:%S %p')
70
102
  end
103
+ else
104
+ return nil
71
105
  end
72
106
 
73
107
  out
@@ -26,16 +26,18 @@ class Cheftacular
26
26
  end
27
27
 
28
28
  class Action
29
- def deploy
30
- nodes = @config['getter'].get_true_node_objects false, true #when this is run in scaling we'll need to make sure we deploy to new nodes
29
+ def deploy deployment_args={ in: :groups, limit: 6, wait: 5 }
30
+ nodes = @config['getter'].get_true_node_objects(false) #when this is run in scaling we'll need to make sure we deploy to new nodes
31
31
 
32
32
  nodes = @config['parser'].exclude_nodes( nodes, [{ if: "role[#{ @options['negative_role'] }]" }]) if @options['negative_role']
33
33
 
34
34
  #this must always precede on () calls so they have the instance variables they need
35
35
  options, locs, ridley, logs_bag_hash, pass_bag_hash, bundle_command, cheftacular, passwords = @config['helper'].set_local_instance_vars
36
36
 
37
+ deployment_args = { in: :groups, limit: 10, wait: 5 } if @options['env'] == 'production'
38
+
37
39
  #on is namespaced to SSHKit::Backend::Netssh.on
38
- on ( nodes.map { |n| @config['cheftacular']['deploy_user'] + "@" + n.public_ipaddress } ), in: :groups, limit: 6, wait: 5 do |host|
40
+ on ( nodes.map { |n| @config['cheftacular']['deploy_user'] + "@" + n.public_ipaddress } ), deployment_args do |host|
39
41
  n = get_node_from_address(nodes, host.hostname)
40
42
 
41
43
  puts("Beginning chef client run for #{ n.name } (#{ n.public_ipaddress }) on role #{ options['role'] }") unless options['quiet']
@@ -40,10 +40,11 @@ class Cheftacular
40
40
  ret_hash
41
41
  end
42
42
 
43
- def compile_audit_hash_entry_as_array audit_hash, entry_number=0, ret_array=[]
43
+ def compile_audit_hash_entry_as_array audit_hash, entry_number=0, ret_array=[], directory_content=''
44
+ directory_content = " (#{ audit_hash['directory'] })" if audit_hash.has_key?('directory')
45
+
44
46
  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 << " Hostname: #{ audit_hash['hostname'] }#{ directory_content }"
47
48
  ret_array << " Arguments: #{ audit_hash['arguments'] }" if !audit_hash['arguments'].nil? && !audit_hash['arguments'].empty?
48
49
  ret_array << " Options: #{ audit_hash['options'].to_hash }" unless audit_hash['options'].empty?
49
50
 
@@ -18,6 +18,7 @@ require 'rbconfig'
18
18
  require 'fog'
19
19
  require 'socket'
20
20
  require 'net/http'
21
+ require 'net/ssh'
21
22
  require 'timeout'
22
23
  require 'slack-notifier'
23
24
  require 'cloudflare'
@@ -6,18 +6,23 @@ class Cheftacular
6
6
  end
7
7
 
8
8
  #public address, private address
9
- def parse_addresses_from_server_create_hash server_hash
10
- ap server_hash
11
- case @options['preferred_cloud']
12
- when 'rackspace'
13
- [server_hash['ipv4_address'], server_hash['addresses']['private'][0]['addr']]
14
- when 'digitalocean'
15
- [
16
- server_hash['networks']['v4'].select { |hash| hash['type'] == 'public' }.first['ip_address'],
17
- server_hash['networks']['v4'].select { |hash| hash['type'] == 'private' }.first['ip_address']
18
- ]
19
- else raise "CRITICAL! Encountered unsupported preferred cloud #{ @options['preferred_cloud'] }"
20
- end
9
+ def parse_addresses_from_server_create_hash cloud_server_hash, ret_array=[]
10
+ ap(cloud_server_hash) if @options['verbose']
11
+
12
+ ret_array = case @options['preferred_cloud']
13
+ when 'rackspace'
14
+ [cloud_server_hash['ipv4_address'], cloud_server_hash['addresses']['private'][0]['addr']]
15
+ when 'digitalocean'
16
+ [
17
+ cloud_server_hash['networks']['v4'].select { |hash| hash['type'] == 'public' }.first['ip_address'],
18
+ cloud_server_hash['networks']['v4'].select { |hash| hash['type'] == 'private' }.first['ip_address']
19
+ ]
20
+ else raise "CRITICAL! Encountered unsupported preferred cloud #{ @options['preferred_cloud'] }"
21
+ end
22
+
23
+ raise "CRITICAL! Unable to capture addresses for the server!" if ret_array[0].nil? || ret_array[1].nil?
24
+
25
+ ret_array
21
26
  end
22
27
 
23
28
  def parse_server_root_password_from_server_create_hash server_hash, real_node_name
@@ -189,6 +189,26 @@ class Cheftacular
189
189
  File.read(File.expand_path("#{ @config['locs']['root'] }/Gemfile"))[/#{ gem_name }.*([\d\.]+)/][/([\d\.]+)/]
190
190
  end
191
191
 
192
+ def scrub_from_known_hosts target
193
+ puts "Clearing #{ target } from known_hosts file."
194
+ case CONFIG['host_os']
195
+ when /mswin|windows/i
196
+ puts "#{ __method__ } does not support this operating system at this time"
197
+ when /linux|arch/i
198
+ puts "#{ __method__ } does not support this operating system at this time"
199
+ when /sunos|solaris/i
200
+ puts "#{ __method__ } does not support this operating system at this time"
201
+ when /darwin/i
202
+ #Removes the entire line containing the string
203
+ `sed -i '' "s/#{ target }.*//g" ~/.ssh/known_hosts`
204
+
205
+ #remove empty lines
206
+ `sed -i '' "/^$/d" ~/.ssh/known_hosts`
207
+ else
208
+ puts "#{ __method__ } does not support this operating system at this time"
209
+ end
210
+ end
211
+
192
212
  private
193
213
  def current_file_path file_name, use_timestamp=true
194
214
  File.join( @config['locs']['app-root'], 'tmp', @config['helper'].declassify, ( use_timestamp ? "#{ Time.now.strftime("%Y%m%d") }-#{ file_name }" : file_name ))
@@ -10,7 +10,7 @@ class Cheftacular
10
10
  end
11
11
 
12
12
  #[TODO] if ridley changes its parsing strategy
13
- def get_true_node_objects get_all_nodes=false, get_new_nodes=false
13
+ def get_true_node_objects get_all_nodes=false
14
14
  nodes, all_nodes, names, iter_arr, file_cache_nodes, h = [],[],[],[],[],{}
15
15
 
16
16
  @config['chef_nodes'] = @config['ridley'].node.all
@@ -126,16 +126,6 @@ class Cheftacular
126
126
  @config['dummy_sshkit'].set_log_loc_and_timestamp @config['locs']
127
127
  end
128
128
 
129
- def knife_bootstrap_command
130
- address = @options['address']
131
- user = @config['cheftacular']['deploy_user']
132
- password = @config['server_passwords'][@options['address']]
133
- nodename = @options['node_name']
134
- chef_ver = @config['cheftacular']['chef_version'].to_i >= 12 ? '12.4.0' : '11.16.4'
135
-
136
- "knife bootstrap #{ address } -x #{ user } -P #{ password } -N #{ nodename } --sudo --use-sudo-password --bootstrap-version #{ chef_ver }"
137
- end
138
-
139
129
  #the documentation hashes must be populated *before* this method runs for it to return anything!
140
130
  def compile_documentation_lines mode, out=[]
141
131
  doc_arr = case mode
@@ -250,24 +240,6 @@ class Cheftacular
250
240
  master_hash
251
241
  end
252
242
 
253
- def install_rvm_sh_file out=[]
254
- puts("Starting rvm.sh installation...") unless @options['quiet']
255
-
256
- commands = [
257
- "#{ @config['helper'].sudo(@options['address']) } mv /home/deploy/rvm.sh /etc/profile.d",
258
- "#{ @config['helper'].sudo(@options['address']) } chmod 755 /etc/profile.d/rvm.sh",
259
- "#{ @config['helper'].sudo(@options['address']) } chown root:root /etc/profile.d/rvm.sh"
260
- ]
261
-
262
- out << `scp -oStrictHostKeyChecking=no #{ @config['locs']['cheftacular-lib-files'] }/rvm.sh #{ @config['cheftacular']['deploy_user'] }@#{ @options['address'] }:/home/#{ @config['cheftacular']['deploy_user'] }`
263
-
264
- commands.each do |command|
265
- out << `ssh -t -oStrictHostKeyChecking=no #{ @config['cheftacular']['deploy_user'] }@#{ @options['address'] } "#{ command }"`
266
- end
267
-
268
- puts("Completed rvm.sh installation into /etc/profile.d/rvm.sh") unless @options['quiet']
269
- end
270
-
271
243
  def send_log_bag_hash_slack_notification logs_bag_hash, method, on_failing_exit_status_message=''
272
244
  if @config['cheftacular']['slack']['webhook']
273
245
  logs_bag_hash.each_pair do |key, hash|
@@ -302,6 +274,47 @@ class Cheftacular
302
274
  @config['helper'].fetch_remote_version
303
275
  end
304
276
  end
277
+
278
+ def return_options_as_hash options_array, return_hash={}
279
+ options_array.each do |key|
280
+ return_hash[key] = @options[key]
281
+ end
282
+
283
+ return_hash
284
+ end
285
+
286
+ def check_if_possible_repo_state repo_state_hash, git_output=''
287
+ revision_to_check = repo_state_hash.has_key?('revision') ? repo_state_hash['revision'] : nil
288
+ org_name_to_check = repo_state_hash.has_key?('deploy_organization') ? repo_state_hash['deploy_organization'] : @config['cheftacular']['TheCheftacularCookbook']['organization_name']
289
+
290
+ revision_to_check = nil if revision_to_check == '<use_default>'
291
+
292
+ @config['cheftacular']['TheCheftacularCookbook']['chef_environment_to_app_repo_branch_mappings'].each_pair do |chef_env, app_env|
293
+ revision_to_check = app_env if @options['env'] == chef_env && revision_to_check.nil?
294
+ end
295
+
296
+ git_output = `git ls-remote --heads git@github.com:#{ org_name_to_check }/#{ @options['repository'] }.git`
297
+
298
+ if git_output.blank?
299
+ puts "! The remote organization #{ org_name_to_check } does not have the repository: #{ @options['repository'] }! Please verify your repositories and try again"
300
+
301
+ exit
302
+ elsif !git_output.include?(revision_to_check)
303
+ puts "! The remote organization #{ org_name_to_check } does not have a revision / branch #{ revision_to_check } for repository: #{ @options['repository'] } !"
304
+
305
+ sorted_heads = git_output.scan(/refs\/heads\/(.*)/).flatten.uniq.sort_by { |head| compare_strings(revision_to_check, head)}
306
+
307
+ puts "The closest matches for #{ revision_to_check } are:"
308
+ puts " #{ sorted_heads.at(0) }"
309
+ puts " #{ sorted_heads.at(1) }"
310
+ puts " #{ sorted_heads.at(2) }"
311
+ puts " #{ sorted_heads.at(3) }\n"
312
+
313
+ puts "Please verify the correct revision / branch and run this command again."
314
+
315
+ exit
316
+ end
317
+ end
305
318
  end
306
319
  end
307
320
 
@@ -168,7 +168,7 @@ class Cheftacular
168
168
  end
169
169
 
170
170
  # client-list
171
- opts.on('-W', '--with-priv', "On client-list this will show each server's private addresses") do
171
+ opts.on('-W', '--with-priv', "On cft client_list this will show each server's private addresses") do
172
172
  @options['with_private'] = true
173
173
  end
174
174
 
@@ -243,7 +243,8 @@ class Cheftacular
243
243
  end
244
244
 
245
245
  def initialize_queues
246
- @config['slack_queue'] ||= []
246
+ @config['slack_queue'] ||= []
247
+ @config['server_creation_queue'] ||= []
247
248
  end
248
249
 
249
250
  def initialize_yaml_configuration
@@ -319,6 +320,7 @@ class Cheftacular
319
320
  locs['chef-log'] = File.expand_path("#{ locs['root']}/log") unless locs['chef-log']
320
321
  locs['app-tmp'] = File.expand_path("#{ locs['app-root']}/tmp")
321
322
  locs['examples'] = File.expand_path("../../../examples", __FILE__)
323
+ locs['doc'] = File.expand_path("../../../doc", __FILE__)
322
324
  locs['cheftacular-lib'] = File.expand_path("../..", __FILE__)
323
325
  locs['cheftacular-lib-files'] = locs['cheftacular-lib'] + '/cheftacular/files'
324
326
 
@@ -472,7 +474,7 @@ class Cheftacular
472
474
  end
473
475
 
474
476
  def initialize_directories
475
- ['applog', 'deploy', 'failed-deploy', 'rolelog', 'rvm', 'stashedlog'].each do |sub_log_directory|
477
+ ['applog', 'deploy', 'failed-deploy', 'rolelog', 'rvm', 'server-setup', 'stashedlog'].each do |sub_log_directory|
476
478
  FileUtils.mkdir_p File.join( @config['locs']['chef-log'], sub_log_directory )
477
479
  end
478
480
 
@@ -113,6 +113,8 @@ class Cheftacular
113
113
  repo_state_hash['deploy_organization'] = nil
114
114
  end
115
115
 
116
+ @config['helper'].check_if_possible_repo_state(repo_state_hash) if @config['cheftacular']['git']['check_remote_for_branch_existence'] && !@config['helper'].running_on_chef_node?
117
+
116
118
  @config['helper'].slack_current_deploy_arguments unless @config['cheftacular']['slack']['notify_on_deployment_args'].blank?
117
119
 
118
120
  @config['ChefDataBag'].save_config_bag
@@ -131,7 +133,7 @@ class Cheftacular
131
133
  end
132
134
 
133
135
  #parse nodes out of array based on hash, ex: [{ unless: 'role[rails]'}, {if: 'role[worker]'}, { if: { run_list: 'role[db]', role: 'pg_data' } }]
134
- def exclude_nodes nodes, statement_arr, only_one_node = false, ret_arr = []
136
+ def exclude_nodes nodes, statement_arr, only_one_node=false, ret_arr=[]
135
137
  nodes.each do |n|
136
138
  go_next = false
137
139
 
@@ -190,17 +192,19 @@ class Cheftacular
190
192
  end
191
193
  end
192
194
 
193
- def parse_to_dns dns_string
194
- raise "Unable to parse DNS without @option['node_name'] for #{ dns_string }!" if dns_string.include?('NODE_NAME') && @options['node_name'].nil?
195
+ def parse_to_dns dns_string, node_name=''
196
+ raise "Unable to parse DNS without node_name for #{ dns_string }!" if dns_string.include?('NODE_NAME') && node_name.blank?
195
197
  raise "Unable to parse DNS without a tld set in the config bag for #{ @options['env'] }!" if dns_string.include?('ENV_TLD') && @config[@options['env']]['config_bag_hash'][@options['sub_env']]['tld'].nil?
196
198
 
197
- dns_string.gsub('NODE_NAME', @options['node_name']).gsub('ENV_TLD', @config[@options['env']]['config_bag_hash'][@options['sub_env']]['tld'])
199
+ dns_string.gsub('NODE_NAME', node_name).gsub('ENV_TLD', @config[@options['env']]['config_bag_hash'][@options['sub_env']]['tld'])
198
200
  end
199
201
 
200
- def parse_repository_hash_from_string string
202
+ def parse_repository_hash_from_string string, checked_hashes={}
201
203
  @config['getter'].get_repo_names_for_repositories.each do |repository, repository_hash|
202
- return repository_hash if string.include?(repository)
204
+ checked_hashes[repository_hash['role']] = @config['helper'].compare_strings(string, repository)
203
205
  end
206
+
207
+ return @config['cheftacular']['repositories'][ Hash[checked_hashes.sort_by { |key, val| val }].keys.first ]
204
208
  end
205
209
 
206
210
  def parse_location_alias string
@@ -14,5 +14,29 @@ class Cheftacular
14
14
 
15
15
  @config['slack_queue'] = []
16
16
  end
17
+
18
+ def sync_server_hash_into_queue server_hash, server_queue='server_creation_queue', found_result=false
19
+ @config[server_queue].select { |hash| hash['node_name'] == server_hash['node_name']}.each do |queue_hash|
20
+ @config[server_queue][ @config[server_queue].index(queue_hash) ] = queue_hash.merge(server_hash)
21
+
22
+ found_result = true
23
+ end
24
+
25
+ @config[server_queue] << server_hash unless found_result
26
+
27
+ server_hash
28
+ end
29
+
30
+ def generate_passwords_for_each_server_hash_in_queue server_queue='server_creation_queue'
31
+ @config[server_queue].each do |queue_hash|
32
+ @config[server_queue][ @config[server_queue].index(queue_hash) ] = queue_hash.merge(
33
+ { 'deploy_password' => @config['helper'].gen_pass(@config['cheftacular']['server_pass_length']) }
34
+ )
35
+ end
36
+ end
37
+
38
+ def return_hash_from_queue queue_name, hash, hash_key
39
+ @config[queue_name].select { |queue_hash| queue_hash[hash_key] == hash[hash_key] }.first
40
+ end
17
41
  end
18
42
  end
@@ -49,7 +49,7 @@ class Cheftacular
49
49
  old_role, old_env, backup_env = @options['role'], @options['env'], @config['cheftacular']['backup_config']['global_backup_environ']
50
50
 
51
51
  if backup_env != @options['env']
52
- @config['initializer'].initialize_data_bags_for_environment(backup_env, false, ['addresses', 'server_passwords'])
52
+ @config['initializer'].initialize_data_bags_for_environment(backup_env, false, ['addresses', 'server_passwords', 'logs'])
53
53
  @config['initializer'].initialize_passwords backup_env
54
54
  end
55
55
 
@@ -57,7 +57,7 @@ class Cheftacular
57
57
  @options['env'] = backup_env
58
58
 
59
59
  puts "Deploying to backup master to force refresh of the ssh keys..."
60
- #@config['action'].deploy
60
+ @config['action'].deploy
61
61
 
62
62
  @options['role'] = old_role
63
63
  @options['env'] = old_env