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
@@ -1,67 +1,32 @@
|
|
1
1
|
class Cheftacular
|
2
2
|
class StatelessActionDocumentation
|
3
|
-
def
|
3
|
+
def update_cloudflare_dns_from_cloud
|
4
4
|
@config['documentation']['stateless_action'] << [
|
5
|
-
"`cft
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
"`cft update_cloudflare_dns_from_cloud` command will force a full dns update for cloudflare. ",
|
6
|
+
|
7
|
+
[
|
8
|
+
" 1. It will ensure all the subdomain entries are correct (based on the contents of the addresses data bag) " +
|
9
|
+
"and update them if they are not. It will also create the local subdomain for the entry as well if it " +
|
10
|
+
"does exist and point it to the correct private address for an environment.",
|
11
|
+
|
12
|
+
" 2. This command will also ensure any dns records on your cloud are also migrated over to cloudflare as well. " +
|
13
|
+
"This also includes the reverse in the event you would like to turn off cloudflare."
|
14
|
+
]
|
9
15
|
]
|
10
16
|
end
|
11
17
|
end
|
12
18
|
|
13
19
|
class StatelessAction
|
14
|
-
def
|
20
|
+
def update_cloudflare_dns_from_cloud
|
15
21
|
raise "This action can only be performed if the mode is set to devops" unless @config['helper'].running_in_mode?('devops')
|
16
22
|
|
17
|
-
|
18
|
-
|
19
|
-
nodes = @config['parser'].exclude_nodes( nodes, [{ unless: { env: @options['env'] }}] )
|
20
|
-
|
21
|
-
addr_data = @config['getter'].get_addresses_hash @options['env']
|
22
|
-
|
23
|
-
unless @config['helper'].does_cheftacular_config_have?(['cloudflare_api_key', 'cloudflare_user_email'])
|
24
|
-
puts "Critical! You tried to run #{ __method__ } but have not set a cloudflare_api_key or cloudflare_user_email! Please set these keys and run this method again!"
|
25
|
-
|
26
|
-
exit
|
27
|
-
end
|
28
|
-
|
29
|
-
exit
|
30
|
-
|
31
|
-
cloudflare = CloudFlare::connection(@config['cheftacular']['cloudflare_api_key'], @config['cheftacular']['cloudflare_user_email'])
|
32
|
-
|
33
|
-
nodes.each do |n|
|
34
|
-
|
35
|
-
@options['node_name'] = n.name
|
36
|
-
|
37
|
-
domain_obj = PublicSuffix.parse addr_data[n.public_ipaddress]['dn']
|
38
|
-
|
39
|
-
next unless domain_obj.domain == @config[@options['env']]['config_bag_hash'][@options['sub_env']]['tld'] #we can't create records for domains we dont manage in rax
|
40
|
-
|
41
|
-
@config['stateless_action'].cloud "domain", "create:#{ tld }:#{ domain_obj.trd }:#{ n.public_ipaddress }"
|
42
|
-
|
43
|
-
sleep 5 #don't want to to push updates to rax too fast
|
44
|
-
|
45
|
-
@config['stateless_action'].cloud "domain", "create:#{ tld }:local.#{ domain_obj.trd }:#{ addr_data[n.public_ipaddress]['priv'] }"
|
46
|
-
|
47
|
-
full_domain = "#{ domain_obj.trd }.#{ tld }"
|
48
|
-
|
49
|
-
target_serv_index = @config[@options['env']]['addresses_bag_hash']['addresses'].count
|
50
|
-
|
51
|
-
@config[@options['env']]['addresses_bag_hash']['addresses'].each do |serv_hash|
|
52
|
-
target_serv_index = @config[@options['env']]['addresses_bag_hash']['addresses'].index(serv_hash) if serv_hash['name'] == n.name
|
53
|
-
end
|
54
|
-
|
55
|
-
@config[@options['env']]['addresses_bag_hash']['addresses'][target_serv_hash] ||= {}
|
56
|
-
@config[@options['env']]['addresses_bag_hash']['addresses'][target_serv_hash]['dn'] = full_domain
|
23
|
+
target_domain = @config[@options['env']]['config_bag_hash'][@options['sub_env']]['tld']
|
57
24
|
|
58
|
-
|
59
|
-
end
|
25
|
+
@config['stateless_action'].update_tld 'self'
|
60
26
|
|
61
|
-
@config[
|
27
|
+
target_domain_records = @config['stateless_action'].cloud('domain', "read:#{ target_domain }")["records_for_#{ target_domain }"]
|
62
28
|
|
63
|
-
@config['
|
64
|
-
@config['ChefDataBag'].save_addresses_bag
|
29
|
+
@config['DNS'].update_cloudflare_from_array_of_domain_hashes target_domain, target_domain_records
|
65
30
|
end
|
66
31
|
end
|
67
32
|
end
|
@@ -11,49 +11,52 @@ class Cheftacular
|
|
11
11
|
end
|
12
12
|
|
13
13
|
class StatelessAction
|
14
|
-
def update_tld
|
14
|
+
def update_tld target_tld=""
|
15
15
|
raise "This action can only be performed if the mode is set to devops" unless @config['helper'].running_in_mode?('devops')
|
16
16
|
|
17
|
-
raise "Undefined new tld to migrate to" if ARGV.length <= 1
|
17
|
+
raise "Undefined new tld to migrate to" if ARGV.length <= 1 && target_tld.blank?
|
18
18
|
|
19
19
|
nodes = @config['getter'].get_true_node_objects(true)
|
20
20
|
|
21
21
|
#We need to manually update beta nodes as they share the same env space as their non-beta counterparts TODO Refactor?
|
22
22
|
nodes = @config['parser'].exclude_nodes( nodes, [{ unless: { env: @options['env'] }}] )
|
23
23
|
|
24
|
-
|
24
|
+
address_hash = @config['getter'].get_addresses_hash @options['env']
|
25
25
|
|
26
|
-
|
26
|
+
target_tld = ARGV[1] if target_tld.blank?
|
27
27
|
|
28
|
-
|
28
|
+
old_tld = @config[@options['env']]['config_bag_hash'][@options['sub_env']]['tld']
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
|
30
|
+
if target_tld == 'self'
|
31
|
+
target_tld = old_tld
|
32
|
+
end
|
33
33
|
|
34
|
-
|
34
|
+
nodes.each do |n|
|
35
35
|
|
36
|
-
@
|
36
|
+
@options['node_name'] = n.name
|
37
37
|
|
38
|
-
|
38
|
+
domain_obj = PublicSuffix.parse address_hash[n.public_ipaddress]['dn']
|
39
39
|
|
40
|
-
|
40
|
+
next unless domain_obj.domain == old_tld #we can't create records for domains not managed under the environment's tld
|
41
41
|
|
42
|
-
|
42
|
+
#TODO CHECK CLOUD IF TLD EXISTS
|
43
43
|
|
44
|
-
|
44
|
+
specific_domain = "#{ domain_obj.trd }.#{ target_tld }"
|
45
45
|
|
46
|
-
@
|
47
|
-
|
46
|
+
if specific_domain != "#{ @options['node_name'] }.#{ target_tld }"
|
47
|
+
@config['DNS'].create_dns_record_for_domain_from_address_hash(specific_domain, address_hash[n.public_ipaddress], "specific_domain_mode")
|
48
48
|
end
|
49
49
|
|
50
|
-
@config[
|
51
|
-
|
50
|
+
@config['DNS'].create_dns_record_for_domain_from_address_hash(target_tld, address_hash[n.public_ipaddress])
|
51
|
+
|
52
|
+
@config['DNS'].compile_address_hash_for_server_from_options("set_specific_domain_name:#{ specific_domain }")
|
52
53
|
|
53
54
|
sleep 5 #prepare for next domain
|
54
55
|
end
|
55
56
|
|
56
|
-
@config[@options['env']]['config_bag_hash'][@options['sub_env']]['tld'] =
|
57
|
+
@config[@options['env']]['config_bag_hash'][@options['sub_env']]['tld'] = target_tld
|
58
|
+
|
59
|
+
puts "BAG TLD::#{ @config[@options['env']]['config_bag_hash'][@options['sub_env']]['tld'] }"
|
57
60
|
|
58
61
|
@config['ChefDataBag'].save_config_bag
|
59
62
|
@config['ChefDataBag'].save_addresses_bag
|
@@ -57,7 +57,7 @@ class Cheftacular
|
|
57
57
|
node_roles_hash.each_pair do |role_name, role_hash|
|
58
58
|
overwrite = false
|
59
59
|
if bag_hash[role_name] != role_hash
|
60
|
-
puts "Detected difference between saved roles hash and updated node_roles json hash."
|
60
|
+
puts "Detected difference between saved roles hash and updated node_roles json hash for #{ role_name }."
|
61
61
|
|
62
62
|
puts "Saved roles hash:"
|
63
63
|
ap(bag_hash[role_name])
|
@@ -90,6 +90,7 @@ class Cheftacular
|
|
90
90
|
allowed_changes_hash[node.name].each_pair do |node_key, node_val|
|
91
91
|
if (node_key =~ /name/) != 0 && node.send(node_key) != node_val
|
92
92
|
puts("Updating #{ node.name } with attribute #{ node_key } = #{ node_val } from #{ node.name }.json") unless @options['quiet']
|
93
|
+
|
93
94
|
node.send("#{ node_key }=", node_val)
|
94
95
|
|
95
96
|
changes_for_current_node, invalidate_file_node_cache = true, true
|
@@ -100,6 +101,7 @@ class Cheftacular
|
|
100
101
|
allowed_changes_hash[node.name.gsub(/\d/,'')].each_pair do |node_key, node_val|
|
101
102
|
if (node_key =~ /name/) != 0 && node.send(node_key) != node_val
|
102
103
|
puts("Updating #{ node.name } with attribute #{ node_key } = #{ node_val } from template json file") unless @options['quiet']
|
104
|
+
|
103
105
|
node.send("#{ node_key }=", node_val)
|
104
106
|
|
105
107
|
changes_for_current_node, invalidate_file_node_cache = true, true
|
data/lib/cheftacular/version.rb
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
class CloudInteractor
|
2
2
|
class Domain
|
3
3
|
def create_record args, already_created=false
|
4
|
-
args['type']
|
5
|
-
args['ttl']
|
4
|
+
args['type'] ||= 'A'
|
5
|
+
args['ttl'] ||= 300
|
6
|
+
args['target_domain'] ||= "#{ args['subdomain'] }.#{ args[IDENTITY.singularize] }"
|
7
|
+
args['target_domain'] = args[IDENTITY.singularize] if args['subdomain'].blank?
|
6
8
|
|
7
9
|
read args, false
|
8
10
|
|
9
11
|
@main_obj['specific_records'][args[IDENTITY.singularize]].each do |record_hash|
|
10
|
-
already_created = true if record_hash['name'] ==
|
12
|
+
already_created = true if record_hash['name'] == args['target_domain'] && record_hash['type'] == args['type']
|
11
13
|
|
12
14
|
break if already_created
|
13
15
|
end
|
@@ -18,9 +20,9 @@ class CloudInteractor
|
|
18
20
|
else
|
19
21
|
specific_fog_object = @classes['auth'].auth_service(RESOURCE).instance_eval('zones').get @main_obj["specific_#{ IDENTITY }"].last['id']
|
20
22
|
|
21
|
-
specific_fog_object.records.create(name:
|
23
|
+
specific_fog_object.records.create(name: args['target_domain'], value: args['target_ip'], type: args['type'], ttl: args['ttl'])
|
22
24
|
|
23
|
-
puts "Attached #{ args['subdomain'] } (#{ args['target_ip'] }) to #{ args[IDENTITY.singularize] }..."
|
25
|
+
puts "Attached #{ args['subdomain'] } (#{ args['target_ip'] }) to #{ args[IDENTITY.singularize] } (#{ args['target_domain'] })..."
|
24
26
|
end
|
25
27
|
end
|
26
28
|
end
|
@@ -13,9 +13,11 @@ class CloudInteractor
|
|
13
13
|
record_obj = JSON.parse(record.to_json)
|
14
14
|
|
15
15
|
@main_obj["specific_#{ IDENTITY }"].last['records'] << record_obj
|
16
|
-
@main_obj['specific_records'][args[IDENTITY.singularize]]
|
16
|
+
@main_obj['specific_records'][args[IDENTITY.singularize]] << record_obj
|
17
17
|
end
|
18
18
|
|
19
|
+
@main_obj['output']["records_for_#{ @main_obj["specific_#{ IDENTITY }"].last['domain'] }"] = @main_obj["specific_#{ IDENTITY }"].last['records']
|
20
|
+
|
19
21
|
ap(@main_obj["specific_#{ IDENTITY }"].last['records']) if output
|
20
22
|
end
|
21
23
|
end
|
@@ -3,13 +3,15 @@ class CloudInteractor
|
|
3
3
|
def update_record args, already_created=false
|
4
4
|
args['type'] ||= 'A'
|
5
5
|
args['ttl'] ||= 300
|
6
|
+
args['target_domain'] ||= "#{ args['subdomain'] }.#{ args[IDENTITY.singularize] }"
|
7
|
+
args['target_domain'] = args[IDENTITY.singularize] if args['subdomain'].blank?
|
6
8
|
|
7
9
|
read args, false
|
8
10
|
|
9
11
|
puts "Updating #{ args['subdomain'] } for #{ args[IDENTITY.singularize] }..."
|
10
12
|
|
11
13
|
@main_obj['specific_records'][args[IDENTITY.singularize]].each do |record_hash|
|
12
|
-
already_created = true if record_hash['name'] ==
|
14
|
+
already_created = true if record_hash['name'] == args['target_domain'] && record_hash['type'] == args['type']
|
13
15
|
|
14
16
|
args['id'] = record_hash['id']
|
15
17
|
|
@@ -33,7 +35,7 @@ class CloudInteractor
|
|
33
35
|
raise "Unsupported action #{ __method__ } for #{ @options['preferred_cloud'] }. Please create an issue on github or submit a PR to fix this issue."
|
34
36
|
end
|
35
37
|
|
36
|
-
puts "Updated #{ args['subdomain'] } (#{ args['target_ip'] }) to #{ args[IDENTITY.singularize] }..."
|
38
|
+
puts "Updated #{ args['subdomain'] } (#{ args['target_ip'] }) to #{ args[IDENTITY.singularize] } (#{ args['target_domain'] })..."
|
37
39
|
else
|
38
40
|
create_record [ args ]
|
39
41
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
#https://github.com/b4k3r/cloudflare/blob/master/lib/cloudflare/connection.rb
|
2
|
+
#TODO this is fixed on master but not in the latest version of the gem, allowing service_mode to be set on creates
|
3
|
+
module CloudFlare
|
4
|
+
class Connection
|
5
|
+
def rec_new(zone, type, name, content, ttl, prio = nil, service = nil, srvname = nil, protocol = nil, weight = nil, port = nil, target = nil, service_mode = '1')
|
6
|
+
send_req({
|
7
|
+
a: :rec_new,
|
8
|
+
z: zone,
|
9
|
+
type: type,
|
10
|
+
name: name,
|
11
|
+
content: content,
|
12
|
+
ttl: ttl,
|
13
|
+
prio: prio,
|
14
|
+
service: service,
|
15
|
+
srvname: srvname,
|
16
|
+
protocol: protocol,
|
17
|
+
weight: weight,
|
18
|
+
port: port,
|
19
|
+
target: target,
|
20
|
+
service_mode: service_mode
|
21
|
+
})
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cheftacular
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Louis Alridge
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-05-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hashie
|
@@ -239,7 +239,7 @@ files:
|
|
239
239
|
- bin/client-list
|
240
240
|
- lib/cheftacular.rb
|
241
241
|
- lib/cheftacular/README.md
|
242
|
-
- lib/cheftacular/
|
242
|
+
- lib/cheftacular/action.rb
|
243
243
|
- lib/cheftacular/actions/check.rb
|
244
244
|
- lib/cheftacular/actions/console.rb
|
245
245
|
- lib/cheftacular/actions/database.rb
|
@@ -253,13 +253,13 @@ files:
|
|
253
253
|
- lib/cheftacular/auditor.rb
|
254
254
|
- lib/cheftacular/chef/data_bag.rb
|
255
255
|
- lib/cheftacular/cheftacular.rb
|
256
|
-
- lib/cheftacular/
|
257
|
-
- lib/cheftacular/
|
258
|
-
- lib/cheftacular/
|
259
|
-
- lib/cheftacular/
|
260
|
-
- lib/cheftacular/
|
261
|
-
- lib/cheftacular/
|
262
|
-
- lib/cheftacular/
|
256
|
+
- lib/cheftacular/decryptor.rb
|
257
|
+
- lib/cheftacular/dns.rb
|
258
|
+
- lib/cheftacular/encryptor.rb
|
259
|
+
- lib/cheftacular/getter.rb
|
260
|
+
- lib/cheftacular/helper.rb
|
261
|
+
- lib/cheftacular/initializer.rb
|
262
|
+
- lib/cheftacular/parser.rb
|
263
263
|
- lib/cheftacular/stateless_action.rb
|
264
264
|
- lib/cheftacular/stateless_actions/add_ssh_key_to_bag.rb
|
265
265
|
- lib/cheftacular/stateless_actions/arguments.rb
|
@@ -292,6 +292,7 @@ files:
|
|
292
292
|
- lib/cheftacular/stateless_actions/get_haproxy_log.rb
|
293
293
|
- lib/cheftacular/stateless_actions/get_log_from_bag.rb
|
294
294
|
- lib/cheftacular/stateless_actions/get_pg_pass.rb
|
295
|
+
- lib/cheftacular/stateless_actions/get_shorewall_allowed_connections.rb
|
295
296
|
- lib/cheftacular/stateless_actions/help.rb
|
296
297
|
- lib/cheftacular/stateless_actions/initialize_data_bag_contents.rb
|
297
298
|
- lib/cheftacular/stateless_actions/knife_upload.rb
|
@@ -344,6 +345,7 @@ files:
|
|
344
345
|
- lib/cloud_interactor/volume/destroy.rb
|
345
346
|
- lib/cloud_interactor/volume/list.rb
|
346
347
|
- lib/cloud_interactor/volume/read.rb
|
348
|
+
- lib/cloudflare/monkeypatches.rb
|
347
349
|
- lib/ridley/monkeypatches.rb
|
348
350
|
- lib/sshkit/actions/start_task.rb
|
349
351
|
- lib/sshkit/getters.rb
|
@@ -1,30 +0,0 @@
|
|
1
|
-
|
2
|
-
class Cheftacular
|
3
|
-
module RemoteHelpers
|
4
|
-
def set_log_loc_and_timestamp
|
5
|
-
@dummy_sshkit.set_log_loc_and_timestamp( @locs )
|
6
|
-
end
|
7
|
-
|
8
|
-
def start_tail_log ip_address, run_list
|
9
|
-
true_env = @config['dummy_sshkit'].get_true_environment run_list, @config['cheftacular']['run_list_environments'], @options['env']
|
10
|
-
|
11
|
-
#special servers should be listed first as most of them will have web role
|
12
|
-
log_loc = case
|
13
|
-
when run_list.include?('role[sensu_server]')
|
14
|
-
"/var/log/sensu/sensu-server.log"
|
15
|
-
when run_list.include?('role[graphite_server]')
|
16
|
-
"/var/log/carbon-cache/current"
|
17
|
-
when run_list.include?('role[web]') && !run_list.include?('nodejs')
|
18
|
-
"/var/www/vhosts/#{ get_codebase_from_role_name( @options['role']) }/current/log/#{ true_env }.log"
|
19
|
-
when run_list.include?('role[worker]') || run_list.include?('nodejs')
|
20
|
-
"/var/log/syslog"
|
21
|
-
else
|
22
|
-
puts "This gem is not currently configured to handle tailing this case"
|
23
|
-
return 0
|
24
|
-
end
|
25
|
-
|
26
|
-
|
27
|
-
`ssh -oStrictHostKeyChecking=no -tt deploy@#{ ip_address } "#{ sudo(ip_address) } tail -f #{ log_loc }" > /dev/tty`
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|