cheftacular 2.5.0 → 2.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/cheftacular/README.md +155 -63
- data/lib/cheftacular/actions/db_console.rb +3 -3
- data/lib/cheftacular/actions/deploy.rb +18 -12
- data/lib/cheftacular/actions/migrate.rb +1 -1
- data/lib/cheftacular/actions/tail.rb +1 -1
- data/lib/cheftacular/auditor.rb +14 -6
- data/lib/cheftacular/chef/data_bag.rb +1 -4
- data/lib/cheftacular/cheftacular.rb +19 -15
- data/lib/cheftacular/cloud_provider.rb +32 -0
- data/lib/cheftacular/dns.rb +1 -1
- data/lib/cheftacular/error.rb +13 -2
- data/lib/cheftacular/file_system.rb +122 -0
- data/lib/cheftacular/files/rvm.sh +55 -0
- data/lib/cheftacular/getter.rb +10 -3
- data/lib/cheftacular/helper.rb +31 -127
- data/lib/cheftacular/initialization_action.rb +8 -0
- data/lib/cheftacular/initializer.rb +104 -44
- data/lib/cheftacular/parser.rb +6 -0
- data/lib/cheftacular/stateless_actions/add_ssh_key_to_bag.rb +2 -2
- data/lib/cheftacular/stateless_actions/arguments.rb +9 -2
- data/lib/cheftacular/stateless_actions/backups.rb +1 -1
- data/lib/cheftacular/stateless_actions/bootstrappers/ubuntu_bootstrap.rb +16 -5
- data/lib/cheftacular/stateless_actions/check_cheftacular_yml_keys.rb +79 -0
- data/lib/cheftacular/stateless_actions/chef_bootstrap.rb +20 -4
- data/lib/cheftacular/stateless_actions/chef_server.rb +78 -0
- data/lib/cheftacular/stateless_actions/clean_cookbooks.rb +3 -3
- data/lib/cheftacular/stateless_actions/clean_server_passwords.rb +3 -1
- data/lib/cheftacular/stateless_actions/cleanup_log_files.rb +1 -0
- data/lib/cheftacular/stateless_actions/client_list.rb +2 -2
- data/lib/cheftacular/stateless_actions/cloud.rb +30 -2
- data/lib/cheftacular/stateless_actions/cloud_bootstrap.rb +7 -13
- data/lib/cheftacular/stateless_actions/compile_audit_log.rb +1 -1
- data/lib/cheftacular/stateless_actions/create_git_key.rb +3 -1
- data/lib/cheftacular/stateless_actions/environment.rb +2 -0
- data/lib/cheftacular/stateless_actions/file.rb +4 -2
- data/lib/cheftacular/stateless_actions/fix_known_hosts.rb +2 -1
- data/lib/cheftacular/stateless_actions/full_bootstrap.rb +2 -0
- data/lib/cheftacular/stateless_actions/get_active_ssh_connections.rb +1 -1
- data/lib/cheftacular/stateless_actions/help.rb +9 -7
- data/lib/cheftacular/stateless_actions/initialize_cheftacular_yml.rb +29 -0
- data/lib/cheftacular/stateless_actions/initialize_data_bag_contents.rb +5 -36
- data/lib/cheftacular/stateless_actions/list_toggleable_roles.rb +45 -0
- data/lib/cheftacular/stateless_actions/location_aliases.rb +24 -0
- data/lib/cheftacular/stateless_actions/pass.rb +4 -4
- data/lib/cheftacular/stateless_actions/reinitialize.rb +0 -6
- data/lib/cheftacular/stateless_actions/remove_client.rb +12 -7
- data/lib/cheftacular/stateless_actions/role_toggle.rb +141 -0
- data/lib/cheftacular/stateless_actions/server_update.rb +2 -2
- data/lib/cheftacular/stateless_actions/update_chef_client.rb +18 -0
- data/lib/cheftacular/stateless_actions/upload_nodes.rb +5 -3
- data/lib/cheftacular/stateless_actions/upload_roles.rb +1 -1
- data/lib/cheftacular/version.rb +1 -1
- data/lib/cloud_interactor/authentication.rb +78 -40
- data/lib/cloud_interactor/cloud_interactor.rb +4 -1
- data/lib/cloud_interactor/cloud_provider.rb +19 -0
- data/lib/cloud_interactor/domain/create.rb +1 -1
- data/lib/cloud_interactor/domain/create_record.rb +1 -1
- data/lib/cloud_interactor/domain/destroy_record.rb +1 -1
- data/lib/cloud_interactor/domain/list_records.rb +1 -1
- data/lib/cloud_interactor/domain/update.rb +1 -1
- data/lib/cloud_interactor/domain/update_record.rb +6 -6
- data/lib/cloud_interactor/helpers.rb +1 -1
- data/lib/cloud_interactor/parser.rb +3 -2
- data/lib/cloud_interactor/region.rb +27 -0
- data/lib/cloud_interactor/server/create.rb +9 -0
- data/lib/cloud_interactor/sshkey.rb +59 -0
- data/lib/ridley/monkeypatches.rb +12 -0
- data/lib/sshkit/actions/start_task.rb +8 -2
- metadata +16 -2
@@ -20,39 +20,44 @@ class Cheftacular
|
|
20
20
|
|
21
21
|
initialize_documentation_hash
|
22
22
|
|
23
|
-
|
23
|
+
initialize_ruby_config
|
24
24
|
|
25
|
-
initialize_ridley
|
25
|
+
initialize_ridley unless @config['helper'].is_initialization_command?(ARGV[0])
|
26
26
|
|
27
|
-
|
27
|
+
initialize_classes
|
28
28
|
|
29
|
-
|
29
|
+
initialize_directories
|
30
30
|
|
31
|
-
|
31
|
+
initialize_cloud_checks
|
32
32
|
|
33
|
-
|
33
|
+
unless @config['helper'].is_initialization_command?(ARGV[0])
|
34
34
|
|
35
|
-
|
35
|
+
@config['helper'].completion_rate? 0, 'initializer'
|
36
36
|
|
37
|
-
|
37
|
+
@config['helper'].completion_rate? 10, 'initializer'
|
38
38
|
|
39
|
-
|
39
|
+
initialize_ridley_environments
|
40
40
|
|
41
|
-
|
41
|
+
@config['helper'].completion_rate? 20, 'initializer'
|
42
42
|
|
43
|
-
|
43
|
+
initialize_ridley_roles_and_nodes
|
44
44
|
|
45
|
-
|
45
|
+
@config['helper'].completion_rate? 30, 'initializer'
|
46
46
|
|
47
|
-
|
47
|
+
initialize_data_bags_for_environment @options['env'], true
|
48
|
+
|
49
|
+
@config['helper'].completion_rate? 90, 'initializer'
|
50
|
+
|
51
|
+
initialize_passwords @options['env']
|
48
52
|
|
49
|
-
|
53
|
+
@config['helper'].completion_rate? 100, 'initializer'
|
50
54
|
|
51
|
-
|
55
|
+
initialize_version_check if @config['cheftacular']['strict_version_checks']
|
52
56
|
|
53
|
-
|
57
|
+
initialize_auditing_checks if @config['cheftacular']['auditing']
|
54
58
|
|
55
|
-
|
59
|
+
initialize_chef_repo_up_to_date if @config['cheftacular']['keep_chef_repo_cheftacular_yml_up_to_date']
|
60
|
+
end
|
56
61
|
end
|
57
62
|
|
58
63
|
#changes to arguments should show up in the documentation methods in their appropriate method file
|
@@ -198,6 +203,10 @@ class Cheftacular
|
|
198
203
|
@options['preferred_cloud'] = 'aws'
|
199
204
|
end
|
200
205
|
|
206
|
+
opts.on('--do', "On cft cloud calls, set the cloud to DigitalOcean") do
|
207
|
+
@options['preferred_cloud'] = 'digitalocean'
|
208
|
+
end
|
209
|
+
|
201
210
|
opts.on('--region REGION', 'On cft cloud calls, set the cloud region to perform operations on to this region') do |region|
|
202
211
|
@options['preferred_cloud_region'] = region
|
203
212
|
end
|
@@ -210,8 +219,12 @@ class Cheftacular
|
|
210
219
|
@options['virtualization_mode'] = v_mode
|
211
220
|
end
|
212
221
|
|
213
|
-
|
214
|
-
|
222
|
+
opts.on('--route-dns-changes-via SERVICE', 'On cft cloud calls, set the default dns provider to this service') do |service|
|
223
|
+
@options['route_dns_changes_via'] = service
|
224
|
+
end
|
225
|
+
|
226
|
+
#file | chef_server
|
227
|
+
opts.on('--save-to-file FILE_NAME', 'On cft file or chef_server, this option can be used to save the output of the file display methods to your system. Also works in the fetch context') do |path|
|
215
228
|
@options['save_to_file'] = path
|
216
229
|
end
|
217
230
|
|
@@ -266,18 +279,21 @@ class Cheftacular
|
|
266
279
|
locs['ssh'] = File.expand_path('/home/deploy/.ssh')
|
267
280
|
end
|
268
281
|
|
269
|
-
locs['chef-repo']
|
270
|
-
locs['roles']
|
271
|
-
locs['nodes']
|
272
|
-
locs['root']
|
273
|
-
locs['app-root']
|
274
|
-
locs['chef']
|
275
|
-
locs['cookbooks']
|
276
|
-
locs['berks']
|
277
|
-
locs['wrapper-cookbooks']
|
278
|
-
locs['ssh']
|
279
|
-
locs['chef-log']
|
280
|
-
locs['app-tmp']
|
282
|
+
locs['chef-repo'] = Dir.getwd
|
283
|
+
locs['roles'] = File.expand_path("#{ locs['chef-repo'] }/roles")
|
284
|
+
locs['nodes'] = File.expand_path("#{ locs['chef-repo'] }/nodes_dir") #DO NOT RENAME THIS TO NODES
|
285
|
+
locs['root'] = locs['chef-repo'] unless locs['root']
|
286
|
+
locs['app-root'] = locs['chef-repo'] unless locs['app-root']
|
287
|
+
locs['chef'] = File.expand_path("~/.chef") unless locs['chef']
|
288
|
+
locs['cookbooks'] = File.expand_path("#{ locs['chef-repo'] }/cookbooks")
|
289
|
+
locs['berks'] = File.expand_path('~/.berkshelf/cookbooks')
|
290
|
+
locs['wrapper-cookbooks'] = @config['cheftacular']['wrapper_cookbooks']
|
291
|
+
locs['ssh'] = File.expand_path('~/.ssh')
|
292
|
+
locs['chef-log'] = File.expand_path("#{ locs['root']}/log") unless locs['chef-log']
|
293
|
+
locs['app-tmp'] = File.expand_path("#{ locs['app-root']}/tmp")
|
294
|
+
locs['examples'] = File.expand_path("../../../examples", __FILE__)
|
295
|
+
locs['cheftacular-lib'] = File.expand_path("../..", __FILE__)
|
296
|
+
locs['cheftacular-lib-files'] = locs['cheftacular-lib'] + '/cheftacular/files'
|
281
297
|
|
282
298
|
@config['locs'] = locs
|
283
299
|
end
|
@@ -354,7 +370,7 @@ class Cheftacular
|
|
354
370
|
"a ruby string to run commands against was not found in either your cheftacular.yml file or your .ruby-version file."
|
355
371
|
].join(' ')
|
356
372
|
|
357
|
-
@config['
|
373
|
+
@config['error'].exception_output msg, e
|
358
374
|
end
|
359
375
|
|
360
376
|
@config['ruby_string'] = "ruby-" + @config['ruby_string'] unless @config['ruby_string'].include?('ruby-')
|
@@ -383,7 +399,7 @@ class Cheftacular
|
|
383
399
|
def initialize_version_check detected_version=""
|
384
400
|
current_version = Cheftacular::VERSION
|
385
401
|
|
386
|
-
detected_version = File.exists?( @config['
|
402
|
+
detected_version = File.exists?( @config['filesystem'].current_version_file_path ) ? File.read( @config['filesystem'].current_version_file_path ) : @config['helper'].fetch_remote_version
|
387
403
|
|
388
404
|
if @config['helper'].is_higher_version? detected_version, current_version
|
389
405
|
puts "\n Your Cheftacular is out of date. Currently #{ current_version } and remote version is #{ detected_version }.\n"
|
@@ -392,16 +408,16 @@ class Cheftacular
|
|
392
408
|
|
393
409
|
exit
|
394
410
|
else
|
395
|
-
unless File.exists?( @config['
|
411
|
+
unless File.exists?( @config['filesystem'].current_version_file_path )
|
396
412
|
puts "Creating file cache for #{ Time.now.strftime("%Y%m%d") } (#{ detected_version }). No new version detected."
|
397
413
|
|
398
|
-
@config['
|
414
|
+
@config['filesystem'].write_version_file detected_version
|
399
415
|
end
|
400
416
|
end
|
401
417
|
end
|
402
418
|
|
403
419
|
def initialize_auditing_checks
|
404
|
-
unless File.exists? @config['
|
420
|
+
unless File.exists? @config['filesystem'].current_audit_file_path
|
405
421
|
puts "Creating file cache for #{ Time.now.strftime("%Y%m%d") } audit data..."
|
406
422
|
|
407
423
|
@config['auditor'].write_audit_cache_file
|
@@ -421,6 +437,7 @@ class Cheftacular
|
|
421
437
|
@config['error'] = Cheftacular::Error.new(@options, @config)
|
422
438
|
@config['dummy_sshkit'] = SSHKit::Backend::Netssh.new(SSHKit::Host.new('127.0.0.1'))
|
423
439
|
@config['DNS'] = Cheftacular::DNS.new(@options, @config)
|
440
|
+
@config['cloud_provider'] = Cheftacular::CloudProvider.new(@options, @config)
|
424
441
|
end
|
425
442
|
|
426
443
|
def initialize_directories
|
@@ -430,16 +447,59 @@ class Cheftacular
|
|
430
447
|
|
431
448
|
FileUtils.mkdir_p File.join( @config['locs']['app-tmp'], @config['helper'].declassify)
|
432
449
|
|
433
|
-
FileUtils.mkdir_p @config['
|
450
|
+
FileUtils.mkdir_p @config['filesystem'].current_nodes_file_cache_path
|
451
|
+
|
452
|
+
@config['filesystem'].cleanup_file_caches
|
453
|
+
end
|
454
|
+
|
455
|
+
def initialize_cloud_checks exit_on_finish = false
|
456
|
+
hash = @config['cheftacular']['cloud_authentication']
|
457
|
+
|
458
|
+
unless hash.has_key?(@options['preferred_cloud'])
|
459
|
+
puts "Critical! No Cloud credentials detected for your preferred cloud #{ @options['preferred_cloud'] }, " +
|
460
|
+
"Please update the cheftacular.yml cloud_authentication:#{ @options['preferred_cloud'] } key!"
|
461
|
+
|
462
|
+
exit_on_finish = true
|
463
|
+
end
|
464
|
+
|
465
|
+
if hash.has_key?('rackspace')
|
466
|
+
if !( hash['rackspace'].has_key?('username') || hash['rackspace'].has_key?('api_key') || hash['rackspace'].has_key?('email'))
|
467
|
+
|
468
|
+
puts "Critical! No cloud credentials detected for the rackspace cloud_authentication hash! There must be both a valid username and an api_key in this hash!"
|
469
|
+
puts "Please update the cheftacular.yml cloud_authentication:rackspace key!"
|
470
|
+
|
471
|
+
exit_on_finish = true
|
472
|
+
elsif hash['rackspace']['username'].empty? || hash['rackspace']['api_key'].empty? || hash['rackspace']['email'].empty?
|
473
|
+
puts "Critical! Cloud credentials detected for the rackspace cloud_authentication hash are blank!"
|
474
|
+
puts "Please update the cheftacular.yml cloud_authentication:rackspace key!"
|
475
|
+
|
476
|
+
exit_on_finish = true
|
477
|
+
end
|
478
|
+
end
|
479
|
+
|
480
|
+
if hash.has_key?('digitalocean')
|
481
|
+
if !( hash['digitalocean'].has_key?('client_id') || hash['digitalocean'].has_key?('api_key'))
|
482
|
+
|
483
|
+
puts "Critical! No cloud credentials detected for the digitalocean cloud_authentication hash! There must be both a valid client_id and an api_key in this hash!"
|
484
|
+
puts "Please update the cheftacular.yml cloud_authentication:digitalocean key!"
|
485
|
+
|
486
|
+
exit_on_finish = true
|
487
|
+
elsif hash['digitalocean']['client_id'].empty? || hash['digitalocean']['api_key'].empty?
|
488
|
+
puts "Critical! Cloud credentials detected for the digitalocean cloud_authentication hash are blank!"
|
489
|
+
puts "Please update the cheftacular.yml cloud_authentication:digitalocean key!"
|
490
|
+
|
491
|
+
exit_on_finish = true
|
492
|
+
end
|
493
|
+
end
|
434
494
|
|
435
|
-
|
495
|
+
exit if exit_on_finish
|
436
496
|
end
|
437
497
|
|
438
498
|
def initialize_chef_repo_up_to_date
|
439
499
|
if @config['helper'].running_in_mode?('devops')
|
440
500
|
@config['cheftacular']['wrapper_cookbooks'].split(',').each do |wrapper_cookbook|
|
441
|
-
parsed_hash = if File.exists?( @config['
|
442
|
-
File.read( @config['
|
501
|
+
parsed_hash = if File.exists?( @config['filesystem'].current_chef_repo_cheftacular_file_cache_path )
|
502
|
+
File.read( @config['filesystem'].current_chef_repo_cheftacular_file_cache_path )
|
443
503
|
else
|
444
504
|
Digest::SHA2.hexdigest(@config['helper'].compile_chef_repo_cheftacular_yml_as_hash.to_yaml.to_s)
|
445
505
|
end
|
@@ -450,20 +510,20 @@ class Cheftacular
|
|
450
510
|
unless File.exist?(wrapper_cookbook_cheftacular_loc)
|
451
511
|
puts "Wrapper cookbook \"#{ wrapper_cookbook }\" does not have a cheftacular.yml file in #{ @config['cheftacular']['location_of_chef_repo_cheftacular_yml'] }! Creating..."
|
452
512
|
|
453
|
-
@config['
|
513
|
+
@config['filesystem'].write_chef_repo_cheftacular_yml_file wrapper_cookbook_cheftacular_loc
|
454
514
|
end
|
455
515
|
|
456
516
|
if parsed_hash == Digest::SHA2.hexdigest(File.read(wrapper_cookbook_cheftacular_loc))
|
457
|
-
next if File.exists?( @config['
|
517
|
+
next if File.exists?( @config['filesystem'].current_chef_repo_cheftacular_file_cache_path )
|
458
518
|
else
|
459
519
|
puts "Wrapper cookbook (#{ wrapper_cookbook }) does not have a current cheftacular.yml file in #{ @config['cheftacular']['location_of_chef_repo_cheftacular_yml'] }\"! Overwriting..."
|
460
520
|
|
461
|
-
@config['
|
521
|
+
@config['filesystem'].write_chef_repo_cheftacular_yml_file wrapper_cookbook_cheftacular_loc
|
462
522
|
end
|
463
523
|
|
464
524
|
puts "Creating file cache for #{ Time.now.strftime("%Y%m%d") }'s cheftacular.yml."
|
465
525
|
|
466
|
-
@config['
|
526
|
+
@config['filesystem'].write_chef_repo_cheftacular_cache_file parsed_hash
|
467
527
|
end
|
468
528
|
end
|
469
529
|
end
|
data/lib/cheftacular/parser.rb
CHANGED
@@ -226,5 +226,11 @@ class Cheftacular
|
|
226
226
|
else mode
|
227
227
|
end
|
228
228
|
end
|
229
|
+
|
230
|
+
def parse_base_chef_server_url
|
231
|
+
domain = PublicSuffix.parse @config['cheftacular']['chef_server_url'].gsub('https://','').split('/').first
|
232
|
+
|
233
|
+
"#{ domain.trd }.#{ domain.domain }"
|
234
|
+
end
|
229
235
|
end
|
230
236
|
end
|
@@ -33,9 +33,9 @@ class Cheftacular
|
|
33
33
|
public_ssh_key = ARGV[1]
|
34
34
|
|
35
35
|
if specific_repository.blank?
|
36
|
-
@config['default']['authentication_bag_hash']["authorized_keys"] << public_ssh_key
|
36
|
+
@config['default']['authentication_bag_hash']["authorized_keys"] << public_ssh_key.gsub("'",'')
|
37
37
|
else
|
38
|
-
@config['default']['authentication_bag_hash']["specific_authorized_keys"] << public_ssh_key
|
38
|
+
@config['default']['authentication_bag_hash']["specific_authorized_keys"] << public_ssh_key.gsub("'",'')
|
39
39
|
end
|
40
40
|
|
41
41
|
@config['ChefDataBag'].save_authentication_bag
|
@@ -55,10 +55,17 @@ class Cheftacular
|
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
|
+
class InitializationAction
|
59
|
+
def arguments
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
58
64
|
class StatelessAction
|
59
65
|
def arguments
|
60
|
-
|
61
|
-
|
66
|
+
@config['stateless_action_documentation'].arguments
|
67
|
+
|
68
|
+
puts @config['documentation']['arguments']
|
62
69
|
end
|
63
70
|
end
|
64
71
|
end
|
@@ -45,7 +45,7 @@ class Cheftacular
|
|
45
45
|
|
46
46
|
deploy_commands = [
|
47
47
|
"#{ sudo } apt-get update",
|
48
|
-
"#{ sudo } apt-get install curl
|
48
|
+
"#{ sudo } apt-get install curl #{ @config['cheftacular']['pre_install_packages'] } -y",
|
49
49
|
"#{ sudo } apt-get upgrade -y"
|
50
50
|
]
|
51
51
|
|
@@ -55,18 +55,29 @@ class Cheftacular
|
|
55
55
|
deploy_commands << "gpg --keyserver hkp://keys.gnupg.net --recv-keys #{ @config['cheftacular']['rvm_gpg_key'] }"
|
56
56
|
deploy_commands << "curl -L https://get.rvm.io | bash -s stable"
|
57
57
|
|
58
|
-
final_commands
|
59
|
-
|
60
58
|
rvm_source = "source /home/deploy/.rvm/bin/rvm &&"
|
61
59
|
|
62
60
|
final_commands = [
|
63
61
|
"#{ rvm_source } echo '#{ new_deploy_pass }' | rvmsudo -S rvm requirements",
|
64
62
|
"#{ rvm_source } rvm install #{ @config['cheftacular']['ruby_version'] }",
|
65
|
-
"#{ rvm_source } rvm
|
63
|
+
"#{ rvm_source } rvm alias create default #{ @config['cheftacular']['ruby_version'] }",
|
64
|
+
"#{ rvm_source } rvm gemset empty --force"
|
66
65
|
]
|
66
|
+
|
67
|
+
final_commands << "#{ rvm_source } rvm install 1.9.3-p327" if @config['cheftacular']['chef_version'].to_i < 12
|
68
|
+
end
|
69
|
+
|
70
|
+
root_execute_string = "sshpass -p \"#{ @options['client_pass'] }\" ssh -t -oStrictHostKeyChecking=no root@#{ @options['address'] } '#{ root_commands.join(' && ') } && service ssh restart'"
|
71
|
+
|
72
|
+
while system(root_execute_string) != true
|
73
|
+
tries ||= 5
|
74
|
+
puts "Unable to complete step 1 of setup process, trying again in 60 seconds, there are #{ tries } more tries"
|
75
|
+
sleep 60
|
76
|
+
tries -= 1
|
77
|
+
raise "Unable to complete step 1 of setup process!" if tries <= 0
|
67
78
|
end
|
68
79
|
|
69
|
-
out <<
|
80
|
+
out << $?.to_s #output from the system command above
|
70
81
|
|
71
82
|
puts("Finished initial setup...stage 1 of 3 for server #{ @options['address'] }") if @options['in_scaling']
|
72
83
|
|
@@ -0,0 +1,79 @@
|
|
1
|
+
|
2
|
+
class Cheftacular
|
3
|
+
class StatelessActionDocumentation
|
4
|
+
def check_cheftacular_yml_keys
|
5
|
+
@config['documentation']['stateless_action'] << [
|
6
|
+
"`cft check_cheftacular_yml_keys` allows you to check to see if your cheftacular yml keys are valid to the current version of cheftacular. " +
|
7
|
+
"It will also set your missing keys to their likely default and let you know to update the cheftacular.yml file."
|
8
|
+
]
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class StatelessAction
|
13
|
+
def check_cheftacular_yml_keys out=[], exit_on_missing=false, warn_on_missing=false
|
14
|
+
base_message = "Your cheftacular.yml is missing the key KEY, its default value is being set to DEFAULT for this run."
|
15
|
+
|
16
|
+
#############################2.6.0################################################
|
17
|
+
unless @config['cheftacular'].has_key?('route_dns_changes_via')
|
18
|
+
puts base_message.gsub('KEY', 'route_dns_changes_via').gsub('DEFAULT', @options['preferred_cloud'])
|
19
|
+
|
20
|
+
@config['cheftacular']['route_dns_changes_via'] = @options['preferred_cloud']
|
21
|
+
|
22
|
+
warn_on_missing = true
|
23
|
+
end
|
24
|
+
|
25
|
+
unless @config['cheftacular'].has_key?('node_name_separator')
|
26
|
+
puts base_message.gsub('KEY', 'node_name_separator').gsub('DEFAULT', '-')
|
27
|
+
|
28
|
+
@config['cheftacular']['node_name_separator'] = '-'
|
29
|
+
|
30
|
+
warn_on_missing = true
|
31
|
+
end
|
32
|
+
|
33
|
+
unless @config['cheftacular'].has_key?('cloud_authentication')
|
34
|
+
puts (base_message.gsub('KEY', 'cloud_authentication').split(',').first + ', this is a critical issue and must be fixed.')
|
35
|
+
|
36
|
+
exit_on_missing = true
|
37
|
+
end
|
38
|
+
|
39
|
+
if !@config['cheftacular'].has_key?('chef_server') && @options['command'] == 'chef_server'
|
40
|
+
puts (base_message.gsub('KEY', 'chef_server').split(',').first + ', this is a critical issue and must be fixed to run the chef_server command.')
|
41
|
+
|
42
|
+
exit_on_missing = true
|
43
|
+
end
|
44
|
+
|
45
|
+
unless @config['cheftacular'].has_key?('chef_version')
|
46
|
+
puts (base_message.gsub('KEY', 'chef_version').split(',').first + ', this is a critical issue and must be fixed.')
|
47
|
+
|
48
|
+
exit_on_missing = true
|
49
|
+
end
|
50
|
+
|
51
|
+
unless @config['cheftacular'].has_key?('pre_install_packages')
|
52
|
+
puts base_message.gsub('KEY', 'pre_install_packages').gsub('DEFAULT', '')
|
53
|
+
|
54
|
+
@config['cheftacular']['pre_install_packages'] = ''
|
55
|
+
|
56
|
+
warn_on_missing = true
|
57
|
+
end
|
58
|
+
|
59
|
+
unless @config['cheftacular'].has_key?('role_toggling')
|
60
|
+
puts base_message.gsub('KEY', 'role_toggling').gsub('DEFAULT', "it's default nested keys")
|
61
|
+
|
62
|
+
@config['cheftacular']['role_toggling'] = {}
|
63
|
+
@config['cheftacular']['role_toggling']['deactivated_role_suffix'] = '_deactivated'
|
64
|
+
@config['cheftacular']['role_toggling']['strict_roles'] = true
|
65
|
+
@config['cheftacular']['role_toggling']['skip_confirm'] = false
|
66
|
+
@config['cheftacular']['role_toggling']['do_not_allow_toggling'] = true
|
67
|
+
|
68
|
+
warn_on_missing = true
|
69
|
+
end
|
70
|
+
|
71
|
+
if warn_on_missing || exit_on_missing
|
72
|
+
puts "Please enter your missing keys into your cheftacular.yml based off of the cheftacular.yml at"
|
73
|
+
puts "\n https://github.com/SocialCentivPublic/cheftacular/blob/master/examples/cheftacular.yml"
|
74
|
+
end
|
75
|
+
|
76
|
+
exit if exit_on_missing || @options['command'] == __method__
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -13,12 +13,28 @@ class Cheftacular
|
|
13
13
|
def chef_bootstrap out=[]
|
14
14
|
raise "This action can only be performed if the mode is set to devops" if !@config['helper'].running_in_mode?('devops') && !@options['in_scaling']
|
15
15
|
|
16
|
-
@options['address']
|
16
|
+
@options['address'] = ARGV[1] unless @options['address']
|
17
17
|
@options['node_name'] = ARGV[2] unless @options['node_name']
|
18
18
|
|
19
|
-
|
19
|
+
#@config['stateless_action'].remove_client #just in case
|
20
20
|
|
21
|
-
|
21
|
+
if @config['cheftacular']['chef_version'].to_i >= 12
|
22
|
+
puts("Starting chef-client installation...") unless @options['quiet']
|
23
|
+
|
24
|
+
commands = [
|
25
|
+
"curl -L https://www.opscode.com/chef/install.sh > ~/chef-install.sh",
|
26
|
+
"#{ @config['helper'].sudo(@options['address']) } bash /home/deploy/chef-install.sh",
|
27
|
+
"rm ~/chef-install.sh"
|
28
|
+
]
|
29
|
+
|
30
|
+
commands.each do |command|
|
31
|
+
out << `ssh -t -oStrictHostKeyChecking=no #{ @config['cheftacular']['deploy_user'] }@#{ @options['address'] } "#{ command }"`
|
32
|
+
|
33
|
+
puts(out.last) unless @options['quiet'] || @options['in_scaling']
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
puts("Starting chef bootstrap...") unless @options['quiet']
|
22
38
|
|
23
39
|
out << `#{ @config['helper'].knife_bootstrap_command }`
|
24
40
|
|
@@ -34,7 +50,7 @@ class Cheftacular
|
|
34
50
|
|
35
51
|
@options['force_yes'] = true # have the upload_nodes grab the new nodes
|
36
52
|
|
37
|
-
@config['stateless_action'].upload_nodes
|
53
|
+
@config['stateless_action'].upload_nodes(true)
|
38
54
|
end
|
39
55
|
end
|
40
56
|
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
class Cheftacular
|
2
|
+
class StatelessActionDocumentation
|
3
|
+
def chef_server
|
4
|
+
@config['documentation']['stateless_action'] << [
|
5
|
+
"`cft chef_server [restart|processes|memory]` this command can be used to query the chef server for stats if the cheftacular.yml " +
|
6
|
+
"has the chef_server key filled out. Useful for low resource chef-servers.",
|
7
|
+
|
8
|
+
[
|
9
|
+
" 1. `restart` restarts all chef processes on the chef server which may alleviate slow cheftacular load times for some users. (NOTE) " +
|
10
|
+
"do not run this command while the chef-server is performing actions or instability may result! Not tested for high volume chef servers.",
|
11
|
+
|
12
|
+
" 2. `processes` runs `ps aux` on the server to return the running processes and their stats.",
|
13
|
+
|
14
|
+
" 3. `memory` runs `free -m` on the server to return the current memory usage.",
|
15
|
+
|
16
|
+
" 4. NOTE! This command (and all arguments to it) bypass the normal environment loading like the help command.",
|
17
|
+
|
18
|
+
" 5. NOTE 2! Cheftacular does not (and will not) support accessing your chef server over ssh with password auth. If you have done this, " +
|
19
|
+
"you should feel bad and immediately switch ssh access to key authentication..."
|
20
|
+
]
|
21
|
+
]
|
22
|
+
|
23
|
+
@config['documentation']['application'] << @config['documentation']['stateless_action'].last
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class InitializationAction
|
28
|
+
def chef_server
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class StatelessAction
|
34
|
+
def chef_server
|
35
|
+
raise "This action can only be performed if the mode is set to devops" unless @config['helper'].running_in_mode?('devops')
|
36
|
+
|
37
|
+
if @config['cheftacular']['chef_server'].nil? || !@config['cheftacular']['chef_server']['interactable']
|
38
|
+
raise "Chef server is not currently set to be interactable with the chef-server command"
|
39
|
+
end
|
40
|
+
|
41
|
+
command = ARGV[1]
|
42
|
+
|
43
|
+
raise "Unsupported command (#{ command }) for cft chef_server" unless command =~ /restart|processes|memory/
|
44
|
+
|
45
|
+
command_prefix = case @config['cheftacular']['chef_server']['ssh_user']
|
46
|
+
when 'root' then ''
|
47
|
+
else "echo #{ @config['cheftacular']['chef_server']['sudo_pass'] } | sudo -S "
|
48
|
+
end
|
49
|
+
|
50
|
+
command = case command
|
51
|
+
when 'restart' then command_prefix + 'chef-server-ctl restart'
|
52
|
+
when 'processes' then 'ps aux'
|
53
|
+
when 'memory' then 'free -m'
|
54
|
+
end
|
55
|
+
|
56
|
+
options = @options
|
57
|
+
|
58
|
+
on ( @config['cheftacular']['chef_server']['ssh_user'] + "@" + @config['parser'].parse_base_chef_server_url ) do |host|
|
59
|
+
|
60
|
+
puts "Beginning chef-server #{ command } run"
|
61
|
+
|
62
|
+
start_chef_server_interactor(command, options)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
module SSHKit
|
69
|
+
module Backend
|
70
|
+
class Netssh
|
71
|
+
def start_chef_server_interactor command, options, out=""
|
72
|
+
puts capture( command )
|
73
|
+
|
74
|
+
puts "Succeeded chef-server interaction run" unless options['quiet']
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -38,7 +38,7 @@ class Cheftacular
|
|
38
38
|
berkshelf_cookbooks = {}
|
39
39
|
|
40
40
|
Dir.foreach(@config['locs']['berks']) do |berkshelf_cookbook|
|
41
|
-
next if @config['
|
41
|
+
next if @config['filesystem'].is_junk_filename?(berkshelf_cookbook)
|
42
42
|
skip = false
|
43
43
|
|
44
44
|
berkshelf_cookbooks.keys.each do |processed_berkshelf_cookbook|
|
@@ -62,7 +62,7 @@ class Cheftacular
|
|
62
62
|
chef_repo_cookbooks = {}
|
63
63
|
|
64
64
|
Dir.foreach(@config['locs']['cookbooks']) do |chef_repo_cookbook|
|
65
|
-
next if @config['
|
65
|
+
next if @config['filesystem'].is_junk_filename?(chef_repo_cookbook)
|
66
66
|
|
67
67
|
new_name = chef_repo_cookbook.rpartition('-').first
|
68
68
|
|
@@ -101,4 +101,4 @@ class Cheftacular
|
|
101
101
|
end
|
102
102
|
end
|
103
103
|
end
|
104
|
-
end
|
104
|
+
end
|
@@ -2,13 +2,15 @@
|
|
2
2
|
class Cheftacular
|
3
3
|
class StatelessActionDocumentation
|
4
4
|
def clean_server_passwords
|
5
|
-
|
5
|
+
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
9
9
|
class StatelessAction
|
10
10
|
def clean_server_passwords
|
11
11
|
#TODO clean up non-existent entries in all envs server_password bags
|
12
|
+
raise "This method is not yet implemented"
|
13
|
+
raise "This action can only be performed if the mode is set to devops" unless @config['helper'].running_in_mode?('devops')
|
12
14
|
end
|
13
15
|
end
|
14
16
|
end
|
@@ -23,7 +23,7 @@ class Cheftacular
|
|
23
23
|
|
24
24
|
class StatelessAction
|
25
25
|
def client_list
|
26
|
-
@config['
|
26
|
+
@config['filesystem'].cleanup_file_caches('current')
|
27
27
|
|
28
28
|
nodes = @config['getter'].get_true_node_objects(true)
|
29
29
|
|
@@ -38,7 +38,7 @@ class Cheftacular
|
|
38
38
|
|
39
39
|
env_nodes = @config['parser'].exclude_nodes(nodes, [{ if: { not_env: env } }])
|
40
40
|
puts "\nFound #{ env_nodes.count } #{ env } nodes:"
|
41
|
-
out = " #{ 'name'.ljust(22) } #{ 'ip_address'.ljust(
|
41
|
+
out = " #{ 'name'.ljust(22) } #{ 'ip_address'.ljust(21) }"
|
42
42
|
out << "#{ 'private_address'.ljust(21) }" if @options['with_private']
|
43
43
|
out << "#{ 'pass?'.ljust(5) } #{ 'domain'.ljust(41) }" if @options['verbose']
|
44
44
|
out << "#{ 'deploy_password'.ljust(21) }" if @options['verbose']
|