cheftacular 2.1.2 → 2.2.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.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/lib/cheftacular/README.md +40 -28
  3. data/lib/cheftacular/{actions.rb → action.rb} +0 -0
  4. data/lib/cheftacular/actions/deploy.rb +2 -1
  5. data/lib/cheftacular/actions/migrate.rb +3 -1
  6. data/lib/cheftacular/{decryptors.rb → decryptor.rb} +0 -0
  7. data/lib/cheftacular/dns.rb +283 -0
  8. data/lib/cheftacular/{encryptors.rb → encryptor.rb} +0 -0
  9. data/lib/cheftacular/{getters.rb → getter.rb} +2 -2
  10. data/lib/cheftacular/{helpers.rb → helper.rb} +6 -14
  11. data/lib/cheftacular/{initializers.rb → initializer.rb} +3 -2
  12. data/lib/cheftacular/{parsers.rb → parser.rb} +6 -0
  13. data/lib/cheftacular/stateless_actions/arguments.rb +2 -4
  14. data/lib/cheftacular/stateless_actions/client_list.rb +6 -6
  15. data/lib/cheftacular/stateless_actions/cloud.rb +1 -1
  16. data/lib/cheftacular/stateless_actions/cloud_bootstrap.rb +8 -34
  17. data/lib/cheftacular/stateless_actions/compile_readme.rb +4 -2
  18. data/lib/cheftacular/stateless_actions/get_pg_pass.rb +0 -2
  19. data/lib/cheftacular/stateless_actions/get_shorewall_allowed_connections.rb +65 -0
  20. data/lib/cheftacular/stateless_actions/help.rb +1 -1
  21. data/lib/cheftacular/stateless_actions/initialize_data_bag_contents.rb +6 -0
  22. data/lib/cheftacular/stateless_actions/remove_client.rb +6 -20
  23. data/lib/cheftacular/stateless_actions/replication_status.rb +0 -1
  24. data/lib/cheftacular/stateless_actions/slack.rb +8 -1
  25. data/lib/cheftacular/stateless_actions/update_cloudflare.rb +16 -51
  26. data/lib/cheftacular/stateless_actions/update_tld.rb +22 -19
  27. data/lib/cheftacular/stateless_actions/upload_nodes.rb +3 -1
  28. data/lib/cheftacular/version.rb +1 -1
  29. data/lib/cloud_interactor/domain/create_record.rb +7 -5
  30. data/lib/cloud_interactor/domain/list_records.rb +3 -1
  31. data/lib/cloud_interactor/domain/update_record.rb +4 -2
  32. data/lib/cloudflare/monkeypatches.rb +24 -0
  33. metadata +12 -10
  34. 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']] = { "dn" => serv_hash['dn'], "priv" => serv_hash['address'], "pub" => 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, *args
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
- " a ruby string to run commands against was not found in either your cheftacular.yml file or your .ruby-version file."
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 (staging branch for staging and master for production)',
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(21) }"
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
- addr_data = @config['getter'].get_addresses_hash env
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 addr_data.has_key?(node.public_ipaddress)
59
- out << addr_data[node.public_ipaddress]['priv'].ljust(20,'_')
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 addr_data.has_key?(node.public_ipaddress)
70
- out << addr_data[node.public_ipaddress]['dn'].ljust(40,'_')
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 apis. " +
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['stateless_action'].cloud "domain", "create_record:#{ tld }:#{ @options['node_name'] }:#{ @options['address'] }"
79
-
80
- sleep 5
62
+ target_serv_index = @config[@options['env']]['addresses_bag_hash']['addresses'].count
81
63
 
82
- @config['stateless_action'].cloud "domain", "create_record:#{ tld }:local.#{ @options['node_name'] }:#{ @options['private_address'] }"
64
+ compile_args = ['set_all_attributes']
83
65
 
84
- full_domain = "#{ @options['node_name'] }.#{ tld }" if full_domain.blank?
66
+ compile_args << "set_specific_domain:#{ @options['with_dn'] }" if @options['with_dn']
85
67
 
86
- @config[@options['env']]['addresses_bag_hash'] = @config[@options['env']]['addresses_bag'].reload.to_hash
68
+ address_hash = @config['DNS'].compile_address_hash_for_server_from_options(*compile_args)
87
69
 
88
- target_serv_index = @config[@options['env']]['addresses_bag_hash']['addresses'].count
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[@options['env']]['addresses_bag_hash']['addresses'].each do |serv_hash|
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))' + "\n"
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['action_documentation'].public_methods(false)
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']['action'] << [
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 "CannotRemoveMultipleClients, Please call this script as hip remove_client <node_name>" unless @options['node_name']
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
- if !target_serv_index.nil? && target_serv_index.is_a?(Fixnum) && !@options['dont_remove_address_or_server']
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
- @config[@options['env']]['addresses_bag_hash']['addresses'][target_serv_index] = nil
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
@@ -47,7 +47,6 @@ class Cheftacular
47
47
  rep_status_hash[n.name] = start_slave_replication_report( n.name, n.public_ipaddress, options, locs, passwords)
48
48
  end
49
49
 
50
-
51
50
  rep_status_hash.each_pair do |serv_name, output|
52
51
  out << "#{ serv_name }:"
53
52
 
@@ -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 = '#default' unless ARGV[2]
22
+ notifier.channel = ARGV[2] ? ARGV[2] : '#default'
16
23
  notifier.ping ARGV[1]
17
24
  end
18
25
  end