cheftacular 2.10.2 → 2.11.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 +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
|