cheftacular 2.0.9 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/lib/cheftacular/README.md +85 -119
  3. data/lib/cheftacular/actions/check.rb +20 -0
  4. data/lib/cheftacular/actions/console.rb +6 -0
  5. data/lib/cheftacular/actions/db_console.rb +6 -0
  6. data/lib/cheftacular/actions/deploy.rb +26 -0
  7. data/lib/cheftacular/actions/log.rb +93 -0
  8. data/lib/cheftacular/actions/migrate.rb +6 -0
  9. data/lib/cheftacular/actions/run.rb +6 -0
  10. data/lib/cheftacular/cheftacular.rb +1 -0
  11. data/lib/cheftacular/initializers.rb +3 -1
  12. data/lib/cheftacular/parsers.rb +1 -1
  13. data/lib/cheftacular/stateless_actions/arguments.rb +0 -2
  14. data/lib/cheftacular/stateless_actions/bootstrappers/ubuntu_bootstrap.rb +1 -1
  15. data/lib/cheftacular/stateless_actions/check_cheftacular_settings.rb +14 -0
  16. data/lib/cheftacular/stateless_actions/chef_environment.rb +3 -3
  17. data/lib/cheftacular/stateless_actions/clean_sensu_plugins.rb +1 -1
  18. data/lib/cheftacular/stateless_actions/create_git_key.rb +0 -2
  19. data/lib/cheftacular/stateless_actions/fetch_file.rb +1 -1
  20. data/lib/cheftacular/stateless_actions/fix_known_hosts.rb +5 -6
  21. data/lib/cheftacular/stateless_actions/get_log_from_bag.rb +2 -2
  22. data/lib/cheftacular/stateless_actions/initialize_data_bag_contents.rb +5 -1
  23. data/lib/cheftacular/stateless_actions/restart_swap.rb +1 -1
  24. data/lib/cheftacular/stateless_actions/rvm.rb +102 -2
  25. data/lib/cheftacular/stateless_actions/slack.rb +19 -0
  26. data/lib/cheftacular/version.rb +1 -1
  27. metadata +6 -21
  28. data/lib/sshkit/actions/start_commit_check.rb +0 -19
  29. data/lib/sshkit/actions/start_deploy.rb +0 -25
  30. data/lib/sshkit/actions/start_log_fetch.rb +0 -92
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d6bbcc9b49ccea06cffbadf482636abbcf5d0b81
4
- data.tar.gz: 2adea39bed590fa3c8686f9c67bac5bbbc15a80f
3
+ metadata.gz: 928f8a004cb74ca10ecca90795caecf6c8bd8af4
4
+ data.tar.gz: e0bcd6f10d0f059c3f852878a3015026bc694152
5
5
  SHA512:
6
- metadata.gz: 18a34f6bb716457ab1a58b80486a9a3fdec88c19a2c8a4e14a1bfc157fd54e3e8a10a52c243dd836acf27dcc5d68469be3268793d62607cf9f999f6527a67ae0
7
- data.tar.gz: 31e896eff9f50e9ae65605dbc4e6d6be29437e275274f5ed8f80c31d5c9c88ee693a7f1bf42e2388b91d82c1aac68937d4b0924ebd5ba8b618f30036675979f7
6
+ metadata.gz: 6cdf8e3448ba4eb57f483f68edf18c20567607402ba3c88f47df410745d836e778b5555a441b5e187dd002572e89a37ff68a72023b35d4d68478d4c377702b7a
7
+ data.tar.gz: 87eefe7516479d2535131ac24e0c5efac2147cab265440c105b2b38ffecb1221064721776f89980f5eb95f99ac291cbeb3ef53ab1d9d277075011b9cd0fff6ac
@@ -1,64 +1,12 @@
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
- ## Arguments and flags for cheftacular
11
-
12
- ### Environment flags
13
-
14
- 1. `-d|--dev-remote` toggles on dev-remote mode. Commands passed to cft will hit the devremote server(s) instead of the default server(s)
15
-
16
- 2. `--env ENV` sets the environment commands hit to one you specify instead of the default one.
17
-
18
- 3. `-p|--prod` toggles on production mode. Commands passed to cft will hit the production server(s) instead of the default server(s)
19
-
20
- 4. `-Q|--qa` toggles on QA mode. Commands passed to cft will hit the QA server(s) instead of the default server(s)
21
-
22
- 5. `-s|--staging` toggles on staging mode. Commands passed to cft will hit the staging server(s) instead of the default server(s)
23
-
24
- 6. `--split-env SPLIT_ENV_NAME` sets the sub-environment to SPLIT_ENV_NAME. This only slightly affects certain commands.
25
-
26
- 7. `-t|--test` toggles on test mode. Commands passed to cft will hit the test server(s) instead of the default server(s)
27
-
28
- ### General Flags
29
-
30
- 1. `-a|--address ADDRESS` will force the command to only run against the specified address if it belongs to a node
31
-
32
- 2. `-D|--debug` toggles on extremely verbose logging. Chef-client runs will generate ~10 times the amounts of logs including any additional effects that the `-v` flag will activate
33
-
34
- 3. `--no-logs` will make the cft commands not generate log files, you must still specify `-v` if you want output of most verbose commands to your terminal.
35
-
36
- 4. `-n|--node-name NODE_NAME` will force the command to only run against the specified name if it belongs to a node
37
-
38
- 5. `-q|--quiet` will make the cft commands only output information that is a direct result of the command being run
39
-
40
- 6. `-r|--role-name ROLE_NAME` will force the command to only run against the specified role if it exists (this argument is generally not needed though it can be used to deploy a codebase for an application you're not currently cd'd into when running this as a gem)
41
-
42
- 7. `-R|--repository NAME` will make the command run against a specific repository or context (automatically set for application mode)
43
-
44
- 8. `-v|--verbose` toggles on verbose logging. All commands that write logs will also output to terminal AND write the logs.
45
-
46
- ### Help Related
47
-
48
- 1. `-h|--help` Displays the full readme and exits.
49
-
50
- ### Action Flags
51
-
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
-
54
- 2. `-z|--unset-revision` will unset a custom revision specified in the arg below and make the codebase utilize the default (staging branch for staging and master for production)
55
-
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
-
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
-
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
10
  ## Arguments and flags for cheftacular
63
11
 
64
12
  ### Environment flags
@@ -118,13 +66,7 @@
118
66
 
119
67
  2. `cft check` Checks the commits for all servers for a repository (for an environment) and returns them in a simple chart. Also shows when these commits were deployed to the server.
120
68
 
121
- 3. `cft chef_environment ENVIRONMENT_NAME [create|destroy]` will allow you to interact with chef environments on the chef server.
122
-
123
- 1. `create` will create an environment if it does not exist.
124
-
125
- 2. `destroy` will destroy a chef environment *IF IT HAS NO NODES*
126
-
127
- 4. `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.
69
+ 3. `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.
128
70
 
129
71
  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.
130
72
 
@@ -132,19 +74,19 @@
132
74
 
133
75
  3. This command is aliased to `client-list` with no arguments or cft prefix.
134
76
 
135
- 5. `cft console` will create a pry session on the first node found for a codebase.
77
+ 4. `cft console` will create a pry session on the first node found for a codebase.
136
78
 
137
- 6. `cft db_console` will create a database console session on the first node found for a database stack in the current environment.
79
+ 5. `cft db_console` will create a database console session on the first node found for a database stack in the current environment.
138
80
 
139
81
  1. This command is aliased to psql, typing `cft psql` will drop you into a rails stack database psql session.
140
82
 
141
- 7. `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.
83
+ 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.
142
84
 
143
85
  1. This command also restarts services on the server and updates the code. Changes behavior slightly with the `-z|-Z` args.
144
86
 
145
- 8. `cft disk_report` will fetch useful statistics from every server for every environment and output it into your log directory.
87
+ 7. `cft disk_report` will fetch useful statistics from every server for every environment and output it into your log directory.
146
88
 
147
- 9. `cft environment boot|destroy` will boot / destroy the current environment
89
+ 8. `cft environment boot|destroy` will boot / destroy the current environment
148
90
 
149
91
  1. `boot` will spin up servers and bring them to a stable state. This includes setting up their subdomains for the target environment.
150
92
 
@@ -152,23 +94,23 @@
152
94
 
153
95
  3. This command will prompt when attempting to destroy servers in staging or production
154
96
 
155
- 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)
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)
156
98
 
157
99
  1. Passing in a hostname will make the command only remove entries with that hostname / ip specifically
158
100
 
159
- 11. `cft get_active_ssh_connections` will fetch the active ssh connections from every server and output it into your log directory.
101
+ 10. `cft get_active_ssh_connections` will fetch the active ssh connections from every server and output it into your log directory.
160
102
 
161
- 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.
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.
162
104
 
163
105
  1. In devops mode, this command will not do anything without the -R repository passed.
164
106
 
165
- 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.
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.
166
108
 
167
- 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.
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.
168
110
 
169
- 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.
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.
170
112
 
171
- 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
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
172
114
 
173
115
  1. `--nginx` will fetch the nginx logs as well as the application logs
174
116
 
@@ -180,15 +122,15 @@
180
122
 
181
123
  4. `--fetch-backup` If doing a pg_data log, this will fetch the latest logs from the pg_data log directory for each database.
182
124
 
183
- 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.
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.
184
126
 
185
- 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
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
186
128
 
187
- 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.
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.
188
130
 
189
- 20. `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
131
+ 19. `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
190
132
 
191
- 21. `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.
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.
192
134
 
193
135
  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.
194
136
 
@@ -198,11 +140,11 @@
198
140
 
199
141
  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"`
200
142
 
201
- 22. `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.
143
+ 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.
202
144
 
203
145
  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.
204
146
 
205
- 23. `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
147
+ 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
206
148
 
207
149
  1. pass `-n NODE_NAME` to grab the output of a node other than the first.
208
150
 
@@ -211,23 +153,35 @@
211
153
 
212
154
  ## Commands that can ONLY be run in the devops context
213
155
 
214
- 1. `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.
156
+ 1. [NYI]`cft chef_environment ENVIRONMENT_NAME [create|destroy]` will allow you to interact with chef environments on the chef server.
157
+
158
+ 1. `create` will create an environment if it does not exist.
159
+
160
+ 2. `destroy` will destroy a chef environment *IF IT HAS NO NODES*
161
+
162
+ 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.
163
+
164
+ 3. [NYI]`cft fetch_file NODE_NAME LOCATION_ALIAS FILE_NAME` fetches a file from the remote node.
165
+
166
+ 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
167
+
168
+ 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
169
+
170
+ 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.
215
171
 
216
172
  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.
217
173
 
218
- 2. `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
174
+ 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
219
175
 
220
- 3. `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.
176
+ 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.
221
177
 
222
- 4. `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).
178
+ 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).
223
179
 
224
180
  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.
225
181
 
226
182
  2. If you would like to remove all the cookbooks on the chef server, run `knife cookbook bulk delete '.*' -p -c ~/.chef/knife.rb`
227
183
 
228
- 5. `cft clean_sensu_plugins` [NYI] 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.
229
-
230
- 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.
184
+ 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.
231
185
 
232
186
  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.
233
187
 
@@ -235,7 +189,7 @@
235
189
 
236
190
  3. This command is aliased to `client-list` with no arguments or cft prefix.
237
191
 
238
- 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.
192
+ 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.
239
193
 
240
194
  1. `domain` 1st level argument for interacting with cloud domains
241
195
 
@@ -307,7 +261,7 @@
307
261
 
308
262
  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.
309
263
 
310
- 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)
264
+ 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)
311
265
 
312
266
  1. If no DOMAIN_NAME is supplied it will use the node's NODE_NAME (IE: api01.example-staging.com)
313
267
 
@@ -317,19 +271,19 @@
317
271
 
318
272
  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]"
319
273
 
320
- 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.
274
+ 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.
321
275
 
322
- 10. `cft compile_readme` compiles all documentation methods and creates a README.md file in the log folder of the application.
276
+ 12. `cft compile_readme` compiles all documentation methods and creates a README.md file in the log folder of the application.
323
277
 
324
- 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.
278
+ 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.
325
279
 
326
280
  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.
327
281
 
328
282
  2. `OAUTH_TOKEN` *must* be generated by logging into github and generating an access token in the account settings -> applications -> personal access tokens
329
283
 
330
- 12. `cft disk_report` will fetch useful statistics from every server for every environment and output it into your log directory.
284
+ 14. `cft disk_report` will fetch useful statistics from every server for every environment and output it into your log directory.
331
285
 
332
- 13. `cft environment boot|destroy` will boot / destroy the current environment
286
+ 15. `cft environment boot|destroy` will boot / destroy the current environment
333
287
 
334
288
  1. `boot` will spin up servers and bring them to a stable state. This includes setting up their subdomains for the target environment.
335
289
 
@@ -337,47 +291,59 @@
337
291
 
338
292
  3. This command will prompt when attempting to destroy servers in staging or production
339
293
 
340
- 14. `cft fetch_file NODE_NAME LOCATION_ALIAS FILE_NAME` fetches a file from the remote node.
341
-
342
- 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
343
-
344
- 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
345
-
346
- 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)
294
+ 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)
347
295
 
348
296
  1. Passing in a hostname will make the command only remove entries with that hostname / ip specifically
349
297
 
350
- 16. `cft full_bootstrap ADDRESS ROOT_PASS NODE_NAME` This command performs both ubuntu_bootstrap and chef_bootstrap.
298
+ 17. `cft full_bootstrap ADDRESS ROOT_PASS NODE_NAME` This command performs both ubuntu_bootstrap and chef_bootstrap.
351
299
 
352
- 17. `cft get_active_ssh_connections` will fetch the active ssh connections from every server and output it into your log directory.
300
+ 18. `cft get_active_ssh_connections` will fetch the active ssh connections from every server and output it into your log directory.
353
301
 
354
- 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.
302
+ 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.
355
303
 
356
304
  1. In devops mode, this command will not do anything without the -R repository passed.
357
305
 
358
- 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.
306
+ 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.
359
307
 
360
- 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.
308
+ 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.
361
309
 
362
- 21. `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.
310
+ 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.
363
311
 
364
- 22. `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.
312
+ 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.
365
313
 
366
- 23. `cft knife_upload` will resync the chef-server with the local chef-repo code. This command is analog for `knife upload /`
314
+ 24. `cft knife_upload` will resync the chef-server with the local chef-repo code. This command is analog for `knife upload /`
367
315
 
368
- 24. `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
316
+ 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
369
317
 
370
- 25. `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.
318
+ 26. `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.
371
319
 
372
- 26. `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 `hip disk_report`
320
+ 27. `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`
373
321
 
374
322
  1. There is no risk in running this command. Sometimes swap doesnt reactivate if the server was rebooted and this command fixes that.
375
323
 
376
- 27. `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.
324
+ 28. `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
+
326
+ 1. When no commands are passed, rvm will just run `rvm list` on each server on all servers in the current environment.
327
+
328
+ 2. When `list|list_rubies` is passed, rvm will run `rvm list rubies` on all servers in the current environment.
329
+
330
+ 3. When `install RUBY_TO_INSTALL` is passed, rvm will attempt to install that ruby on each system in the current environment. It is a good idea to use strings like ruby-2.2.1
331
+
332
+ 4. `run [RVM_COMMANDS]+` will run the rest of the arguments as a complete rvm command. An example of this being `cft rvm run gemset update`. This will run on all servers in the current environment.
333
+
334
+ 5. `all_environments [RVM_COMMANDS]+` will run the rest of the arguments as a complete rvm command *on all of the servers in every environment*.
335
+
336
+ 6. `test [RVM_COMMANDS]+` will run the rest of the arguments as a complete rvm command with scoping. By default, rvm commands run against all servers in the environment but with test you can pass -n NODE_NAME or -r ROLE_NAME flags to scope the servers the rvm command will be run on. Useful for testing.
337
+
338
+ 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
+
340
+ 29. `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.
377
341
 
378
342
  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.
379
343
 
380
- 28. `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
344
+ 30. `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.
345
+
346
+ 31. `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
381
347
 
382
348
  1. TARGET_ENV changes functionality depending on the overall (like staging / production) environment
383
349
 
@@ -387,9 +353,9 @@
387
353
 
388
354
  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
389
355
 
390
- 29. `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.
356
+ 32. `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.
391
357
 
392
- 30. `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.
358
+ 33. `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.
393
359
 
394
360
  1. Repository must be set with `-R REPOSITORY_NAME` for this command to work.
395
361
 
@@ -399,9 +365,9 @@
399
365
 
400
366
  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.
401
367
 
402
- 31. `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.
368
+ 34. `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.
403
369
 
404
- 32. `cft upload_nodes` This command will resync the chef server's nodes with the data in our chef-repo/node_roles.
370
+ 35. `cft upload_nodes` This command will resync the chef server's nodes with the data in our chef-repo/node_roles.
405
371
 
406
372
  1. This command changes behavior depending on several factors about both your mode and the state of your environment
407
373
 
@@ -413,4 +379,4 @@
413
379
 
414
380
  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.
415
381
 
416
- 33. `cft upload_roles` This command will resync the chef server's roles with the data in the chef-repo/roles.
382
+ 36. `cft upload_roles` This command will resync the chef server's roles with the data in the chef-repo/roles.
@@ -30,3 +30,23 @@ class Cheftacular
30
30
  end
31
31
  end
32
32
  end
33
+
34
+ module SSHKit
35
+ module Backend
36
+ class Netssh
37
+ def start_commit_check name, ip_address, options, locs, cheftacular, out={'name'=>'', 'time'=> ''}
38
+ app_loc = "#{ cheftacular['base_file_path'] }/#{ options['repository'] }/releases"
39
+
40
+ if test("[ -d #{ app_loc } ]") #true if file exists
41
+ within app_loc do
42
+ out['name'] = capture( :ls, '-rt', :|, :tail, '-1' )
43
+
44
+ out['time'] = Time.parse(capture( :stat, out['name'], '--printf=%y' )).strftime('%Y-%m-%d %I:%M:%S %p')
45
+ end
46
+ end
47
+
48
+ out
49
+ end
50
+ end
51
+ end
52
+ end
@@ -58,5 +58,11 @@ class Cheftacular
58
58
  def start_console_all
59
59
  raise "Not yet implemented"
60
60
  end
61
+
62
+ def console_
63
+ puts "Console method tried to create a console for the role \"#{ @options['role'] }\" but it doesn't appear to have a repository set! Skipping..."
64
+
65
+ return false
66
+ end
61
67
  end
62
68
  end
@@ -42,6 +42,12 @@ class Cheftacular
42
42
  raise "You attempted to create a database console for a role that had no database type attached to it, this is not possible."
43
43
  end
44
44
 
45
+ def db_console_
46
+ puts "db_console method tried to create a db_console for the role \"#{ @options['role'] }\" but it doesn't appear to have a repository set! Skipping..."
47
+
48
+ return false
49
+ end
50
+
45
51
  alias_method :psql, :db_console_postgresql
46
52
 
47
53
  private
@@ -38,3 +38,29 @@ class Cheftacular
38
38
  end
39
39
  end
40
40
  end
41
+
42
+ module SSHKit
43
+ module Backend
44
+ class Netssh
45
+ def start_deploy name, ip_address, options, locs, passwords, out=""
46
+ log_loc, timestamp = set_log_loc_and_timestamp(locs)
47
+
48
+ puts "Generating log file for #{ name } (#{ ip_address }) at #{ log_loc }/deploy/#{ name }-deploy-#{ timestamp }.txt"
49
+
50
+ capture_args = [ "chef-client" ]
51
+ capture_args << [ '-l', 'debug' ] if options['debug']
52
+ #capture_args << [ '>', '/dev/tty']
53
+
54
+ out << sudo_capture( passwords[ip_address], *capture_args.flatten )
55
+
56
+ ::File.open("#{ log_loc }/deploy/#{ name }-deploy-#{ timestamp }.txt", "w") { |f| f.write(out.scrub_pretty_text) } unless options['no_logs']
57
+
58
+ puts(out) if options['output'] || options['verbose']
59
+
60
+ puts "Succeeded deploy of #{ name } (#{ ip_address }) on role #{ options['role'] }"
61
+
62
+ [out, timestamp] #return out to send to logs_bag
63
+ end
64
+ end
65
+ end
66
+ end
@@ -45,3 +45,96 @@ class Cheftacular
45
45
  end
46
46
  end
47
47
  end
48
+
49
+ module SSHKit
50
+ module Backend
51
+ class Netssh
52
+ def start_log_role_map name, ip_address, target_log_loc, options, locs, cheftacular, passwords, out=""
53
+ log_loc, timestamp = set_log_loc_and_timestamp(locs)
54
+ log_cmnd, log_lines = get_log_command_and_lines(options)
55
+
56
+
57
+ puts "Fetching log file(s) for #{ name } (#{ ip_address }). Outputting to #{ log_loc }/rolelog with timestamp: #{ timestamp }"
58
+
59
+ target_log_loc.split(',').each do |parsed_log_loc|
60
+ parsed_log_loc = parsed_log_loc.gsub('|current_repo_location|', "#{ cheftacular['base_file_path'] }/#{ options['repository'] }/current")
61
+
62
+ if parsed_log_loc != '/var/log/syslog' && !test("[ -e #{ parsed_log_loc }]") #true if file exists ()
63
+ puts "#{ name } (#{ ip_address }) does not have a #{ parsed_log_loc } log file for #{ options['env'] } at the moment..."
64
+ else
65
+ if log_lines.nil?
66
+ out << sudo_capture(passwords[ip_address], log_cmnd.to_sym, parsed_log_loc)
67
+
68
+ else
69
+ out << sudo_capture(passwords[ip_address], log_cmnd.to_sym, log_lines, parsed_log_loc)
70
+ end
71
+
72
+ ::File.open("#{ log_loc }/rolelog/#{ name }-#{ parsed_log_loc.split('/').last.split('.').first }-#{ timestamp }.txt", "w") { |f| f.write(out.scrub_pretty_text) } unless options['no_logs']
73
+ end
74
+ end
75
+ end
76
+
77
+ def start_log_fetch_ruby_on_rails name, ip_address, run_list, options, locs, cheftacular, passwords, out=""
78
+ log_loc, timestamp = set_log_loc_and_timestamp(locs)
79
+ true_env = get_true_environment run_list, cheftacular['run_list_environments'], options['env']
80
+ app_log_loc = "#{ cheftacular['base_file_path'] }/#{ options['repository'] }/current/log"
81
+ log_cmnd, log_lines = get_log_command_and_lines(options)
82
+
83
+ if !test("[ -e /#{ app_log_loc }/#{ true_env }.log ]") #true if file exists
84
+ puts "#{ name } (#{ ip_address }) does not have a log file for #{ true_env } at the moment..."
85
+
86
+ else
87
+
88
+ puts "Fetching log file(s) for #{ name } (#{ ip_address }). Outputting to #{ log_loc }/applog/#{ name }-applog-#{ timestamp }.txt"
89
+
90
+ within app_log_loc do
91
+ if log_lines.nil?
92
+ out << capture(log_cmnd.to_sym, "#{ true_env }.log")
93
+
94
+ else
95
+ out << capture(log_cmnd.to_sym, log_lines, "#{ true_env }.log")
96
+ end
97
+ end
98
+
99
+ #To create the file locally you must namespace like this
100
+ ::File.open("#{ log_loc }/applog/#{ name }-applog-#{ timestamp }.txt", "w") { |f| f.write(out.scrub_pretty_text) } unless options['no_logs']
101
+ end
102
+
103
+ out << start_log_fetch_nginx(name, log_loc, log_cmnd, timestamp, options, out) if run_list.include?('role[web]') && options['get_nginx_logs']
104
+
105
+ out << start_log_role_map(name, ip_address, get_role_map(cheftacular, get_worker_role(cheftacular))['log_location'], log_cmnd, app_log_loc, timestamp, options) if run_list.include?("role[#{ get_worker_role(cheftacular) }]")
106
+
107
+ puts(out) if options['verbose']
108
+ end
109
+
110
+ def start_log_fetch_nginx name, log_loc, log_cmnd, timestamp, options, out=""
111
+ out = "" unless options['no_logs']
112
+
113
+ nginx_log_loc = "/var/log/nginx/#{ options['repository'] }_access.log"
114
+
115
+ puts "Fetching nginx log file... Outputting to #{ log_loc }/applog/#{ name }-nginxlog-#{ timestamp }.txt "
116
+
117
+ if log_lines.nil?
118
+ out << capture(log_cmnd.to_sym, nginx_log_loc)
119
+
120
+ else
121
+ out << capture(log_cmnd.to_sym, log_lines, nginx_log_loc)
122
+ end
123
+
124
+ ::File.open("#{ log_loc }/applog/#{ name }-nginxlog-#{ timestamp }.txt", "w") { |f| f.write(out.scrub_pretty_text) } unless options['no_logs']
125
+
126
+ out
127
+ end
128
+
129
+ private
130
+
131
+ def get_log_command_and_lines options
132
+ log_cmnd = options['get_full_logs'] ? 'cat' : 'tail'
133
+
134
+ log_lines = options['get_full_logs'] ? nil : "-" + ( options['get_log_lines'] ? options['get_log_lines'] : "500" )
135
+
136
+ [log_cmnd, log_lines]
137
+ end
138
+ end
139
+ end
140
+ end
@@ -53,5 +53,11 @@ class Cheftacular
53
53
  def migrate_all nodes=[]
54
54
  raise "You attempted to migrate the all role, this is not possible."
55
55
  end
56
+
57
+ def migrate_ nodes=[]
58
+ puts "Migrate method tried to migrate the role \"#{ @options['role'] }\" but it doesn't appear to have a repository set! Skipping..."
59
+
60
+ return false
61
+ end
56
62
  end
57
63
  end
@@ -60,5 +60,11 @@ class Cheftacular
60
60
  def run_all
61
61
  raise "You attempted to run a command for the all role, this is not possible."
62
62
  end
63
+
64
+ def run_
65
+ puts "Run method tried to run a command for the role \"#{ @options['role'] }\" but it doesn't appear to have a repository set! Skipping..."
66
+
67
+ return false
68
+ end
63
69
  end
64
70
  end
@@ -19,6 +19,7 @@ require 'fog'
19
19
  require 'socket'
20
20
  require 'net/http'
21
21
  require 'timeout'
22
+ require 'slack-notifier'
22
23
 
23
24
  Dir["#{File.dirname(__FILE__)}/../**/*.rb"].each { |f| require f }
24
25
 
@@ -427,7 +427,9 @@ class Cheftacular
427
427
  end
428
428
 
429
429
  def initialize_directories
430
- FileUtils.mkdir_p @config['locs']['chef-log']
430
+ ['applog', 'deploy', 'rolelog', 'rvm', 'stashedlog'].each do |sub_log_directory|
431
+ FileUtils.mkdir_p File.join( @config['locs']['chef-log'], sub_log_directory )
432
+ end
431
433
 
432
434
  FileUtils.mkdir_p File.join( @config['locs']['app-root'], 'tmp', @config['helper'].declassify)
433
435
 
@@ -61,7 +61,7 @@ class Cheftacular
61
61
 
62
62
  elsif repo_check_array.include?(true)
63
63
  @config['cheftacular']['repositories'].each_pair do |key, repo_hash|
64
- @options['role'] = key if repo_hash['repo_name'] == repository && set_variables
64
+ @options['role'] = key if repo_hash['repo_name'] == repository && set_variables && @options['role'].nil?
65
65
  end
66
66
  else
67
67
  raise "Unable to parse repository: #{ repository }, the repository you're referring to does not exist in your cheftacular.yml."
@@ -55,8 +55,6 @@ class Cheftacular
55
55
  ' 2. *You will not be able to set a custom revision for beta environments.* The beta environments are tied to split-staging and splita/b/c/d respectively.',
56
56
  ]
57
57
  end
58
-
59
- alias_method :stateless_arguments, :arguments
60
58
  end
61
59
 
62
60
  class StatelessAction
@@ -57,7 +57,7 @@ class Cheftacular
57
57
 
58
58
  final_commands
59
59
 
60
- rvm_source = "source /home/deploy/.rvm/scripts/rvm &&"
60
+ rvm_source = "source /home/deploy/.rvm/bin/rvm &&"
61
61
 
62
62
  final_commands = [
63
63
  "#{ rvm_source } echo '#{ new_deploy_pass }' | rvmsudo -S rvm requirements",
@@ -0,0 +1,14 @@
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,8 +1,8 @@
1
1
  class Cheftacular
2
2
  class StatelessActionDocumentation
3
3
  def chef_environment
4
- @config['documentation']['action'] << [
5
- "`cft chef_environment ENVIRONMENT_NAME [create|destroy]` will allow you to interact with chef environments on the chef server.",
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
6
 
7
7
  [
8
8
  " 1. `create` will create an environment if it does not exist.",
@@ -18,4 +18,4 @@ class Cheftacular
18
18
  #TODO
19
19
  end
20
20
  end
21
- end
21
+ end
@@ -2,7 +2,7 @@ class Cheftacular
2
2
  class StatelessActionDocumentation
3
3
  def clean_sensu_plugins
4
4
  @config['documentation']['stateless_action'] << [
5
- "`cft clean_sensu_plugins` [NYI] will checkout / update the sensu community plugins github repo on your " +
5
+ "[NYI]`cft clean_sensu_plugins` will checkout / update the sensu community plugins github repo on your " +
6
6
  "local machine and sync any sensu plugin files in your wrapper cookbook directory with what is in the repo."
7
7
  ]
8
8
  end
@@ -1,5 +1,3 @@
1
-
2
- #Uploads a private key found in ~/.ssh/id_rsa to an encrypted bag to let the chef-server access private repos.
3
1
  class Cheftacular
4
2
  class StatelessActionDocumentation
5
3
  def create_git_key
@@ -2,7 +2,7 @@ class Cheftacular
2
2
  class StatelessActionDocumentation
3
3
  def fetch_file
4
4
  @config['documentation']['stateless_action'] << [
5
- "`cft fetch_file NODE_NAME LOCATION_ALIAS FILE_NAME` fetches a file from the remote node. ",
5
+ "[NYI]`cft fetch_file NODE_NAME LOCATION_ALIAS FILE_NAME` fetches a file from the remote node. ",
6
6
 
7
7
  [
8
8
  " 1. `LOCATION_ALIAS` will be parsed as a path if it has backslash characters. Otherwise it will be parsed from your " +
@@ -17,8 +17,6 @@ class Cheftacular
17
17
 
18
18
  class StatelessAction
19
19
  def fix_known_hosts
20
- include Config
21
-
22
20
  targets = ["all"]
23
21
 
24
22
  if ARGV[1].class == String
@@ -28,12 +26,13 @@ class Cheftacular
28
26
  if targets.first == 'all'
29
27
  nodes = @config['getter'].get_true_node_objects(true)
30
28
  arr = []
31
- environments = (nodes.map { |n| n.chef_environment }).uniq
32
29
 
33
- environments.delete("_default")
30
+ @config['chef_environments'].each do |env|
31
+ @config['initializer'].initialize_data_bags_for_environment env, false, ['addresses']
32
+
33
+ @config['initializer'].initialize_addresses_bag_contents env
34
34
 
35
- environments.each do |env|
36
- @config[env]['addresses_bag_hash'].each do |serv_hash|
35
+ @config[env]['addresses_bag_hash']['addresses'].each do |serv_hash|
37
36
  arr << serv_hash['dn'].split('.').first
38
37
  arr << serv_hash['public']
39
38
  end
@@ -24,9 +24,9 @@ class Cheftacular
24
24
 
25
25
  nodes.each do |node|
26
26
  if @config[@options['env']]['logs_bag_hash'].has_key?("#{ node.name }-deploy")
27
- puts("Found log data in logs bag. Outputting to #{ log_loc }/#{ node.name }-deploystash-#{ @config[@options['env']]['logs_bag_hash']["#{ node.name }-deploy"][:timestamp] }.txt") unless @options['quiet']
27
+ puts("Found log data in logs bag. Outputting to #{ log_loc }/stashedlog/#{ node.name }-deploystash-#{ @config[@options['env']]['logs_bag_hash']["#{ node.name }-deploy"][:timestamp] }.txt") unless @options['quiet']
28
28
 
29
- File.open("#{ log_loc }/#{ node.name }-deploystash-#{@config[@options['env']]['logs_bag_hash']["#{ node.name }-deploy"][:timestamp] }.txt", "w") do |f|
29
+ File.open("#{ log_loc }/stashedlog/#{ node.name }-deploystash-#{@config[@options['env']]['logs_bag_hash']["#{ node.name }-deploy"][:timestamp] }.txt", "w") do |f|
30
30
  f.write(@config[@options['env']]['logs_bag_hash']["#{ node.name }-deploy"][:text])
31
31
  end
32
32
 
@@ -9,9 +9,11 @@ class Cheftacular
9
9
  end
10
10
 
11
11
  class StatelessAction
12
- def initialize_data_bag_contents env
12
+ def initialize_data_bag_contents env=""
13
13
  raise "Environment does not exist on chef server!" unless @config['chef_environments'].include?(env)
14
14
 
15
+ env = ARGV[1] if env.blank?
16
+
15
17
  @config['initializer'].initialize_audit_bag_contents env
16
18
 
17
19
  @config['initializer'].initialize_authentication_bag_contents
@@ -166,6 +168,8 @@ class Cheftacular
166
168
  end
167
169
 
168
170
  envs_to_build_in_hash.each do |env|
171
+ hash[env] ||= {}
172
+
169
173
  if !hash[env].has_key?('tld') || ( hash[env].has_key?('tld') && hash[env]['tld'].blank? )
170
174
  hash[env]['tld'] = "" unless hash[env].has_key?('tld')
171
175
 
@@ -3,7 +3,7 @@ class Cheftacular
3
3
  def restart_swap
4
4
  @config['documentation']['stateless_action'] << [
5
5
  "`cft restart_swap` will restart the swap on every server that doesn't have swap currently on. " +
6
- "Useful if you notice servers with no swap activated from `hip disk_report`",
6
+ "Useful if you notice servers with no swap activated from `cft disk_report`",
7
7
 
8
8
  [
9
9
  " 1. There is no risk in running this command. Sometimes swap doesnt reactivate if " +
@@ -2,13 +2,113 @@
2
2
  class Cheftacular
3
3
  class StatelessActionDocumentation
4
4
  def rvm
5
- #TODO
5
+ @config['documentation']['stateless_action'] << [
6
+ "`cft rvm [COMMAND] [ADDITIONAL_COMMANDS]*` will run rvm commands on the remote servers. " +
7
+ "Output from this command for each server will go into your rvm directory under the log directory. " +
8
+ "Please refer to [the rvm help page](https://rvm.io/rvm) for more information on rvm commands.",
9
+
10
+ [
11
+ " 1. When no commands are passed, rvm will just run `rvm list` on each server on all servers in " +
12
+ "the current environment.",
13
+
14
+ " 2. When `list|list_rubies` is passed, rvm will run `rvm list rubies` on all servers in the " +
15
+ "current environment.",
16
+
17
+ " 3. When `install RUBY_TO_INSTALL` is passed, rvm will attempt to install that ruby on each " +
18
+ "system in the current environment. It is a good idea to use strings like ruby-2.2.1",
19
+
20
+ " 4. `run [RVM_COMMANDS]+` will run the rest of the arguments as a complete rvm command. An example " +
21
+ "of this being `cft rvm run gemset update`. This will run on all servers in the current environment.",
22
+
23
+ " 5. `all_environments [RVM_COMMANDS]+` will run the rest of the arguments as a complete rvm command " +
24
+ "*on all of the servers in every environment*.",
25
+
26
+ " 6. `test [RVM_COMMANDS]+` will run the rest of the arguments as a complete rvm command with scoping. " +
27
+ "By default, rvm commands run against all servers in the environment but with test you can pass -n NODE_NAME " +
28
+ " or -r ROLE_NAME flags to scope the servers the rvm command will be run on. Useful for testing.",
29
+
30
+ " 7. `upgrade_rvm` will run `rvm get stable --auth-dotfiles` on all servers for the current environment. " +
31
+ "It will also check and attempt to upgrade pre 1.25 installations of RVM to 1.26+ (which requires a GPG key)."
32
+ ]
33
+ ]
6
34
  end
7
35
  end
8
36
 
9
37
  class StatelessAction
10
- def rvm action="list"
38
+ def rvm command=''
39
+ raise "This action can only be performed if the mode is set to devops" unless @config['helper'].running_in_mode?('devops')
40
+
41
+ command = case ARGV[1]
42
+ when nil then 'list'
43
+ when /list|list_rubies/ then 'list rubies'
44
+ when 'install' then "install #{ ARGV[2] }"
45
+ when 'run' then ARGV[2..(ARGV.length-1)].join(' ')
46
+ when 'all_environments' then ARGV[2..(ARGV.length-1)].join(' ')
47
+ when 'test' then ARGV[2..(ARGV.length-1)].join(' ')
48
+ when 'upgrade_rvm' then 'get stable --auto-dotfiles'
49
+ else 'list'
50
+ end
51
+
52
+ if @config['cheftacular']['rvm_gpg_key'].nil? || @config['cheftacular']['rvm_gpg_key'].blank?
53
+ raise "GPG Key not found in cheftacular.yml! Please update your rvm_gpg_key in the file!"
54
+ end
55
+
56
+ nodes = ARGV[1] == 'test' ? @config['getter'].get_true_node_objects : @config['getter'].get_true_node_objects(true)
57
+
58
+ nodes = @config['parser'].exclude_nodes( nodes, [{ unless: { env: @options['env'] }}] ) unless ARGV[1] == 'all_servers'
59
+
60
+ @config['chef_environments'].each do |env|
61
+ @config['initializer'].initialize_data_bags_for_environment env, false, ['addresses', 'server_passwords']
62
+
63
+ @config['initializer'].initialize_passwords env
64
+ end if ARGV[1] == 'all_servers'
65
+
66
+ options, locs, ridley, logs_bag_hash, pass_bag_hash, bundle_command, cheftacular, passwords = @config['helper'].set_local_instance_vars
67
+
68
+ on ( nodes.map { |n| "deploy@" + n.public_ipaddress } ), in: :groups, limit: 5, wait: 2 do |host|
69
+ n = get_node_from_address(nodes, host.hostname)
70
+
71
+ puts "Beginning run of \"rvm #{ command }\" for #{ n.name } (#{ n.public_ipaddress })"
72
+
73
+ start_rvm( n.name, n.public_ipaddress, options, locs, passwords, command, cheftacular )
74
+ end
75
+ end
76
+ end
77
+ end
78
+
79
+ module SSHKit
80
+ module Backend
81
+ class Netssh
82
+ def start_rvm name, ip_address, options, locs, passwords, command, cheftacular, out=""
83
+ log_loc, timestamp = set_log_loc_and_timestamp(locs)
84
+ upgrade_rvm = command.include?('get stable')
85
+ rvm_location = "/home/#{ cheftacular['deploy_user'] }/.rvm/bin/rvm"
86
+
87
+ puts "Generating rvm log file for #{ name } (#{ ip_address }) at #{ log_loc }/rvm/#{ name }-rvm-#{ timestamp }.txt"
88
+
89
+
90
+ if !test("[ -e /home/#{ cheftacular['deploy_user'] }/.rvm/bin/rvm ]") #true if file exists
91
+ puts "#{ name } (#{ ip_address }) does not have a rvm bin command at the moment! Updating installation to latest..."
92
+
93
+ upgrade_rvm = true
94
+ end
95
+
96
+ if upgrade_rvm
97
+ out << sudo_capture( passwords[ip_address], :chown, "#{ cheftacular['deploy_user'] }:root", '-R', "/home/#{ cheftacular['deploy_user'] }/.gnupg")
98
+
99
+ out << capture( :gpg, '--keyserver hkp://keys.gnupg.net', "--recv-keys #{ cheftacular['rvm_gpg_key'] }")
100
+
101
+ rvm_location = "/home/#{ cheftacular['deploy_user'] }/.rvm/.rvm/bin/rvm" if test("[ -e /home/#{ cheftacular['deploy_user'] }/.rvm/.rvm/bin/rvm ]")
102
+ end
103
+
104
+ out << capture( rvm_location, command )
105
+
106
+ ::File.open("#{ log_loc }/rvm/#{ name }-rvm-#{ timestamp }.txt", "w") { |f| f.write(out.scrub_pretty_text) } unless options['no_logs']
107
+
108
+ puts(out.scrub_pretty_text) if options['output'] || options['verbose']
11
109
 
110
+ puts "Succeeded run of \"rvm #{ command }\" for #{ name } (#{ ip_address })"
111
+ end
12
112
  end
13
113
  end
14
114
  end
@@ -0,0 +1,19 @@
1
+ class Cheftacular
2
+ class StatelessActionDocumentation
3
+ def slack
4
+ @config['documentation']['stateless_action'] << [
5
+ "`cft slack \"MESSAGE\" [CHANNEL]` will attempt to post the message to the webhook set in your cheftacular.yml. " +
6
+ "Slack posts to your default channel by default but if the CHANNEL argument is supplied the message will post there.",
7
+ ]
8
+ end
9
+ end
10
+
11
+ class StatelessAction
12
+ def slack
13
+ notifier = Slack::Notifier.new @config['cheftacular']['slack_webhook'], username: 'Cheftacular'
14
+
15
+ notifier.channel = '#default' unless ARGV[2]
16
+ notifier.ping ARGV[1]
17
+ end
18
+ end
19
+ end
@@ -1,5 +1,5 @@
1
1
  class Cheftacular
2
2
  #major_version.minor_version.bugfixes
3
- VERSION = "2.0.9"
3
+ VERSION = "2.1.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.0.9
4
+ version: 2.1.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-04-24 00:00:00.000000000 Z
11
+ date: 2015-04-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hashie
@@ -193,27 +193,13 @@ dependencies:
193
193
  - !ruby/object:Gem::Version
194
194
  version: '0'
195
195
  - !ruby/object:Gem::Dependency
196
- name: nokogiri
197
- requirement: !ruby/object:Gem::Requirement
198
- requirements:
199
- - - '='
200
- - !ruby/object:Gem::Version
201
- version: 1.6.1
202
- type: :development
203
- prerelease: false
204
- version_requirements: !ruby/object:Gem::Requirement
205
- requirements:
206
- - - '='
207
- - !ruby/object:Gem::Version
208
- version: 1.6.1
209
- - !ruby/object:Gem::Dependency
210
- name: mechanize
196
+ name: slack-notifier
211
197
  requirement: !ruby/object:Gem::Requirement
212
198
  requirements:
213
199
  - - ">="
214
200
  - !ruby/object:Gem::Version
215
201
  version: '0'
216
- type: :development
202
+ type: :runtime
217
203
  prerelease: false
218
204
  version_requirements: !ruby/object:Gem::Requirement
219
205
  requirements:
@@ -270,6 +256,7 @@ files:
270
256
  - lib/cheftacular/stateless_actions/bootstrappers/redhat_bootstrap.rb
271
257
  - lib/cheftacular/stateless_actions/bootstrappers/ubuntu_bootstrap.rb
272
258
  - lib/cheftacular/stateless_actions/bootstrappers/vyatta_bootstrap.rb
259
+ - lib/cheftacular/stateless_actions/check_cheftacular_settings.rb
273
260
  - lib/cheftacular/stateless_actions/chef_bootstrap.rb
274
261
  - lib/cheftacular/stateless_actions/chef_environment.rb
275
262
  - lib/cheftacular/stateless_actions/clean_cookbooks.rb
@@ -302,6 +289,7 @@ files:
302
289
  - lib/cheftacular/stateless_actions/rvm.rb
303
290
  - lib/cheftacular/stateless_actions/server_update.rb
304
291
  - lib/cheftacular/stateless_actions/service.rb
292
+ - lib/cheftacular/stateless_actions/slack.rb
305
293
  - lib/cheftacular/stateless_actions/test_env.rb
306
294
  - lib/cheftacular/stateless_actions/update_split_branches.rb
307
295
  - lib/cheftacular/stateless_actions/update_tld.rb
@@ -342,9 +330,6 @@ files:
342
330
  - lib/cloud_interactor/volume/list.rb
343
331
  - lib/cloud_interactor/volume/read.rb
344
332
  - lib/ridley/monkeypatches.rb
345
- - lib/sshkit/actions/start_commit_check.rb
346
- - lib/sshkit/actions/start_deploy.rb
347
- - lib/sshkit/actions/start_log_fetch.rb
348
333
  - lib/sshkit/actions/start_task.rb
349
334
  - lib/sshkit/getters.rb
350
335
  - lib/sshkit/helpers.rb
@@ -1,19 +0,0 @@
1
- module SSHKit
2
- module Backend
3
- class Netssh
4
- def start_commit_check name, ip_address, options, locs, cheftacular, out={'name'=>'', 'time'=> ''}
5
- app_loc = "#{ cheftacular['base_file_path'] }/#{ options['repository'] }/releases"
6
-
7
- if test("[ -d #{ app_loc } ]") #true if file exists
8
- within app_loc do
9
- out['name'] = capture( :ls, '-rt', :|, :tail, '-1' )
10
-
11
- out['time'] = Time.parse(capture( :stat, out['name'], '--printf=%y' )).strftime('%Y-%m-%d %I:%M:%S %p')
12
- end
13
- end
14
-
15
- out
16
- end
17
- end
18
- end
19
- end
@@ -1,25 +0,0 @@
1
- module SSHKit
2
- module Backend
3
- class Netssh
4
- def start_deploy name, ip_address, options, locs, passwords, out=""
5
- log_loc, timestamp = set_log_loc_and_timestamp(locs)
6
-
7
- puts "Generating log file for #{ name } (#{ ip_address }) at #{ log_loc }/#{ name }-deploy-#{ timestamp }.txt"
8
-
9
- capture_args = [ "chef-client" ]
10
- capture_args << [ '-l', 'debug' ] if options['debug']
11
- #capture_args << [ '>', '/dev/tty']
12
-
13
- out << sudo_capture( passwords[ip_address], *capture_args.flatten )
14
-
15
- ::File.open("#{ log_loc }/#{ name }-deploy-#{ timestamp }.txt", "w") { |f| f.write(out.scrub_pretty_text) } unless options['no_logs']
16
-
17
- puts(out) if options['output'] || options['verbose']
18
-
19
- puts "Succeeded deploy of #{ name } (#{ ip_address }) on role #{ options['role'] }"
20
-
21
- [out, timestamp] #return out to send to logs_bag
22
- end
23
- end
24
- end
25
- end
@@ -1,92 +0,0 @@
1
- module SSHKit
2
- module Backend
3
- class Netssh
4
- def start_log_role_map name, ip_address, target_log_loc, options, locs, cheftacular, passwords, out=""
5
- log_loc, timestamp = set_log_loc_and_timestamp(locs)
6
- log_cmnd, log_lines = get_log_command_and_lines(options)
7
-
8
-
9
- puts "Fetching log file(s) for #{ name } (#{ ip_address }). Outputting to #{ log_loc } with timestamp: #{ timestamp }"
10
-
11
- target_log_loc.split(',').each do |parsed_log_loc|
12
- parsed_log_loc = parsed_log_loc.gsub('|current_repo_location|', "#{ cheftacular['base_file_path'] }/#{ options['repository'] }/current")
13
-
14
- if parsed_log_loc != '/var/log/syslog' && !test("[ -e #{ parsed_log_loc }]") #true if file exists ()
15
- puts "#{ name } (#{ ip_address }) does not have a #{ parsed_log_loc } log file for #{ options['env'] } at the moment..."
16
- else
17
- if log_lines.nil?
18
- out << sudo_capture(passwords[ip_address], log_cmnd.to_sym, parsed_log_loc)
19
-
20
- else
21
- out << sudo_capture(passwords[ip_address], log_cmnd.to_sym, log_lines, parsed_log_loc)
22
- end
23
-
24
- ::File.open("#{ log_loc }/#{ name }-#{ parsed_log_loc.split('/').last.split('.').first }-#{ timestamp }.txt", "w") { |f| f.write(out.scrub_pretty_text) } unless options['no_logs']
25
- end
26
- end
27
- end
28
-
29
- def start_log_fetch_ruby_on_rails name, ip_address, run_list, options, locs, cheftacular, passwords, out=""
30
- log_loc, timestamp = set_log_loc_and_timestamp(locs)
31
- true_env = get_true_environment run_list, cheftacular['run_list_environments'], options['env']
32
- app_log_loc = "#{ cheftacular['base_file_path'] }/#{ options['repository'] }/current/log"
33
- log_cmnd, log_lines = get_log_command_and_lines(options)
34
-
35
- if !test("[ -e /#{ app_log_loc }/#{ true_env }.log ]") #true if file exists
36
- puts "#{ name } (#{ ip_address }) does not have a log file for #{ true_env } at the moment..."
37
-
38
- else
39
-
40
- puts "Fetching log file(s) for #{ name } (#{ ip_address }). Outputting to #{ log_loc }/#{ name }-applog-#{ timestamp }.txt"
41
-
42
- within app_log_loc do
43
- if log_lines.nil?
44
- out << capture(log_cmnd.to_sym, "#{ true_env }.log")
45
-
46
- else
47
- out << capture(log_cmnd.to_sym, log_lines, "#{ true_env }.log")
48
- end
49
- end
50
-
51
- #To create the file locally you must namespace like this
52
- ::File.open("#{ log_loc }/#{ name }-applog-#{ timestamp }.txt", "w") { |f| f.write(out.scrub_pretty_text) } unless options['no_logs']
53
- end
54
-
55
- out << start_log_fetch_nginx(name, log_loc, log_cmnd, timestamp, options, out) if run_list.include?('role[web]') && options['get_nginx_logs']
56
-
57
- out << start_log_role_map(name, ip_address, get_role_map(cheftacular, get_worker_role(cheftacular))['log_location'], log_cmnd, app_log_loc, timestamp, options) if run_list.include?("role[#{ get_worker_role(cheftacular) }]")
58
-
59
- puts(out) if options['verbose']
60
- end
61
-
62
- def start_log_fetch_nginx name, log_loc, log_cmnd, timestamp, options, out=""
63
- out = "" unless options['no_logs']
64
-
65
- nginx_log_loc = "/var/log/nginx/#{ options['repository'] }_access.log"
66
-
67
- puts "Fetching nginx log file... Outputting to #{ log_loc }/#{ name }-nginxlog-#{ timestamp }.txt "
68
-
69
- if log_lines.nil?
70
- out << capture(log_cmnd.to_sym, nginx_log_loc)
71
-
72
- else
73
- out << capture(log_cmnd.to_sym, log_lines, nginx_log_loc)
74
- end
75
-
76
- ::File.open("#{ log_loc }/#{ name }-nginxlog-#{ timestamp }.txt", "w") { |f| f.write(out.scrub_pretty_text) } unless options['no_logs']
77
-
78
- out
79
- end
80
-
81
- private
82
-
83
- def get_log_command_and_lines options
84
- log_cmnd = options['get_full_logs'] ? 'cat' : 'tail'
85
-
86
- log_lines = options['get_full_logs'] ? nil : "-" + ( options['get_log_lines'] ? options['get_log_lines'] : "500" )
87
-
88
- [log_cmnd, log_lines]
89
- end
90
- end
91
- end
92
- end