cheftacular 2.5.0 → 2.6.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/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']
|