cheftacular 2.1.2 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
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