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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 432e618db73dd2f0c3c13dde66a0ba2d48139404
|
4
|
+
data.tar.gz: 24eba2f067f13d14f95075101b1eaabdbd2b767d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 879cda27b14935f3e68ef5570d24c1e60bcfd2e33b3a25fd0126fb25b0f1669b4b5f8f9d55716f7b5e9de50046d7099fbaebc710c6074aca7e0e710630efa874
|
7
|
+
data.tar.gz: 745b5247a4393cda8a083a8215230d9e6d1a41c0653e91e8d537c13fd2f7ab7be8b387ac1d11cde2c71cf9e73f5bb52d32a66ade4c3f8b7519714bdb6449a6bb
|
data/lib/cheftacular/README.md
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# Table of Contents for Cheftacular Commands
|
2
2
|
|
3
|
-
1. [Cheftacular Arguments and Flags](https://github.com/SocialCentivPublic/cheftacular/blob/master/lib/cheftacular/README.md#arguments-and-flags-for-cheftacular)
|
3
|
+
1. [Cheftacular Arguments and Flags](https://github.com/SocialCentivPublic/cheftacular/blob/master/lib/cheftacular/README.md#arguments-and-flags-for-cheftacular)
|
4
4
|
|
5
5
|
2. [Application Commands](https://github.com/SocialCentivPublic/cheftacular/blob/master/lib/cheftacular/README.md#commands-that-can-be-run-in-the-application-context)
|
6
6
|
|
7
|
-
3. [DevOps Commands](https://github.com/SocialCentivPublic/cheftacular/blob/master/lib/cheftacular/README.md#commands-that-can-only-be-run-in-the-devops-context)
|
7
|
+
3. [DevOps Commands](https://github.com/SocialCentivPublic/cheftacular/blob/master/lib/cheftacular/README.md#commands-that-can-only-be-run-in-the-devops-context)
|
8
8
|
|
9
9
|
|
10
10
|
## Arguments and flags for cheftacular
|
@@ -51,14 +51,12 @@
|
|
51
51
|
|
52
52
|
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.
|
53
53
|
|
54
|
-
2. `-z|--unset-revision` will unset a custom revision specified in the arg below and make the codebase utilize the default
|
54
|
+
2. `-z|--unset-revision` will unset a custom revision specified in the arg below and make the codebase utilize the default.
|
55
55
|
|
56
56
|
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.
|
57
57
|
|
58
58
|
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.
|
59
59
|
|
60
|
-
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.
|
61
|
-
|
62
60
|
|
63
61
|
## Commands that can be run in the application context
|
64
62
|
|
@@ -82,7 +80,7 @@
|
|
82
80
|
|
83
81
|
6. `cft deploy` will do a simple chef-client run on the servers for a role. Logs of the run itself will be sent to the local log directory in the application (or chef-repo) where the run was conducted.
|
84
82
|
|
85
|
-
1. This command also restarts services on the server and updates the code. Changes behavior slightly with the `-z|-Z` args.
|
83
|
+
1. This command also restarts services on the server and updates the code. Changes behavior slightly with the `-z|-Z` args but only if your cookbooks support switching revisions based on tags / branch names.
|
86
84
|
|
87
85
|
7. `cft disk_report` will fetch useful statistics from every server for every environment and output it into your log directory.
|
88
86
|
|
@@ -128,9 +126,7 @@
|
|
128
126
|
|
129
127
|
18. `cft reinitialize IP_ADDRESS NODE_NAME` will reconnect a server previously managed by chef to a new chef server. The node name MUST MATCH THE NODE'S ORIGINAL NODE NAME for the roles to be setup correctly.
|
130
128
|
|
131
|
-
19. `cft
|
132
|
-
|
133
|
-
20. `cft run COMMAND [--all]` will trigger the command on the first server in the role. Can be used to run rake commands or anything else.
|
129
|
+
19. `cft run COMMAND [--all]` will trigger the command on the first server in the role. Can be used to run rake commands or anything else.
|
134
130
|
|
135
131
|
1. `--all` will make the command run against all servers in a role rather than the first server it comes across. Don't do this if you're modifying the database with the command.
|
136
132
|
|
@@ -140,11 +136,11 @@
|
|
140
136
|
|
141
137
|
4. IMPORTANT NOTE: You cannot run `cft run rake -T` as is, you have to enclose any command that uses command line dash arguments in quotes like `cft run "rake -T"`
|
142
138
|
|
143
|
-
|
139
|
+
20. `cft scale up|down [NUM_TO_SCALE]` will add (or remove) NUM_TO_SCALE servers from the server array. This command will not let you scale down below 1 server.
|
144
140
|
|
145
141
|
1. In the case of server creation, this command takes a great deal of time to execute. It will output what stage it is currently on to the terminal but <b>you must not kill this command while it is executing</b>.A failed build may require the server to be destroyed / examined by a DevOps engineer.
|
146
142
|
|
147
|
-
|
143
|
+
21. `cft tail` will tail the logs (return continuous output) of the first node if finds that has an application matching the repository running on it. Currently only supports rails stacks
|
148
144
|
|
149
145
|
1. pass `-n NODE_NAME` to grab the output of a node other than the first.
|
150
146
|
|
@@ -189,7 +185,7 @@
|
|
189
185
|
|
190
186
|
3. This command is aliased to `client-list` with no arguments or cft prefix.
|
191
187
|
|
192
|
-
9. `cft cloud <FIRST_LEVEL_ARG> [<SECOND_LEVEL_ARG>[:<SECOND_LEVEL_ARG_QUERY>]*] ` this command handles talking to various cloud
|
188
|
+
9. `cft cloud <FIRST_LEVEL_ARG> [<SECOND_LEVEL_ARG>[:<SECOND_LEVEL_ARG_QUERY>]*] ` this command handles talking to various cloud APIs. If no args are passed nothing will happen.
|
193
189
|
|
194
190
|
1. `domain` 1st level argument for interacting with cloud domains
|
195
191
|
|
@@ -307,21 +303,27 @@
|
|
307
303
|
|
308
304
|
21. `cft get_pg_pass ['clip']` command will output the current environment's pg_password to your terminal. Optionally you can pass in clip like `cft get_pg_pass clip` to have it also copy the pass to your clipboard.
|
309
305
|
|
310
|
-
22. `cft
|
306
|
+
22. `cft get_shorewall_allowed_connections` command will query a single server and return all of its ACCEPT connections from shorewall in it's syslog and return the results in a CSV format. Useful for tracking IP activity.
|
307
|
+
|
308
|
+
1. This command will attempt to `dig` each ip address to give you the most likely culprit.
|
309
|
+
|
310
|
+
23. `cft help COMMAND|MODE` this command returns the documentation for a specific command if COMMAND matches the name of a command. Alternatively, it can be passed `action|arguments|application|current|devops|stateless_action` to fetch the commands for a specific mode.Misspellings of commands will display near hits.
|
311
|
+
|
312
|
+
24. `cft initialize_data_bag_contents ENVIRONMENT_NAME` will ensure the data bags always have the correct structure before each run. This command is run every time the gem is started and if called directly, will exit after completion.
|
311
313
|
|
312
|
-
|
314
|
+
25. `cft knife_upload` will resync the chef-server with the local chef-repo code. This command is analog for `knife upload /`
|
313
315
|
|
314
|
-
|
316
|
+
26. `cft pass NODE_NAME` will drop the server's sudo password into your clipboard. Useful for when you need to ssh into the server itself and try advanced linux commands
|
315
317
|
|
316
|
-
|
318
|
+
27. `cft remove_client -n NODE_NAME` removes a client (and its node data) from the chef-server. It also removes its dns records from the cloud service (if possible). 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
|
317
319
|
|
318
|
-
|
320
|
+
28. `cft replication_status` will check the status of the database master and slaves in every environment. Also lists how far behind the slaves are from the master in milliseconds.
|
319
321
|
|
320
|
-
|
322
|
+
29. `cft restart_swap` will restart the swap on every server that doesn't have swap currently on. Useful if you notice servers with no swap activated from `cft disk_report`
|
321
323
|
|
322
324
|
1. There is no risk in running this command. Sometimes swap doesnt reactivate if the server was rebooted and this command fixes that.
|
323
325
|
|
324
|
-
|
326
|
+
30. `cft rvm [COMMAND] [ADDITIONAL_COMMANDS]*` will run rvm commands on the remote servers. Output from this command for each server will go into your rvm directory under the log directory. Please refer to [the rvm help page](https://rvm.io/rvm) for more information on rvm commands.
|
325
327
|
|
326
328
|
1. When no commands are passed, rvm will just run `rvm list` on each server on all servers in the current environment.
|
327
329
|
|
@@ -337,11 +339,11 @@
|
|
337
339
|
|
338
340
|
7. `upgrade_rvm` will run `rvm get stable --auth-dotfiles` on all servers for the current environment. It will also check and attempt to upgrade pre 1.25 installations of RVM to 1.26+ (which requires a GPG key).
|
339
341
|
|
340
|
-
|
342
|
+
31. `cft server_update [restart]` allows you to force update all nodes' packages for a specific environment. This should be done with caution as this *might* break something.
|
341
343
|
|
342
344
|
1. `hip apt_update restart` will prompt to ask if you also want to restart all servers in a rolling restart. This should be done with extreme caution and only in a worst-case scenario.
|
343
345
|
|
344
|
-
|
346
|
+
32. `cft service [COMMAND] [SERVICE]` will run service commands on remote servers. This command only runs on the first server it comes across. Specify others with -n NODE_NAME.
|
345
347
|
|
346
348
|
1. When no commands are passed, the command will list all the services in the /etc/init directory
|
347
349
|
|
@@ -349,9 +351,13 @@
|
|
349
351
|
|
350
352
|
3. When `restart|stop|start SERVICE` is passed, the command will attempt to restart|stop|start the service if it has a .conf file on the remote server in the /etc/init directory.
|
351
353
|
|
352
|
-
|
354
|
+
33. `cft slack "MESSAGE" [CHANNEL]` will attempt to post the message to the webhook set in your cheftacular.yml. Slack posts to your default channel by default but if the CHANNEL argument is supplied the message will post there.
|
353
355
|
|
354
|
-
|
356
|
+
1. NOTE: To prevent confusing spam from many possible sources, the username posted to slack will always be *Cheftacular*. This can be overloaded in the StatelessAction method "slack" but this is not recommended.
|
357
|
+
|
358
|
+
2. Remember, if you have auditing turned on in your cheftacular.yml, you can track who sends what to slack.
|
359
|
+
|
360
|
+
34. `cft test_env [TARGET_ENV] boot|destroy` will create (or destroy) the test nodes for a particular environment (defaults to staging, prod split-envs can be set with `-p`). Please read below for how TARGET_ENV works
|
355
361
|
|
356
362
|
1. TARGET_ENV changes functionality depending on the overall (like staging / production) environment
|
357
363
|
|
@@ -361,9 +367,15 @@
|
|
361
367
|
|
362
368
|
3. The default tld used should change depending on which environment you are booting / destroying. This is set in the environment's config data bag under the tld key
|
363
369
|
|
364
|
-
|
370
|
+
35. `cft ubuntu_bootstrap ADDRESS ROOT_PASS` This command will bring a fresh server to a state where chef-client can be run on it via `cft chef-bootstrap`. It should be noted that it is in this step where a server's randomized deploy_user sudo password is generated.
|
371
|
+
|
372
|
+
36. `cft update_cloudflare_dns_from_cloud` command will force a full dns update for cloudflare.
|
373
|
+
|
374
|
+
1. It will ensure all the subdomain entries are correct (based on the contents of the addresses data bag) and update them if they are not. It will also create the local subdomain for the entry as well if it does exist and point it to the correct private address for an environment.
|
375
|
+
|
376
|
+
2. This command will also ensure any dns records on your cloud are also migrated over to cloudflare as well. This also includes the reverse in the event you would like to turn off cloudflare.
|
365
377
|
|
366
|
-
|
378
|
+
37. `cft update_split_branches` will perform a series of git commands that will merge all the split branches for your split_branch enabled repositories with what is currently on master and push them.
|
367
379
|
|
368
380
|
1. Repository must be set with `-R REPOSITORY_NAME` for this command to work.
|
369
381
|
|
@@ -373,9 +385,9 @@
|
|
373
385
|
|
374
386
|
4. This command will return a helpful error statement if you attempt to run the command with changes to your current working directory. You must commit these changes before running this command.
|
375
387
|
|
376
|
-
|
388
|
+
38. `cft update_tld TLD` command will force a full dns update for a tld in the preferred cloud. It will ensure all the subdomain entries are correct (based on the contents of the addresses data bag) and update them if they are not. It will also create the local subdomain for the entry as well if it does exist and point it to the correct private address.
|
377
389
|
|
378
|
-
|
390
|
+
39. `cft upload_nodes` This command will resync the chef server's nodes with the data in our chef-repo/node_roles.
|
379
391
|
|
380
392
|
1. This command changes behavior depending on several factors about both your mode and the state of your environment
|
381
393
|
|
@@ -387,4 +399,4 @@
|
|
387
399
|
|
388
400
|
1. Due to this, only users running this against their chef-repo need to worry about having a nodes_dir, the way it should be.
|
389
401
|
|
390
|
-
|
402
|
+
40. `cft upload_roles` This command will resync the chef server's roles with the data in the chef-repo/roles.
|
File without changes
|
@@ -6,7 +6,8 @@ class Cheftacular
|
|
6
6
|
"Logs of the run itself will be sent to the local log directory in the application (or chef-repo) where the run was conducted.",
|
7
7
|
|
8
8
|
[
|
9
|
-
" 1. This command also restarts services on the server and updates the code. Changes behavior slightly with the `-z|-Z` args
|
9
|
+
" 1. This command also restarts services on the server and updates the code. Changes behavior slightly with the `-z|-Z` args " +
|
10
|
+
"but only if your cookbooks support switching revisions based on tags / branch names."
|
10
11
|
]
|
11
12
|
]
|
12
13
|
end
|
File without changes
|
@@ -0,0 +1,283 @@
|
|
1
|
+
|
2
|
+
class Cheftacular
|
3
|
+
class DNS
|
4
|
+
def initialize options, config
|
5
|
+
@options, @config = options, config
|
6
|
+
end
|
7
|
+
|
8
|
+
def update_cloudflare_from_array_of_domain_hashes target_domain, target_domain_records
|
9
|
+
unless @config['helper'].does_cheftacular_config_have?(['cloudflare:api_key', 'cloudflare:user_email'])
|
10
|
+
puts "Critical! You tried to run update_cloudflare but have not set a cloudflare_api_key or cloudflare_user_email! Please set these keys and run this method again!"
|
11
|
+
|
12
|
+
exit
|
13
|
+
end
|
14
|
+
|
15
|
+
if @config[@options['env']]['config_bag_hash'][@options['sub_env']]['cloudflare_activated_domains'].empty?
|
16
|
+
puts "Critical! Tere are no entries in the 'cloudflare_activated_domains' array for domain #{ target_domain }! Please open the #{ @options['env'] } data bag item " +
|
17
|
+
"\"config\" and add the domains you want to be protected by cloudflare to the array as strings!"
|
18
|
+
|
19
|
+
exit
|
20
|
+
end
|
21
|
+
|
22
|
+
@config['cloudflare'] = CloudFlare::connection(@config['cheftacular']['cloudflare']['api_key'], @config['cheftacular']['cloudflare']['user_email'])
|
23
|
+
|
24
|
+
puts("Preparing to update cloudflare for domain #{ target_domain }...") unless @options['quiet']
|
25
|
+
|
26
|
+
cloudflare_records_hash = fetch_cloudflare_records_as_hash target_domain
|
27
|
+
|
28
|
+
puts('#'.ljust(4) + 'subdomain'.ljust(50) + 'type'.ljust(6) + 'ttl'.ljust(5) + 'mode'.ljust(20) + 'value') unless @options['quiet']
|
29
|
+
|
30
|
+
domain_count = 1
|
31
|
+
|
32
|
+
target_domain_records.each do |record_hash|
|
33
|
+
next if record_hash['type'] =~ /NS/
|
34
|
+
|
35
|
+
if record_hash['type'] =~ /A/
|
36
|
+
record_hash['activate_cloudflare'] = @config[@options['env']]['config_bag_hash'][@options['sub_env']]['cloudflare_activated_domains'].include?(record_hash['name'])
|
37
|
+
end
|
38
|
+
|
39
|
+
print(domain_count.to_s.ljust(4, '_') + record_hash['name'].ljust(50, '_') + record_hash['type'].ljust(6, '_') + record_hash['ttl'].to_s.ljust(5, '_'))
|
40
|
+
|
41
|
+
if cloudflare_records_hash.has_key?("#{ record_hash['name'] }-#{ record_hash['type'] }") && ( !cloudflare_records_hash["#{ record_hash['name'] }-#{ record_hash['type'] }"].empty? ||
|
42
|
+
cloudflare_record_does_include_value?(cloudflare_records_hash["#{ record_hash['name'] }-#{ record_hash['type'] }"], record_hash['value']) )
|
43
|
+
|
44
|
+
edit_cloudflare_record target_domain, record_hash, cloudflare_records_hash
|
45
|
+
else
|
46
|
+
compile_cloudflare_record_srv_attributes_on_record_hash record_hash, target_domain
|
47
|
+
|
48
|
+
@config['cloudflare'].rec_new(
|
49
|
+
target_domain,
|
50
|
+
record_hash['type'],
|
51
|
+
record_hash['name'],
|
52
|
+
record_hash['value'],
|
53
|
+
record_hash['ttl'],
|
54
|
+
record_hash['SRV_service'],
|
55
|
+
record_hash['SRV_srvname'],
|
56
|
+
record_hash['SRV_protocol'],
|
57
|
+
record_hash['SRV_weight'],
|
58
|
+
record_hash['SRV_port'],
|
59
|
+
record_hash['SRV_target'],
|
60
|
+
(record_hash['activate_cloudflare'] ? '1' : '0') #service_mode
|
61
|
+
)
|
62
|
+
|
63
|
+
print 'create'.ljust(20, '_')
|
64
|
+
end
|
65
|
+
|
66
|
+
domain_count += 1
|
67
|
+
|
68
|
+
print record_hash['value'] unless @options['quiet']
|
69
|
+
|
70
|
+
puts unless @options['quiet']
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def create_dns_record_for_domain_from_address_hash domain, address_hash, *args
|
75
|
+
domain_obj = PublicSuffix.parse domain
|
76
|
+
|
77
|
+
if args.include?('specific_domain_mode')
|
78
|
+
puts("running cloud domain create_record:#{ domain_obj.domain }:#{ domain_obj.trd }:#{ address_hash['public'] }") if @options['verbose']
|
79
|
+
|
80
|
+
@config['stateless_action'].cloud "domain", "create_record:#{ domain_obj.domain }:#{ domain_obj.trd }:#{ address_hash['public'] }"
|
81
|
+
|
82
|
+
sleep 5
|
83
|
+
|
84
|
+
puts("running cloud domain create_record:#{ domain_obj.domain }:local.#{ domain_obj.trd }:#{ address_hash['address'] }") if @options['verbose']
|
85
|
+
|
86
|
+
@config['stateless_action'].cloud "domain", "create_record:#{ domain_obj.domain }:local.#{ domain_obj.trd }:#{ address_hash['address'] }"
|
87
|
+
|
88
|
+
#set the wildcard domain for frontend load balancers
|
89
|
+
if should_route_wildcard_requests?(address_hash['name'], @options['env'], address_hash['descriptor'])
|
90
|
+
puts("running cloud domain create_record:#{ domain_obj.domain }:*:#{ address_hash['public'] }") if @options['verbose']
|
91
|
+
|
92
|
+
@config['stateless_action'].cloud "domain", "create_record:#{ domain_obj.domain }:*:#{ address_hash['public'] }"
|
93
|
+
end
|
94
|
+
elsif args.empty?
|
95
|
+
puts("running cloud domain create_record:#{ domain }:#{ address_hash['name'] }:#{ address_hash['public'] }") if @options['verbose']
|
96
|
+
|
97
|
+
@config['stateless_action'].cloud "domain", "create_record:#{ domain }:#{ address_hash['name'] }:#{ address_hash['public'] }"
|
98
|
+
|
99
|
+
sleep 5
|
100
|
+
|
101
|
+
puts("running cloud domain create:create_record:#{ domain }:local.#{ address_hash['name'] }:#{ address_hash['address'] }") if @options['verbose']
|
102
|
+
|
103
|
+
@config['stateless_action'].cloud "domain", "create_record:#{ domain }:local.#{ address_hash['name'] }:#{ address_hash['address'] }"
|
104
|
+
end
|
105
|
+
|
106
|
+
unless @config[@options['env']]['config_bag_hash'][@options['sub_env']]['cloudflare_activated_domains'].empty?
|
107
|
+
return true unless @config[@options['env']]['config_bag_hash'][@options['sub_env']]['tld'] != domain_obj.tld
|
108
|
+
|
109
|
+
target_domain_records = []
|
110
|
+
target_domain_records << {
|
111
|
+
'name' => "#{ domain_obj.trd }.#{ domain_obj.domain }",
|
112
|
+
'type' => 'A',
|
113
|
+
'value' => address_hash['public'],
|
114
|
+
'ttl' => 300
|
115
|
+
}
|
116
|
+
|
117
|
+
target_domain_records << {
|
118
|
+
'name' => "local.#{ domain_obj.trd }.#{ domain_obj.domain }",
|
119
|
+
'type' => 'A',
|
120
|
+
'value' => address_hash['address'],
|
121
|
+
'ttl' => 300
|
122
|
+
}
|
123
|
+
|
124
|
+
update_cloudflare_from_array_of_domain_hashes domain_obj.tld, target_domain_records
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def should_route_wildcard_requests? node_name, env, descriptor, should_route_requests=false
|
129
|
+
repository_hash = descriptor.blank? ? {} : @config['parser'].parse_repository_hash_from_string(descriptor)
|
130
|
+
|
131
|
+
if repository_hash.empty?
|
132
|
+
puts "Blank repository hash parsed for #{ node_name } in #{ env } with descriptor #{ descriptor }. Setting should route wildcard requests for server to false."
|
133
|
+
end
|
134
|
+
|
135
|
+
#puts "repositories:#{ repository_hash['role'] }:#{ repository_hash['repo_name'] }:route_wildcard_requests_for_tld"
|
136
|
+
|
137
|
+
if @config['helper'].does_cheftacular_config_have?(["repositories:#{ repository_hash['role'] }:route_wildcard_requests_for_tld"])
|
138
|
+
should_route_requests = @config['cheftacular']['repositories'][repository_hash['role']]['route_wildcard_requests_for_tld'] == 'true'
|
139
|
+
end
|
140
|
+
|
141
|
+
should_route_requests
|
142
|
+
end
|
143
|
+
|
144
|
+
def compile_address_hash_for_server_from_options *args
|
145
|
+
target_serv_index = nil
|
146
|
+
tld = @config[@options['env']]['config_bag_hash'][@options['sub_env']]['tld']
|
147
|
+
|
148
|
+
args.each do |arg|
|
149
|
+
if arg.include?('set_specific_domain:')
|
150
|
+
full_domain = arg.split(':').last
|
151
|
+
|
152
|
+
args << 'set_domain_name'
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
full_domain ||= "#{ @options['node_name'] }.#{ tld }"
|
157
|
+
|
158
|
+
@config[@options['env']]['addresses_bag_hash']['addresses'].each do |serv_hash|
|
159
|
+
target_serv_index = @config[@options['env']]['addresses_bag_hash']['addresses'].index(serv_hash) if serv_hash['name'] == @options['node_name']
|
160
|
+
end
|
161
|
+
|
162
|
+
#EX: "name": "api1", "public": "1.2.3.4", "address": "10.208.1.2", "dn":"api1.example.com", "descriptor": "lb:my-backend-codebase"
|
163
|
+
@config[@options['env']]['addresses_bag_hash']['addresses'][target_serv_index] ||= {} unless args.include?('set_hash_to_nil')
|
164
|
+
@config[@options['env']]['addresses_bag_hash']['addresses'][target_serv_index]['name'] = @options['node_name'] if args.include?('set_node_name') || args.include?('set_all_attributes')
|
165
|
+
@config[@options['env']]['addresses_bag_hash']['addresses'][target_serv_index]['public'] = @options['address'] if args.include?('set_public_address') || args.include?('set_all_attributes')
|
166
|
+
@config[@options['env']]['addresses_bag_hash']['addresses'][target_serv_index]['address'] = @options['private_address'] if args.include?('set_private_address') || args.include?('set_all_attributes')
|
167
|
+
@config[@options['env']]['addresses_bag_hash']['addresses'][target_serv_index]['dn'] = full_domain if args.include?('set_domain_name') || args.include?('set_all_attributes')
|
168
|
+
@config[@options['env']]['addresses_bag_hash']['addresses'][target_serv_index]['descriptor'] = (@options['descriptor'].nil? ? @options['node_name'] : @options['descriptor']) if args.include?('set_descriptor') || args.include?('set_all_attributes')
|
169
|
+
|
170
|
+
if !target_serv_index.nil? && target_serv_index.is_a?(Fixnum) && !@options['dont_remove_address_or_server'] && args.include?('set_hash_to_nil')
|
171
|
+
puts("Found entry in addresses data bag corresponding to #{ @options['node_name'] } for #{ @options['env'] }, removing...") unless @options['quiet']
|
172
|
+
|
173
|
+
@config[@options['env']]['addresses_bag_hash']['addresses'][target_serv_index] = nil
|
174
|
+
|
175
|
+
@config[@options['env']]['addresses_bag_hash']['addresses'] = @config[@options['env']]['addresses_bag_hash']['addresses'].compact
|
176
|
+
|
177
|
+
domain_obj = PublicSuffix.parse @config[@options['env']]['addresses_bag_hash']['addresses'][target_serv_index]['dn']
|
178
|
+
|
179
|
+
@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']
|
180
|
+
end
|
181
|
+
|
182
|
+
@config[@options['env']]['addresses_bag_hash']['addresses'][target_serv_index] unless args.include?('set_hash_to_nil')
|
183
|
+
end
|
184
|
+
|
185
|
+
private
|
186
|
+
|
187
|
+
def fetch_cloudflare_records_as_hash target_domain, ret_hash={}
|
188
|
+
request = @config['cloudflare'].rec_load_all(target_domain)['response']['recs']
|
189
|
+
original_records, count = [], 0
|
190
|
+
|
191
|
+
while request['has_more']
|
192
|
+
original_records << request['objs']
|
193
|
+
|
194
|
+
count += request['count']
|
195
|
+
|
196
|
+
request = @config['cloudflare'].rec_load_all(target_domain, count)['response']['recs']
|
197
|
+
end
|
198
|
+
|
199
|
+
original_records << request['objs']
|
200
|
+
|
201
|
+
original_records.flatten.each do |record_hash|
|
202
|
+
ret_hash["#{ record_hash['name'] }-#{ record_hash['type'] }"] ||= []
|
203
|
+
ret_hash["#{ record_hash['name'] }-#{ record_hash['type'] }"] << record_hash
|
204
|
+
end
|
205
|
+
|
206
|
+
ret_hash
|
207
|
+
end
|
208
|
+
|
209
|
+
def edit_cloudflare_record target_domain, record_hash, cloudflare_records_hash
|
210
|
+
possible_matches = cloudflare_records_hash["#{ record_hash['name'] }-#{ record_hash['type'] }"]
|
211
|
+
|
212
|
+
raise "Critical! No cloudflare record was found to edit for #{ target_domain }: #{ record_hash['name'] }!" if possible_matches.nil?
|
213
|
+
|
214
|
+
if possible_matches.count > 1
|
215
|
+
possible_matches.each do |match_hash|
|
216
|
+
if match_hash.has_key?('matched_already')
|
217
|
+
next
|
218
|
+
else
|
219
|
+
compile_cloudflare_record_srv_attributes_on_record_hash record_hash, target_domain
|
220
|
+
|
221
|
+
begin
|
222
|
+
@config['cloudflare'].rec_edit(
|
223
|
+
target_domain,
|
224
|
+
record_hash['type'],
|
225
|
+
match_hash['rec_id'],
|
226
|
+
record_hash['name'],
|
227
|
+
record_hash['value'],
|
228
|
+
record_hash['ttl'],
|
229
|
+
record_hash['activate_cloudflare'],
|
230
|
+
record_hash['priority'],
|
231
|
+
record_hash['SRV_service'],
|
232
|
+
record_hash['SRV_srvname'],
|
233
|
+
record_hash['SRV_protocol'],
|
234
|
+
record_hash['SRV_weight'],
|
235
|
+
record_hash['SRV_port'],
|
236
|
+
record_hash['SRV_target']
|
237
|
+
)
|
238
|
+
|
239
|
+
match_hash['matched_already'] = true
|
240
|
+
|
241
|
+
print 'edit_on_multi_match_'.ljust(19, '_')
|
242
|
+
rescue CloudFlare::RequestError => e
|
243
|
+
if e.message == 'A record with those settings already exists.'
|
244
|
+
print 'edit_fail_match_'
|
245
|
+
|
246
|
+
next
|
247
|
+
else
|
248
|
+
@config['helper'].exception_output "There was an issue updating Cloudflare! Please create an issue on the cheftacular repository with this stacktrace!", e
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
break
|
253
|
+
end
|
254
|
+
end
|
255
|
+
else
|
256
|
+
print 'edit'.ljust(20, '_')
|
257
|
+
|
258
|
+
@config['cloudflare'].rec_edit(target_domain, record_hash['type'], possible_matches[0]['rec_id'], record_hash['name'], record_hash['value'], record_hash['ttl'])
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
def cloudflare_record_does_include_value? cloudflare_record, record_hash_value
|
263
|
+
cloudflare_record.each do |match_record|
|
264
|
+
return true if record_hash_value == match_record['content']
|
265
|
+
end
|
266
|
+
|
267
|
+
false
|
268
|
+
end
|
269
|
+
|
270
|
+
def compile_cloudflare_record_srv_attributes_on_record_hash record_hash, target_domain
|
271
|
+
return false unless record_hash['type'].upcase == 'SRV'
|
272
|
+
|
273
|
+
record_hash['SRV_service'] = record_hash['name'].split('.')[0]
|
274
|
+
record_hash['SRV_srvname'] = target_domain
|
275
|
+
record_hash['SRV_protocol'] = record_hash['name'].split('.')[1]
|
276
|
+
record_hash['SRV_weight'] = record_hash['value'].split(' ')[0].to_i
|
277
|
+
record_hash['SRV_port'] = record_hash['value'].split(' ')[1].to_i
|
278
|
+
record_hash['SRV_target'] = record_hash['value'].split(' ')[2]
|
279
|
+
record_hash['value'] = "#{ record_hash['priority'] } IN SRV #{ record_hash['SRV_weight'] } #{ record_hash['SRV_port'] } #{ record_hash['SRV_target'] }."#10 IN SRV 5 8806 somewhere.com
|
280
|
+
#record_hash['name'] = ''
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|