cheftacular 2.4.1 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/lib/cheftacular/README.md +111 -63
  3. data/lib/cheftacular/actions/check.rb +1 -1
  4. data/lib/cheftacular/actions/console.rb +1 -1
  5. data/lib/cheftacular/actions/db_console.rb +1 -1
  6. data/lib/cheftacular/actions/deploy.rb +2 -2
  7. data/lib/cheftacular/actions/log.rb +2 -1
  8. data/lib/cheftacular/actions/migrate.rb +1 -1
  9. data/lib/cheftacular/actions/run.rb +1 -1
  10. data/lib/cheftacular/actions/tail.rb +2 -2
  11. data/lib/cheftacular/decryptor.rb +2 -0
  12. data/lib/cheftacular/encryptor.rb +2 -0
  13. data/lib/cheftacular/error.rb +20 -0
  14. data/lib/cheftacular/initializer.rb +8 -1
  15. data/lib/cheftacular/parser.rb +25 -0
  16. data/lib/cheftacular/stateless_actions/backups.rb +1 -1
  17. data/lib/cheftacular/stateless_actions/disk_report.rb +1 -1
  18. data/lib/cheftacular/stateless_actions/file.rb +184 -0
  19. data/lib/cheftacular/stateless_actions/get_haproxy_log.rb +1 -1
  20. data/lib/cheftacular/stateless_actions/get_shorewall_allowed_connections.rb +1 -1
  21. data/lib/cheftacular/stateless_actions/pass.rb +1 -7
  22. data/lib/cheftacular/stateless_actions/replication_status.rb +2 -2
  23. data/lib/cheftacular/stateless_actions/restart_swap.rb +1 -1
  24. data/lib/cheftacular/stateless_actions/rvm.rb +1 -1
  25. data/lib/cheftacular/stateless_actions/server_update.rb +2 -2
  26. data/lib/cheftacular/stateless_actions/service.rb +1 -1
  27. data/lib/cheftacular/version.rb +1 -1
  28. metadata +4 -5
  29. data/lib/cheftacular/stateless_actions/check_cheftacular_settings.rb +0 -14
  30. data/lib/cheftacular/stateless_actions/chef_environment.rb +0 -21
  31. data/lib/cheftacular/stateless_actions/fetch_file.rb +0 -24
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d1824b19ce37e0733ceb249e6bbac87eecbb81d5
4
- data.tar.gz: b448ce029765480b636de8ec62f4b0bd74a214a0
3
+ metadata.gz: 7233d8cadcae175bcd92d273a3605839a2d53ad9
4
+ data.tar.gz: fdb827fd1402bdd10a00a6825562a73141bb6061
5
5
  SHA512:
6
- metadata.gz: 513496fe5d458cc5131dfad0bf573888b6a05a762b1bce7070bf2dd639eabe03bf1ccfba52a2e8a3919048cfd22ff3a2eac0217f09417c207a005d48cadbe599
7
- data.tar.gz: 941ccd83c2d7eaf0fcdaa40512a4f7b87c96d9b8f89caa5d6df5b9c608639ed86838c70c6eee2a83056a500f2c8a20161506a3b2ff44c0c2b14e44b4dda8149b
6
+ metadata.gz: cb98181f78e93dffaed9569a924a5bd405e350af1379cffb0ccb44f1230c59ec54d34651b77d1b40b747c6a02e4e56a4e2a085a2613edd639bd285ece64bf17d
7
+ data.tar.gz: 775787e78bc7d997d94eabaa5011e72bc78aeb9b6295ae73d91f14d00c8acb5f5b634e917cb660880c5d2787aa23a49a18a91696216d5870a09e53062155003b
@@ -94,23 +94,53 @@
94
94
 
95
95
  3. This command will prompt when attempting to destroy servers in staging or production
96
96
 
97
- 9. `cft fix_known_hosts [HOSTNAME]` this command will delete entries in your known_hosts file for all the servers that are in our system (ip addresses AND dns names)
97
+ 9. `cft file NODE_NAME LOCATION_ALIAS MODE FILE_NAME` interacts with a file on the remote server
98
+
99
+ 1. `LOCATION_ALIAS` will be parsed as a path if it has backslash characters. Otherwise it will be parsed from your location_aliases hash in your cheftacular.yml
100
+
101
+ 2. `FILE_NAME` is the actual name (can also be additional path to the file) of the file to be interacted with. If no value is passed or the file does not exist in the LOCATION_ALIAS, the command will return the entries in LOCATION_ALIAS
102
+
103
+ 1. *NOTE! If you plan to use FILE_NAME as a path, do prepend the path with a / character!*
104
+
105
+ 3. `MODE` can be `cat|display|edit|fetch|list|scp|tail|tail-f`.
106
+
107
+ 1. The default mode is display, this is what will be run at LOCATION_ALIAS for FILE_NAME if no MODE is passed.
108
+
109
+ 2. `cat|display` will attempt to display the FILE_NAME listed to your terminal.
110
+
111
+ 3. `edit:TEXT_EDITOR` will attempt to edit the file with the TEXT_EDITOR listed. NOTE! This editor must be installed on the node you're accessing. If the editor is not present via a `which` command, the cft file command will say so.
112
+
113
+ 4. `fetch|scp` will attempt to fetch the FILE_NAME listed via SCP. This file is saved to /Users/mrlocus/Code/chef-repo/tmp (based on your directory structure) under the same FILE_NAME as the remote file.
114
+
115
+ 1. The deploy must have access to said file without sudo!
116
+
117
+ 5. `list` the default behavior if the file does not exist. Otherwise must be manually called.
118
+
119
+ 6. `tail:NUMBER_OF_LINES` tails the file for the last `NUMBER_OF_LINES` lines, defaults to 500.
120
+
121
+ 7. `tail-f` enables continuous output of the file.
122
+
123
+ 4. `--save-to-file FILE_NAME option will save the output of `cat|display|tail` to a file on your local system instead of displaying the file to your terminal window.
124
+
125
+ 1. `--save-to-file FILE_PATH` can also be used in the `fetch` context to specify where exactly to save the file and what to name it as.
126
+
127
+ 10. `cft fix_known_hosts [HOSTNAME]` this command will delete entries in your known_hosts file for all the servers that are in our system (ip addresses AND dns names)
98
128
 
99
129
  1. Passing in a hostname will make the command only remove entries with that hostname / ip specifically
100
130
 
101
- 10. `cft get_active_ssh_connections` will fetch the active ssh connections from every server and output it into your log directory.
131
+ 11. `cft get_active_ssh_connections` will fetch the active ssh connections from every server and output it into your log directory.
102
132
 
103
- 11. `cft get_haproxy_log` this command will generate a haproxy html file for the load balancer(s) associated with a repository in the log directory. Opening this log file in the browser will show the status of that haproxy at the time of the log.
133
+ 12. `cft get_haproxy_log` this command will generate a haproxy html file for the load balancer(s) associated with a repository in the log directory. Opening this log file in the browser will show the status of that haproxy at the time of the log.
104
134
 
105
135
  1. In devops mode, this command will not do anything without the -R repository passed.
106
136
 
107
- 12. `cft get_log_from_bag <NODE_NAME-COMMAND_TYPE>` this command grabs the latest command run log from the data bags and saves it to your log directory. There are different types of logs saved per server depending on command.
137
+ 13. `cft get_log_from_bag <NODE_NAME-COMMAND_TYPE>` this command grabs the latest command run log from the data bags and saves it to your log directory. There are different types of logs saved per server depending on command.
108
138
 
109
- 13. `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.
139
+ 14. `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.
110
140
 
111
- 14. `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.
141
+ 15. `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.
112
142
 
113
- 15. `cft log` this command will output the last 500 lines of logs from every server set for CODEBASE (can be given additional args to specify) to the log directory
143
+ 16. `cft log` this command will output the last 500 lines of logs from every server set for CODEBASE (can be given additional args to specify) to the log directory
114
144
 
115
145
  1. `--nginx` will fetch the nginx logs as well as the application logs
116
146
 
@@ -122,13 +152,13 @@
122
152
 
123
153
  4. `--fetch-backup` If doing a pg_data log, this will fetch the latest logs from the pg_data log directory for each database.
124
154
 
125
- 16. `cft migrate` this command will grab the first alphabetical node for a repository and run a migration that will hit the database primary server.
155
+ 17. `cft migrate` this command will grab the first alphabetical node for a repository and run a migration that will hit the database primary server.
126
156
 
127
- 17. `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
157
+ 18. `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
128
158
 
129
- 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.
159
+ 19. `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
160
 
131
- 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.
161
+ 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.
132
162
 
133
163
  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.
134
164
 
@@ -138,11 +168,11 @@
138
168
 
139
169
  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"`
140
170
 
141
- 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.
171
+ 21. `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.
142
172
 
143
173
  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.
144
174
 
145
- 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
175
+ 22. `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
146
176
 
147
177
  1. pass `-n NODE_NAME` to grab the output of a node other than the first.
148
178
 
@@ -151,35 +181,23 @@
151
181
 
152
182
  ## Commands that can ONLY be run in the devops context
153
183
 
154
- 1. [NYI]`cft chef_environment ENVIRONMENT_NAME [create|destroy]` will allow you to interact with chef environments on the chef server.
155
-
156
- 1. `create` will create an environment if it does not exist.
157
-
158
- 2. `destroy` will destroy a chef environment *IF IT HAS NO NODES*
184
+ 1. [NYI]`cft clean_sensu_plugins` will checkout / update the sensu community plugins github repo on your local machine and sync any sensu plugin files in your wrapper cookbook directory with what is in the repo.
159
185
 
160
- 2. [NYI]`cft clean_sensu_plugins` will checkout / update the sensu community plugins github repo on your local machine and sync any sensu plugin files in your wrapper cookbook directory with what is in the repo.
161
-
162
- 3. [NYI]`cft fetch_file NODE_NAME LOCATION_ALIAS FILE_NAME` fetches a file from the remote node.
163
-
164
- 1. `LOCATION_ALIAS` will be parsed as a path if it has backslash characters. Otherwise it will be parsed from your location_aliases hash in your cheftacular.yml
165
-
166
- 2. `FILE_NAME` is the actual name of the file to be fetched. If no value is passed or the file does not exist in the LOCATION_ALIAS, the command will return the entries in LOCATION_ALIAS
167
-
168
- 4. `cft add_ssh_key_to_bag "<NEW SSH PUB KEY>" [SPECIFIC_REPOSITORY]` this command will add the given ssh key to the default authentication data bag. After this your server recipes should read the contents of the 'default' 'authentication' bag for the authorized_keys array.
186
+ 2. `cft add_ssh_key_to_bag "<NEW SSH PUB KEY>" [SPECIFIC_REPOSITORY]` this command will add the given ssh key to the default authentication data bag. After this your server recipes should read the contents of the 'default' 'authentication' bag for the authorized_keys array.
169
187
 
170
188
  1. `SPECIFIC_REPOSITORY` is a special argument, if left blank the key will be placed in the authorized_keys array in the bag, otherwise it will be placed in the specific_authorized_keys hash under a key named for the repository that is passed. The script will error if SPECIFIC_REPOSITORY does not exist in the cheftacular.yml respositories hash. You can then use this data to give users selective ssh access to certain servers.
171
189
 
172
- 5. `cft backup [activate|deactivate]` this command sets the fetch_backups and restore_backups flags in your config data bag for an environment. These can be used to give application developers a way to trigger / untrigger restores in an environment
190
+ 3. `cft backup [activate|deactivate]` this command sets the fetch_backups and restore_backups flags in your config data bag for an environment. These can be used to give application developers a way to trigger / untrigger restores in an environment
173
191
 
174
- 6. `cft chef_bootstrap ADDRESS NODE_NAME` allows you to register a node in the chef system, remove any lingering data that may be associated with it and update the node's runlist if it has an entry in nodes_dir for its NODE_NAME.
192
+ 4. `cft chef_bootstrap ADDRESS NODE_NAME` allows you to register a node in the chef system, remove any lingering data that may be associated with it and update the node's runlist if it has an entry in nodes_dir for its NODE_NAME.
175
193
 
176
- 7. `cft clean_cookbooks [force] [remove_cookbooks]` allows you to update the internal chef-repo's cookbooks easily. By default this script will force you to decide what to do with each cookbook individually (shows version numbers and whether to overwrite it to cookbooks or not).
194
+ 5. `cft clean_cookbooks [force] [remove_cookbooks]` allows you to update the internal chef-repo's cookbooks easily. By default this script will force you to decide what to do with each cookbook individually (shows version numbers and whether to overwrite it to cookbooks or not).
177
195
 
178
196
  1. `force` argument will cause the downloaded cookbooks to *always* overwrite the chef-repo's cookbooks as long as the downloaded cookbook has a higher version number.
179
197
 
180
198
  2. If you would like to remove all the cookbooks on the chef server, run `knife cookbook bulk delete '.*' -p -c ~/.chef/knife.rb`
181
199
 
182
- 8. `cft client_list` Allows you check the basic information for all the servers setup via chef. Shows the server's short name, its public ip address and roles (run_list) by default.
200
+ 6. `cft client_list` Allows you check the basic information for all the servers setup via chef. Shows the server's short name, its public ip address and roles (run_list) by default.
183
201
 
184
202
  1. `-v` option will make this command display the server's domain name, whether its password is stored on the chef server and what that password is.
185
203
 
@@ -187,7 +205,7 @@
187
205
 
188
206
  3. This command is aliased to `client-list` with no arguments or cft prefix.
189
207
 
190
- 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.
208
+ 7. `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.
191
209
 
192
210
  1. `domain` first level argument for interacting with cloud domains
193
211
 
@@ -259,7 +277,7 @@
259
277
 
260
278
  1. Standard servers are listed as XGB with no spaces in their size, performance servers are listed as X GB with a space in their size. If you are about to create a server and are unsure, query flavors first.
261
279
 
262
- 10. `cft cloud_bootstrap NODE_NAME FLAVOR_NAME [DESCRIPTOR] [--with-dn DOMAIN]` uses a cloud api to create a server and attaches its DOMAIN_NAME to the TLD specified for that environment (IE: example-staging.com for staging)
280
+ 8. `cft cloud_bootstrap NODE_NAME FLAVOR_NAME [DESCRIPTOR] [--with-dn DOMAIN]` uses a cloud api to create a server and attaches its DOMAIN_NAME to the TLD specified for that environment (IE: example-staging.com for staging)
263
281
 
264
282
  1. If no DOMAIN_NAME is supplied it will use the node's NODE_NAME (IE: api01.example-staging.com)
265
283
 
@@ -269,19 +287,19 @@
269
287
 
270
288
  4. DESCRIPTOR is used as an internal tag for the node, if left blank it will become the name of the node. It is recommended to enter a custom repository-dependent tag here to make nodes easier to load-balance like "lb:[CODEBASE_NAME]"
271
289
 
272
- 11. `cft compile_audit_log [clean]` compiles the audit logs in each environment's audit data bag a audit-log-CURRENTDAY.md file in the log folder of the application. Bear in mind that the bag can only hold 100K bytes and will need to have that data removed to store more than that.
290
+ 9. `cft compile_audit_log [clean]` compiles the audit logs in each environment's audit data bag a audit-log-CURRENTDAY.md file in the log folder of the application. Bear in mind that the bag can only hold 100K bytes and will need to have that data removed to store more than that.
273
291
 
274
- 12. `cft compile_readme` compiles all documentation methods and creates a README.md file in the log folder of the application.
292
+ 10. `cft compile_readme` compiles all documentation methods and creates a README.md file in the log folder of the application.
275
293
 
276
- 13. `cft create_git_key ID_RSA_FILE [OAUTH_TOKEN]` This command will update the default/authentication data bag with new credentials. The [ID_RSA_FILE](https://help.github.com/articles/generating-ssh-keys) needs to exist beforehand.
294
+ 11. `cft create_git_key ID_RSA_FILE [OAUTH_TOKEN]` This command will update the default/authentication data bag with new credentials. The [ID_RSA_FILE](https://help.github.com/articles/generating-ssh-keys) needs to exist beforehand.
277
295
 
278
296
  1. This command will upload both the private and public key to the data bag. The public key should be the one that matches the github user for your deployment github user.
279
297
 
280
298
  2. `OAUTH_TOKEN` *must* be generated by logging into github and generating an access token in the account settings -> applications -> personal access tokens
281
299
 
282
- 14. `cft disk_report` will fetch useful statistics from every server for every environment and output it into your log directory.
300
+ 12. `cft disk_report` will fetch useful statistics from every server for every environment and output it into your log directory.
283
301
 
284
- 15. `cft environment boot|destroy` will boot / destroy the current environment
302
+ 13. `cft environment boot|destroy` will boot / destroy the current environment
285
303
 
286
304
  1. `boot` will spin up servers and bring them to a stable state. This includes setting up their subdomains for the target environment.
287
305
 
@@ -289,23 +307,53 @@
289
307
 
290
308
  3. This command will prompt when attempting to destroy servers in staging or production
291
309
 
292
- 16. `cft fix_known_hosts [HOSTNAME]` this command will delete entries in your known_hosts file for all the servers that are in our system (ip addresses AND dns names)
310
+ 14. `cft file NODE_NAME LOCATION_ALIAS MODE FILE_NAME` interacts with a file on the remote server
311
+
312
+ 1. `LOCATION_ALIAS` will be parsed as a path if it has backslash characters. Otherwise it will be parsed from your location_aliases hash in your cheftacular.yml
313
+
314
+ 2. `FILE_NAME` is the actual name (can also be additional path to the file) of the file to be interacted with. If no value is passed or the file does not exist in the LOCATION_ALIAS, the command will return the entries in LOCATION_ALIAS
315
+
316
+ 1. *NOTE! If you plan to use FILE_NAME as a path, do prepend the path with a / character!*
317
+
318
+ 3. `MODE` can be `cat|display|edit|fetch|list|scp|tail|tail-f`.
319
+
320
+ 1. The default mode is display, this is what will be run at LOCATION_ALIAS for FILE_NAME if no MODE is passed.
321
+
322
+ 2. `cat|display` will attempt to display the FILE_NAME listed to your terminal.
323
+
324
+ 3. `edit:TEXT_EDITOR` will attempt to edit the file with the TEXT_EDITOR listed. NOTE! This editor must be installed on the node you're accessing. If the editor is not present via a `which` command, the cft file command will say so.
325
+
326
+ 4. `fetch|scp` will attempt to fetch the FILE_NAME listed via SCP. This file is saved to /Users/mrlocus/Code/chef-repo/tmp (based on your directory structure) under the same FILE_NAME as the remote file.
327
+
328
+ 1. The deploy must have access to said file without sudo!
329
+
330
+ 5. `list` the default behavior if the file does not exist. Otherwise must be manually called.
331
+
332
+ 6. `tail:NUMBER_OF_LINES` tails the file for the last `NUMBER_OF_LINES` lines, defaults to 500.
333
+
334
+ 7. `tail-f` enables continuous output of the file.
335
+
336
+ 4. `--save-to-file FILE_NAME option will save the output of `cat|display|tail` to a file on your local system instead of displaying the file to your terminal window.
337
+
338
+ 1. `--save-to-file FILE_PATH` can also be used in the `fetch` context to specify where exactly to save the file and what to name it as.
339
+
340
+ 15. `cft fix_known_hosts [HOSTNAME]` this command will delete entries in your known_hosts file for all the servers that are in our system (ip addresses AND dns names)
293
341
 
294
342
  1. Passing in a hostname will make the command only remove entries with that hostname / ip specifically
295
343
 
296
- 17. `cft full_bootstrap ADDRESS ROOT_PASS NODE_NAME` This command performs both ubuntu_bootstrap and chef_bootstrap.
344
+ 16. `cft full_bootstrap ADDRESS ROOT_PASS NODE_NAME` This command performs both ubuntu_bootstrap and chef_bootstrap.
297
345
 
298
- 18. `cft get_active_ssh_connections` will fetch the active ssh connections from every server and output it into your log directory.
346
+ 17. `cft get_active_ssh_connections` will fetch the active ssh connections from every server and output it into your log directory.
299
347
 
300
- 19. `cft get_haproxy_log` this command will generate a haproxy html file for the load balancer(s) associated with a repository in the log directory. Opening this log file in the browser will show the status of that haproxy at the time of the log.
348
+ 18. `cft get_haproxy_log` this command will generate a haproxy html file for the load balancer(s) associated with a repository in the log directory. Opening this log file in the browser will show the status of that haproxy at the time of the log.
301
349
 
302
350
  1. In devops mode, this command will not do anything without the -R repository passed.
303
351
 
304
- 20. `cft get_log_from_bag <NODE_NAME-COMMAND_TYPE>` this command grabs the latest command run log from the data bags and saves it to your log directory. There are different types of logs saved per server depending on command.
352
+ 19. `cft get_log_from_bag <NODE_NAME-COMMAND_TYPE>` this command grabs the latest command run log from the data bags and saves it to your log directory. There are different types of logs saved per server depending on command.
305
353
 
306
- 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.
354
+ 20. `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.
307
355
 
308
- 22. `cft get_shorewall_allowed_connections [PATH_TO_LOCAL_FILE] -n NODE_NAME` 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.
356
+ 21. `cft get_shorewall_allowed_connections [PATH_TO_LOCAL_FILE] -n NODE_NAME` 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.
309
357
 
310
358
  1. You must pass in a node name to query with `-n NODE_NAME`
311
359
 
@@ -313,23 +361,23 @@
313
361
 
314
362
  3. If `PATH_TO_LOCAL_FILE` is not blank, the command will use that file instead of building a file on the remote server
315
363
 
316
- 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.
364
+ 22. `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.
317
365
 
318
- 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.
366
+ 23. `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.
319
367
 
320
- 25. `cft knife_upload` will resync the chef-server with the local chef-repo code. This command is analog for `knife upload /`
368
+ 24. `cft knife_upload` will resync the chef-server with the local chef-repo code. This command is analog for `knife upload /`
321
369
 
322
- 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
370
+ 25. `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
323
371
 
324
- 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
372
+ 26. `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
325
373
 
326
- 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.
374
+ 27. `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.
327
375
 
328
- 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`
376
+ 28. `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`
329
377
 
330
378
  1. There is no risk in running this command. Sometimes swap doesnt reactivate if the server was rebooted and this command fixes that.
331
379
 
332
- 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.
380
+ 29. `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.
333
381
 
334
382
  1. When no commands are passed, rvm will just run `rvm list` on each server on all servers in the current environment.
335
383
 
@@ -345,11 +393,11 @@
345
393
 
346
394
  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).
347
395
 
348
- 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.
396
+ 30. `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.
349
397
 
350
398
  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.
351
399
 
352
- 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.
400
+ 31. `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.
353
401
 
354
402
  1. When no commands are passed, the command will list all the services in the /etc/init directory
355
403
 
@@ -357,13 +405,13 @@
357
405
 
358
406
  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.
359
407
 
360
- 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.
408
+ 32. `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.
361
409
 
362
410
  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.
363
411
 
364
412
  2. Remember, if you have auditing turned on in your cheftacular.yml, you can track who sends what to slack.
365
413
 
366
- 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
414
+ 33. `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
367
415
 
368
416
  1. TARGET_ENV changes functionality depending on the overall (like staging / production) environment
369
417
 
@@ -373,9 +421,9 @@
373
421
 
374
422
  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
375
423
 
376
- 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.
424
+ 34. `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.
377
425
 
378
- 36. `cft update_cloudflare_dns_from_cloud [skip_update_tld]` command will force a full dns update for cloudflare.
426
+ 35. `cft update_cloudflare_dns_from_cloud [skip_update_tld]` command will force a full dns update for cloudflare.
379
427
 
380
428
  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.
381
429
 
@@ -383,7 +431,7 @@
383
431
 
384
432
  3. The argument `skip_update_tld` will stop the long process of checking and updating all the server domains _before_ cloudflare is updated. Only skip if you believe your domain info on your cloud is accurate.
385
433
 
386
- 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.
434
+ 36. `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.
387
435
 
388
436
  1. Repository must be set with `-R REPOSITORY_NAME` for this command to work.
389
437
 
@@ -393,9 +441,9 @@
393
441
 
394
442
  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.
395
443
 
396
- 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.
444
+ 37. `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.
397
445
 
398
- 39. `cft upload_nodes` This command will resync the chef server's nodes with the data in our chef-repo/node_roles.
446
+ 38. `cft upload_nodes` This command will resync the chef server's nodes with the data in our chef-repo/node_roles.
399
447
 
400
448
  1. This command changes behavior depending on several factors about both your mode and the state of your environment
401
449
 
@@ -407,4 +455,4 @@
407
455
 
408
456
  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.
409
457
 
410
- 40. `cft upload_roles` This command will resync the chef server's roles with the data in the chef-repo/roles.
458
+ 39. `cft upload_roles` This command will resync the chef server's roles with the data in the chef-repo/roles.
@@ -15,7 +15,7 @@ class Cheftacular
15
15
  #this must always precede on () calls so they have the instance variables they need
16
16
  options, locs, ridley, logs_bag_hash, pass_bag_hash, bundle_command, cheftacular, passwords = @config['helper'].set_local_instance_vars
17
17
 
18
- on ( nodes.map { |n| "deploy@" + n.public_ipaddress } ), in: :parallel do |host|
18
+ on ( nodes.map { |n| @config['cheftacular']['deploy_user'] + "@" + n.public_ipaddress } ), in: :parallel do |host|
19
19
  n = get_node_from_address(nodes, host.hostname)
20
20
 
21
21
  puts("Beginning commit check run for #{ n.name } (#{ n.public_ipaddress }) on role #{ options['role'] }") unless options['quiet']
@@ -44,7 +44,7 @@ class Cheftacular
44
44
  true_env = @config['dummy_sshkit'].get_true_environment run_list, @config['cheftacular']['run_list_environments'][@options['env']], @options['env']
45
45
 
46
46
  #the >/dev/tty after the ssh block redirects the full output to stdout, not /dev/null where it normally goes
47
- `ssh -oStrictHostKeyChecking=no -tt deploy@#{ ip_address } "cd #{ app_loc } && RAILS_ENV=#{ true_env } #{ @config['bundle_command'] } exec rails c" > /dev/tty`
47
+ `ssh -oStrictHostKeyChecking=no -tt #{ @config['cheftacular']['deploy_user'] }@#{ ip_address } "cd #{ app_loc } && RAILS_ENV=#{ true_env } #{ @config['bundle_command'] } exec rails c" > /dev/tty`
48
48
  end
49
49
 
50
50
  def start_console_nodejs
@@ -63,7 +63,7 @@ class Cheftacular
63
63
  end
64
64
 
65
65
  #the >/dev/tty after the ssh block redirects the full output to stdout, not /dev/null where it normally goes
66
- `ssh -oStrictHostKeyChecking=no -tt deploy@#{ ip_address } "PGPASSWORD=#{ pg_pass } psql -U #{ db_user } -h #{ database_host }" -d #{ db_name } > /dev/tty`
66
+ `ssh -oStrictHostKeyChecking=no -tt #{ @config['cheftacular']['deploy_user'] }@#{ ip_address } "PGPASSWORD=#{ pg_pass } psql -U #{ db_user } -h #{ database_host }" -d #{ db_name } > /dev/tty`
67
67
  end
68
68
 
69
69
  def start_console_mysql
@@ -26,7 +26,7 @@ class Cheftacular
26
26
  options, locs, ridley, logs_bag_hash, pass_bag_hash, bundle_command, cheftacular, passwords = @config['helper'].set_local_instance_vars
27
27
 
28
28
  #on is namespaced to SSHKit::Backend::Netssh.on
29
- on ( nodes.map { |n| "deploy@" + n.public_ipaddress } ), in: :groups, limit: 10, wait: 5 do |host|
29
+ on ( nodes.map { |n| @config['cheftacular']['deploy_user'] + "@" + n.public_ipaddress } ), in: :groups, limit: 10, wait: 5 do |host|
30
30
  n = get_node_from_address(nodes, host.hostname)
31
31
 
32
32
  puts("Beginning chef client run for #{ n.name } (#{ n.public_ipaddress }) on role #{ options['role'] }") unless options['quiet']
@@ -96,7 +96,7 @@ module SSHKit
96
96
 
97
97
  lines = e.message.split("\n").last(100).join("\n")
98
98
 
99
- ::File.open("#{ log_loc }/failed-deploy/#{ name }-deploy-#{ timestamp }.txt", "w") { |f| f.write(lines.scrub_pretty_text) }
99
+ ::File.open("#{ log_loc }/failed-deploy/#{ name }-deploy-#{ timestamp }.txt", "w") { |f| f.write(e.message.scrub_pretty_text) }
100
100
 
101
101
  [lines, timestamp, 1]
102
102
  end
@@ -31,7 +31,7 @@ class Cheftacular
31
31
 
32
32
  getter = @config['getter']
33
33
 
34
- on ( nodes.map { |n| "deploy@" + n.public_ipaddress } ), in: :parallel do |host|
34
+ on ( nodes.map { |n| @config['cheftacular']['deploy_user'] + "@" + n.public_ipaddress } ), in: :parallel do |host|
35
35
  n = get_node_from_address(nodes, host.hostname)
36
36
 
37
37
  puts("Beginning log fetch run for #{ n.name } (#{ n.public_ipaddress }) on role #{ options['role'] }") unless options['quiet']
@@ -109,6 +109,7 @@ module SSHKit
109
109
 
110
110
  def start_log_fetch_nginx name, log_loc, log_cmnd, timestamp, options, out=""
111
111
  out = "" unless options['no_logs']
112
+ log_cmnd, log_lines = get_log_command_and_lines(options)
112
113
 
113
114
  nginx_log_loc = "/var/log/nginx/#{ options['repository'] }_access.log"
114
115
 
@@ -24,7 +24,7 @@ class Cheftacular
24
24
  #this must always precede on () calls so they have the instance variables they need
25
25
  options, locs, ridley, logs_bag_hash, pass_bag_hash, bundle_command, cheftacular, passwords = @config['helper'].set_local_instance_vars
26
26
 
27
- on ( nodes.map { |n| "deploy@" + n.public_ipaddress } ) do |host|
27
+ on ( nodes.map { |n| @config['cheftacular']['deploy_user'] + "@" + n.public_ipaddress } ) do |host|
28
28
  n = get_node_from_address(nodes, host.hostname)
29
29
 
30
30
  puts("Beginning migration run for #{ n.name } (#{ n.public_ipaddress }) on role #{ options['role'] }") unless options['quiet']
@@ -36,7 +36,7 @@ class Cheftacular
36
36
  #this must always precede on () calls so they have the instance variables they need
37
37
  options, locs, ridley, logs_bag_hash, pass_bag_hash, bundle_command, cheftacular, passwords = @config['helper'].set_local_instance_vars
38
38
 
39
- on ( nodes.map { |n| "deploy@" + n.public_ipaddress } ) do |host|
39
+ on ( nodes.map { |n| @config['cheftacular']['deploy_user'] + "@" + n.public_ipaddress } ) do |host|
40
40
  n = get_node_from_address(nodes, host.hostname)
41
41
 
42
42
  puts("Beginning task run for #{ n.name } (#{ n.public_ipaddress }) on role #{ options['role'] }") unless options['quiet']
@@ -39,7 +39,7 @@ class Cheftacular
39
39
  def start_tail_role_map ip_address, run_list
40
40
  log_loc = @config['getter'].get_current_role_map(run_list)['log_location'].split(',').first.gsub('|current_repo_location|', "#{ @config['cheftacular']['base_file_path'] }/#{ @options['repository'] }/current")
41
41
 
42
- `ssh -oStrictHostKeyChecking=no -tt deploy@#{ ip_address } "#{ @config['helper'].sudo(ip_address) } tail -f #{ log_loc }" > /dev/tty`
42
+ `ssh -oStrictHostKeyChecking=no -tt #{ @config['cheftacular']['deploy_user'] }@#{ ip_address } "#{ @config['helper'].sudo(ip_address) } tail -f #{ log_loc }" > /dev/tty`
43
43
  end
44
44
 
45
45
  def start_tail_ruby_on_rails ip_address, run_list
@@ -48,7 +48,7 @@ class Cheftacular
48
48
  #special servers should be listed first as most of them will have web role
49
49
  log_loc = "#{ @config['cheftacular']['base_file_path'] }/#{ @options['repository'] }/current/log/#{ true_env }.log"
50
50
 
51
- `ssh -oStrictHostKeyChecking=no -tt deploy@#{ ip_address } "#{ @config['helper'].sudo(ip_address) } tail -f #{ log_loc }" > /dev/tty`
51
+ `ssh -oStrictHostKeyChecking=no -tt #{ @config['cheftacular']['deploy_user'] }@#{ ip_address } "#{ @config['helper'].sudo(ip_address) } tail -f #{ log_loc }" > /dev/tty`
52
52
  end
53
53
  end
54
54
  end
@@ -20,6 +20,8 @@ class Cheftacular
20
20
  return_hash
21
21
  end
22
22
 
23
+ private
24
+
23
25
  def openssl_decryptor
24
26
  openssl_decryptor = begin
25
27
  decryptor = OpenSSL::Cipher::Cipher.new(ALGORITHM)
@@ -15,6 +15,8 @@ class Cheftacular
15
15
  hash
16
16
  end
17
17
 
18
+ private
19
+
18
20
  #https://github.com/opscode/chef/blob/master/lib/chef/encrypted_data_bag_item/encryptor.rb
19
21
  def encrypt_data_for_databag string
20
22
  encryptor = openssl_encryptor
@@ -0,0 +1,20 @@
1
+
2
+ class Cheftacular
3
+ class Error
4
+ def initialize options, config
5
+ @options, @config = options, config
6
+ end
7
+
8
+ def is_valid_node_name_option?
9
+ raise "Too few arguments, please supply a node name" if @options['node_name'].nil?
10
+
11
+ nodes = @config['getter'].get_true_node_objects(true)
12
+
13
+ nodes = @config['parser'].exclude_nodes( nodes, [{ if: { not_node: @options["node_name"] } }], true )
14
+
15
+ raise "Node not found for #{ @options['node_name'] }" if nodes.empty?
16
+
17
+ nodes
18
+ end
19
+ end
20
+ end
@@ -210,6 +210,11 @@ class Cheftacular
210
210
  @options['virtualization_mode'] = v_mode
211
211
  end
212
212
 
213
+ #file
214
+ opts.on('--save-to-file FILE_NAME', 'On cft file, this option can be used to save the output of the file display methods to your system. Also works in the fetch context') do |path|
215
+ @options['save_to_file'] = path
216
+ end
217
+
213
218
  end.parse!
214
219
  end
215
220
 
@@ -272,6 +277,7 @@ class Cheftacular
272
277
  locs['wrapper-cookbooks'] = @config['cheftacular']['wrapper-cookbooks']
273
278
  locs['ssh'] = File.expand_path('~/.ssh')
274
279
  locs['chef-log'] = File.expand_path("#{ locs['root']}/log") unless locs['chef-log']
280
+ locs['app-tmp'] = File.expand_path("#{ locs['app-root']}/tmp")
275
281
 
276
282
  @config['locs'] = locs
277
283
  end
@@ -412,6 +418,7 @@ class Cheftacular
412
418
  @config['decryptor'] = Cheftacular::Decryptor.new(@config['data_bag_secret'])
413
419
  @config['action_documentation'] = Cheftacular::ActionDocumentation.new(@options, @config)
414
420
  @config['stateless_action_documentation'] = Cheftacular::StatelessActionDocumentation.new(@options, @config)
421
+ @config['error'] = Cheftacular::Error.new(@options, @config)
415
422
  @config['dummy_sshkit'] = SSHKit::Backend::Netssh.new(SSHKit::Host.new('127.0.0.1'))
416
423
  @config['DNS'] = Cheftacular::DNS.new(@options, @config)
417
424
  end
@@ -421,7 +428,7 @@ class Cheftacular
421
428
  FileUtils.mkdir_p File.join( @config['locs']['chef-log'], sub_log_directory )
422
429
  end
423
430
 
424
- FileUtils.mkdir_p File.join( @config['locs']['app-root'], 'tmp', @config['helper'].declassify)
431
+ FileUtils.mkdir_p File.join( @config['locs']['app-tmp'], @config['helper'].declassify)
425
432
 
426
433
  FileUtils.mkdir_p @config['helper'].current_nodes_file_cache_path
427
434
 
@@ -201,5 +201,30 @@ class Cheftacular
201
201
  return repository_hash if string.include?(repository)
202
202
  end
203
203
  end
204
+
205
+ def parse_location_alias string
206
+ if @config['cheftacular']['location_aliases'].keys.include?(string)
207
+ puts("Matched location_alias #{ string } to #{ @config['cheftacular']['location_aliases'][string] }") unless @options['quiet']
208
+
209
+ string = @config['cheftacular']['location_aliases'][string]
210
+ end
211
+
212
+ string
213
+ end
214
+
215
+ def parse_mode_into_command mode
216
+ case mode.split(':').first
217
+ when /display/ then 'cat'
218
+ when 'edit' then mode.split(':').last
219
+ when 'tail'
220
+ if mode.split(':').last == 'tail'
221
+ 'tail -500'
222
+ else
223
+ "tail -#{ mode.split(':').last }"
224
+ end
225
+ when 'tail-f' then 'tail -f'
226
+ else mode
227
+ end
228
+ end
204
229
  end
205
230
  end
@@ -46,7 +46,7 @@ class Cheftacular
46
46
 
47
47
  options, locs, ridley, logs_bag_hash, pass_bag_hash, bundle_command, cheftacular, passwords = set_local_instance_vars
48
48
 
49
- on ( db_primary_nodes.map { |n| "deploy@" + n.public_ipaddress } ) do |host|
49
+ on ( db_primary_nodes.map { |n| @config['cheftacular']['deploy_user'] + "@" + n.public_ipaddress } ) do |host|
50
50
  n = get_node_from_address(nodes, host.hostname)
51
51
 
52
52
  puts("Beginning db fetch_and_restore for #{ n.name } (#{ n.public_ipaddress }) for env #{ options['env'] }") unless options['quiet']
@@ -24,7 +24,7 @@ class Cheftacular
24
24
 
25
25
  options, locs, ridley, logs_bag_hash, pass_bag_hash, bundle_command, cheftacular, passwords = @config['helper'].set_local_instance_vars
26
26
 
27
- on ( nodes.map { |n| "deploy@" + n.public_ipaddress } ), in: :groups, limit: 5, wait: 2 do |host|
27
+ on ( nodes.map { |n| @config['cheftacular']['deploy_user'] + "@" + n.public_ipaddress } ), in: :groups, limit: 5, wait: 2 do |host|
28
28
  n = get_node_from_address(nodes, host.hostname)
29
29
 
30
30
  puts "Beginning disk report run for #{ n.name } (#{ n.public_ipaddress })"
@@ -0,0 +1,184 @@
1
+ class Cheftacular
2
+ class StatelessActionDocumentation
3
+ def file
4
+ @config['documentation']['stateless_action'] << [
5
+ "`cft file NODE_NAME LOCATION_ALIAS MODE FILE_NAME` interacts with a file on the remote server",
6
+
7
+ [
8
+ " 1. `LOCATION_ALIAS` will be parsed as a path if it has backslash characters. Otherwise it will be parsed from your " +
9
+ "location_aliases hash in your cheftacular.yml",
10
+
11
+ " 2. `FILE_NAME` is the actual name (can also be additional path to the file) of the file to be interacted with. If no " +
12
+ "value is passed or the file does not exist in the LOCATION_ALIAS, the command will return the entries in LOCATION_ALIAS",
13
+
14
+ " 1. *NOTE! If you plan to use FILE_NAME as a path, do prepend the path with a / character!*",
15
+
16
+ " 3. `MODE` can be `cat|display|edit|fetch|list|scp|tail|tail-f`.",
17
+
18
+ " 1. The default mode is display, this is what will be run at LOCATION_ALIAS for FILE_NAME if no MODE is passed.",
19
+
20
+ " 2. `cat|display` will attempt to display the FILE_NAME listed to your terminal.",
21
+
22
+ " 3. `edit:TEXT_EDITOR` will attempt to edit the file with the TEXT_EDITOR listed. NOTE! This editor must be installed " +
23
+ "on the node you're accessing. If the editor is not present via a `which` command, the cft file command will say so.",
24
+
25
+ " 4. `fetch|scp` will attempt to fetch the FILE_NAME listed via SCP. This file is saved to #{ @config['locs']['app-tmp'] } " +
26
+ "(based on your directory structure) under the same FILE_NAME as the remote file.",
27
+
28
+ " 1. The #{ @config['cheftacular']['deploy_user'] } must have access to said file without sudo!",
29
+
30
+ " 5. `list` the default behavior if the file does not exist. Otherwise must be manually called.",
31
+
32
+ " 6. `tail:NUMBER_OF_LINES` tails the file for the last `NUMBER_OF_LINES` lines, defaults to 500.",
33
+
34
+ " 7. `tail-f` enables continuous output of the file.",
35
+
36
+ " 4. `--save-to-file FILE_NAME option will save the output of `cat|display|tail` to a file on your local system instead of " +
37
+ "displaying the file to your terminal window.",
38
+
39
+ " 1. `--save-to-file FILE_PATH` can also be used in the `fetch` context to specify where exactly to save the file and " +
40
+ "what to name it as."
41
+ ]
42
+ ]
43
+
44
+ @config['documentation']['application'] << @config['documentation']['stateless_action'].last
45
+ end
46
+ end
47
+
48
+ class StatelessAction
49
+ def file location='', file_name='',mode=''
50
+ @options['node_name'] = ARGV[1] unless @options['node_name']
51
+ location = ARGV[2] if location.blank?
52
+ mode = ARGV[3] if mode.blank?
53
+ file_name = ARGV[4] if file_name.blank?
54
+
55
+ nodes = @config['error'].is_valid_node_name_option?
56
+
57
+ mode = 'display' if mode.nil?
58
+ mode = 'list' if file_name.nil? || file_name.blank?
59
+
60
+ interaction_mode = case mode.split(':').first
61
+ when 'cat' then 'sshkit'
62
+ when 'display' then 'sshkit'
63
+ when 'edit' then 'ssh'
64
+ when /fetch|scp/ then 'scp'
65
+ when 'list' then 'sshkit'
66
+ when 'tail' then 'sshkit'
67
+ when 'tail-f' then 'ssh'
68
+ else raise "Unsupported Mode for cft file: #{ mode }, "
69
+ end
70
+
71
+
72
+ location = @config['parser'].parse_location_alias(location)
73
+ command = @config['parser'].parse_mode_into_command(mode)
74
+
75
+ nodes = @config['parser'].exclude_nodes( nodes, [{ unless: { env: @options['env'] }}], true )
76
+
77
+ case interaction_mode
78
+ when 'sshkit' then file_sshkit_execute(nodes, command, location, file_name)
79
+ when 'ssh' then file_ssh_execute(nodes, mode, command, location, file_name)
80
+ when 'scp' then file_scp_execute(nodes, command, location, file_name)
81
+ end
82
+ end
83
+
84
+ private
85
+
86
+ def file_sshkit_execute nodes, command, location, file_name, exit_status=true
87
+ options, locs, ridley, logs_bag_hash, pass_bag_hash, bundle_command, cheftacular, passwords = @config['helper'].set_local_instance_vars
88
+
89
+ on ( nodes.map { |n| @config['cheftacular']['deploy_user'] + "@" + n.public_ipaddress } ) do |host|
90
+ n = get_node_from_address(nodes, host.hostname)
91
+
92
+ puts("Beginning run of \"file #{ command }\" for #{ n.name } (#{ n.public_ipaddress })") if command != 'check_existence' || options['quiet']
93
+
94
+ exit_status = start_command_run( n.name, n.public_ipaddress, options, locs, passwords, cheftacular, command, location, file_name)
95
+ end
96
+
97
+ exit_status
98
+ end
99
+
100
+ def file_ssh_execute nodes, mode, command, location, file_name
101
+ unless file_sshkit_execute( nodes, 'check_existence', location, file_name)
102
+ puts "Not executing #{ command } due to failing exit status..."
103
+
104
+ return false
105
+ end
106
+
107
+ nodes.each do |n|
108
+ target_loc = "#{ location }/#{ file_name }"
109
+ puts("Beginning #{ command } run on #{ target_loc } for #{ n.name } (#{ n.public_ipaddress })") unless @options['quiet']
110
+
111
+ sudo_mode = "#{ @config['helper'].sudo(n.public_ipaddress) }"
112
+ sudo_mode = '' if mode.split(':').first == 'edit'
113
+
114
+ `ssh -oStrictHostKeyChecking=no -tt #{ @config['cheftacular']['deploy_user'] }@#{ n.public_ipaddress } "#{ sudo_mode } #{ command } #{ target_loc }" > /dev/tty`
115
+ end
116
+ end
117
+
118
+ def file_scp_execute nodes, command, location, file_name
119
+ unless file_sshkit_execute( nodes, 'check_existence', location, file_name)
120
+ puts "Not executing #{ command } due to failing exit status..."
121
+
122
+ return false
123
+ end
124
+
125
+ nodes.each do |n|
126
+ target_loc = "#{ location }/#{ file_name }"
127
+ puts("Beginning #{ command } run on #{ target_loc } for #{ n.name } (#{ n.public_ipaddress })") unless @options['quiet']
128
+
129
+ download_location = @options['save_to_file'] ? @options['save_to_file'] : "#{ @config['locs']['chef-log'] }/#{ file_name }"
130
+
131
+ `scp -oStrictHostKeyChecking=no #{ @config['cheftacular']['deploy_user'] }@#{ n.public_ipaddress }:#{ location }/#{ file_name } #{ download_location } > /dev/tty`
132
+ end
133
+ end
134
+ end
135
+ end
136
+
137
+ module SSHKit
138
+ module Backend
139
+ class Netssh
140
+ def start_command_run name, ip_address, options, locs, passwords, cheftacular, command, location, file_name, out="", exit_status=true
141
+ log_loc, timestamp = set_log_loc_and_timestamp(locs)
142
+ run_list_command = command == 'list'
143
+ target_loc = "#{ location }/#{ file_name }"
144
+
145
+ if !sudo_test( passwords[ip_address], location ) #true if file exists
146
+ puts "#{ name } (#{ ip_address }) cannot run #{ command } as there is no directory at #{ location }!"
147
+
148
+ return false
149
+ end
150
+
151
+ if !run_list_command && !sudo_test( passwords[ip_address], target_loc ) #true if file exists
152
+ puts "#{ name } (#{ ip_address }) cannot run #{ command } as there is no file at #{ location }/#{ file_name }! Running list instead..."
153
+
154
+ exit_status = false
155
+
156
+ run_list_command = true
157
+ end
158
+
159
+ return exit_status if command == 'check_existence'
160
+
161
+ if run_list_command
162
+ out << sudo_capture( passwords[ip_address], :ls, '-al', location )
163
+ else
164
+ puts "Running #{ command } on #{ target_loc }"
165
+ out << sudo_capture( passwords[ip_address], command, target_loc)
166
+ end
167
+
168
+ if options['save_to_file']
169
+ out_location = "#{ log_loc }/#{ options['save_to_file'] }"
170
+
171
+ puts "Saving output of file at #{ out_location } }..."
172
+
173
+ ::File.open(out_location, "w") { |f| f.write(out) }
174
+ end
175
+
176
+ puts out.scrub_pretty_text unless options['save_to_file']
177
+
178
+ puts("Succeeded run of \"#{ command }\" for #{ name } (#{ ip_address })") unless run_list_command
179
+
180
+ exit_status
181
+ end
182
+ end
183
+ end
184
+ end
@@ -25,7 +25,7 @@ class Cheftacular
25
25
  options, locs, ridley, logs_bag_hash, pass_bag_hash, bundle_command, cheftacular, passwords = @config['helper'].set_local_instance_vars
26
26
 
27
27
  #on is namespaced to SSHKit::Backend::Netssh.on
28
- on ( nodes.map { |n| "deploy@" + n.public_ipaddress } ) do |host|
28
+ on ( nodes.map { |n| @config['cheftacular']['deploy_user'] + "@" + n.public_ipaddress } ) do |host|
29
29
  n = get_node_from_address(nodes, host.hostname)
30
30
 
31
31
  puts("Beginning haproxy log generation run for #{ n.name } (#{ n.public_ipaddress })") unless options['quiet']
@@ -30,7 +30,7 @@ class Cheftacular
30
30
  options, locs, ridley, logs_bag_hash, pass_bag_hash, bundle_command, cheftacular, passwords = @config['helper'].set_local_instance_vars
31
31
 
32
32
  #on is namespaced to SSHKit::Backend::Netssh.on
33
- on ( nodes.map { |n| "deploy@" + n.public_ipaddress } ) do |host|
33
+ on ( nodes.map { |n| @config['cheftacular']['deploy_user'] + "@" + n.public_ipaddress } ) do |host|
34
34
  n = get_node_from_address(nodes, host.hostname)
35
35
 
36
36
  puts("Beginning shorewall log capture run for #{ n.name } (#{ n.public_ipaddress })") unless options['quiet']
@@ -15,13 +15,7 @@ class Cheftacular
15
15
  def pass
16
16
  @options['node_name'] = ARGV[1] unless @options['node_name']
17
17
 
18
- raise "Too few arguments, please supply a node name" if ARGV.length < 2
19
-
20
- nodes = @config['getter'].get_true_node_objects(true)
21
-
22
- nodes = @config['parser'].exclude_nodes( nodes, [{ if: { not_node: @options["node_name"] } }], true )
23
-
24
- raise "Node not found for #{ @options['node_name'] }" if nodes.empty?
18
+ nodes = @config['error'].is_valid_node_name_option?
25
19
 
26
20
  if nodes.first.chef_environment != @options['env']
27
21
  @config['initializer'].initialize_data_bags_for_environment nodes.first.chef_environment, false, ['server_passwords']
@@ -27,7 +27,7 @@ class Cheftacular
27
27
  #this must always precede on () calls so they have the instance variables they need
28
28
  options, locs, ridley, logs_bag_hash, pass_bag_hash, bundle_command, cheftacular, passwords = @config['helper'].set_local_instance_vars
29
29
 
30
- on ( primary_nodes.map { |n| "deploy@" + n.public_ipaddress } ) do |host|
30
+ on ( primary_nodes.map { |n| @config['cheftacular']['deploy_user'] + "@" + n.public_ipaddress } ) do |host|
31
31
  n = get_node_from_address(nodes, host.hostname)
32
32
 
33
33
  puts "Beginning replication status report run for #{ n.name } (#{ n.public_ipaddress })"
@@ -37,7 +37,7 @@ class Cheftacular
37
37
  rep_status_hash[n.name] = start_replication_report( n.name, n.public_ipaddress, options, locs, passwords)
38
38
  end
39
39
 
40
- on ( slave_nodes.map { |n| "deploy@" + n.public_ipaddress } ) do |host|
40
+ on ( slave_nodes.map { |n| @config['cheftacular']['deploy_user'] + "@" + n.public_ipaddress } ) do |host|
41
41
  n = get_node_from_address(nodes, host.hostname)
42
42
 
43
43
  puts "Beginning slave replication status report run for #{ n.name } (#{ n.public_ipaddress })"
@@ -23,7 +23,7 @@ class Cheftacular
23
23
  #this must always precede on () calls so they have the instance variables they need
24
24
  options, locs, ridley, logs_bag_hash, pass_bag_hash, bundle_command, cheftacular, passwords = @config['helper'].set_local_instance_vars
25
25
 
26
- on ( nodes.map { |n| "deploy@" + n.public_ipaddress } ), in: :groups, limit: 5, wait: 2 do |host|
26
+ on ( nodes.map { |n| @config['cheftacular']['deploy_user'] + "@" + n.public_ipaddress } ), in: :groups, limit: 5, wait: 2 do |host|
27
27
  n = get_node_from_address(nodes, host.hostname)
28
28
 
29
29
  puts "Beginning swap restart run for #{ n.name } (#{ n.public_ipaddress })"
@@ -65,7 +65,7 @@ class Cheftacular
65
65
 
66
66
  options, locs, ridley, logs_bag_hash, pass_bag_hash, bundle_command, cheftacular, passwords = @config['helper'].set_local_instance_vars
67
67
 
68
- on ( nodes.map { |n| "deploy@" + n.public_ipaddress } ), in: :groups, limit: 5, wait: 2 do |host|
68
+ on ( nodes.map { |n| @config['cheftacular']['deploy_user'] + "@" + n.public_ipaddress } ), in: :groups, limit: 5, wait: 2 do |host|
69
69
  n = get_node_from_address(nodes, host.hostname)
70
70
 
71
71
  puts "Beginning run of \"rvm #{ command }\" for #{ n.name } (#{ n.public_ipaddress })"
@@ -38,7 +38,7 @@ class Cheftacular
38
38
  #this must always precede on () calls so they have the instance variables they need
39
39
  options, locs, ridley, logs_bag_hash, pass_bag_hash, bundle_command, cheftacular, passwords = @config['helper'].set_local_instance_vars
40
40
 
41
- on ( nodes.map { |n| "deploy@" + n.public_ipaddress } ), in: :groups, limit: 5, wait: 5 do |host|
41
+ on ( nodes.map { |n| @config['cheftacular']['deploy_user'] + "@" + n.public_ipaddress } ), in: :groups, limit: 5, wait: 5 do |host|
42
42
  n = get_node_from_address(nodes, host.hostname)
43
43
 
44
44
  puts "Beginning apt-get run for #{ n.name } (#{ n.public_ipaddress })"
@@ -48,7 +48,7 @@ class Cheftacular
48
48
  logs_bag_hash["#{ n.name }-upgrade"] = { text: log_data.scrub_pretty_text, timestamp: timestamp }
49
49
  end
50
50
 
51
- on ( nodes.map { |n| "deploy@" + n.public_ipaddress } ), in: :groups, limit: 5, wait: 120 do |host|
51
+ on ( nodes.map { |n| @config['cheftacular']['deploy_user'] + "@" + n.public_ipaddress } ), in: :groups, limit: 5, wait: 120 do |host|
52
52
  n = get_node_from_address(nodes, host.hostname)
53
53
 
54
54
  puts "Beginning restart run for #{ n.name } (#{ n.public_ipaddress })"
@@ -41,7 +41,7 @@ class Cheftacular
41
41
 
42
42
  options, locs, ridley, logs_bag_hash, pass_bag_hash, bundle_command, cheftacular, passwords = @config['helper'].set_local_instance_vars
43
43
 
44
- on ( nodes.map { |n| "deploy@" + n.public_ipaddress } ) do |host|
44
+ on ( nodes.map { |n| @config['cheftacular']['deploy_user'] + "@" + n.public_ipaddress } ) do |host|
45
45
  n = get_node_from_address(nodes, host.hostname)
46
46
 
47
47
  puts "Beginning run of \"service #{ command }\" for #{ n.name } (#{ n.public_ipaddress })"
@@ -1,5 +1,5 @@
1
1
  class Cheftacular
2
2
  #major_version.minor_version.bugfixes
3
- VERSION = "2.4.1"
3
+ VERSION = "2.5.0"
4
4
  RUBY_VERSION = "2.2.2"
5
5
  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.1
4
+ version: 2.5.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-06-17 00:00:00.000000000 Z
11
+ date: 2015-06-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hashie
@@ -241,6 +241,7 @@ files:
241
241
  - lib/cheftacular/decryptor.rb
242
242
  - lib/cheftacular/dns.rb
243
243
  - lib/cheftacular/encryptor.rb
244
+ - lib/cheftacular/error.rb
244
245
  - lib/cheftacular/getter.rb
245
246
  - lib/cheftacular/helper.rb
246
247
  - lib/cheftacular/initializer.rb
@@ -255,9 +256,7 @@ files:
255
256
  - lib/cheftacular/stateless_actions/bootstrappers/redhat_bootstrap.rb
256
257
  - lib/cheftacular/stateless_actions/bootstrappers/ubuntu_bootstrap.rb
257
258
  - lib/cheftacular/stateless_actions/bootstrappers/vyatta_bootstrap.rb
258
- - lib/cheftacular/stateless_actions/check_cheftacular_settings.rb
259
259
  - lib/cheftacular/stateless_actions/chef_bootstrap.rb
260
- - lib/cheftacular/stateless_actions/chef_environment.rb
261
260
  - lib/cheftacular/stateless_actions/clean_cookbooks.rb
262
261
  - lib/cheftacular/stateless_actions/clean_sensu_plugins.rb
263
262
  - lib/cheftacular/stateless_actions/clean_server_passwords.rb
@@ -270,7 +269,7 @@ files:
270
269
  - lib/cheftacular/stateless_actions/create_git_key.rb
271
270
  - lib/cheftacular/stateless_actions/disk_report.rb
272
271
  - lib/cheftacular/stateless_actions/environment.rb
273
- - lib/cheftacular/stateless_actions/fetch_file.rb
272
+ - lib/cheftacular/stateless_actions/file.rb
274
273
  - lib/cheftacular/stateless_actions/fix_known_hosts.rb
275
274
  - lib/cheftacular/stateless_actions/full_bootstrap.rb
276
275
  - lib/cheftacular/stateless_actions/get_active_ssh_connections.rb
@@ -1,14 +0,0 @@
1
- #interact with an rvm installation on servers
2
- class Cheftacular
3
- class StatelessActionDocumentation
4
- def check_cheftacular_settings
5
- #TODO
6
- end
7
- end
8
-
9
- class StatelessAction
10
- def check_cheftacular_settings
11
- raise "Not Yet Implemented"
12
- end
13
- end
14
- end
@@ -1,21 +0,0 @@
1
- class Cheftacular
2
- class StatelessActionDocumentation
3
- def chef_environment
4
- @config['documentation']['stateless_action'] << [
5
- "[NYI]`cft chef_environment ENVIRONMENT_NAME [create|destroy]` will allow you to interact with chef environments on the chef server.",
6
-
7
- [
8
- " 1. `create` will create an environment if it does not exist.",
9
-
10
- " 2. `destroy` will destroy a chef environment *IF IT HAS NO NODES*"
11
- ]
12
- ]
13
- end
14
- end
15
-
16
- class StatelessAction
17
- def chef_environment
18
- raise "Not yet Implemented"
19
- end
20
- end
21
- end
@@ -1,24 +0,0 @@
1
- class Cheftacular
2
- class StatelessActionDocumentation
3
- def fetch_file
4
- @config['documentation']['stateless_action'] << [
5
- "[NYI]`cft fetch_file NODE_NAME LOCATION_ALIAS FILE_NAME` fetches a file from the remote node. ",
6
-
7
- [
8
- " 1. `LOCATION_ALIAS` will be parsed as a path if it has backslash characters. Otherwise it will be parsed from your " +
9
- "location_aliases hash in your cheftacular.yml",
10
-
11
- " 2. `FILE_NAME` is the actual name of the file to be fetched. If no value is passed or the file does not exist in the " +
12
- "LOCATION_ALIAS, the command will return the entries in LOCATION_ALIAS"
13
- ]
14
- ]
15
- end
16
- end
17
-
18
- class StatelessAction
19
- def fetch_file out=[]
20
- #TODO
21
- raise "Not yet implemented"
22
- end
23
- end
24
- end