cheftacular 2.1.2 → 2.2.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 +40 -28
- data/lib/cheftacular/{actions.rb → action.rb} +0 -0
- data/lib/cheftacular/actions/deploy.rb +2 -1
- data/lib/cheftacular/actions/migrate.rb +3 -1
- data/lib/cheftacular/{decryptors.rb → decryptor.rb} +0 -0
- data/lib/cheftacular/dns.rb +283 -0
- data/lib/cheftacular/{encryptors.rb → encryptor.rb} +0 -0
- data/lib/cheftacular/{getters.rb → getter.rb} +2 -2
- data/lib/cheftacular/{helpers.rb → helper.rb} +6 -14
- data/lib/cheftacular/{initializers.rb → initializer.rb} +3 -2
- data/lib/cheftacular/{parsers.rb → parser.rb} +6 -0
- data/lib/cheftacular/stateless_actions/arguments.rb +2 -4
- data/lib/cheftacular/stateless_actions/client_list.rb +6 -6
- data/lib/cheftacular/stateless_actions/cloud.rb +1 -1
- data/lib/cheftacular/stateless_actions/cloud_bootstrap.rb +8 -34
- data/lib/cheftacular/stateless_actions/compile_readme.rb +4 -2
- data/lib/cheftacular/stateless_actions/get_pg_pass.rb +0 -2
- data/lib/cheftacular/stateless_actions/get_shorewall_allowed_connections.rb +65 -0
- data/lib/cheftacular/stateless_actions/help.rb +1 -1
- data/lib/cheftacular/stateless_actions/initialize_data_bag_contents.rb +6 -0
- data/lib/cheftacular/stateless_actions/remove_client.rb +6 -20
- data/lib/cheftacular/stateless_actions/replication_status.rb +0 -1
- data/lib/cheftacular/stateless_actions/slack.rb +8 -1
- data/lib/cheftacular/stateless_actions/update_cloudflare.rb +16 -51
- data/lib/cheftacular/stateless_actions/update_tld.rb +22 -19
- data/lib/cheftacular/stateless_actions/upload_nodes.rb +3 -1
- data/lib/cheftacular/version.rb +1 -1
- data/lib/cloud_interactor/domain/create_record.rb +7 -5
- data/lib/cloud_interactor/domain/list_records.rb +3 -1
- data/lib/cloud_interactor/domain/update_record.rb +4 -2
- data/lib/cloudflare/monkeypatches.rb +24 -0
- metadata +12 -10
- data/lib/cheftacular/remote_helpers.rb +0 -30
File without changes
|
@@ -111,9 +111,9 @@ class Cheftacular
|
|
111
111
|
ret
|
112
112
|
end
|
113
113
|
|
114
|
-
def get_addresses_hash env='staging', ret_hash={}
|
114
|
+
def get_addresses_hash env='staging', ret_hash={}, mode=""
|
115
115
|
@config[env]['addresses_bag_hash']['addresses'].each do |serv_hash|
|
116
|
-
ret_hash[serv_hash['public']] =
|
116
|
+
ret_hash[serv_hash['public']] = serv_hash
|
117
117
|
|
118
118
|
end if @config[env].has_key?('addresses_bag_hash')
|
119
119
|
|
@@ -10,14 +10,6 @@ class Cheftacular
|
|
10
10
|
Cheftacular.to_s.underscore.dasherize
|
11
11
|
end
|
12
12
|
|
13
|
-
#[TODO] Refactor to more accurate solution
|
14
|
-
def running_in_gem?
|
15
|
-
File.expand_path('.', __FILE__).split('/').include?('.rvm') ||
|
16
|
-
(File.exist?(File.expand_path("#{ Dir.getwd }/.ruby-gemset")) &&
|
17
|
-
File.read(File.expand_path("#{ Dir.getwd }/.ruby-gemset")) != 'hiplogiq-deploy')
|
18
|
-
end
|
19
|
-
|
20
|
-
#TODO add command check
|
21
13
|
def is_command? command
|
22
14
|
@config['action'].public_methods(false).include?(command.to_sym)
|
23
15
|
end
|
@@ -30,7 +22,6 @@ class Cheftacular
|
|
30
22
|
!@config['action'].public_methods(false).include?(command.to_sym) && !@config['stateless_action'].public_methods(false).include?(command.to_sym)
|
31
23
|
end
|
32
24
|
|
33
|
-
#[TODO] Refactor to running_on_chef_node?
|
34
25
|
def running_on_chef_node?
|
35
26
|
Dir.entries('/etc').include?('chef')
|
36
27
|
rescue StandardError => e
|
@@ -275,7 +266,7 @@ class Cheftacular
|
|
275
266
|
end
|
276
267
|
end
|
277
268
|
|
278
|
-
def does_cheftacular_config_have? key_array
|
269
|
+
def does_cheftacular_config_have? key_array
|
279
270
|
cheftacular = @config['cheftacular']
|
280
271
|
key_array = [key_array] if key_array.is_a?(String)
|
281
272
|
key_checks = []
|
@@ -289,16 +280,16 @@ class Cheftacular
|
|
289
280
|
|
290
281
|
def recursive_hash_check keys, hash
|
291
282
|
if hash.has_key?(keys[0])
|
292
|
-
case hash[keys[0]].class
|
293
|
-
when Hash
|
283
|
+
case hash[keys[0]].class.to_s
|
284
|
+
when 'Hash'
|
294
285
|
if !hash[keys[0]].empty?
|
295
286
|
recursive_hash_check keys[1..keys.count-1], hash[keys[0]]
|
296
287
|
else
|
297
288
|
return true
|
298
289
|
end
|
299
|
-
when String
|
290
|
+
when 'String'
|
300
291
|
return !hash[keys[0]].blank?
|
301
|
-
when Array
|
292
|
+
when 'Array'
|
302
293
|
return !hash[keys[0]].empty?
|
303
294
|
end
|
304
295
|
else
|
@@ -306,6 +297,7 @@ class Cheftacular
|
|
306
297
|
end
|
307
298
|
end
|
308
299
|
|
300
|
+
#this must be in helpers because parser class is not yet loaded at the time this method is needed.
|
309
301
|
def parse_node_name_from_client_file ret=""
|
310
302
|
config = File.read(File.expand_path("#{ @config['locs']['chef'] }/client.rb"))
|
311
303
|
|
@@ -356,8 +356,8 @@ class Cheftacular
|
|
356
356
|
rescue StandardError => e
|
357
357
|
msg = [
|
358
358
|
"Please run this in the root of your application directory,",
|
359
|
-
"
|
360
|
-
]
|
359
|
+
"a ruby string to run commands against was not found in either your cheftacular.yml file or your .ruby-version file."
|
360
|
+
].join(' ')
|
361
361
|
|
362
362
|
@config['helper'].exception_output msg, e
|
363
363
|
end
|
@@ -424,6 +424,7 @@ class Cheftacular
|
|
424
424
|
@config['action_documentation'] = Cheftacular::ActionDocumentation.new(@options, @config)
|
425
425
|
@config['stateless_action_documentation'] = Cheftacular::StatelessActionDocumentation.new(@options, @config)
|
426
426
|
@config['dummy_sshkit'] = SSHKit::Backend::Netssh.new(SSHKit::Host.new('127.0.0.1'))
|
427
|
+
@config['DNS'] = Cheftacular::DNS.new(@options, @config)
|
427
428
|
end
|
428
429
|
|
429
430
|
def initialize_directories
|
@@ -195,5 +195,11 @@ class Cheftacular
|
|
195
195
|
|
196
196
|
dns_string.gsub('NODE_NAME', @options['node_name']).gsub('ENV_TLD', @config[@options['env']]['config_bag_hash']['tld'])
|
197
197
|
end
|
198
|
+
|
199
|
+
def parse_repository_hash_from_string string
|
200
|
+
@config['getter'].get_repo_names_for_repositories.each do |repository, repository_hash|
|
201
|
+
return repository_hash if string.include?(repository)
|
202
|
+
end
|
203
|
+
end
|
198
204
|
end
|
199
205
|
end
|
@@ -46,13 +46,11 @@ class Cheftacular
|
|
46
46
|
|
47
47
|
'1. `-e|--except-role ROLE_NAME` will *prevent* any server with this role from being *deployed to* for the deploy command. Other commands will ignore this argument.',
|
48
48
|
|
49
|
-
'2. `-z|--unset-revision` will unset a custom revision specified in the arg below and make the codebase utilize the default
|
49
|
+
'2. `-z|--unset-revision` will unset a custom revision specified in the arg below and make the codebase utilize the default.',
|
50
50
|
|
51
51
|
"3. `-Z|--revision REVISION` will force the role you're deploying to to utilize the revision specified here. This can be a specific commit or a branch name.",
|
52
52
|
|
53
|
-
' 1. Note: The system does not check if the revision exists, if you pass a non-existent revision no one will be able to deploy to that role until -Z with a correction revision or -z is passed.'
|
54
|
-
|
55
|
-
' 2. *You will not be able to set a custom revision for beta environments.* The beta environments are tied to split-staging and splita/b/c/d respectively.',
|
53
|
+
' 1. Note: The system does not check if the revision exists, if you pass a non-existent revision no one will be able to deploy to that role until -Z with a correction revision or -z is passed.'
|
56
54
|
]
|
57
55
|
end
|
58
56
|
end
|
@@ -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(20) }"
|
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']
|
@@ -48,15 +48,15 @@ class Cheftacular
|
|
48
48
|
|
49
49
|
auth_hash = @config[env]['server_passwords_bag_hash']
|
50
50
|
|
51
|
-
|
51
|
+
addresses_hash = @config['getter'].get_addresses_hash env
|
52
52
|
|
53
53
|
env_nodes.each do |node|
|
54
54
|
#client = @ridley.client.find(options['node_name'])
|
55
55
|
out = " #{ node.chef_id.ljust(22,'_') }_#{ node.public_ipaddress.ljust(20,'_') }"
|
56
56
|
|
57
57
|
if @options['with_private']
|
58
|
-
if
|
59
|
-
out <<
|
58
|
+
if addresses_hash.has_key?(node.public_ipaddress)
|
59
|
+
out << addresses_hash[node.public_ipaddress]['address'].ljust(20,'_')
|
60
60
|
else
|
61
61
|
out << ''.ljust(20,'_')
|
62
62
|
end
|
@@ -66,8 +66,8 @@ class Cheftacular
|
|
66
66
|
|
67
67
|
out << "_" + auth_hash.has_key?("#{ node.public_ipaddress }-deploy-pass").to_s.ljust(5,'_') + "_"
|
68
68
|
|
69
|
-
if
|
70
|
-
out <<
|
69
|
+
if addresses_hash.has_key?(node.public_ipaddress)
|
70
|
+
out << addresses_hash[node.public_ipaddress]['dn'].ljust(40,'_')
|
71
71
|
else
|
72
72
|
out << ''.ljust(40,'_')
|
73
73
|
end
|
@@ -3,7 +3,7 @@ class Cheftacular
|
|
3
3
|
class StatelessActionDocumentation
|
4
4
|
def cloud
|
5
5
|
@config['documentation']['stateless_action'] << [
|
6
|
-
"`cft cloud <FIRST_LEVEL_ARG> [<SECOND_LEVEL_ARG>[:<SECOND_LEVEL_ARG_QUERY>]*] ` this command handles talking to various cloud
|
6
|
+
"`cft cloud <FIRST_LEVEL_ARG> [<SECOND_LEVEL_ARG>[:<SECOND_LEVEL_ARG_QUERY>]*] ` this command handles talking to various cloud APIs. " +
|
7
7
|
"If no args are passed nothing will happen.",
|
8
8
|
|
9
9
|
[
|
@@ -31,7 +31,6 @@ class Cheftacular
|
|
31
31
|
@options['node_name'] = ARGV[1] unless @options['node_name']
|
32
32
|
@options['flavor_name'] = ARGV[2] unless @options['flavor_name']
|
33
33
|
@options['descriptor'] = ARGV[3] if ARGV[3] && !@options['descriptor']
|
34
|
-
full_domain = ""
|
35
34
|
|
36
35
|
if `which sshpass`.empty?
|
37
36
|
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)"
|
@@ -58,47 +57,22 @@ class Cheftacular
|
|
58
57
|
return false
|
59
58
|
end
|
60
59
|
|
61
|
-
if @options['with_dn']
|
62
|
-
domain_obj = PublicSuffix.parse @options['with_dn']
|
63
|
-
|
64
|
-
@config['stateless_action'].cloud "domain", "create_record:#{ domain_obj.domain }:#{ domain_obj.trd }:#{ @options['address'] }"
|
65
|
-
|
66
|
-
sleep 5
|
67
|
-
|
68
|
-
@config['stateless_action'].cloud "domain", "create_record:#{ domain_obj.domain }:local.#{ domain_obj.trd }:#{ @options['private_address'] }"
|
69
|
-
|
70
|
-
full_domain = @options['with_dn']
|
71
|
-
|
72
|
-
#set the wildcard domain for frontend load balancers
|
73
|
-
@config['stateless_action'].cloud "domain", "create_record:#{ domain_obj.domain }:*:#{ @options['address'] }" if ( @options['node_name'] =~ /mysc.*lb/ ) == 0
|
74
|
-
end
|
75
|
-
|
76
60
|
tld = @config[@options['env']]['config_bag_hash'][@options['sub_env']]['tld']
|
77
61
|
|
78
|
-
@config['
|
79
|
-
|
80
|
-
sleep 5
|
62
|
+
target_serv_index = @config[@options['env']]['addresses_bag_hash']['addresses'].count
|
81
63
|
|
82
|
-
|
64
|
+
compile_args = ['set_all_attributes']
|
83
65
|
|
84
|
-
|
66
|
+
compile_args << "set_specific_domain:#{ @options['with_dn'] }" if @options['with_dn']
|
85
67
|
|
86
|
-
|
68
|
+
address_hash = @config['DNS'].compile_address_hash_for_server_from_options(*compile_args)
|
87
69
|
|
88
|
-
|
70
|
+
@config['DNS'].create_dns_record_for_domain_from_address_hash(@options['with_dn'], address_hash, "specific_domain_mode") if @options['with_dn']
|
89
71
|
|
90
|
-
@config[
|
91
|
-
target_serv_index = @config[@options['env']]['addresses_bag_hash']['addresses'].index(serv_hash) if serv_hash['name'] == @options['node_name']
|
92
|
-
end
|
93
|
-
|
94
|
-
#EX: "name": "api1", "public": "1.2.3.4", "address": "10.208.1.2", "dn":"api1.example.com", "descriptor": "lb:my-backend-codebase"
|
95
|
-
@config[@options['env']]['addresses_bag_hash']['addresses'][target_serv_index] ||= {}
|
96
|
-
@config[@options['env']]['addresses_bag_hash']['addresses'][target_serv_index]['name'] = @options['node_name']
|
97
|
-
@config[@options['env']]['addresses_bag_hash']['addresses'][target_serv_index]['public'] = @options['address']
|
98
|
-
@config[@options['env']]['addresses_bag_hash']['addresses'][target_serv_index]['address'] = @options['private_address']
|
99
|
-
@config[@options['env']]['addresses_bag_hash']['addresses'][target_serv_index]['dn'] = full_domain
|
100
|
-
@config[@options['env']]['addresses_bag_hash']['addresses'][target_serv_index]['descriptor'] = @options['descriptor'].nil? ? @options['node_name'] : @options['descriptor']
|
72
|
+
@config['DNS'].create_dns_record_for_domain_from_address_hash(tld, address_hash)
|
101
73
|
|
74
|
+
@config[@options['env']]['addresses_bag_hash'] = @config[@options['env']]['addresses_bag'].reload.to_hash
|
75
|
+
|
102
76
|
@config['ChefDataBag'].save_addresses_bag
|
103
77
|
|
104
78
|
@options['dont_remove_address_or_server'] = true #flag to make sure our entry isnt removed in addresses bag
|
@@ -19,11 +19,11 @@ class Cheftacular
|
|
19
19
|
|
20
20
|
out << '# Table of Contents for Cheftacular Commands'
|
21
21
|
|
22
|
-
out << '1. [Cheftacular Arguments and Flags](https://github.com/SocialCentivPublic/cheftacular/blob/master/lib/cheftacular/README.md#arguments-and-flags-for-cheftacular)
|
22
|
+
out << '1. [Cheftacular Arguments and Flags](https://github.com/SocialCentivPublic/cheftacular/blob/master/lib/cheftacular/README.md#arguments-and-flags-for-cheftacular)'
|
23
23
|
|
24
24
|
out << '2. [Application Commands](https://github.com/SocialCentivPublic/cheftacular/blob/master/lib/cheftacular/README.md#commands-that-can-be-run-in-the-application-context)'
|
25
25
|
|
26
|
-
out << '3. [DevOps Commands](https://github.com/SocialCentivPublic/cheftacular/blob/master/lib/cheftacular/README.md#commands-that-can-only-be-run-in-the-devops-context)
|
26
|
+
out << '3. [DevOps Commands](https://github.com/SocialCentivPublic/cheftacular/blob/master/lib/cheftacular/README.md#commands-that-can-only-be-run-in-the-devops-context)' + "\n"
|
27
27
|
|
28
28
|
out << @config['documentation']['arguments']
|
29
29
|
|
@@ -35,6 +35,8 @@ class Cheftacular
|
|
35
35
|
|
36
36
|
out << @config['helper'].compile_documentation_lines('stateless_action')
|
37
37
|
|
38
|
+
FileUtils.rm("#{ @config['locs']['chef-log'] }/README.md") if File.exist?("#{ @config['locs']['chef-log'] }/README.md")
|
39
|
+
|
38
40
|
File.open("#{ @config['locs']['chef-log'] }/README.md", "w") { |f| f.write(out.flatten.join("\n\n")) }
|
39
41
|
end
|
40
42
|
end
|
@@ -31,8 +31,6 @@ class Cheftacular
|
|
31
31
|
database = repo_hash.has_key?('custom_database_name') ? repo_hash['custom_database_name'] : repo_hash['repo_name']
|
32
32
|
password = @config[@options['env']]['chef_passwords_bag_hash']['pg_pass']
|
33
33
|
|
34
|
-
ap @config[@options['env']]['chef_passwords_bag_hash']
|
35
|
-
|
36
34
|
if @config[@options['env']]['chef_passwords_bag_hash'].has_key?(repo_hash['repo_name']) && @config[@options['env']]['chef_passwords_bag_hash'][repo_hash['repo_name']].has_key?('pg_pass')
|
37
35
|
password = @config[@options['env']]['chef_passwords_bag_hash'][repo_hash['repo_name']]['pg_pass'] unless @config[@options['env']]['chef_passwords_bag_hash'][repo_hash['repo_name']]['pg_pass'].empty?
|
38
36
|
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
class Cheftacular
|
2
|
+
class StatelessActionDocumentation
|
3
|
+
def get_shorewall_allowed_connections
|
4
|
+
@config['documentation']['stateless_action'] << [
|
5
|
+
"`cft get_shorewall_allowed_connections` command will query a single server and return all of its ACCEPT connections " +
|
6
|
+
"from shorewall in it's syslog and return the results in a CSV format. Useful for tracking IP activity.",
|
7
|
+
|
8
|
+
[
|
9
|
+
" 1. This command will attempt to `dig` each ip address to give you the most likely culprit."
|
10
|
+
]
|
11
|
+
]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class StatelessAction
|
16
|
+
def get_shorewall_allowed_connections
|
17
|
+
#TODO find and load syslog files from nodes!
|
18
|
+
log_data << File.read(File.expand_path("#{ @locs['chef-log'] }/marketing_site_syslog_2.txt"))
|
19
|
+
log_data << File.read(File.expand_path("#{ @locs['chef-log'] }/marketing_site_syslog_1.txt"))
|
20
|
+
log_data << File.read(File.expand_path("#{ @locs['chef-log'] }/marketing_site_syslog.txt"))
|
21
|
+
|
22
|
+
exit
|
23
|
+
|
24
|
+
addresses = {}
|
25
|
+
|
26
|
+
log_data.join("\n").scan(/^.*Shorewall:net2fw:ACCEPT.*SRC=([\d]+\.[\d]+\.[\d]+\.[\d]+) DST.*DPT=80.*$/).each do |ip_address|
|
27
|
+
addresses[ip_address] ||= 0
|
28
|
+
addresses[ip_address] += 1
|
29
|
+
end
|
30
|
+
|
31
|
+
final_addresses = {}
|
32
|
+
check_count = 0
|
33
|
+
addresses.each_pair do |address, count|
|
34
|
+
domain = `dig +short -x #{ address[0] }`.chomp.split("\n").join('|')
|
35
|
+
domain = domain[0..(domain.length-2)]
|
36
|
+
|
37
|
+
domain = address[0] if domain.blank?
|
38
|
+
|
39
|
+
final_addresses[domain] ||= {}
|
40
|
+
final_addresses[domain]['addresses'] ||= []
|
41
|
+
final_addresses[domain]['addresses'] << address[0] unless final_addresses[domain]['addresses'].include?(address[0])
|
42
|
+
final_addresses[domain]['count'] = count unless final_addresses[domain].has_key?('count')
|
43
|
+
final_addresses[domain]['count'] += count if final_addresses[domain].has_key?('count')
|
44
|
+
|
45
|
+
check_count += 1
|
46
|
+
|
47
|
+
puts "Processed #{ check_count } addresses (#{ address[0] }):#{ domain }:#{ count }"
|
48
|
+
end
|
49
|
+
|
50
|
+
final_addresses = final_addresses.sort_by {|key, value_hash| value_hash['count']}.to_h
|
51
|
+
|
52
|
+
final_addresses = Hash[final_addresses.to_a.reverse]
|
53
|
+
|
54
|
+
ap(final_addresses)
|
55
|
+
|
56
|
+
log_loc, timestamp = @config['helper'].set_log_loc_and_timestamp
|
57
|
+
|
58
|
+
CSV.open(File.expand_path("#{ @locs['chef-log'] }/#{ @options['node_name'] }-shorewall-parse-#{ timestamp }.csv"), "wb") do |csv|
|
59
|
+
final_addresses.each_pair do |dns, info_hash|
|
60
|
+
csv << [dns, info_hash['addresses'].join('|'), info_hash['count']]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -56,7 +56,7 @@ class Cheftacular
|
|
56
56
|
puts @config['helper'].compile_documentation_lines('devops').flatten.join("\n\n") if target_command == 'devops'
|
57
57
|
|
58
58
|
if inference_modes.empty? && @config['helper'].is_not_command_or_stateless_command?(target_command)
|
59
|
-
methods = @config['action_documentation'].public_methods(false) + @config['
|
59
|
+
methods = @config['action_documentation'].public_methods(false) + @config['stateless_action_documentation'].public_methods(false)
|
60
60
|
|
61
61
|
sorted_methods = methods.uniq.sort_by { |method| @config['helper'].compare_strings(target_command, method.to_s)}
|
62
62
|
|
@@ -196,6 +196,12 @@ class Cheftacular
|
|
196
196
|
|
197
197
|
save_on_finish = true
|
198
198
|
end
|
199
|
+
|
200
|
+
unless hash[env].has_key?('cloudflare_activated_domains')
|
201
|
+
hash[env]['cloudflare_activated_domains'] = []
|
202
|
+
|
203
|
+
save_on_finish = true
|
204
|
+
end
|
199
205
|
end
|
200
206
|
|
201
207
|
@config['ChefDataBag'].save_config_bag(main_env) if save_on_finish
|
@@ -2,7 +2,7 @@
|
|
2
2
|
class Cheftacular
|
3
3
|
class StatelessActionDocumentation
|
4
4
|
def remove_client
|
5
|
-
@config['documentation']['
|
5
|
+
@config['documentation']['stateless_action'] << [
|
6
6
|
"`cft remove_client -n NODE_NAME` removes a client (and its node data) from the chef-server. " +
|
7
7
|
"It also removes its dns records from the cloud service (if possible). " +
|
8
8
|
"This should not be done lightly as you will have to wipe the server and trigger another chef-client run to get it to register again"
|
@@ -16,9 +16,11 @@ class Cheftacular
|
|
16
16
|
@options['delete_server_on_remove'] = ARGV[2] if !@options['delete_server_on_remove'] && !@options['dont_remove_address_or_server'] && ARGV[2]
|
17
17
|
@options['delete_server_on_remove'] = 'destroy' if delete_server || @options['delete_server_on_remove']
|
18
18
|
|
19
|
+
raise "This action can only be performed if the mode is set to devops" if !@config['helper'].running_in_mode?('devops') && !@options['in_scaling']
|
20
|
+
|
19
21
|
raise "The only valid argument for the 2nd argument of this command is 'destroy', please enter this or leave it blank." if ARGV[2] && ARGV[2] != 'destroy' && !@options['dont_remove_address_or_server']
|
20
22
|
|
21
|
-
raise "
|
23
|
+
raise "Invalid arguments! Node name is blank. Please call this script as cft remove_client <node_name>" unless @options['node_name']
|
22
24
|
|
23
25
|
nodes = @config['getter'].get_true_node_objects(false, true)
|
24
26
|
|
@@ -47,27 +49,11 @@ class Cheftacular
|
|
47
49
|
if @options['delete_server_on_remove'] == 'destroy'
|
48
50
|
@config['stateless_action'].cloud "server", "destroy:#{ @options['env'] }_#{ n.name }"
|
49
51
|
end
|
50
|
-
end
|
51
|
-
|
52
|
-
@config[@options['env']]['addresses_bag_hash'] = @config[@options['env']]['addresses_bag'].reload.to_hash
|
53
|
-
|
54
|
-
target_serv_index = nil
|
55
|
-
|
56
|
-
@config[@options['env']]['addresses_bag_hash']['addresses'].each do |serv_hash|
|
57
|
-
target_serv_index = @config[@options['env']]['addresses_bag_hash']['addresses'].index(serv_hash) if serv_hash['name'] == @options['node_name']
|
58
52
|
end
|
59
53
|
|
60
|
-
|
61
|
-
puts("Found entry in addresses data bag corresponding to #{ @options['node_name'] } for #{ @options['env'] }, removing...") unless @options['quiet']
|
62
|
-
|
63
|
-
domain_obj = PublicSuffix.parse @config[@options['env']]['addresses_bag_hash']['addresses'][target_serv_index]['dn']
|
64
|
-
|
65
|
-
#delete the domain on rax if its a domain we host there for its environment
|
66
|
-
@config['stateless_action'].cloud "domain", "destroy_record:#{ domain_obj.tld }:#{ domain_obj.trd }" if domain_obj.tld == @config[@options['env']]['config_bag_hash'][@options['sub_env']]['tld']
|
54
|
+
@config[@options['env']]['addresses_bag_hash'] = @config[@options['env']]['addresses_bag'].reload.to_hash
|
67
55
|
|
68
|
-
|
69
|
-
@config[@options['env']]['addresses_bag_hash']['addresses'] = @config[@options['env']]['addresses_bag_hash']['addresses'].compact
|
70
|
-
end
|
56
|
+
@config['DNS'].compile_address_hash_for_server_from_options('set_hash_to_nil')
|
71
57
|
|
72
58
|
@config['ChefDataBag'].save_addresses_bag
|
73
59
|
end
|
@@ -4,6 +4,13 @@ class Cheftacular
|
|
4
4
|
@config['documentation']['stateless_action'] << [
|
5
5
|
"`cft slack \"MESSAGE\" [CHANNEL]` will attempt to post the message to the webhook set in your cheftacular.yml. " +
|
6
6
|
"Slack posts to your default channel by default but if the CHANNEL argument is supplied the message will post there.",
|
7
|
+
|
8
|
+
[
|
9
|
+
" 1. NOTE: To prevent confusing spam from many possible sources, the username posted to slack will always be " +
|
10
|
+
"*Cheftacular*. This can be overloaded in the StatelessAction method \"slack\" but this is not recommended.",
|
11
|
+
|
12
|
+
" 2. Remember, if you have auditing turned on in your cheftacular.yml, you can track who sends what to slack."
|
13
|
+
]
|
7
14
|
]
|
8
15
|
end
|
9
16
|
end
|
@@ -12,7 +19,7 @@ class Cheftacular
|
|
12
19
|
def slack
|
13
20
|
notifier = Slack::Notifier.new @config['cheftacular']['slack_webhook'], username: 'Cheftacular'
|
14
21
|
|
15
|
-
notifier.channel =
|
22
|
+
notifier.channel = ARGV[2] ? ARGV[2] : '#default'
|
16
23
|
notifier.ping ARGV[1]
|
17
24
|
end
|
18
25
|
end
|