cheftacular 2.10.2 → 2.11.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 +119 -77
- data/lib/cheftacular/actions/check.rb +58 -24
- data/lib/cheftacular/actions/deploy.rb +5 -3
- data/lib/cheftacular/auditor.rb +4 -3
- data/lib/cheftacular/cheftacular.rb +1 -0
- data/lib/cheftacular/cloud_provider.rb +17 -12
- data/lib/cheftacular/file_system.rb +20 -0
- data/lib/cheftacular/getter.rb +1 -1
- data/lib/cheftacular/helper.rb +41 -28
- data/lib/cheftacular/initializer.rb +5 -3
- data/lib/cheftacular/parser.rb +10 -6
- data/lib/cheftacular/queue_master.rb +24 -0
- data/lib/cheftacular/stateless_actions/backups.rb +2 -2
- data/lib/cheftacular/stateless_actions/bootstrappers/{centos_bootstrap.rb → centos_bootstrap_from_queue.rb} +1 -1
- data/lib/cheftacular/stateless_actions/bootstrappers/{coreos_bootstrap.rb → coreos_bootstrap_from_queue.rb} +1 -1
- data/lib/cheftacular/stateless_actions/bootstrappers/{fedora_bootstrap.rb → fedora_bootstrap_from_queue.rb} +1 -1
- data/lib/cheftacular/stateless_actions/bootstrappers/{redhat_bootstrap.rb → redhat_bootstrap_from_queue.rb} +1 -1
- data/lib/cheftacular/stateless_actions/bootstrappers/ubuntu_bootstrap_from_queue.rb +203 -0
- data/lib/cheftacular/stateless_actions/bootstrappers/vyatta_bootstrap_from_queue.rb +7 -0
- data/lib/cheftacular/stateless_actions/check_cheftacular_yml_keys.rb +30 -0
- data/lib/cheftacular/stateless_actions/chef_bootstrap_from_queue.rb +89 -0
- data/lib/cheftacular/stateless_actions/cheftacular_yml_help.rb +55 -6
- data/lib/cheftacular/stateless_actions/client_list.rb +1 -3
- data/lib/cheftacular/stateless_actions/cloud_bootstrap.rb +24 -15
- data/lib/cheftacular/stateless_actions/cloud_bootstrap_from_queue.rb +37 -0
- data/lib/cheftacular/stateless_actions/environment.rb +80 -31
- data/lib/cheftacular/stateless_actions/fix_known_hosts.rb +1 -22
- data/lib/cheftacular/stateless_actions/{full_bootstrap.rb → full_bootstrap_from_queue.rb} +8 -15
- data/lib/cheftacular/stateless_actions/knife_upload.rb +14 -3
- data/lib/cheftacular/stateless_actions/reinitialize.rb +1 -1
- data/lib/cheftacular/stateless_actions/remove_client.rb +3 -3
- data/lib/cheftacular/stateless_actions/restart_swap.rb +0 -1
- data/lib/cheftacular/stateless_actions/test_env.rb +24 -18
- data/lib/cheftacular/stateless_actions/update_thecheftacularcookbook.rb +1 -1
- data/lib/cheftacular/stateless_actions/upload_nodes.rb +2 -2
- data/lib/cheftacular/version.rb +1 -1
- data/lib/cloud_interactor/domain/create.rb +2 -2
- data/lib/cloud_interactor/domain/create_record.rb +1 -1
- data/lib/cloud_interactor/domain/destroy.rb +2 -2
- 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/read.rb +1 -1
- data/lib/cloud_interactor/domain/read_record.rb +1 -1
- data/lib/cloud_interactor/domain/update.rb +2 -2
- data/lib/cloud_interactor/domain/update_record.rb +2 -2
- data/lib/cloud_interactor/helpers.rb +11 -6
- data/lib/cloud_interactor/server/attach_volume.rb +1 -1
- data/lib/cloud_interactor/server/create.rb +4 -4
- data/lib/cloud_interactor/server/detach_volume.rb +2 -2
- data/lib/cloud_interactor/server/list_volumes.rb +1 -1
- data/lib/cloud_interactor/server/poll.rb +2 -2
- data/lib/cloud_interactor/server/read_volume.rb +1 -1
- data/lib/cloud_interactor/version.rb +1 -1
- data/lib/cloud_interactor/volume/create.rb +1 -1
- data/lib/sshkit/getters.rb +9 -1
- metadata +25 -10
- data/lib/cheftacular/stateless_actions/bootstrappers/ubuntu_bootstrap.rb +0 -116
- data/lib/cheftacular/stateless_actions/bootstrappers/vyatta_bootstrap.rb +0 -7
- data/lib/cheftacular/stateless_actions/chef_bootstrap.rb +0 -63
@@ -0,0 +1,203 @@
|
|
1
|
+
class Cheftacular
|
2
|
+
class StatelessActionDocumentation
|
3
|
+
def ubuntu_bootstrap_from_queue
|
4
|
+
@config['documentation']['stateless_action'][__method__] ||= {}
|
5
|
+
@config['documentation']['stateless_action'][__method__]['long_description'] = [
|
6
|
+
"`cft ubuntu_bootstrap_from_queue` This command will bring a fresh server to a state " +
|
7
|
+
"where chef-client can be run on it via `cft chef-bootstrap`. It should be noted that it is in "+
|
8
|
+
"this step where a server's randomized deploy_user sudo password is generated."
|
9
|
+
]
|
10
|
+
|
11
|
+
@config['documentation']['stateless_action'][__method__]['short_description'] = '[Not Directly Callable]'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class StatelessAction
|
16
|
+
def ubuntu_bootstrap_from_queue threads=[], execution_hash_array=[]
|
17
|
+
raise "This action is not meant to be called directly!" if !@options['in_scaling'] && !@options['in_single_server_creation']
|
18
|
+
|
19
|
+
if `which sshpass`.empty?
|
20
|
+
raise "sshpass not installed! Please run brew install https://raw.github.com/eugeneoden/homebrew/eca9de1/Library/Formula/sshpass.rb (or get it from your repo for linux)"
|
21
|
+
end
|
22
|
+
|
23
|
+
@config['bootstrap_timestamp'] ||= Time.now.strftime("%Y%m%d%H%M%S")
|
24
|
+
|
25
|
+
@config['queue_master'].generate_passwords_for_each_server_hash_in_queue
|
26
|
+
|
27
|
+
execution_hash_array << compile_root_execute_hash
|
28
|
+
execution_hash_array << compile_deploy_execute_hash
|
29
|
+
execution_hash_array << compile_rvm_execute_hash if @config['cheftacular']['install_rvm_on_boot']
|
30
|
+
execution_hash_array << compile_install_rvm_sh_file_hashes if @config['cheftacular']['install_rvm_on_boot']
|
31
|
+
execution_hash_array = execution_hash_array.flatten(1)
|
32
|
+
|
33
|
+
@config['server_creation_queue'].each do |server_hash|
|
34
|
+
puts("#{ server_name_output(server_hash) }_Starting initial setup for server...") if @options['in_scaling']
|
35
|
+
|
36
|
+
threads << Thread.new { execute_execution_hash_array(server_hash, execution_hash_array) }
|
37
|
+
end
|
38
|
+
|
39
|
+
threads.each { |thread| thread.join }
|
40
|
+
|
41
|
+
@config['server_creation_queue'].each do |server_hash|
|
42
|
+
@config[@options['env']]['server_passwords_bag_hash']["#{ server_hash['address'] }-root-pass"] = server_hash['client_pass']
|
43
|
+
@config[@options['env']]['server_passwords_bag_hash']["#{ server_hash['address'] }-deploy-pass"] = server_hash['deploy_password']
|
44
|
+
@config[@options['env']]['server_passwords_bag_hash']["#{ server_hash['address'] }-name"] = server_hash['node_name']
|
45
|
+
end
|
46
|
+
|
47
|
+
@config['ChefDataBag'].save_server_passwords_bag unless @config['in_server_creation_queue']
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def compile_root_execute_hash
|
53
|
+
deploy_user = @config['cheftacular']['deploy_user']
|
54
|
+
|
55
|
+
root_commands = [
|
56
|
+
"cd /home",
|
57
|
+
"adduser #{ deploy_user } --gecos \",,,,\" --disabled-password",
|
58
|
+
"echo #{ deploy_user }:NEW_DEPLOY_PASS | chpasswd",
|
59
|
+
"adduser #{ deploy_user } www-data",
|
60
|
+
"adduser #{ deploy_user } sudo",
|
61
|
+
"mkdir -p /home/#{ deploy_user }/.ssh",
|
62
|
+
"touch /home/#{ deploy_user }/.ssh/authorized_keys && touch /home/#{ deploy_user }/.ssh/known_hosts",
|
63
|
+
"chown -R #{ deploy_user }:www-data /home/#{ deploy_user }/.ssh",
|
64
|
+
'sed -i "s/StrictModes yes/StrictModes yes\nPasswordAuthentication no\nUseDNS no\nAllowUsers deploy postgres\n/" /etc/ssh/sshd_config'.gsub('deploy', deploy_user),
|
65
|
+
'sed -i "s/PermitRootLogin yes/PermitRootLogin no/" /etc/ssh/sshd_config'
|
66
|
+
]
|
67
|
+
|
68
|
+
@config['default']['authentication_bag_hash']['authorized_keys'].each do |line|
|
69
|
+
root_commands << "echo \"#{ line }\" >> /home/#{ deploy_user }/.ssh/authorized_keys"
|
70
|
+
end
|
71
|
+
|
72
|
+
{
|
73
|
+
run_as: 'ssh',
|
74
|
+
command: root_commands.join(' && ').insert(-1, ' && service ssh restart'),
|
75
|
+
retries: @config['cheftacular']['server_creation_tries'].to_i,
|
76
|
+
use_root_pass: true
|
77
|
+
}
|
78
|
+
end
|
79
|
+
|
80
|
+
def compile_deploy_execute_hash
|
81
|
+
sudo = "echo NEW_DEPLOY_PASS | sudo -S"
|
82
|
+
|
83
|
+
deploy_commands = [
|
84
|
+
"#{ sudo } apt-get update",
|
85
|
+
"#{ sudo } apt-get install curl #{ @config['cheftacular']['pre_install_packages'] } -y",
|
86
|
+
"#{ sudo } apt-get upgrade -y"
|
87
|
+
]
|
88
|
+
|
89
|
+
if @config['cheftacular']['install_rvm_on_boot']
|
90
|
+
deploy_commands << "gpg --keyserver hkp://keys.gnupg.net --recv-keys #{ @config['cheftacular']['rvm_gpg_key'] }"
|
91
|
+
deploy_commands << "curl -L https://get.rvm.io | bash -s stable"
|
92
|
+
end
|
93
|
+
|
94
|
+
{ run_as: 'ssh', command_array: deploy_commands }
|
95
|
+
end
|
96
|
+
|
97
|
+
def compile_rvm_execute_hash
|
98
|
+
rvm_source = "source /home/#{ @config['cheftacular']['deploy_user'] }/.rvm/bin/rvm &&"
|
99
|
+
|
100
|
+
final_commands = [
|
101
|
+
"#{ rvm_source } echo NEW_DEPLOY_PASS | rvmsudo -S rvm requirements",
|
102
|
+
"#{ rvm_source } rvm install #{ @config['cheftacular']['ruby_version'] }",
|
103
|
+
"#{ rvm_source } rvm alias create default #{ @config['cheftacular']['ruby_version'] }",
|
104
|
+
"#{ rvm_source } rvm gemset empty --force"
|
105
|
+
]
|
106
|
+
|
107
|
+
final_commands << "#{ rvm_source } rvm install 1.9.3-p327" if @config['cheftacular']['chef_version'].to_i < 12
|
108
|
+
|
109
|
+
{ run_as: 'ssh', command_array: final_commands }
|
110
|
+
end
|
111
|
+
|
112
|
+
def compile_install_rvm_sh_file_hashes ret_array=[]
|
113
|
+
sudo = "echo NEW_DEPLOY_PASS | sudo -S"
|
114
|
+
|
115
|
+
ssh_commands = [
|
116
|
+
"#{ sudo } mv /home/#{ @config['cheftacular']['deploy_user'] }/rvm.sh /etc/profile.d",
|
117
|
+
"#{ sudo } chmod 755 /etc/profile.d/rvm.sh",
|
118
|
+
"#{ sudo } chown root:root /etc/profile.d/rvm.sh"
|
119
|
+
]
|
120
|
+
|
121
|
+
ret_array << { run_as: 'scp', upload: "#{ @config['locs']['cheftacular-lib-files'] }/rvm.sh", to: "/home/#{ @config['cheftacular']['deploy_user'] }"}
|
122
|
+
ret_array << { run_as: 'ssh', command: ssh_commands.join(' && ') }
|
123
|
+
ret_array
|
124
|
+
end
|
125
|
+
|
126
|
+
def execute_execution_hash_array server_hash, execution_array, output=[], create_logs=true, log_sub_dir='initial-setup'
|
127
|
+
execution_array.each do |execution_hash|
|
128
|
+
ssh_arguments = [server_hash['address']]
|
129
|
+
ssh_arguments << ( execution_hash.has_key?(:use_root_pass) ? 'root' : @config['cheftacular']['deploy_user'] )
|
130
|
+
ssh_arguments << [{ password: server_hash['client_pass'] }] if execution_hash.has_key?(:use_root_pass)
|
131
|
+
begin
|
132
|
+
case execution_hash[:run_as]
|
133
|
+
when 'ssh'
|
134
|
+
if execution_hash.has_key?(:command)
|
135
|
+
Net::SSH.start(*ssh_arguments.flatten) do |ssh|
|
136
|
+
output << ssh.exec!(replace_placeholders_in_command(server_hash, execution_hash[:command]))
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
if execution_hash.has_key?(:command_array)
|
141
|
+
execution_hash[:command_array].each do |command|
|
142
|
+
puts("#{ server_name_output(server_hash) }_Preparing to execute #{ command }")
|
143
|
+
|
144
|
+
Net::SSH.start(*ssh_arguments.flatten) do |ssh|
|
145
|
+
output << ssh.exec!(replace_placeholders_in_command(server_hash, command))
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
when 'scp'
|
150
|
+
if execution_hash.has_key?(:upload) && execution_hash.has_key?(:to)
|
151
|
+
puts("#{ server_name_output(server_hash) }_Preparing to upload #{ execution_hash[:upload] } to #{ execution_hash[:to] }")
|
152
|
+
|
153
|
+
Net::SCP.upload!(server_hash['address'], @config['cheftacular']['deploy_user'], execution_hash[:upload], execution_hash[:to])
|
154
|
+
end
|
155
|
+
when 'raw'
|
156
|
+
if execution_hash.has_key?(:command)
|
157
|
+
output << `#{ replace_placeholders_in_command(server_hash, execution_hash[:command]) }`
|
158
|
+
end
|
159
|
+
|
160
|
+
if execution_hash.has_key?(:command_array)
|
161
|
+
execution_hash[:command_array].each do |command|
|
162
|
+
puts("#{ server_name_output(server_hash) }_Preparing to execute #{ command }")
|
163
|
+
|
164
|
+
output << `#{ replace_placeholders_in_command(server_hash, command) }`
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
rescue Net::SSH::HostKeyMismatch => e
|
169
|
+
puts "#{ server_name_output(server_hash) }_Has a host key mismatch! Rewriting known_hosts file..."
|
170
|
+
|
171
|
+
@config['filesystem'].scrub_from_known_hosts(server_hash['address'])
|
172
|
+
|
173
|
+
sleep 15
|
174
|
+
|
175
|
+
retry
|
176
|
+
rescue StandardError => e
|
177
|
+
puts "#{ server_name_output(server_hash) }_@@@@@@@@@@@ Failing execution hash because of #{ e }!@@@@@@@@@@"
|
178
|
+
puts "#{ e.backtrace.join("\n") }" if @options['verbose']
|
179
|
+
|
180
|
+
if execution_hash.has_key?(:retries)
|
181
|
+
execution_hash[:retries] = execution_hash[:retries] -= 1
|
182
|
+
puts "There are #{ execution_hash[:retries] } tries left to evaluate the command."
|
183
|
+
|
184
|
+
sleep 60
|
185
|
+
|
186
|
+
raise "#{ server_name_output(server_hash) }_@@@@@@@@@@@ Unable to complete setup process!@@@@@@@@@@" if execution_hash[:retries] <= 0
|
187
|
+
retry
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
File.open("#{ @config['locs']['chef-log'] }/server-setup/#{ server_hash['node_name'] }-#{ log_sub_dir }-#{ @config['bootstrap_timestamp'] }.txt", 'a+') { |f| f.write(output.join("\n").scrub_pretty_text) }
|
193
|
+
end
|
194
|
+
|
195
|
+
def server_name_output server_hash
|
196
|
+
"#{ server_hash['node_name'] }".ljust(17,'_') + "#{ server_hash['address'] }".ljust(18,'_')
|
197
|
+
end
|
198
|
+
|
199
|
+
def replace_placeholders_in_command server_hash, command
|
200
|
+
command.gsub('NEW_DEPLOY_PASS', server_hash['deploy_password']).gsub('ADDRESS', server_hash['address']).gsub('CLIENT_PASS', server_hash['client_pass']).gsub('NODE_NAME', server_hash['node_name'])
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
@@ -16,6 +16,36 @@ 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.11.0################################################
|
20
|
+
|
21
|
+
unless @config['cheftacular'].has_key?('server_creation_tries')
|
22
|
+
@config['cheftacular']['server_creation_tries'] = 2
|
23
|
+
end
|
24
|
+
|
25
|
+
unless @config['cheftacular']['backup_config'].has_key?('db_primary_role')
|
26
|
+
puts base_message.gsub('KEY', 'backup_config:db_primary_role').gsub('DEFAULT', 'db_primary')
|
27
|
+
|
28
|
+
@config['cheftacular']['backup_config']['db_primary_role'] = 'db_primary'
|
29
|
+
|
30
|
+
warn_on_missing = true
|
31
|
+
end
|
32
|
+
|
33
|
+
unless @config['cheftacular'].has_key?('git')
|
34
|
+
puts(base_message.gsub('KEY', 'git').split(',').first + ', Please add the git high level key to your cheftacular.yml.')
|
35
|
+
|
36
|
+
@config['cheftacular']['git'] ||= {}
|
37
|
+
|
38
|
+
warn_on_missing = true
|
39
|
+
end
|
40
|
+
|
41
|
+
unless @config['cheftacular']['git'].has_key?('check_remote_for_branch_existence')
|
42
|
+
puts base_message.gsub('KEY', 'git:check_remote_for_branch_existence').gsub('DEFAULT', 'false')
|
43
|
+
|
44
|
+
@config['cheftacular']['git']['check_remote_for_branch_existence'] = false
|
45
|
+
|
46
|
+
warn_on_missing = true
|
47
|
+
end
|
48
|
+
|
19
49
|
#############################2.10.0################################################
|
20
50
|
|
21
51
|
unless @config['cheftacular'].has_key?('self_update_repository')
|
@@ -0,0 +1,89 @@
|
|
1
|
+
|
2
|
+
class Cheftacular
|
3
|
+
class StatelessActionDocumentation
|
4
|
+
def chef_bootstrap_from_queue
|
5
|
+
@config['documentation']['stateless_action'][__method__] ||= {}
|
6
|
+
@config['documentation']['stateless_action'][__method__]['long_description'] = [
|
7
|
+
"`cft chef_bootstrap_from_queue` allows you to register a node in the chef system, " +
|
8
|
+
"remove any lingering data that may be associated with it and update the node's runlist if it has an entry in nodes_dir for its NODE_NAME.",
|
9
|
+
|
10
|
+
[
|
11
|
+
" 1. This command is part of the `cft full_bootstrap` command and cannot be called directly"
|
12
|
+
]
|
13
|
+
]
|
14
|
+
|
15
|
+
@config['documentation']['stateless_action'][__method__]['short_description'] = 'Bootstraps basic chef properties on the target server'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class StatelessAction
|
20
|
+
def chef_bootstrap_from_queue threads=[]
|
21
|
+
raise "This action is not meant to be called directly!" if !@options['in_scaling'] && !@options['in_single_server_creation']
|
22
|
+
|
23
|
+
#@config['stateless_action'].remove_client #just in case
|
24
|
+
|
25
|
+
execution_hash_array = compile_chef_bootstrap_commands
|
26
|
+
|
27
|
+
@config['bootstrap_timestamp'] ||= Time.now.strftime("%Y%m%d%H%M%S")
|
28
|
+
|
29
|
+
@config['server_creation_queue'].each do |server_hash|
|
30
|
+
puts("(#{ server_hash['node_name'] })[#{ server_hash['address'] }] Starting chef-client installation...") unless @options['quiet']
|
31
|
+
|
32
|
+
threads << Thread.new { execute_execution_hash_array(server_hash, execution_hash_array) }
|
33
|
+
end
|
34
|
+
|
35
|
+
threads.each { |thread| thread.join }
|
36
|
+
|
37
|
+
@options['force_yes'] = true # have the upload_nodes grab the new nodes
|
38
|
+
|
39
|
+
@config['stateless_action'].upload_nodes(true)
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def compile_chef_bootstrap_commands final_command=[]
|
45
|
+
sudo = "echo NEW_DEPLOY_PASS | sudo -S"
|
46
|
+
|
47
|
+
if @config['cheftacular']['chef_version'].to_i >= 12
|
48
|
+
commands = [
|
49
|
+
"curl -L https://www.opscode.com/chef/install.sh > ~/chef-install.sh",
|
50
|
+
"#{ sudo } bash /home/#{ @config['cheftacular']['deploy_user'] }/chef-install.sh",
|
51
|
+
"rm ~/chef-install.sh"
|
52
|
+
]
|
53
|
+
|
54
|
+
final_command << { run_as: 'ssh', command_array: commands }
|
55
|
+
end
|
56
|
+
|
57
|
+
final_command << knife_bootstrap_command
|
58
|
+
final_command << export_data_bag_key_file_command
|
59
|
+
final_command << move_data_bag_key_file_command
|
60
|
+
|
61
|
+
final_command
|
62
|
+
end
|
63
|
+
|
64
|
+
def knife_bootstrap_command
|
65
|
+
user = @config['cheftacular']['deploy_user']
|
66
|
+
chef_ver = @config['cheftacular']['chef_version'].to_i >= 12 ? '12.4.0' : '11.16.4'
|
67
|
+
|
68
|
+
{ run_as: 'raw', command: "knife bootstrap ADDRESS -x #{ user } -P NEW_DEPLOY_PASS -N NODE_NAME --sudo --use-sudo-password --bootstrap-version #{ chef_ver }" }
|
69
|
+
end
|
70
|
+
|
71
|
+
def export_data_bag_key_file_command
|
72
|
+
chef_loc, key_file, user, address = set_data_bag_key_variables
|
73
|
+
|
74
|
+
#"scp -oStrictHostKeyChecking=no #{ chef_loc }/#{ key_file } #{ user }@#{ address }:/home/#{ user }"
|
75
|
+
{ run_as: 'scp', upload: "#{ chef_loc }/#{ key_file }", to: "/home/#{ user }" }
|
76
|
+
end
|
77
|
+
|
78
|
+
def move_data_bag_key_file_command
|
79
|
+
chef_loc, key_file, user, address = set_data_bag_key_variables
|
80
|
+
|
81
|
+
#"ssh -t -oStrictHostKeyChecking=no #{ user }@#{ address } \"#{ @config['helper'].sudo(address) } mv -f /home/#{ user }/#{ key_file } /etc/chef\""
|
82
|
+
{ run_as: 'ssh', command: "echo NEW_DEPLOY_PASS | sudo -S mv -f /home/#{ user }/#{ key_file } /etc/chef" }
|
83
|
+
end
|
84
|
+
|
85
|
+
def set_data_bag_key_variables
|
86
|
+
[ @config['locs']['chef'], @config['cheftacular']['data_bag_key_file'], @config['cheftacular']['deploy_user'], 'ADDRESS' ]
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -4,28 +4,77 @@ class Cheftacular
|
|
4
4
|
def cheftacular_yml_help
|
5
5
|
@config['documentation']['stateless_action'][__method__] ||= {}
|
6
6
|
@config['documentation']['stateless_action'][__method__]['long_description'] = [
|
7
|
-
"
|
7
|
+
"`cft cheftacular_yml_help KEY` this command" +
|
8
8
|
"allows you to get help on the meaning of each key in your cheftacular.yml overall config.",
|
9
9
|
|
10
10
|
[
|
11
|
-
" 1. This command can also by run with `cft yaml_help`."
|
11
|
+
" 1. This command can also by run with `cft yaml_help`.",
|
12
|
+
|
13
|
+
" 2. To examine nested keys, you can use colons inbetween the keys like cloud_authentication:rackspace:email"
|
12
14
|
]
|
13
15
|
]
|
14
16
|
|
15
|
-
@config['documentation']['stateless_action'][__method__]['short_description'] = '
|
17
|
+
@config['documentation']['stateless_action'][__method__]['short_description'] = 'Gives help on the keys in your cheftacular.yml'
|
16
18
|
|
17
19
|
@config['documentation']['application'][__method__] = @config['documentation']['stateless_action'][__method__]
|
18
20
|
end
|
21
|
+
|
22
|
+
alias_method :yml_help, :cheftacular_yml_help
|
23
|
+
end
|
24
|
+
|
25
|
+
class InitializationAction
|
26
|
+
def cheftacular_yml_help
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
alias_method :yml_help, :cheftacular_yml_help
|
19
31
|
end
|
20
32
|
|
21
33
|
class StatelessAction
|
22
|
-
def cheftacular_yml_help command=''
|
23
|
-
|
34
|
+
def cheftacular_yml_help command='', key_nesting_array=[]
|
35
|
+
key_to_check = ARGV[1]
|
24
36
|
|
37
|
+
raise "This command requires a key to check the documentation, please enter one as the first argument" if key_to_check.nil?
|
38
|
+
|
39
|
+
key_to_check.split(':').each { |key| key_nesting_array << key }
|
40
|
+
|
41
|
+
doc_hash = YAML::load(ERB.new(IO.read(File.open(File.expand_path("#{ @config['locs']['doc'] }/cheftacular_yml_help.yml")))).result)
|
42
|
+
|
43
|
+
traverse_documentation_hash(doc_hash, key_nesting_array)
|
25
44
|
end
|
26
45
|
|
27
|
-
alias_method :
|
46
|
+
alias_method :yml_help, :cheftacular_yml_help
|
28
47
|
|
29
48
|
private
|
49
|
+
|
50
|
+
def traverse_documentation_hash doc_hash, key_array, index=0
|
51
|
+
if doc_hash.has_key?(key_array[index])
|
52
|
+
if doc_hash[key_array[index]].class == Hash && key_array.length-1 == index
|
53
|
+
if doc_hash[key_array[index]]['key_description'].nil?
|
54
|
+
puts "Missing documentation for key #{ key_array[index] }!"
|
55
|
+
else
|
56
|
+
puts doc_hash[key_array[index]]['key_description']
|
57
|
+
end
|
58
|
+
elsif doc_hash[key_array[index]].class != Hash && key_array.length-1 == index
|
59
|
+
puts doc_hash[key_array[index]]
|
60
|
+
elsif doc_hash[key_array[index]].class == Hash && key_array.length-1 != index
|
61
|
+
traverse_documentation_hash(doc_hash[key_array[index]], key_array, index+1)
|
62
|
+
else
|
63
|
+
puts "You attempted to traverse the documentation with a value that was not a key to a hash (#{ key_array[index] }), the value of this key is:"
|
64
|
+
|
65
|
+
puts doc_hash[key_array[index]]
|
66
|
+
|
67
|
+
puts "If this is not what you were searching for, please verify your config tree with `cft cheftacular_config display`"
|
68
|
+
end
|
69
|
+
elsif doc_hash.has_key?('STAR_MATCHER') && key_array.length-1 != index
|
70
|
+
traverse_documentation_hash(doc_hash['STAR_MATCHER'], key_array, index+1)
|
71
|
+
elsif doc_hash.has_key?('STAR_MATCHER') && key_array.length-1 == index
|
72
|
+
puts doc_hash['STAR_MATCHER']['key_description']
|
73
|
+
else
|
74
|
+
puts "The documentation hash does not have the key #{ key_array[index] }, the keys available here are:"
|
75
|
+
|
76
|
+
ap doc_hash.keys
|
77
|
+
end
|
78
|
+
end
|
30
79
|
end
|
31
80
|
end
|