orats 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +3 -3
- data/README.md +176 -41
- data/lib/orats/cli.rb +85 -35
- data/lib/orats/server.rb +3 -2
- data/lib/orats/shell.rb +83 -11
- data/lib/orats/templates/{commands/auth.rb → auth.rb} +0 -0
- data/lib/orats/templates/{commands/base.rb → base.rb} +1 -1
- data/lib/orats/templates/cook.rb +630 -0
- data/lib/orats/version.rb +1 -1
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0a6c0e8dbdf731aa4475b5146b8e7816d42dd9db
|
4
|
+
data.tar.gz: 2574c41229f58b27670a7d6caff9af1a6b4cc2a7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e0629f4d2632b7697ea66880de7723762ac23714a110f770b4a221e22f7ac0d293eda935cc7e6a29b27179a3ca6dce448d1c5cdb7dfcc6d4b63e88f360c5cd3f
|
7
|
+
data.tar.gz: 30eaf60bafff537a7ed5931d15715addde4e548955286fedb51258e6af4135d4f71d79530933e205c947b9e4e89df0c286f3f0d2ed0455ac90a10e48fc29d1a6
|
data/Gemfile.lock
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
orats (0.
|
4
|
+
orats (0.3.0)
|
5
5
|
thor (~> 0)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
-
rake (
|
10
|
+
rake (0.9.6)
|
11
11
|
thor (0.18.1)
|
12
12
|
|
13
13
|
PLATFORMS
|
@@ -16,4 +16,4 @@ PLATFORMS
|
|
16
16
|
DEPENDENCIES
|
17
17
|
bundler (~> 1.5)
|
18
18
|
orats!
|
19
|
-
rake
|
19
|
+
rake (~> 0)
|
data/README.md
CHANGED
@@ -1,12 +1,10 @@
|
|
1
1
|
## What is orats and what problem does it solve?
|
2
2
|
|
3
|
-
It stands for opinionated rails application templates.
|
4
|
-
|
3
|
+
It stands for opinionated rails application templates. The templates include solving tedious tasks that you would do for most
|
4
|
+
projects. It handles creating a rails application with a bunch of opinions and optionally a chef cookbook so you can deploy
|
5
|
+
your app quickly.
|
5
6
|
|
6
|
-
|
7
|
-
setup all of this manually each time you make an app.
|
8
|
-
|
9
|
-
It is clearly a problem that can be automated so I sat down and started to create a few templates to do just that.
|
7
|
+
Everything is accessed through the [orats gem](#installation).
|
10
8
|
|
11
9
|
## What version of Rails and Ruby are you targeting?
|
12
10
|
|
@@ -15,14 +13,14 @@ It is clearly a problem that can be automated so I sat down and started to creat
|
|
15
13
|
I will be updating them as new versions come out and when the gems used are proven to work. All important gems in the Gemfile
|
16
14
|
are locked using the pessimistic operator `~>` so you can be sure that everything plays nice as long as rubygems.org is up!
|
17
15
|
|
18
|
-
## System dependencies that
|
16
|
+
## System dependencies that you must have on your dev box
|
19
17
|
|
20
18
|
- [The orats gem](#installation)
|
21
19
|
- To download each rails template and automate running certain tasks.
|
22
20
|
- Ruby 2.1.x
|
23
21
|
- Yep, you really need Ruby to run Ruby modules.
|
24
22
|
- Rails 4.0.x
|
25
|
-
- You
|
23
|
+
- You need Rails installed so that you can run the project generator.
|
26
24
|
- Git
|
27
25
|
- The weapon of choice for version control.
|
28
26
|
- Postgres
|
@@ -30,19 +28,34 @@ are locked using the pessimistic operator `~>` so you can be sure that everythin
|
|
30
28
|
- Redis
|
31
29
|
- Used as a sidekiq background worker and as the rails cache back end.
|
32
30
|
|
31
|
+
### Additional system dependencies for creating cookbooks
|
32
|
+
|
33
|
+
`orats` is smart enough to skip trying to create a cookbook if it cannot find the necessary dependencies to successfully
|
34
|
+
create the cookbook, but to successfully create a cookbook you must fulfil the requirements below:
|
35
|
+
|
36
|
+
- Chef is installed and setup in such a way that `knife` is on your system path.
|
37
|
+
- Berkshelf has been gem installed and you can run `berks` from anywhere.
|
38
|
+
|
39
|
+
Not sure what chef or berkshelf is? No problem, learn about chef from these resources:
|
40
|
+
|
41
|
+
- [Learn chef course](https://learnchef.opscode.com/)
|
42
|
+
- [Berkshelf readme](http://www.berkshelf.com/)
|
43
|
+
- [Berkshelf tutorial series](http://misheska.com/blog/2013/06/16/getting-started-writing-chef-cookbooks-the-berkshelf-way/)
|
44
|
+
|
33
45
|
## Contents
|
34
46
|
|
35
47
|
- orats
|
36
48
|
- [Installation](#installation)
|
37
49
|
- [Commands](#commands)
|
38
50
|
- Templates
|
39
|
-
- [Base](#base
|
51
|
+
- [Base](#base)
|
40
52
|
- [Authentication and authorization](#authentication-and-authorization)
|
41
|
-
- [
|
42
|
-
|
53
|
+
- [Cookbook](#cookbook)
|
54
|
+
- [Overview](#the-cookbook-comes-with-the-following-features)
|
43
55
|
- Sections
|
44
|
-
- [Expanding beyond the base template](#expanding-beyond-the-base-template)
|
45
56
|
- [Production tweaks](#production-tweaks)
|
57
|
+
- Wikis
|
58
|
+
- [Chef walk through](https://github.com/nickjj/orats/wiki/Chef-walk-through)
|
46
59
|
|
47
60
|
## orats
|
48
61
|
|
@@ -50,36 +63,38 @@ are locked using the pessimistic operator `~>` so you can be sure that everythin
|
|
50
63
|
|
51
64
|
`gem install orats`
|
52
65
|
|
53
|
-
|
54
66
|
### Commands
|
55
67
|
|
56
|
-
|
68
|
+
Here is an overview of the available commands. You can find out more information about each command and flag by simply
|
69
|
+
running `orats <command name> help` from your terminal. You can also type `orats` on its own to see a list of all commands.
|
57
70
|
|
58
|
-
- Create a new
|
59
|
-
- `orats
|
60
|
-
-
|
61
|
-
|
71
|
+
- Create a new orats project
|
72
|
+
- `orats new <APP_PATH> --pg-password <development postgres db password>`
|
73
|
+
- Configuration:
|
74
|
+
- Optionally takes: `--pg-location [localhost]`
|
75
|
+
- Optionally takes: `--pg-username [postgres]`
|
76
|
+
- Template features:
|
77
|
+
- Optionally takes: `--auth [false]`
|
78
|
+
- Project features:
|
79
|
+
- Optionally takes: `--skip-cook [false]`
|
80
|
+
- Optionally takes: `--skip-extras [false]`
|
62
81
|
|
63
|
-
- Create a
|
64
|
-
- `orats
|
65
|
-
- Optionally takes `--postgres-location [localhost]`
|
66
|
-
- Optionally takes `--postgres-username [postgres]`
|
82
|
+
- Create a stand alone chef cookbook
|
83
|
+
- `orats cook <APP_PATH>`
|
67
84
|
|
68
|
-
- Delete
|
69
|
-
- `orats nuke <
|
70
|
-
- Optionally takes `--
|
85
|
+
- Delete the directory and optionally all data associated to it
|
86
|
+
- `orats nuke <APP_PATH>`
|
87
|
+
- Optionally takes `--skip-data [false]`
|
71
88
|
|
72
89
|
#### Why is it asking me for my development postgres password?
|
73
90
|
|
74
|
-
The password is it asking for is only for your development database. It will **never** ask for your production passwords.
|
75
|
-
|
76
91
|
In order to automate certain tasks such as running database migrations the script must be able to talk to your database.
|
77
92
|
It cannot talk to your database without knowing the location, username and password for postgres. In most cases the
|
78
93
|
location will be `localhost` and the username will be `postgres` so these values are provided by default.
|
79
94
|
|
80
|
-
|
95
|
+
Remember, this is only your development postgres password. It will **never** ask for your production passwords.
|
81
96
|
|
82
|
-
## Base
|
97
|
+
## Base
|
83
98
|
|
84
99
|
This is the starter template that every other template will append to. I feel like when I make a new project, 95% of the time
|
85
100
|
it includes these features and when I do not want a specific thing it is much quicker to remove it than add it.
|
@@ -117,7 +132,20 @@ Everything has been added with proper git commits so you have a trail of changes
|
|
117
132
|
|
118
133
|
### Try it
|
119
134
|
|
120
|
-
`orats
|
135
|
+
`orats new myapp --pg-password <development postgres db password> -C`
|
136
|
+
|
137
|
+
*We are running the command with `-C` to ignore creating a cookbook so the installation is faster.*
|
138
|
+
|
139
|
+
#### What's with the services directory?
|
140
|
+
|
141
|
+
It is just a naming convention that I like to apply, you can name it whatever you want later or remove it with a flag. My thought
|
142
|
+
process was you might have multiple services which when put together create your web application. In many cases your web
|
143
|
+
application might just be a single rails app, but maybe not.
|
144
|
+
|
145
|
+
What if you introduced a Go service to do something which your rails application talks to for a certain area of your site?
|
146
|
+
Perhaps you have 2 rails applications too. One of them for your admin app and the other for the public facing app.
|
147
|
+
|
148
|
+
Long story short the extra directory is probably worth it in the long run and it's simple to remove if you don't like it.
|
121
149
|
|
122
150
|
### All I see is the default rails page
|
123
151
|
|
@@ -182,18 +210,125 @@ I feel like this is the cleanest way to disable registrations while still allowi
|
|
182
210
|
|
183
211
|
### Try it
|
184
212
|
|
185
|
-
`orats
|
213
|
+
`orats new myauthapp --pg-password <development postgres db password> --auth -C`
|
214
|
+
|
215
|
+
*We are running the command with `-C` to ignore creating a cookbook so the installation is faster.*
|
216
|
+
|
217
|
+
## Cookbook
|
218
|
+
|
219
|
+
Building your application is only one piece of the puzzle. If you want to ship your application you have to host it somewhere.
|
220
|
+
You have a few options when it comes to managed hosts like Heroku but they tend to be very expensive if you fall out of
|
221
|
+
their free tier.
|
222
|
+
|
223
|
+
The cookbook template creates a chef cookbook that will provision a **ubuntu 12.04 LTS server**. It can be hosted anywhere
|
224
|
+
as there are no hard requirements on any specific host. Chef is a server management framework. This template uses the
|
225
|
+
application cookbook pattern and depends on Berkshelf. Berkshelf is very similar to bundler but for chef cookbooks.
|
226
|
+
|
227
|
+
### The cookbook comes with the following features
|
228
|
+
|
229
|
+
- Security
|
230
|
+
- A random username is generated each time you generate a new cookbook.
|
231
|
+
- A random ssh port is generated each time you generate a new cookbook.
|
232
|
+
- Logging into the server is only possible with an SSH key.
|
233
|
+
- fail2ban is setup.
|
234
|
+
- ufw (firewall) is setup to block any ports not exposed.
|
235
|
+
- All stack specific processes are running with less privileges than root.
|
236
|
+
- Stack specific processes that are installed and configured
|
237
|
+
- Nginx
|
238
|
+
- Postgres
|
239
|
+
- Redis
|
240
|
+
- Runtimes
|
241
|
+
- Ruby 2.1.0 managed via rvm
|
242
|
+
- Nodejs 0.10.x
|
243
|
+
- Utils and features
|
244
|
+
- htop for emergency live monitoring
|
245
|
+
- logrotate with log rotation setup for anything that needs it.
|
246
|
+
- git
|
247
|
+
- A git repo in the deploy user's home directory which you can push to.
|
248
|
+
|
249
|
+
### Cookbook structure
|
250
|
+
|
251
|
+
It is broken up into 5 recipes:
|
252
|
+
|
253
|
+
- Base
|
254
|
+
- Database
|
255
|
+
- Cache
|
256
|
+
- Web
|
257
|
+
- Default
|
258
|
+
|
259
|
+
With the application style cookbook pattern it is a good idea to only run one recipe on your node. The default recipe
|
260
|
+
just composes the other 4 together. This makes it trivial to break out past one node in the future. If you wanted to
|
261
|
+
put your web server on server A and the database/cache servers on server B all you would have to do is create a new recipe
|
262
|
+
called something like `database_cache` (the name is arbitrary) and pull in both the database and cache recipes.
|
263
|
+
|
264
|
+
Then when you bootstrap the node you can tell it to use the new `database_cache` recipe. Awesome right? Yeah I know, chef rocks.
|
265
|
+
|
266
|
+
### Try it
|
267
|
+
|
268
|
+
`orats new mychefapp --pg-password <development postgres db password>`
|
269
|
+
|
270
|
+
#### Why is the cookbooks directory plural?
|
271
|
+
|
272
|
+
It is not uncommon for some projects to have multiple cookbooks. Of course that is completely out of scope for orats but
|
273
|
+
at least it generates a directory structure capable of sustaining multiple cookbooks.
|
274
|
+
|
275
|
+
### Tweakable attributes and meta data
|
276
|
+
|
277
|
+
You can quickly tweak a bunch of values by investigating the `attributes/default.rb` file. The values here are used in each
|
278
|
+
recipe. They are also namespaced to match the recipe file that uses them.
|
279
|
+
|
280
|
+
It is important that you change all of these values to match your setup. The only non-obvious one might be the SSH key. You
|
281
|
+
should use the key inside of your `.ssh/id_rsa.pub` file. It is the key that ends with your work station's username@hostname. Make
|
282
|
+
sure you do not include the trailing line break too.
|
283
|
+
|
284
|
+
You should also edit the details in the `metadata.rb` file.
|
285
|
+
|
286
|
+
### Encrypted values
|
287
|
+
|
288
|
+
Chef has this notion of encrypted data bags. They are used to protect sensitive information like passwords or secret tokens.
|
289
|
+
You can check out the `data_bags/<app_name>_secrets/production.json` file to know which fields you need to fill out later.
|
290
|
+
|
291
|
+
Please keep in mind that you should never input your real passwords/etc. in this file, it is only here to remind you which
|
292
|
+
settings are in your bag. This file is checked into version control. We will cover setting up the data bag with your real
|
293
|
+
information in [chef walk through on the wiki](https://github.com/nickjj/orats/wiki/Chef-walk-through).
|
294
|
+
|
295
|
+
### Workflow for customizing the cookbook
|
296
|
+
|
297
|
+
This cookbook is designed to be a generic base to get you started. It is highly encouraged to change the cookbook to suite your
|
298
|
+
exact needs. A typical workflow for making changes to the cookbook is this:
|
299
|
+
|
300
|
+
- Edit any files that you want to change.
|
301
|
+
- Bump the version in the `metadata.rb` file. *Never forget to do this step!*
|
302
|
+
- Run `berks upload` which sends the cookbooks up to your hosted chef server.
|
303
|
+
|
304
|
+
If you need to add new cookbooks then add them to `metadata.rb` and run `berks install`. If you need to pull in a cookbook
|
305
|
+
from a git repo or your local file system then put them in your `Berksfile` and also place them in `metadata.rb`. Check the
|
306
|
+
berkshelf documentation for more details.
|
307
|
+
|
308
|
+
#### Applying the cookbook changes on your server
|
309
|
+
|
310
|
+
This step is highly dependent but you have a few options. The first option is to ssh into your node and run `sudo chef-client`.
|
311
|
+
Replace ssh with capistrano if you want but the idea is the same. You would be manually invoking the `chef-client` command
|
312
|
+
which tells your node to contact the hosted chef server and pull in the changes.
|
313
|
+
|
314
|
+
The second option would be to setup a cronjob to run `chef-client` automatically at whatever interval you want. By default
|
315
|
+
I did not include this because by default chef does not do this.
|
316
|
+
|
317
|
+
Chef is idempotent so it will not re-run tasks that result in nothing changing so feel free to make changes whenever you
|
318
|
+
see fit.
|
319
|
+
|
320
|
+
### The server is up but how do I deploy my application?
|
186
321
|
|
187
|
-
|
322
|
+
This is another area where there are many options. You could use capistrano but you could also have chef manage the application
|
323
|
+
deployment too. I have a few old capistrano 2.x scripts that work fine and I really do not have any intentions of porting
|
324
|
+
them over to capistrano 3 scripts so they can be included as an orats template because I do not want to use capistrano anymore.
|
188
325
|
|
189
|
-
I
|
190
|
-
|
326
|
+
I'm calling out to the community for help. Can a chef expert please leverage the `deploy` or `application` resources
|
327
|
+
and provide us with a well documented solution to deploy a rails application with chef? Complete with runit scripts for
|
328
|
+
ensuring puma and sidekiq are always running of course.
|
191
329
|
|
192
|
-
|
193
|
-
dump out a ~200 line cookbook that configures everything to get a server up and running and all you would have to do is
|
194
|
-
change a few settings in the chef attributes file and setup an encrypted data bag like usual.
|
330
|
+
### Walk through
|
195
331
|
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
requests to add this functionality in.
|
332
|
+
If you have very little chef experience and want to go through the steps of creating a new orats project with a cookbook,
|
333
|
+
pushing it to a free managed chef server solution and bootstrapping a server on a local virtual machine then check out the
|
334
|
+
[chef walk through on the wiki](https://github.com/nickjj/orats/wiki/Chef-walk-through).
|
data/lib/orats/cli.rb
CHANGED
@@ -8,78 +8,128 @@ module Orats
|
|
8
8
|
include Shell
|
9
9
|
include Server
|
10
10
|
|
11
|
-
attr_accessor :
|
11
|
+
attr_accessor :active_path, :active_project
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
option :pg_location, default: 'localhost'
|
14
|
+
option :pg_username, default: 'postgres'
|
15
|
+
option :pg_password, required: true
|
16
|
+
option :auth, type: :boolean, default: false, aliases: '-a'
|
17
|
+
option :skip_cook, type: :boolean, default: false, aliases: '-C'
|
18
|
+
option :skip_extras, type: :boolean, default: false, aliases: '-E'
|
19
|
+
desc 'new APP_PATH [options]', ''
|
20
|
+
long_desc <<-LONGDESC
|
21
|
+
`orats new myapp --pg-password supersecret` will create a new orats project and it will also create a chef cookbook to go with it by default.
|
15
22
|
|
16
|
-
|
17
|
-
desc 'base APP_NAME', 'Create a new rails application using the base template.'
|
18
|
-
def base(app_name)
|
19
|
-
@app_name = app_name
|
23
|
+
You must supply at least this flag:
|
20
24
|
|
21
|
-
|
25
|
+
`--pg-password` to supply your development postgres password so the rails application can run database migrations
|
22
26
|
|
23
|
-
|
24
|
-
git_commit 'Change the postgres information'
|
27
|
+
Configuration:
|
25
28
|
|
26
|
-
|
27
|
-
git_commit 'Add gem lock file'
|
29
|
+
`--pg-location` to supply a custom postgres location [localhost]
|
28
30
|
|
29
|
-
|
30
|
-
git_commit 'Add the database schema file'
|
31
|
+
`--pg-username` to supply a custom postgres username [postgres]
|
31
32
|
|
32
|
-
|
33
|
-
|
33
|
+
Template features:
|
34
|
+
|
35
|
+
`--auth` will include authentication and authorization [false]
|
34
36
|
|
35
|
-
|
36
|
-
desc 'auth APP_NAME', 'Create a new rails application with authentication/authorization.'
|
37
|
-
def auth(app_name)
|
38
|
-
@app_name = app_name
|
37
|
+
Project features:
|
39
38
|
|
40
|
-
|
39
|
+
`--skip-cook` skip creating the cookbook [false]
|
41
40
|
|
42
|
-
|
41
|
+
`--skip-extras` skip creating the services directory and cookbook [false]
|
42
|
+
LONGDESC
|
43
|
+
def new(app_name)
|
44
|
+
@options = options
|
45
|
+
@active_path = app_name
|
43
46
|
|
44
|
-
|
47
|
+
@active_path = services_path(app_name)
|
48
|
+
rails_template 'base' do
|
49
|
+
gsub_postgres_info
|
50
|
+
|
51
|
+
bundle_install
|
52
|
+
git_commit 'Change the postgres information'
|
53
|
+
git_commit 'Add gem lock file'
|
54
|
+
|
55
|
+
run_rake 'db:create:all db:migrate db:test:prepare'
|
56
|
+
git_commit 'Add the database schema file'
|
57
|
+
end
|
58
|
+
|
59
|
+
if options[:auth]
|
60
|
+
rails_template 'auth', '--skip ' do
|
61
|
+
run_rake 'db:migrate db:seed'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
unless options[:skip_cook] || options[:skip_extras]
|
66
|
+
cook_app cookbooks_path(app_name)
|
67
|
+
end
|
45
68
|
|
69
|
+
@active_path = services_path(app_name)
|
46
70
|
foreman_start unless invoked?
|
47
71
|
end
|
48
72
|
|
49
|
-
desc '
|
50
|
-
|
51
|
-
|
73
|
+
desc 'cook APP_PATH', ''
|
74
|
+
long_desc <<-LONGDESC
|
75
|
+
`orats cook myapp` will create a stand alone cookbook.
|
76
|
+
LONGDESC
|
77
|
+
def cook(app_name)
|
78
|
+
@options = options
|
79
|
+
@active_path = app_name
|
80
|
+
|
81
|
+
cook_app app_name
|
82
|
+
end
|
83
|
+
|
84
|
+
option :skip_data, type: :boolean, default: false, aliases: '-S'
|
85
|
+
desc 'nuke APP_PATH [options]', ''
|
86
|
+
long_desc <<-LONGDESC
|
87
|
+
`orats nuke myapp` will delete the directory and optionally all data associated to it.
|
88
|
+
|
89
|
+
Options:
|
90
|
+
|
91
|
+
`--skip-data` will skip deleting app specific postgres databases and redis namespaces [false]
|
92
|
+
LONGDESC
|
52
93
|
def nuke(app_name)
|
53
|
-
@
|
94
|
+
@active_path = app_name
|
54
95
|
|
55
96
|
puts
|
56
97
|
say_status 'nuke', "\e[1mYou are about to permanently delete this directory:\e[0m", :red
|
57
|
-
say_status 'path', "#{File.expand_path(
|
98
|
+
say_status 'path', "#{File.expand_path(@active_path)}", :yellow
|
58
99
|
|
59
|
-
|
100
|
+
unless options[:skip_data]
|
60
101
|
puts
|
61
102
|
say_status 'nuke', "\e[1mYou are about to permanently delete these postgres databases:\e[0m", :red
|
62
|
-
say_status 'databases', "#{
|
103
|
+
say_status 'databases', "#{active_project} and #{active_project}_test", :yellow
|
63
104
|
puts
|
64
105
|
say_status 'nuke', "\e[1mYou are about to permanently delete this redis namespace:\e[0m", :red
|
65
|
-
say_status 'namespace',
|
106
|
+
say_status 'namespace', active_project, :yellow
|
66
107
|
end
|
67
108
|
puts
|
68
109
|
|
69
110
|
confirmed_to_delete = yes?('Are you sure? (y/N)', :cyan)
|
70
111
|
|
71
112
|
if confirmed_to_delete
|
72
|
-
|
113
|
+
unless options[:skip_data]
|
73
114
|
run_rake 'db:drop:all'
|
74
115
|
nuke_redis
|
75
|
-
nuke_directory
|
76
116
|
end
|
117
|
+
|
118
|
+
nuke_directory
|
77
119
|
end
|
78
120
|
end
|
79
121
|
|
80
122
|
private
|
81
|
-
def
|
82
|
-
@
|
123
|
+
def active_project
|
124
|
+
@active_path.split('/').last
|
125
|
+
end
|
126
|
+
|
127
|
+
def services_path(app_name)
|
128
|
+
options[:skip_extras] ? app_name : "#{app_name}/services/#{active_project}"
|
129
|
+
end
|
130
|
+
|
131
|
+
def cookbooks_path(app_name)
|
132
|
+
"#{app_name}/cookbooks/#{active_project}"
|
83
133
|
end
|
84
134
|
|
85
135
|
def invoked?
|
data/lib/orats/server.rb
CHANGED
@@ -6,7 +6,7 @@ module Orats
|
|
6
6
|
def foreman_start
|
7
7
|
puts '', '='*80
|
8
8
|
say_status 'action', "\e[1mStarting server with the following commands:\e[0m", :cyan
|
9
|
-
say_status 'command', "cd #{@
|
9
|
+
say_status 'command', "cd #{@active_path}", :magenta
|
10
10
|
say_status 'command', 'bundle exec foreman start', :magenta
|
11
11
|
puts '='*80, ''
|
12
12
|
|
@@ -25,7 +25,8 @@ module Orats
|
|
25
25
|
end
|
26
26
|
|
27
27
|
puts
|
28
|
-
|
28
|
+
|
29
|
+
run_from @active_path, 'bundle exec foreman start'
|
29
30
|
end
|
30
31
|
|
31
32
|
def port_taken?
|
data/lib/orats/shell.rb
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
module Orats
|
2
2
|
module Shell
|
3
|
-
def
|
4
|
-
run "cd #{
|
3
|
+
def run_from(path, command)
|
4
|
+
run "cd #{path} && #{command} && cd -"
|
5
|
+
end
|
6
|
+
|
7
|
+
def cd_inside(path, &block)
|
8
|
+
run "cd #{path}"
|
9
|
+
yield
|
10
|
+
run 'cd -'
|
5
11
|
end
|
6
12
|
|
7
13
|
def log_message(type, message)
|
@@ -11,39 +17,105 @@ module Orats
|
|
11
17
|
end
|
12
18
|
|
13
19
|
def git_commit(message)
|
14
|
-
|
20
|
+
run_from @active_path, "git add . && git commit -m '#{message}'"
|
15
21
|
end
|
16
22
|
|
17
|
-
def gsub_postgres_info
|
23
|
+
def gsub_postgres_info
|
18
24
|
log_message 'root', 'Changing the postgres information'
|
19
25
|
|
20
|
-
gsub_file "#{@
|
21
|
-
gsub_file "#{@
|
22
|
-
gsub_file "#{@
|
26
|
+
gsub_file "#{@active_path}/.env", ': localhost', ": #{@options[:pg_location]}"
|
27
|
+
gsub_file "#{@active_path}/.env", ': postgres', ": #{@options[:pg_username]}"
|
28
|
+
gsub_file "#{@active_path}/.env", ': supersecrets', ": #{@options[:pg_password]}"
|
23
29
|
end
|
24
30
|
|
25
31
|
def run_rake(command)
|
26
32
|
log_message 'shell', 'Running rake commands'
|
27
33
|
|
28
|
-
|
34
|
+
run_from @active_path, "bundle exec rake #{command}"
|
29
35
|
end
|
30
36
|
|
31
37
|
def bundle_install
|
32
38
|
log_message 'shell', 'Running bundle install, this may take a while'
|
33
39
|
|
34
|
-
|
40
|
+
run_from @active_path, 'bundle install'
|
35
41
|
end
|
36
42
|
|
37
43
|
def nuke_redis
|
38
44
|
log_message 'root', 'Removing redis keys'
|
39
45
|
|
40
|
-
run "redis-cli KEYS '#{
|
46
|
+
run "redis-cli KEYS '#{active_project}:*' | xargs --delim='\n' redis-cli DEL"
|
41
47
|
end
|
42
48
|
|
43
49
|
def nuke_directory
|
44
50
|
log_message 'root', 'Deleting directory'
|
45
51
|
|
46
|
-
run "rm -rf #{@
|
52
|
+
run "rm -rf #{@active_path}"
|
53
|
+
end
|
54
|
+
|
55
|
+
def exit_if_exists
|
56
|
+
log_message 'shell', 'Checking if a file or directory already exists'
|
57
|
+
|
58
|
+
if Dir.exist?(@active_path) || File.exist?(@active_path)
|
59
|
+
puts
|
60
|
+
say_status 'aborting', "\e[1mA file or directory already exists at this location:\e[0m", :red
|
61
|
+
say_status 'location', @active_path, :yellow
|
62
|
+
puts '-'*80
|
63
|
+
puts
|
64
|
+
|
65
|
+
exit 1
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def exit_if_cannot_cook
|
70
|
+
log_message 'shell', 'Checking for the cookbook system dependencies'
|
71
|
+
|
72
|
+
has_knife = run('which knife', capture: true)
|
73
|
+
has_berks = run('which berks', capture: true)
|
74
|
+
|
75
|
+
dependency_error 'Cannot access knife',
|
76
|
+
'Are you sure you have chef setup correctly?',
|
77
|
+
'http://www.getchef.com/chef/install/`' if has_knife.empty?
|
78
|
+
|
79
|
+
|
80
|
+
dependency_error 'Cannot access berkshelf',
|
81
|
+
'Are you sure you have berkshelf installed correctly?',
|
82
|
+
'You can install it by running `gem install berkshelf`' if has_berks.empty?
|
83
|
+
end
|
84
|
+
|
85
|
+
def exit_if_cannot_rails
|
86
|
+
log_message 'shell', 'Checking for rails'
|
87
|
+
|
88
|
+
has_rails = run('which rails', capture: true)
|
89
|
+
|
90
|
+
dependency_error 'Cannot access rails',
|
91
|
+
'Are you sure you have rails setup correctly?',
|
92
|
+
'You can install it by running `gem install rails`' if has_rails.empty?
|
93
|
+
end
|
94
|
+
|
95
|
+
def dependency_error(message, question, answer)
|
96
|
+
puts
|
97
|
+
say_status 'error', "\e[1m#{message}\e[0m", :red
|
98
|
+
say_status 'question', question, :yellow
|
99
|
+
say_status 'answer', answer, :cyan
|
100
|
+
puts '-'*80
|
101
|
+
puts
|
102
|
+
|
103
|
+
exit 1
|
104
|
+
end
|
105
|
+
|
106
|
+
def rails_template(command, flags = '', &block)
|
107
|
+
exit_if_cannot_rails
|
108
|
+
exit_if_exists unless flags.index(/--skip /)
|
109
|
+
|
110
|
+
run "rails new #{@active_path} #{flags}--skip-bundle --template #{File.expand_path File.dirname(__FILE__)}/templates/#{command}.rb"
|
111
|
+
yield if block_given?
|
112
|
+
end
|
113
|
+
|
114
|
+
def cook_app(app_path)
|
115
|
+
exit_if_cannot_cook
|
116
|
+
|
117
|
+
@active_path = app_path
|
118
|
+
rails_template 'cook'
|
47
119
|
end
|
48
120
|
end
|
49
121
|
end
|
File without changes
|
@@ -11,7 +11,7 @@ def generate_token
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def from_gem(source, destination = nil)
|
14
|
-
base_path = "#{File.expand_path File.dirname(__FILE__)}
|
14
|
+
base_path = "#{File.expand_path File.dirname(__FILE__)}/includes"
|
15
15
|
file_name = source.split('/').last
|
16
16
|
|
17
17
|
if destination.present? && file_name != destination
|
@@ -0,0 +1,630 @@
|
|
1
|
+
# =====================================================================================================
|
2
|
+
# Template for generating a chef cookbook
|
3
|
+
# =====================================================================================================
|
4
|
+
|
5
|
+
# ----- Helper functions and variables ----------------------------------------------------------------
|
6
|
+
|
7
|
+
require 'securerandom'
|
8
|
+
|
9
|
+
def generate_token
|
10
|
+
SecureRandom.hex(64)
|
11
|
+
end
|
12
|
+
|
13
|
+
def git_config(field)
|
14
|
+
command = "git config --global user.#{field}"
|
15
|
+
git_field_value = run(command, capture: true).gsub("\n", '')
|
16
|
+
default_value = "YOUR_#{field.upcase}"
|
17
|
+
|
18
|
+
git_field_value.to_s.empty? ? default_value : git_field_value
|
19
|
+
end
|
20
|
+
|
21
|
+
app_name_upper = app_name.upcase
|
22
|
+
app_name_class = app_name.humanize
|
23
|
+
|
24
|
+
author_name = git_config 'name'
|
25
|
+
author_email = git_config 'email'
|
26
|
+
|
27
|
+
# ----- Nuke all of the rails code --------------------------------------------------------------------
|
28
|
+
|
29
|
+
puts
|
30
|
+
say_status 'shell', 'Removing all of the generated rails code...', :yellow
|
31
|
+
puts '-'*80, ''; sleep 0.25
|
32
|
+
|
33
|
+
run 'rm -rf * .git .gitignore'
|
34
|
+
|
35
|
+
# ----- Install berkshelf -----------------------------------------------------------------------------
|
36
|
+
|
37
|
+
puts
|
38
|
+
say_status 'tool', 'Gem installing berkshelf, this may take a while...', :yellow
|
39
|
+
puts '-'*80, ''; sleep 0.25
|
40
|
+
|
41
|
+
run 'gem install berkshelf'
|
42
|
+
|
43
|
+
# ----- Create cookbook -------------------------------------------------------------------------------
|
44
|
+
|
45
|
+
puts
|
46
|
+
say_status 'init', 'Creating skeleton cookbook...', :yellow
|
47
|
+
puts '-'*80, ''; sleep 0.25
|
48
|
+
|
49
|
+
run "berks cookbook #{app_name}"
|
50
|
+
|
51
|
+
# ----- Move cookbook back one directory --------------------------------------------------------------
|
52
|
+
|
53
|
+
puts
|
54
|
+
say_status 'shell', 'Moving cookbook back one directory...', :yellow
|
55
|
+
puts '-'*80, ''; sleep 0.25
|
56
|
+
|
57
|
+
run "mv #{app_name}/* ."
|
58
|
+
run "rm -rf #{app_name}"
|
59
|
+
|
60
|
+
# ----- Create the git repo ---------------------------------------------------------------------------
|
61
|
+
|
62
|
+
puts
|
63
|
+
say_status 'git', 'Creating initial commit...', :yellow
|
64
|
+
puts '-'*80, ''; sleep 0.25
|
65
|
+
|
66
|
+
git :init
|
67
|
+
git add: '.'
|
68
|
+
git commit: "-m 'Initial commit'"
|
69
|
+
|
70
|
+
# ----- Create the license ----------------------------------------------------------------------------
|
71
|
+
|
72
|
+
puts
|
73
|
+
say_status 'root', 'Creating the license', :yellow
|
74
|
+
puts '-'*80, ''; sleep 0.25
|
75
|
+
|
76
|
+
run 'rm -rf LICENSE'
|
77
|
+
|
78
|
+
file 'LICENSE' do <<-TEXT
|
79
|
+
The MIT License (MIT)
|
80
|
+
|
81
|
+
Copyright (c) #{Time.now.year} #{author_name} <#{author_email}>
|
82
|
+
|
83
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
84
|
+
a copy of this software and associated documentation files (the
|
85
|
+
'Software'), to deal in the Software without restriction, including
|
86
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
87
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
88
|
+
permit persons to whom the Software is furnished to do so, subject to
|
89
|
+
the following conditions:
|
90
|
+
|
91
|
+
The above copyright notice and this permission notice shall be
|
92
|
+
included in all copies or substantial portions of the Software.
|
93
|
+
|
94
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
95
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
96
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
97
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
98
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
99
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
100
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
101
|
+
TEXT
|
102
|
+
end
|
103
|
+
|
104
|
+
git add: '.'
|
105
|
+
git commit: "-m 'Add MIT license'"
|
106
|
+
|
107
|
+
# ----- Customize meta data ---------------------------------------------------------------------------
|
108
|
+
|
109
|
+
puts
|
110
|
+
say_status 'root', 'Changing metadata file', :yellow
|
111
|
+
puts '-'*80, ''; sleep 0.25
|
112
|
+
|
113
|
+
puts author_name
|
114
|
+
puts author_email
|
115
|
+
|
116
|
+
gsub_file 'metadata.rb', 'YOUR_NAME', author_name
|
117
|
+
gsub_file 'metadata.rb', 'YOUR_EMAIL', author_email
|
118
|
+
gsub_file 'metadata.rb', 'All rights reserved', 'MIT LICENSE'
|
119
|
+
|
120
|
+
git add: '.'
|
121
|
+
git commit: "-m 'Change meta data in the metadata.rb file'"
|
122
|
+
|
123
|
+
# ----- Add application dependencies ------------------------------------------------------------------
|
124
|
+
|
125
|
+
puts
|
126
|
+
say_status 'root', 'Adding application dependencies...', :yellow
|
127
|
+
puts '-'*80, ''; sleep 0.25
|
128
|
+
|
129
|
+
append_file 'Berksfile' do <<-CODE
|
130
|
+
cookbook 'postgresql', git: 'git://github.com/phlipper/chef-postgresql.git'
|
131
|
+
cookbook 'rvm', git: 'git://github.com/fnichol/chef-rvm'
|
132
|
+
CODE
|
133
|
+
end
|
134
|
+
|
135
|
+
git add: '.'
|
136
|
+
git commit: "-m 'Add dependencies to the Berksfile'"
|
137
|
+
|
138
|
+
append_file 'metadata.rb' do <<-CODE
|
139
|
+
# base
|
140
|
+
depends 'openssh', '~> 1.3.2'
|
141
|
+
depends 'user', '~> 0.3.0'
|
142
|
+
depends 'sudo', '~> 2.3.0'
|
143
|
+
depends 'fail2ban', '~> 2.1.2'
|
144
|
+
depends 'ufw', '~> 0.7.4'
|
145
|
+
depends 'swap', '~> 0.3.6'
|
146
|
+
|
147
|
+
# database
|
148
|
+
depends 'postgresql', '~> 0.13.0'
|
149
|
+
|
150
|
+
# cache
|
151
|
+
depends 'redisio', '~> 1.7.0'
|
152
|
+
|
153
|
+
# web
|
154
|
+
depends 'git', '~> 2.9.0'
|
155
|
+
depends 'rvm', '~> 0.9.1'
|
156
|
+
depends 'nodejs', '~> 1.3.0'
|
157
|
+
depends 'nginx', '~> 2.2.0'
|
158
|
+
depends 'logrotate', '~> 1.4.0'
|
159
|
+
CODE
|
160
|
+
end
|
161
|
+
|
162
|
+
git add: '.'
|
163
|
+
git commit: "-m 'Add dependencies to the metadata file'"
|
164
|
+
|
165
|
+
# ----- Install cookbooks locally ---------------------------------------------------------------------
|
166
|
+
|
167
|
+
puts
|
168
|
+
say_status 'tool', 'Berks installing the cookbooks, this may take a while...', :yellow
|
169
|
+
puts '-'*80, ''; sleep 0.25
|
170
|
+
|
171
|
+
run 'berks install'
|
172
|
+
|
173
|
+
git add: '.'
|
174
|
+
git commit: "-m 'Change meta data in the metadata.rb file'"
|
175
|
+
|
176
|
+
# ----- Configure attributes file ---------------------------------------------------------------------
|
177
|
+
|
178
|
+
puts
|
179
|
+
say_status 'attr', 'Modifying the attributes file...', :yellow
|
180
|
+
puts '-'*80, ''; sleep 0.25
|
181
|
+
|
182
|
+
random_ssh_port = rand(11000..55000)
|
183
|
+
random_username = SecureRandom.hex[0...8]
|
184
|
+
|
185
|
+
file 'attributes/default.rb' do <<-CODE
|
186
|
+
default[:#{app_name}][:base][:ssh_port] = '#{random_ssh_port}'
|
187
|
+
default[:#{app_name}][:base][:username] = '#{random_username}'
|
188
|
+
default[:#{app_name}][:base][:swap_size] = 1024 # MBs
|
189
|
+
default[:#{app_name}][:base][:ssh_key] = 'INSERT_YOUR_PUBLIC_SSH_KEY_HERE'
|
190
|
+
|
191
|
+
default[:#{app_name}][:database][:host] = 'localhost'
|
192
|
+
default[:#{app_name}][:database][:pool] = '25'
|
193
|
+
default[:#{app_name}][:database][:timeout] = '5000'
|
194
|
+
|
195
|
+
default[:#{app_name}][:cache][:host] = 'localhost'
|
196
|
+
default[:#{app_name}][:cache][:port] = '6379'
|
197
|
+
default[:#{app_name}][:cache][:database] = '0'
|
198
|
+
default[:#{app_name}][:cache][:sidekiq_concurrency] = '25'
|
199
|
+
|
200
|
+
default[:#{app_name}][:web][:ruby_version] = '2.1.0'
|
201
|
+
default[:#{app_name}][:web][:puma_threads_min] = '0'
|
202
|
+
default[:#{app_name}][:web][:puma_threads_max] = '16'
|
203
|
+
default[:#{app_name}][:web][:puma_workers] = '2'
|
204
|
+
default[:#{app_name}][:web][:mail_address] = 'smtp.#{app_name}.com'
|
205
|
+
default[:#{app_name}][:web][:mail_port] = '25'
|
206
|
+
default[:#{app_name}][:web][:mail_domain] = '#{app_name}.com'
|
207
|
+
default[:#{app_name}][:web][:mail_username] = 'info@#{app_name}.com'
|
208
|
+
default[:#{app_name}][:web][:mail_auth] = 'plain'
|
209
|
+
default[:#{app_name}][:web][:mail_startttls_auto] = 'true'
|
210
|
+
default[:#{app_name}][:web][:action_mailer_host] = 'www.#{app_name}.com'
|
211
|
+
default[:#{app_name}][:web][:action_mailer_default_email] = 'info@#{app_name}.com'
|
212
|
+
default[:#{app_name}][:web][:action_mailer_devise_default_email] = 'info@#{app_name}.com'
|
213
|
+
CODE
|
214
|
+
end
|
215
|
+
|
216
|
+
git add: '.'
|
217
|
+
git commit: "-m 'Add tweakable settings to the attributes file'"
|
218
|
+
|
219
|
+
# ----- Create dummy data for the encrypted data bag --------------------------------------------------
|
220
|
+
|
221
|
+
puts
|
222
|
+
say_status 'data_bags', 'Creating dummy encrypted data bag...', :yellow
|
223
|
+
puts '-'*80, ''; sleep 0.25
|
224
|
+
|
225
|
+
data_bag_path = "data_bags/#{app_name}_secrets"
|
226
|
+
|
227
|
+
run "mkdir -p #{data_bag_path}"
|
228
|
+
|
229
|
+
file "#{data_bag_path}/production.json" do <<-JSON
|
230
|
+
{
|
231
|
+
"id": "production",
|
232
|
+
"database_password": "<real password is protected>",
|
233
|
+
"cache_password": "<real password is protected>",
|
234
|
+
"mail_password": "<real password is protected>",
|
235
|
+
"token_rails_secret": "<real token is protected>",
|
236
|
+
"token_devise_secret": "<real token is protected>",
|
237
|
+
"token_devise_pepper": "<real token is protected>"
|
238
|
+
}
|
239
|
+
JSON
|
240
|
+
end
|
241
|
+
|
242
|
+
git add: '.'
|
243
|
+
git commit: "-m 'Add the dummy data bag as a point of reference'"
|
244
|
+
|
245
|
+
# ----- Create nginx config ---------------------------------------------------------------------------
|
246
|
+
|
247
|
+
puts
|
248
|
+
say_status 'files', 'Creating nginx config...', :yellow
|
249
|
+
puts '-'*80, ''; sleep 0.25
|
250
|
+
|
251
|
+
file "files/default/nginx_virtualhost.conf" do <<-CONF
|
252
|
+
upstream #{app_name} {
|
253
|
+
server unix:///tmp/#{app_name}.sock;
|
254
|
+
}
|
255
|
+
|
256
|
+
# redirect non-www to www (remove this block if you do not want to do this)
|
257
|
+
server {
|
258
|
+
listen 80;
|
259
|
+
server_name #{app_name}.com;
|
260
|
+
return 301 $scheme://www.#{app_name}.com$request_uri;
|
261
|
+
}
|
262
|
+
|
263
|
+
server {
|
264
|
+
listen 80;
|
265
|
+
server_name www.#{app_name}.com;
|
266
|
+
root /home/#{random_username}/www/#{app_name}/current/public;
|
267
|
+
|
268
|
+
error_page 404 /404.html;
|
269
|
+
error_page 500 /500.html;
|
270
|
+
error_page 502 503 504 /502.html;
|
271
|
+
|
272
|
+
location ~ ^/(system|assets)/ {
|
273
|
+
root /home/#{random_username}/www/#{app_name}/current/public;
|
274
|
+
gzip_static on;
|
275
|
+
expires 1y;
|
276
|
+
add_header Cache-Control public;
|
277
|
+
add_header ETag "";
|
278
|
+
break;
|
279
|
+
}
|
280
|
+
|
281
|
+
try_files $uri @puma;
|
282
|
+
|
283
|
+
location @puma {
|
284
|
+
proxy_set_header X-Real-IP $remote_addr;
|
285
|
+
proxy_set_header X-Forwarded-Proto http;
|
286
|
+
proxy_set_header Host $http_host;
|
287
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
288
|
+
proxy_redirect off;
|
289
|
+
|
290
|
+
proxy_pass http://#{app_name};
|
291
|
+
break;
|
292
|
+
}
|
293
|
+
}
|
294
|
+
CONF
|
295
|
+
end
|
296
|
+
|
297
|
+
git add: '.'
|
298
|
+
git commit: "-m 'Add the nginx virtualhost config'"
|
299
|
+
|
300
|
+
# ----- Create system wide profile -------------------------------------------------------------------------
|
301
|
+
|
302
|
+
puts
|
303
|
+
say_status 'templates', 'Creating system wide profile config', :yellow
|
304
|
+
puts '-'*80, ''; sleep 0.25
|
305
|
+
|
306
|
+
file 'templates/default/profile.erb' do <<-CONF
|
307
|
+
# /etc/profile: system-wide .profile file for the Bourne shell (sh(1))
|
308
|
+
# and Bourne compatible shells (bash(1), ksh(1), ash(1), ...).
|
309
|
+
|
310
|
+
if [ "$PS1" ]; then
|
311
|
+
if [ "$BASH" ] && [ "$BASH" != "/bin/sh" ]; then
|
312
|
+
# The file bash.bashrc already sets the default PS1.
|
313
|
+
# PS1='\h:\w\$ '
|
314
|
+
if [ -f /etc/bash.bashrc ]; then
|
315
|
+
. /etc/bash.bashrc
|
316
|
+
fi
|
317
|
+
else
|
318
|
+
if [ "`id -u`" -eq 0 ]; then
|
319
|
+
PS1='# '
|
320
|
+
else
|
321
|
+
PS1='$ '
|
322
|
+
fi
|
323
|
+
fi
|
324
|
+
fi
|
325
|
+
|
326
|
+
# The default umask is now handled by pam_umask.
|
327
|
+
# See pam_umask(8) and /etc/login.defs.
|
328
|
+
|
329
|
+
if [ -d /etc/profile.d ]; then
|
330
|
+
for i in /etc/profile.d/*.sh; do
|
331
|
+
if [ -r $i ]; then
|
332
|
+
. $i
|
333
|
+
fi
|
334
|
+
done
|
335
|
+
unset i
|
336
|
+
fi
|
337
|
+
|
338
|
+
export <%= @cookbook_name.upcase %>_TOKEN_RAILS_SECRET='<%= @token_rails_secret %>'
|
339
|
+
export <%= @cookbook_name.upcase %>_TOKEN_DEVISE_SECRET='<%= @token_devise_secret %>'
|
340
|
+
export <%= @cookbook_name.upcase %>_TOKEN_DEVISE_PEPPER='<%= @token_devise_pepper %>'
|
341
|
+
|
342
|
+
export <%= @cookbook_name.upcase %>_SMTP_ADDRESS='<%= node[:#{app_name}][:web][:mail_address] %>'
|
343
|
+
export <%= @cookbook_name.upcase %>_SMTP_PORT='<%= node[:#{app_name}][:web][:mail_port] %>'
|
344
|
+
export <%= @cookbook_name.upcase %>_SMTP_DOMAIN='<%= node[:#{app_name}][:web][:mail_domain] %>'
|
345
|
+
export <%= @cookbook_name.upcase %>_SMTP_USERNAME='<%= node[:#{app_name}][:web][:mail_username] %>'
|
346
|
+
export <%= @cookbook_name.upcase %>_SMTP_PASSWORD='<%= @mail_password %>'
|
347
|
+
export <%= @cookbook_name.upcase %>_SMTP_AUTH='<%= node[:#{app_name}][:web][:mail_auth] %>'
|
348
|
+
export <%= @cookbook_name.upcase %>_SMTP_STARTTTLS_AUTO='<%= node[:#{app_name}][:web][:mail_startttls_auto] %>'
|
349
|
+
|
350
|
+
export <%= @cookbook_name.upcase %>_ACTION_MAILER_HOST='<%= node[:#{app_name}][:web][:action_mailer_host] %>'
|
351
|
+
export <%= @cookbook_name.upcase %>_ACTION_MAILER_DEFAULT_EMAIL='<%= node[:#{app_name}][:web][:action_mailer_default_email] %>'
|
352
|
+
export <%= @cookbook_name.upcase %>_ACTION_MAILER_DEVISE_DEFAULT_EMAIL='<%= node[:#{app_name}][:web][:action_mailer_devise_default_email] %>'
|
353
|
+
|
354
|
+
export <%= @cookbook_name.upcase %>_DATABASE_HOST='<%= node[:#{app_name}][:database][:host] %>'
|
355
|
+
export <%= @cookbook_name.upcase %>_DATABASE_NAME='<%= @cookbook_name.downcase %>'
|
356
|
+
export <%= @cookbook_name.upcase %>_DATABASE_USERNAME='postgres'
|
357
|
+
export <%= @cookbook_name.upcase %>_DATABASE_PASSWORD='<%= @database_password %>'
|
358
|
+
export <%= @cookbook_name.upcase %>_DATABASE_POOL='<%= node[:#{app_name}][:database][:pool] %>'
|
359
|
+
export <%= @cookbook_name.upcase %>_DATABASE_TIMEOUT='<%= node[:#{app_name}][:database][:timeout] %>'
|
360
|
+
|
361
|
+
export <%= @cookbook_name.upcase %>_CACHE_HOST='<%= node[:#{app_name}][:cache][:host] %>'
|
362
|
+
export <%= @cookbook_name.upcase %>_CACHE_DATABASE='<%= node[:#{app_name}][:cache][:database] %>'
|
363
|
+
export <%= @cookbook_name.upcase %>_CACHE_USERNAME='redis'
|
364
|
+
export <%= @cookbook_name.upcase %>_CACHE_PASSWORD='<%= @cache_password %>'
|
365
|
+
|
366
|
+
export <%= @cookbook_name.upcase %>_SIDEKIQ_CONCURRENCY='<%= node[:#{app_name}][:cache][:sidekiq_concurrency] %>'
|
367
|
+
|
368
|
+
export <%= @cookbook_name.upcase %>_PUMA_THREADS_MIN='<%= node[:#{app_name}][:web][:puma_threads_min] %>'
|
369
|
+
export <%= @cookbook_name.upcase %>_PUMA_THREADS_MAX='<%= node[:#{app_name}][:web][:puma_threads_max] %>'
|
370
|
+
export <%= @cookbook_name.upcase %>_PUMA_WORKERS='<%= node[:#{app_name}][:web][:puma_workers] %>'
|
371
|
+
CONF
|
372
|
+
end
|
373
|
+
|
374
|
+
git add: '.'
|
375
|
+
git commit: "-m 'Add the system wide profile config'"
|
376
|
+
|
377
|
+
# ----- Create base recipe ----------------------------------------------------------------------------
|
378
|
+
|
379
|
+
puts
|
380
|
+
say_status 'recipes', 'Creating base recipe...', :yellow
|
381
|
+
puts '-'*80, ''; sleep 0.25
|
382
|
+
|
383
|
+
file 'recipes/base.rb' do <<-'CODE'
|
384
|
+
# openssh
|
385
|
+
|
386
|
+
node.override[:openssh][:server][:port] = node[:app_name][:base][:ssh_port]
|
387
|
+
node.override[:openssh][:server][:password_authentication] = 'no'
|
388
|
+
node.override[:openssh][:server][:permit_root_login] = 'no'
|
389
|
+
include_recipe 'openssh'
|
390
|
+
|
391
|
+
# user
|
392
|
+
|
393
|
+
include_recipe 'user'
|
394
|
+
|
395
|
+
user_account node[:app_name][:base][:username] do
|
396
|
+
ssh_keys [ node[:app_name][:base][:ssh_key] ]
|
397
|
+
end
|
398
|
+
|
399
|
+
# sudo
|
400
|
+
|
401
|
+
node.override[:authorization][:sudo][:users] = [ node[:app_name][:base][:username] ]
|
402
|
+
node.override[:authorization][:sudo][:passwordless] = true
|
403
|
+
|
404
|
+
include_recipe 'sudo'
|
405
|
+
|
406
|
+
# fail2ban
|
407
|
+
|
408
|
+
include_recipe 'fail2ban'
|
409
|
+
|
410
|
+
# ufw
|
411
|
+
|
412
|
+
node.override[:firewall][:rules] = [
|
413
|
+
{
|
414
|
+
'ssh' => {
|
415
|
+
'port'=> node[:app_name][:base][:ssh_port]
|
416
|
+
}
|
417
|
+
},
|
418
|
+
{
|
419
|
+
'http' => {
|
420
|
+
'port'=> '80'
|
421
|
+
}
|
422
|
+
}
|
423
|
+
]
|
424
|
+
include_recipe 'ufw'
|
425
|
+
|
426
|
+
# swapfile
|
427
|
+
swap_file '/mnt/swap' do
|
428
|
+
size node[:app_name][:base][:swap_size]
|
429
|
+
end
|
430
|
+
|
431
|
+
# htop
|
432
|
+
package 'htop'
|
433
|
+
CODE
|
434
|
+
end
|
435
|
+
|
436
|
+
gsub_file 'recipes/base.rb', 'app_name', app_name
|
437
|
+
|
438
|
+
git add: '.'
|
439
|
+
git commit: "-m 'Add the base recipe'"
|
440
|
+
|
441
|
+
# ----- Create database recipe ------------------------------------------------------------------------
|
442
|
+
|
443
|
+
puts
|
444
|
+
say_status 'recipes', 'Creating database recipe...', :yellow
|
445
|
+
puts '-'*80, ''; sleep 0.25
|
446
|
+
|
447
|
+
file 'recipes/database.rb' do <<-CODE
|
448
|
+
# This is where you will store a copy of your key on the chef-client
|
449
|
+
secret = Chef::EncryptedDataBagItem.load_secret('/etc/chef/encrypted_data_bag_secret')
|
450
|
+
|
451
|
+
# This decrypts the data bag contents of "#{app_name}_secrets/production.json" and uses the key defined at variable "secret"
|
452
|
+
encrypted_data_bag = Chef::EncryptedDataBagItem.load('#{app_name}_secrets', 'production', secret)
|
453
|
+
|
454
|
+
include_recipe '#{app_name}::base'
|
455
|
+
include_recipe 'postgresql'
|
456
|
+
include_recipe 'postgresql::client'
|
457
|
+
include_recipe 'postgresql::server'
|
458
|
+
include_recipe 'postgresql::libpq'
|
459
|
+
|
460
|
+
pg_user 'postgres' do
|
461
|
+
privileges superuser: true, createdb: true, login: true
|
462
|
+
password encrypted_data_bag['database_password']
|
463
|
+
end
|
464
|
+
CODE
|
465
|
+
end
|
466
|
+
|
467
|
+
git add: '.'
|
468
|
+
git commit: "-m 'Add the database recipe'"
|
469
|
+
|
470
|
+
# ----- Create cache recipe ---------------------------------------------------------------------------
|
471
|
+
|
472
|
+
puts
|
473
|
+
say_status 'recipes', 'Creating cache recipe...', :yellow
|
474
|
+
puts '-'*80, ''; sleep 0.25
|
475
|
+
|
476
|
+
file 'recipes/cache.rb' do <<-CODE
|
477
|
+
include_recipe '#{app_name}::base'
|
478
|
+
|
479
|
+
node.override[:redisio][:mirror] = 'http://download.redis.io/releases'
|
480
|
+
node.override[:redisio][:version] = '2.8.3'
|
481
|
+
include_recipe 'redisio::install'
|
482
|
+
include_recipe 'redisio::enable'
|
483
|
+
CODE
|
484
|
+
end
|
485
|
+
|
486
|
+
git add: '.'
|
487
|
+
git commit: "-m 'Add the cache recipe'"
|
488
|
+
|
489
|
+
# ----- Create web recipe -----------------------------------------------------------------------------
|
490
|
+
|
491
|
+
puts
|
492
|
+
say_status 'recipes', 'Creating web recipe...', :yellow
|
493
|
+
puts '-'*80, ''; sleep 0.25
|
494
|
+
|
495
|
+
file 'recipes/web.rb' do <<-'CODE'
|
496
|
+
secret = Chef::EncryptedDataBagItem.load_secret('/etc/chef/encrypted_data_bag_secret')
|
497
|
+
encrypted_data_bag = Chef::EncryptedDataBagItem.load('app_name_secrets', 'production', secret)
|
498
|
+
|
499
|
+
include_recipe 'app_name::base'
|
500
|
+
|
501
|
+
# environment variables
|
502
|
+
|
503
|
+
template '/etc/profile' do
|
504
|
+
source 'profile.erb'
|
505
|
+
variables({
|
506
|
+
:cookbook_name => cookbook_name,
|
507
|
+
:database_password => encrypted_data_bag['database_password'],
|
508
|
+
:cache_password => encrypted_data_bag['cache_password'],
|
509
|
+
:mail_password => encrypted_data_bag['mail_password'],
|
510
|
+
:token_rails_secret => encrypted_data_bag['token_rails_secret'],
|
511
|
+
:token_devise_secret => encrypted_data_bag['token_devise_secret'],
|
512
|
+
:token_devise_pepper => encrypted_data_bag['token_devise_pepper']
|
513
|
+
})
|
514
|
+
end
|
515
|
+
|
516
|
+
# git
|
517
|
+
|
518
|
+
apt_repository 'git' do
|
519
|
+
uri 'http://ppa.launchpad.net/git-core/ppa/ubuntu'
|
520
|
+
distribution node[:lsb][:codename]
|
521
|
+
components %w[main]
|
522
|
+
keyserver 'keyserver.ubuntu.com'
|
523
|
+
key 'E1DF1F24'
|
524
|
+
action :add
|
525
|
+
end
|
526
|
+
|
527
|
+
include_recipe 'git'
|
528
|
+
|
529
|
+
repo_path = "/home/#{node[:app_name][:base][:username]}/#{cookbook_name}.git"
|
530
|
+
|
531
|
+
directory repo_path do
|
532
|
+
owner node[:app_name][:base][:username]
|
533
|
+
group node[:app_name][:base][:username]
|
534
|
+
mode 0755
|
535
|
+
end
|
536
|
+
|
537
|
+
execute 'initialize new bare git repo' do
|
538
|
+
user node[:app_name][:base][:username]
|
539
|
+
group node[:app_name][:base][:username]
|
540
|
+
command "cd #{repo_path} && git init --bare"
|
541
|
+
only_if { !File.exists? "#{repo_path}/HEAD" }
|
542
|
+
end
|
543
|
+
|
544
|
+
# node
|
545
|
+
|
546
|
+
node.override[:nodejs][:install_method] = 'binary'
|
547
|
+
node.override[:nodejs][:version] = '0.10.24'
|
548
|
+
node.override[:nodejs][:checksum] = 'fb6487e72d953451d55e28319c446151c1812ed21919168b82ab1664088ecf46'
|
549
|
+
node.override[:nodejs][:checksum_linux_x64] = '423018f6a60b18d0dddf3007c325e0cc8cf55099'
|
550
|
+
node.override[:nodejs][:checksum_linux_x86] = 'fb6487e72d953451d55e28319c446151c1812ed21919168b82ab1664088ecf46'
|
551
|
+
include_recipe 'nodejs::install_from_binary'
|
552
|
+
|
553
|
+
# ruby
|
554
|
+
|
555
|
+
node.override[:rvm][:default_ruby] = node[:app_name][:web][:ruby_version]
|
556
|
+
node.override[:rvm][:global_gems] = [ { 'name' => 'bundler', 'version' => '1.5.1' } ]
|
557
|
+
node.override[:rvm][:group_users] = [ node[:app_name][:base][:username] ]
|
558
|
+
|
559
|
+
include_recipe 'rvm::system'
|
560
|
+
|
561
|
+
# nginx
|
562
|
+
|
563
|
+
apt_repository 'nginx' do
|
564
|
+
uri 'http://ppa.launchpad.net/nginx/stable/ubuntu'
|
565
|
+
distribution node[:lsb][:codename]
|
566
|
+
components %w[main]
|
567
|
+
keyserver 'keyserver.ubuntu.com'
|
568
|
+
key 'C300EE8C'
|
569
|
+
action :add
|
570
|
+
end
|
571
|
+
|
572
|
+
node.override[:nginx][:gzip_comp_level] = '4'
|
573
|
+
|
574
|
+
include_recipe 'nginx'
|
575
|
+
|
576
|
+
cookbook_file 'nginx_virtualhost.conf' do
|
577
|
+
path "#{node[:nginx][:dir]}/sites-available/#{cookbook_name}.conf"
|
578
|
+
group node[:nginx][:user]
|
579
|
+
owner node[:nginx][:user]
|
580
|
+
mode '0644'
|
581
|
+
end
|
582
|
+
|
583
|
+
nginx_site "#{cookbook_name}.conf"
|
584
|
+
|
585
|
+
include_recipe 'logrotate'
|
586
|
+
|
587
|
+
logrotate_app 'nginx' do
|
588
|
+
cookbook 'logrotate'
|
589
|
+
path ["#{node[:nginx][:log_dir]}/access.log", "#{node[:nginx][:log_dir]}/error.log"]
|
590
|
+
options ['missingok', 'notifempty']
|
591
|
+
frequency 'daily'
|
592
|
+
create '0644 root adm'
|
593
|
+
rotate 365
|
594
|
+
end
|
595
|
+
CODE
|
596
|
+
end
|
597
|
+
|
598
|
+
gsub_file 'recipes/web.rb', 'app_name', app_name
|
599
|
+
|
600
|
+
git add: '.'
|
601
|
+
git commit: "-m 'Add the web recipe'"
|
602
|
+
|
603
|
+
# ----- Create default recipe -------------------------------------------------------------------------
|
604
|
+
|
605
|
+
puts
|
606
|
+
say_status 'recipes', 'Creating default recipe...', :yellow
|
607
|
+
puts '-'*80, ''; sleep 0.25
|
608
|
+
|
609
|
+
run 'rm -f recipes/default.rb'
|
610
|
+
file 'recipes/default.rb' do <<-CODE
|
611
|
+
include_recipe '#{app_name}::database'
|
612
|
+
include_recipe '#{app_name}::cache'
|
613
|
+
include_recipe '#{app_name}::web'
|
614
|
+
CODE
|
615
|
+
end
|
616
|
+
|
617
|
+
git add: '.'
|
618
|
+
git commit: "-m 'Add the default recipe'"
|
619
|
+
|
620
|
+
# ----- Installation complete message -----------------------------------------------------------------
|
621
|
+
|
622
|
+
puts
|
623
|
+
say_status 'success', "\e[1m\Everything has been setup successfully\e[0m", :cyan
|
624
|
+
puts
|
625
|
+
say_status 'question', 'Are you new to chef and berkshelf?', :yellow
|
626
|
+
say_status 'answer', 'Check the orats wiki for the walk through', :white
|
627
|
+
puts
|
628
|
+
say_status 'question', 'Are you somewhat experienced with chef?', :yellow
|
629
|
+
say_status 'answer', 'Setup your encrypted data bag and bootstrap the node', :white
|
630
|
+
puts '-'*80
|
data/lib/orats/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: orats
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Janetakis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-02-
|
11
|
+
date: 2014-02-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -72,8 +72,9 @@ files:
|
|
72
72
|
- lib/orats/cli.rb
|
73
73
|
- lib/orats/server.rb
|
74
74
|
- lib/orats/shell.rb
|
75
|
-
- lib/orats/templates/
|
76
|
-
- lib/orats/templates/
|
75
|
+
- lib/orats/templates/auth.rb
|
76
|
+
- lib/orats/templates/base.rb
|
77
|
+
- lib/orats/templates/cook.rb
|
77
78
|
- lib/orats/templates/includes/Gemfile
|
78
79
|
- lib/orats/version.rb
|
79
80
|
- orats.gemspec
|