dice_bag 1.4.0 → 1.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +88 -0
- data/MIT-LICENSE +19 -0
- data/README.md +174 -0
- data/lib/dice_bag/available_templates.rb +3 -2
- data/lib/dice_bag/command.rb +2 -0
- data/lib/dice_bag/config_file.rb +3 -1
- data/lib/dice_bag/configuration.rb +3 -0
- data/lib/dice_bag/default_template_file.rb +3 -3
- data/lib/dice_bag/dice_bag_file.rb +8 -5
- data/lib/dice_bag/private_key.rb +13 -3
- data/lib/dice_bag/project.rb +5 -1
- data/lib/dice_bag/railtie.rb +2 -0
- data/lib/dice_bag/tasks/config.rake +16 -10
- data/lib/dice_bag/tasks.rb +2 -0
- data/lib/dice_bag/template_file.rb +16 -6
- data/lib/dice_bag/template_helpers.rb +54 -0
- data/lib/dice_bag/templates/gems_checker.rb +5 -9
- data/lib/dice_bag/version.rb +3 -1
- data/lib/dice_bag/warning.rb +4 -2
- data/lib/dice_bag.rb +2 -0
- data/spec/command_spec.rb +2 -0
- data/spec/configuration_spec.rb +2 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/support/config/database.yml.dice +4 -0
- data/spec/template_file_spec.rb +25 -0
- metadata +39 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e5bb488ea8f0b38b938b9fd4ac13a69a1f60a8df544d546c123478bb31bb25ae
|
4
|
+
data.tar.gz: 7a351f59b04eaa6703e00608c2e9f90a3c53199529536ffe0ce3eb01f49d698e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c4b40020b59067e98abe32f5bdceb5fc93a1dd4d543674423e6c8740f749e1d42563b7d7fcedd06afb99c4869c654c75dcb4e8d1963d41aee1c350a337a70653
|
7
|
+
data.tar.gz: a2470807821c5a6247f1cc8c7581a82b6a0d8195d5a2f3c391b3f74c4af9b31ac39145a766e63cc27b66503b3c461d88482e018ded8500c9de461852ae6f7e47
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
# 1.6.1
|
2
|
+
* Use keyword argument for ERB.new to suppress deprecated warnings.
|
3
|
+
* Use default bundle path (`vendor/bundle`) when `Bundler.settings[:path]` returns nil.
|
4
|
+
|
5
|
+
# 1.6.0
|
6
|
+
* Drop support for Ruby 2.3 and 2.4.
|
7
|
+
|
8
|
+
# 1.5.0
|
9
|
+
* Add ability to generate and verify x509 certificates.
|
10
|
+
|
11
|
+
# 1.4.1
|
12
|
+
* Bundle extra files in the gem (MIT-LICENSE etc.).
|
13
|
+
|
14
|
+
# 1.4.0
|
15
|
+
* Allow thor 0.x and 1.x.
|
16
|
+
|
17
|
+
# 1.3.4
|
18
|
+
* Remove extra spaces from the database templates.
|
19
|
+
|
20
|
+
# 1.3.3
|
21
|
+
* Address a deprecation warning when using Rails 6.0.
|
22
|
+
|
23
|
+
# 1.3.2
|
24
|
+
* Gem specifies MIT license.
|
25
|
+
|
26
|
+
# 1.3.1
|
27
|
+
* Fix adapter name in the database.yml.dice template for PostgreSQL.
|
28
|
+
|
29
|
+
# 1.3.0
|
30
|
+
* Detect pg gem and generate database.yml.dice for PostgreSQL.
|
31
|
+
|
32
|
+
# 1.2.3
|
33
|
+
* Fix: Add missing newline after ruby warning message.
|
34
|
+
|
35
|
+
# 1.2.2
|
36
|
+
* Remove trailing space from the message generated by `<%= warning.as_yaml_comment %>`.
|
37
|
+
|
38
|
+
# 1.2.1
|
39
|
+
* Replaces `starts_with?` with `start_with?` to remove Rails dependency.
|
40
|
+
|
41
|
+
# 1.2.0
|
42
|
+
* Adds a `config:generate_from_gems` task to generate the templates from the specified gems only
|
43
|
+
|
44
|
+
# 1.1.1
|
45
|
+
* Updates the database.yml.dice file to not provide settings for test and development when
|
46
|
+
building in production.
|
47
|
+
|
48
|
+
# 1.1.0
|
49
|
+
* Removed the template for Newrelic.
|
50
|
+
|
51
|
+
# 1.0.0
|
52
|
+
* `config:generate_all` task allows user to choose an appropriate action when source and local templates are different.
|
53
|
+
* `config:generate_all:force` allows user to generate templates in 'force mode' (replacing local templates with the source).
|
54
|
+
|
55
|
+
# 0.9.0
|
56
|
+
* Feature: Adding a bang (!) at the end of method names, will raise when the variable
|
57
|
+
is not found in production.
|
58
|
+
* New relic template to use SSL by default
|
59
|
+
|
60
|
+
# 0.8.0
|
61
|
+
* Fix Template generation fails if the target directory is missing
|
62
|
+
* Document that configuration files must not be loaded in Rails config/application.rb
|
63
|
+
* Don't overwrite config files if user responds 'No' instead of just 'N'.
|
64
|
+
* Omit .dice files in Bundler path or in dot-prefixed directories
|
65
|
+
|
66
|
+
# 0.7.1
|
67
|
+
* The ensure_is_private_key method now additionally supports RSA keys without spaces.
|
68
|
+
|
69
|
+
# 0.7.0
|
70
|
+
* New ensure_is_private_key helper method to process RSA private keys.
|
71
|
+
* New config:deploy rake task to use for deployments, which overwrites config files without prompting.
|
72
|
+
|
73
|
+
# 0.6.0
|
74
|
+
* **Breaking change:** Only templates with the '.dice' extension are processed.
|
75
|
+
* **Breaking change:** Local override via the '.local' extension has been removed.
|
76
|
+
* Templates are processed in all directories.
|
77
|
+
|
78
|
+
# 0.5.0
|
79
|
+
* Generated templates should be committed to source control.
|
80
|
+
* New '.dice' extension for templates.
|
81
|
+
* Better testing infrastructure.
|
82
|
+
* Plugins and rake task can specify custom location for templates.
|
83
|
+
|
84
|
+
# 0.4.1
|
85
|
+
* Fix: Templates are generated in 'config' directory for Rails projects.
|
86
|
+
|
87
|
+
# 0.4.0
|
88
|
+
* Initial open source release.
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2012-2020 Medidata Solutions Worldwide
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,174 @@
|
|
1
|
+
# DiceBag
|
2
|
+
|
3
|
+
[![Build Status](https://travis-ci.com/mdsol/dice_bag.svg?branch=develop)](https://travis-ci.com/mdsol/dice_bag)
|
4
|
+
[![Code Climate](https://codeclimate.com/github/mdsol/dice_bag.png)](https://codeclimate.com/github/mdsol/dice_bag)
|
5
|
+
|
6
|
+
DiceBag is a library of rake tasks for configuring web apps in the style of [The
|
7
|
+
Twelve-Factor App][1]. Configuration values are picked up from the environment
|
8
|
+
and used to populate configuration files from templates. Pre-packaged templates
|
9
|
+
for common configuration files are provided.
|
10
|
+
|
11
|
+
Although Rails already supports ERB syntax for its YML configuration files, DiceBag will generate a final
|
12
|
+
static file that will work without keeping your deployment environment variables in sync with your
|
13
|
+
production environment variables. For security reasons, these environments may sometimes differ.
|
14
|
+
|
15
|
+
Also DiceBag will work with any kind of text files, not only YML files. It can be very useful for
|
16
|
+
ruby initializer files for instance.
|
17
|
+
|
18
|
+
[1]: http://www.12factor.net/
|
19
|
+
|
20
|
+
## Installation
|
21
|
+
|
22
|
+
Add the following to your `Gemfile`:
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
gem 'dice_bag'
|
26
|
+
```
|
27
|
+
|
28
|
+
If you are using these tasks outside of a Rails project, add the following to
|
29
|
+
your `Rakefile` or wherever your local rake tasks are defined:
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
require 'dice_bag/tasks'
|
33
|
+
```
|
34
|
+
|
35
|
+
Run the following command to see the new tasks:
|
36
|
+
|
37
|
+
```
|
38
|
+
[bundle exec] rake -T | grep "rake config"
|
39
|
+
```
|
40
|
+
|
41
|
+
## Create configuration files from templates
|
42
|
+
|
43
|
+
When the rake "config" task is run, configuration files are populated for all
|
44
|
+
ERB template files in the project that have a ".dice" extension. Configuration
|
45
|
+
values from the environment are made available to the templates through the
|
46
|
+
`configured` object.
|
47
|
+
|
48
|
+
For example, take a "database.yml.dice" file containing this template:
|
49
|
+
|
50
|
+
```erb
|
51
|
+
development:
|
52
|
+
database: development
|
53
|
+
username: <%= configured.database_username || 'root' %>
|
54
|
+
password: <%= configured.database_password %>
|
55
|
+
```
|
56
|
+
|
57
|
+
Then running the following command:
|
58
|
+
|
59
|
+
```
|
60
|
+
DATABASE_USERNAME=alice DATABASE_PASSWORD=xyzzy [bundle exec] rake config
|
61
|
+
```
|
62
|
+
|
63
|
+
will generate a "database.yml" file with the following contents:
|
64
|
+
|
65
|
+
```yaml
|
66
|
+
development:
|
67
|
+
database: development
|
68
|
+
username: alice
|
69
|
+
password: xyzzy
|
70
|
+
```
|
71
|
+
|
72
|
+
See the [feature documentation][features] for further examples and
|
73
|
+
functionality.
|
74
|
+
|
75
|
+
[features]: https://www.relishapp.com/mdsol/dice-bag/docs
|
76
|
+
|
77
|
+
As discussed in [The Twelve-Factor App section on configuration][2], do not
|
78
|
+
commit your generated configuration files to source control. Instead, commit the
|
79
|
+
templates to source control and then regenerate the configuration files at
|
80
|
+
deployment time by running the rake `config:deploy` task.
|
81
|
+
|
82
|
+
[2]: http://www.12factor.net/config
|
83
|
+
|
84
|
+
|
85
|
+
### Ensuring variables are set in production
|
86
|
+
|
87
|
+
It is a common pattern to use default information for development but to not
|
88
|
+
allow defaults in production, instead we want to always set up the environment variables
|
89
|
+
in production.
|
90
|
+
|
91
|
+
It is very easy to discover what variables have not been set in production using a bang after
|
92
|
+
the variable name, for instance:
|
93
|
+
```
|
94
|
+
secret_key: <%= configured.secret_key_base! || 'any text is ok' %>
|
95
|
+
```
|
96
|
+
Will raise an explanatory error if we are using Rails, we are in production and the
|
97
|
+
variable SECRET_KEY_BASE is not set. In other environments will not care about it
|
98
|
+
not being set and will use the default.
|
99
|
+
|
100
|
+
|
101
|
+
### Generating the templates of given gems only
|
102
|
+
|
103
|
+
`config:generate_all` will generate all the templates it can find. Since sometimes this behavior
|
104
|
+
is not desirable you can use the `config:generate_from_gems` task to specify gem names:
|
105
|
+
|
106
|
+
```
|
107
|
+
[bundle exec] rake config:generate_from_gems gem1 gem2 gemN
|
108
|
+
```
|
109
|
+
|
110
|
+
will generate only the templates provided by `gem1`, `gem2` and `gemN`.
|
111
|
+
|
112
|
+
To force-generate set the `DICEBAG_FORCE` environment variable to any value when running the task.
|
113
|
+
|
114
|
+
|
115
|
+
## Generating the pre-packaged templates
|
116
|
+
|
117
|
+
If the corresponding gems are installed, the following pre-packaged templates are provided:
|
118
|
+
|
119
|
+
* mysql2 or pg: `database.yml.dice` for [Rails](https://github.com/rails/rails/)
|
120
|
+
* aws-sdk: `aws.yml.dice`
|
121
|
+
* dalli: `dalli.yml.dice`
|
122
|
+
|
123
|
+
Run the following command to generate them:
|
124
|
+
|
125
|
+
```
|
126
|
+
[bundle exec] rake config:generate_all
|
127
|
+
```
|
128
|
+
|
129
|
+
This command provides options to compare changes between source and local templates, so new additions to the source templates can be safely added while preserving any project specific customization to local templates.
|
130
|
+
|
131
|
+
Alternatively, to force generate templates (replacing existing local templates with the source), run the following:
|
132
|
+
|
133
|
+
```
|
134
|
+
[bundle exec] rake config:generate_all:force
|
135
|
+
```
|
136
|
+
|
137
|
+
|
138
|
+
As with your own templates, you should commit these pre-packaged templates to
|
139
|
+
source control.
|
140
|
+
|
141
|
+
You can customize these pre-packaged template to your needs but if the change is
|
142
|
+
a generic fix or extension, please consider contributing it back to this project
|
143
|
+
so that everyone benefits.
|
144
|
+
|
145
|
+
### Defining your own pre-packaged templates
|
146
|
+
|
147
|
+
If you want DiceBag to generate your own pre-packaged templates when you run the
|
148
|
+
rake "config:generate_all" task, you can create a plug-in. Read the
|
149
|
+
[templates.md](./templates.md) file to learn how to do this.
|
150
|
+
|
151
|
+
## Troubleshooting
|
152
|
+
|
153
|
+
### rake config fails in Rails project with file not found
|
154
|
+
|
155
|
+
Due to rake running ``` config/application.rb ``` before kicking off a task,
|
156
|
+
if ``` config/application.rb ``` loads any configuration files that dice_bag
|
157
|
+
must generate a 'file not found' error may occur. Makes sense that a file
|
158
|
+
``` rake config:generate_all ``` needs to create, does not exist before it has ran.
|
159
|
+
|
160
|
+
Solution: Move any config loading that depends on files generated by dice_bag out of `application.rb` and into `config/initializers/*`. Since the commands
|
161
|
+
`rails server` or `rails console` etc. always run the initializers, moving the logic
|
162
|
+
here should be a safe bet.
|
163
|
+
|
164
|
+
## Contributors
|
165
|
+
|
166
|
+
* [Andrew Smith](https://github.com/asmith-mdsol)
|
167
|
+
* [Jordi Carres](https://github.com/jcarres-mdsol)
|
168
|
+
* [Dan Hoizner](https://github.com/dhoizner-mdsol)
|
169
|
+
* [Aaron Weiner](https://github.com/HonoreDB)
|
170
|
+
* [Luke Greene](https://github.com/lgreene-mdsol)
|
171
|
+
* [Johnny Lo](https://github.com/jlo188)
|
172
|
+
* [Connor Ross](https://github.com/cross311)
|
173
|
+
* [Mathieu Jobin](https://github.com/mjobin-mdsol)
|
174
|
+
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "rubygems"
|
2
4
|
require "dice_bag/default_template_file"
|
3
5
|
|
@@ -14,11 +16,10 @@ module DiceBag
|
|
14
16
|
|
15
17
|
class << self
|
16
18
|
def gem_specs
|
17
|
-
@gem_specs ||=
|
19
|
+
@gem_specs ||=
|
18
20
|
Gem::Specification.sort.each_with_object({}) do |spec, hsh|
|
19
21
|
hsh[spec.name] = spec.full_gem_path
|
20
22
|
end
|
21
|
-
end
|
22
23
|
end
|
23
24
|
|
24
25
|
def checker_within_given_gems?(checker, gem_names)
|
data/lib/dice_bag/command.rb
CHANGED
data/lib/dice_bag/config_file.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module DiceBag
|
2
4
|
# This class abstracts access to configuration values, to be used within ERB
|
3
5
|
# templates. Currently, the values are read from the environment, as per the
|
@@ -29,6 +31,7 @@ module DiceBag
|
|
29
31
|
if in_production? && value.nil?
|
30
32
|
raise "Environment variable #{variable_name} required in production but it was not provided"
|
31
33
|
end
|
34
|
+
|
32
35
|
value
|
33
36
|
end
|
34
37
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "dice_bag/dice_bag_file"
|
2
4
|
require "dice_bag/project"
|
3
5
|
|
@@ -11,9 +13,7 @@ module DiceBag
|
|
11
13
|
|
12
14
|
def initialize(name, location = nil, save_as = nil)
|
13
15
|
# if called from command line with only a name we search in all our templates for the file
|
14
|
-
if File.dirname(name) == "."
|
15
|
-
name = AvailableTemplates.template_filename_for(name)
|
16
|
-
end
|
16
|
+
name = AvailableTemplates.template_filename_for(name) if File.dirname(name) == "."
|
17
17
|
@filename = File.basename(save_as || name)
|
18
18
|
@file = name
|
19
19
|
@template_location = location
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "dice_bag/version"
|
2
4
|
|
3
5
|
# This module contains common methods for all the type of files Dicebag knows about:
|
@@ -5,12 +7,11 @@ require "dice_bag/version"
|
|
5
7
|
module DiceBag
|
6
8
|
module DiceBagFile
|
7
9
|
attr_reader :file, :filename, :destination
|
10
|
+
|
8
11
|
@@overwrite_all = false
|
9
12
|
|
10
13
|
def assert_existence
|
11
|
-
unless File.
|
12
|
-
raise "File #{@file} not found. Configuration file not created"
|
13
|
-
end
|
14
|
+
raise "File #{@file} not found. Configuration file not created" unless File.exist?(@file)
|
14
15
|
end
|
15
16
|
|
16
17
|
def write(contents)
|
@@ -20,10 +21,11 @@ module DiceBag
|
|
20
21
|
end
|
21
22
|
|
22
23
|
def should_write?(new_contents)
|
23
|
-
return true if @@overwrite_all || !File.
|
24
|
+
return true if @@overwrite_all || !File.exist?(file)
|
24
25
|
return false if diff(file, new_contents).empty?
|
25
26
|
|
26
|
-
|
27
|
+
# rubocop:disable Metrics/BlockLength
|
28
|
+
loop do
|
27
29
|
puts "Overwrite #{file} ? Recommended: Yes. "
|
28
30
|
puts " [Y]es, [n]o, [a]ll files, [q]uit, [d]show diff"
|
29
31
|
answer = $stdin.gets
|
@@ -43,6 +45,7 @@ module DiceBag
|
|
43
45
|
return true
|
44
46
|
end
|
45
47
|
end
|
48
|
+
# rubocop:enable Metrics/BlockLength
|
46
49
|
end
|
47
50
|
|
48
51
|
private
|
data/lib/dice_bag/private_key.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module DiceBag
|
2
4
|
class PrivateKey
|
3
5
|
attr_accessor :private_key
|
@@ -10,7 +12,7 @@ module DiceBag
|
|
10
12
|
require "openssl"
|
11
13
|
|
12
14
|
begin
|
13
|
-
|
15
|
+
rsa_object
|
14
16
|
true
|
15
17
|
rescue => e
|
16
18
|
puts "#{e.message}\n#{e.backtrace}"
|
@@ -25,10 +27,18 @@ module DiceBag
|
|
25
27
|
@private_key = [HEADER, body, FOOTER].flatten.join("\n")
|
26
28
|
end
|
27
29
|
|
30
|
+
def public_key
|
31
|
+
rsa_object.public_key
|
32
|
+
end
|
33
|
+
|
34
|
+
def rsa_object
|
35
|
+
@rsa_object ||= OpenSSL::PKey::RSA.new(@private_key)
|
36
|
+
end
|
37
|
+
|
28
38
|
private
|
29
39
|
|
30
|
-
HEADER = "-----BEGIN RSA PRIVATE KEY-----"
|
31
|
-
FOOTER = "-----END RSA PRIVATE KEY-----"
|
40
|
+
HEADER = "-----BEGIN RSA PRIVATE KEY-----"
|
41
|
+
FOOTER = "-----END RSA PRIVATE KEY-----"
|
32
42
|
|
33
43
|
def strip_down_key
|
34
44
|
@private_key.gsub!(HEADER, "")
|
data/lib/dice_bag/project.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This class encapsulate data about the project dice_bag got in
|
2
4
|
module DiceBag
|
3
5
|
class Project
|
4
6
|
DEFAULT_NAME = "project"
|
7
|
+
DEFAULT_BUNDLE_PATH = "vendor/bundle"
|
5
8
|
|
6
9
|
# TODO: how to find the name of the project in non Rails apps?
|
7
10
|
def self.name
|
@@ -20,8 +23,9 @@ module DiceBag
|
|
20
23
|
end
|
21
24
|
|
22
25
|
def self.templates_to_generate
|
26
|
+
bundle_path = (defined?(Bundler) && Bundler.settings[:path]) || DEFAULT_BUNDLE_PATH
|
23
27
|
FileList.new("**/*.dice") do |fl|
|
24
|
-
fl.exclude(File.join(
|
28
|
+
fl.exclude(File.join(bundle_path, "/**/*"))
|
25
29
|
end
|
26
30
|
end
|
27
31
|
end
|
data/lib/dice_bag/railtie.rb
CHANGED
@@ -1,30 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "erb"
|
2
4
|
require "dice_bag/command"
|
3
5
|
|
4
|
-
FORCE_ENV_VAR = "DICEBAG_FORCE"
|
6
|
+
FORCE_ENV_VAR = "DICEBAG_FORCE"
|
5
7
|
|
6
8
|
desc "Populate all templates using values from the environment to create configuration files"
|
7
|
-
task :
|
9
|
+
task config: ["config:all"]
|
8
10
|
|
9
11
|
namespace :config do
|
10
|
-
# Deprecated, present only for backward compatibility.
|
11
12
|
task :all do
|
12
13
|
DiceBag::Command.new.write_all
|
13
14
|
end
|
14
15
|
|
15
16
|
desc "As per the config task but automatically overwrites pre-existing configuration files"
|
16
17
|
task :deploy do
|
17
|
-
DiceBag::Command.new.write_all(:
|
18
|
+
DiceBag::Command.new.write_all(deploy: true)
|
18
19
|
end
|
19
20
|
|
20
21
|
desc "Populate just the specified template to create the associated configuration file"
|
21
|
-
task :file, :filename do |
|
22
|
+
task :file, :filename do |_t, args|
|
22
23
|
filename = args[:filename]
|
23
24
|
raise "A filename needs to be provided" if filename.nil?
|
25
|
+
|
24
26
|
DiceBag::Command.new.write(filename)
|
25
27
|
end
|
26
28
|
|
27
|
-
desc "Generate all configuration file templates with interactive commands
|
29
|
+
desc "Generate all configuration file templates with interactive commands " \
|
30
|
+
"(use config:generate_all:force to replace all without asking for input)"
|
28
31
|
task :generate_all do
|
29
32
|
DiceBag::Command.new.generate_all_templates(false)
|
30
33
|
end
|
@@ -36,18 +39,21 @@ namespace :config do
|
|
36
39
|
end
|
37
40
|
|
38
41
|
desc "Generate specified template, optionally in the specified location with options to control file actions"
|
39
|
-
task :generate, :filename, :location do |
|
42
|
+
task :generate, :filename, :location do |_t, args|
|
40
43
|
filename = args[:filename]
|
41
44
|
location = args[:location]
|
42
45
|
raise "A filename needs to be provided" if filename.nil?
|
46
|
+
|
43
47
|
DiceBag::Command.new.generate_template(DiceBag::DefaultTemplateFile.new(filename, location), false)
|
44
48
|
end
|
45
49
|
|
46
|
-
desc "Generate the templates from the specified gems only ('config:generate_from_gems gem1 gem2 gemN',
|
47
|
-
|
48
|
-
|
50
|
+
desc "Generate the templates from the specified gems only ('config:generate_from_gems gem1 gem2 gemN'," \
|
51
|
+
" set the env variable '#{FORCE_ENV_VAR}' to overwrite the templates without asking for confirmation)"
|
52
|
+
task :generate_from_gems, :names do |_t, _args|
|
53
|
+
ARGV.each { |a| task a.to_sym do; end }
|
49
54
|
names = ARGV[1..-1]
|
50
55
|
raise "One or more gem names need to be provided" if names.empty?
|
56
|
+
|
51
57
|
DiceBag::Command.new.generate_gems_templates(names, !ENV[FORCE_ENV_VAR].nil?)
|
52
58
|
end
|
53
59
|
end
|
data/lib/dice_bag/tasks.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dice_bag/dice_bag_file"
|
2
4
|
require "dice_bag/template_helpers"
|
3
5
|
require "dice_bag/configuration"
|
4
6
|
require "dice_bag/warning"
|
@@ -17,11 +19,6 @@ module DiceBag
|
|
17
19
|
end
|
18
20
|
|
19
21
|
def create_file(config_file, params)
|
20
|
-
# By passing "<>" we're trimming trailing newlines on lines that are
|
21
|
-
# nothing but ERB blocks (see documentation). This is useful for files
|
22
|
-
# like mauth_key where we want to control newlines carefully.
|
23
|
-
template = ERB.new(File.read(@file), nil, "<>")
|
24
|
-
|
25
22
|
# templates expect a configured object
|
26
23
|
configured = Configuration.new
|
27
24
|
warning = Warning.new(@filename)
|
@@ -32,5 +29,18 @@ module DiceBag
|
|
32
29
|
config_file.write(contents)
|
33
30
|
puts "File '#{config_file.file}' created"
|
34
31
|
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def template
|
36
|
+
# By passing "<>" we're trimming trailing newlines on lines that are
|
37
|
+
# nothing but ERB blocks (see documentation). This is useful for files
|
38
|
+
# like mauth_key where we want to control newlines carefully.
|
39
|
+
if ERB.instance_method(:initialize).parameters.assoc(:key) # Ruby 2.6+
|
40
|
+
ERB.new(File.read(@file), trim_mode: "<>")
|
41
|
+
else
|
42
|
+
ERB.new(File.read(@file), nil, "<>")
|
43
|
+
end
|
44
|
+
end
|
35
45
|
end
|
36
46
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "dice_bag/private_key"
|
2
4
|
|
3
5
|
module DiceBag
|
@@ -17,5 +19,57 @@ module DiceBag
|
|
17
19
|
raise "The private key provided is invalid"
|
18
20
|
end
|
19
21
|
end
|
22
|
+
|
23
|
+
# Generates https://en.wikipedia.org/wiki/X.509 certificate, commonly used in authentication services
|
24
|
+
def generate_509_certificate(private_key, root_ca: nil, root_key: nil)
|
25
|
+
root_key ||= OpenSSL::PKey::RSA.new(2048) # the CA's public/private key
|
26
|
+
root_ca ||= default_root_ca(root_key)
|
27
|
+
|
28
|
+
cert = OpenSSL::X509::Certificate.new
|
29
|
+
cert.version = 2
|
30
|
+
cert.serial = 2
|
31
|
+
cert.subject = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=Ruby certificate")
|
32
|
+
cert.issuer = root_ca.subject # root CA is the issuer
|
33
|
+
cert.public_key = PrivateKey.new(private_key.dup).public_key
|
34
|
+
cert.not_before = Time.now
|
35
|
+
cert.not_after = cert.not_before + (1 * 365 * 24 * 60 * 60) # 1 years validity
|
36
|
+
ef = OpenSSL::X509::ExtensionFactory.new
|
37
|
+
ef.subject_certificate = cert
|
38
|
+
ef.issuer_certificate = root_ca
|
39
|
+
cert.add_extension(ef.create_extension("keyUsage", "digitalSignature", true))
|
40
|
+
cert.add_extension(ef.create_extension("subjectKeyIdentifier", "hash", false))
|
41
|
+
cert.sign(root_key, OpenSSL::Digest.new("SHA256"))
|
42
|
+
cert
|
43
|
+
end
|
44
|
+
|
45
|
+
# raw_cert: DER or PEM encoded certificate
|
46
|
+
def ensure_is_509_certificate(raw_cert)
|
47
|
+
certificate = OpenSSL::X509::Certificate.new(raw_cert)
|
48
|
+
rescue OpenSSL::X509::CertificateError
|
49
|
+
false
|
50
|
+
end
|
51
|
+
|
52
|
+
def default_root_ca(root_key)
|
53
|
+
@default_root_ca ||= generate_root_ca(root_key)
|
54
|
+
end
|
55
|
+
|
56
|
+
def generate_root_ca(root_key)
|
57
|
+
root_ca = OpenSSL::X509::Certificate.new
|
58
|
+
root_ca.version = 2 # cf. RFC 5280 - to make it a "v3" certificate
|
59
|
+
root_ca.serial = 1 # considered a security flaw for real certificates
|
60
|
+
root_ca.subject = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=Ruby CA")
|
61
|
+
root_ca.issuer = root_ca.subject # root CA's are "self-signed"
|
62
|
+
root_ca.public_key = root_key.public_key
|
63
|
+
root_ca.not_before = Time.now
|
64
|
+
root_ca.not_after = root_ca.not_before + (2 * 365 * 24 * 60 * 60) # 2 years validity
|
65
|
+
ef = OpenSSL::X509::ExtensionFactory.new
|
66
|
+
ef.subject_certificate = root_ca
|
67
|
+
ef.issuer_certificate = root_ca
|
68
|
+
root_ca.add_extension(ef.create_extension("basicConstraints", "CA:TRUE", true))
|
69
|
+
root_ca.add_extension(ef.create_extension("keyUsage", "keyCertSign, cRLSign", true))
|
70
|
+
root_ca.add_extension(ef.create_extension("subjectKeyIdentifier", "hash", false))
|
71
|
+
root_ca.add_extension(ef.create_extension("authorityKeyIdentifier", "keyid:always", false))
|
72
|
+
root_ca.sign(root_key, OpenSSL::Digest.new("SHA256"))
|
73
|
+
end
|
20
74
|
end
|
21
75
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This module has the logic that decides what templates will be
|
2
4
|
# generated for this project.
|
3
5
|
# this file lives in the same directory than all the templates it
|
@@ -10,9 +12,7 @@ module DiceBag
|
|
10
12
|
@needed_templates = []
|
11
13
|
configured = Configuration.new
|
12
14
|
|
13
|
-
if defined?(Dalli)
|
14
|
-
add_template("dalli.yml.dice")
|
15
|
-
end
|
15
|
+
add_template("dalli.yml.dice") if defined?(Dalli)
|
16
16
|
|
17
17
|
if defined?(Mysql2)
|
18
18
|
add_template("databases/mysql.yml.dice", save_as: "database.yml.dice")
|
@@ -20,13 +20,9 @@ module DiceBag
|
|
20
20
|
add_template("databases/postgres.yml.dice", save_as: "database.yml.dice")
|
21
21
|
end
|
22
22
|
|
23
|
-
if defined?(AWS)
|
24
|
-
add_template("aws.yml.dice")
|
25
|
-
end
|
23
|
+
add_template("aws.yml.dice") if defined?(AWS)
|
26
24
|
|
27
|
-
if configured.google_analytics_id
|
28
|
-
add_template("google_analytics.yml.dice")
|
29
|
-
end
|
25
|
+
add_template("google_analytics.yml.dice") if configured.google_analytics_id
|
30
26
|
|
31
27
|
@needed_templates
|
32
28
|
end
|
data/lib/dice_bag/version.rb
CHANGED
data/lib/dice_bag/warning.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module DiceBag
|
2
4
|
class Warning
|
3
5
|
def initialize(template_filename)
|
@@ -8,7 +10,7 @@ module DiceBag
|
|
8
10
|
lines.map { |line| "# #{line}".rstrip }.join("\n") + "\n"
|
9
11
|
end
|
10
12
|
|
11
|
-
alias
|
13
|
+
alias as_yaml_comment as_ruby_comment
|
12
14
|
|
13
15
|
def as_xml_comment
|
14
16
|
["<!--", lines, "-->"].flatten.join("\n")
|
@@ -19,7 +21,7 @@ module DiceBag
|
|
19
21
|
def lines
|
20
22
|
[
|
21
23
|
"WARNING! Do not modify this file directly. It was generated from the",
|
22
|
-
"'
|
24
|
+
"'#{@template_filename}' template file.",
|
23
25
|
"",
|
24
26
|
"Use the rake config task to reconfigure. See the template file for",
|
25
27
|
"further guidance."
|
data/lib/dice_bag.rb
CHANGED
data/spec/command_spec.rb
CHANGED
data/spec/configuration_spec.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
require "dice_bag/project"
|
5
|
+
require "dice_bag/template_file"
|
6
|
+
|
7
|
+
RSpec.describe DiceBag::TemplateFile do
|
8
|
+
let(:file_name) { "config/database.yml" }
|
9
|
+
let(:template_name) { "#{file_name}.dice" }
|
10
|
+
let(:template_file) { DiceBag::TemplateFile.new(template_name) }
|
11
|
+
let(:config_file) { double(file: file_name) }
|
12
|
+
let(:params) { { deploy: true } }
|
13
|
+
|
14
|
+
before do
|
15
|
+
allow(ENV).to receive(:[]).with("DATABASE_USERNAME").and_return("alice")
|
16
|
+
allow(ENV).to receive(:[]).with("DATABASE_PASSWORD").and_return("xyzzy")
|
17
|
+
allow(DiceBag::Project).to receive(:root).and_return(File.join(__dir__, "support"))
|
18
|
+
end
|
19
|
+
|
20
|
+
it "writes to configuration file" do
|
21
|
+
expect(config_file)
|
22
|
+
.to receive(:write).with("development:\n database: development\n username: alice\n password: xyzzy\n")
|
23
|
+
template_file.create_file(config_file, params)
|
24
|
+
end
|
25
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dice_bag
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Smith
|
@@ -9,8 +9,22 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2022-02-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: diff-lcs
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '1.0'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '1.0'
|
14
28
|
- !ruby/object:Gem::Dependency
|
15
29
|
name: rake
|
16
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -40,33 +54,33 @@ dependencies:
|
|
40
54
|
- !ruby/object:Gem::Version
|
41
55
|
version: '2.0'
|
42
56
|
- !ruby/object:Gem::Dependency
|
43
|
-
name:
|
57
|
+
name: aruba
|
44
58
|
requirement: !ruby/object:Gem::Requirement
|
45
59
|
requirements:
|
46
60
|
- - "~>"
|
47
61
|
- !ruby/object:Gem::Version
|
48
|
-
version:
|
49
|
-
type: :
|
62
|
+
version: 0.6.0
|
63
|
+
type: :development
|
50
64
|
prerelease: false
|
51
65
|
version_requirements: !ruby/object:Gem::Requirement
|
52
66
|
requirements:
|
53
67
|
- - "~>"
|
54
68
|
- !ruby/object:Gem::Version
|
55
|
-
version:
|
69
|
+
version: 0.6.0
|
56
70
|
- !ruby/object:Gem::Dependency
|
57
|
-
name:
|
71
|
+
name: bundler
|
58
72
|
requirement: !ruby/object:Gem::Requirement
|
59
73
|
requirements:
|
60
|
-
- - "
|
74
|
+
- - ">="
|
61
75
|
- !ruby/object:Gem::Version
|
62
|
-
version: 0
|
76
|
+
version: '0'
|
63
77
|
type: :development
|
64
78
|
prerelease: false
|
65
79
|
version_requirements: !ruby/object:Gem::Requirement
|
66
80
|
requirements:
|
67
|
-
- - "
|
81
|
+
- - ">="
|
68
82
|
- !ruby/object:Gem::Version
|
69
|
-
version: 0
|
83
|
+
version: '0'
|
70
84
|
- !ruby/object:Gem::Dependency
|
71
85
|
name: rspec
|
72
86
|
requirement: !ruby/object:Gem::Requirement
|
@@ -82,19 +96,19 @@ dependencies:
|
|
82
96
|
- !ruby/object:Gem::Version
|
83
97
|
version: '3.0'
|
84
98
|
- !ruby/object:Gem::Dependency
|
85
|
-
name:
|
99
|
+
name: rubocop
|
86
100
|
requirement: !ruby/object:Gem::Requirement
|
87
101
|
requirements:
|
88
|
-
- - "
|
102
|
+
- - "~>"
|
89
103
|
- !ruby/object:Gem::Version
|
90
|
-
version: '
|
104
|
+
version: '1.8'
|
91
105
|
type: :development
|
92
106
|
prerelease: false
|
93
107
|
version_requirements: !ruby/object:Gem::Requirement
|
94
108
|
requirements:
|
95
|
-
- - "
|
109
|
+
- - "~>"
|
96
110
|
- !ruby/object:Gem::Version
|
97
|
-
version: '
|
111
|
+
version: '1.8'
|
98
112
|
description:
|
99
113
|
email:
|
100
114
|
- asmith@mdsol.com
|
@@ -103,6 +117,9 @@ executables: []
|
|
103
117
|
extensions: []
|
104
118
|
extra_rdoc_files: []
|
105
119
|
files:
|
120
|
+
- CHANGELOG.md
|
121
|
+
- MIT-LICENSE
|
122
|
+
- README.md
|
106
123
|
- lib/dice_bag.rb
|
107
124
|
- lib/dice_bag/available_templates.rb
|
108
125
|
- lib/dice_bag/command.rb
|
@@ -128,6 +145,8 @@ files:
|
|
128
145
|
- spec/command_spec.rb
|
129
146
|
- spec/configuration_spec.rb
|
130
147
|
- spec/spec_helper.rb
|
148
|
+
- spec/support/config/database.yml.dice
|
149
|
+
- spec/template_file_spec.rb
|
131
150
|
homepage:
|
132
151
|
licenses:
|
133
152
|
- MIT
|
@@ -142,7 +161,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
142
161
|
requirements:
|
143
162
|
- - ">="
|
144
163
|
- !ruby/object:Gem::Version
|
145
|
-
version: 2.
|
164
|
+
version: '2.5'
|
146
165
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
147
166
|
requirements:
|
148
167
|
- - ">="
|
@@ -156,6 +175,8 @@ summary: Dice Bag is a library of rake tasks for configuring web apps in the sty
|
|
156
175
|
of The Twelve-Factor App. It also provides continuous integration tasks that rely
|
157
176
|
on the configuration tasks.
|
158
177
|
test_files:
|
159
|
-
- spec/spec_helper.rb
|
160
178
|
- spec/configuration_spec.rb
|
179
|
+
- spec/spec_helper.rb
|
180
|
+
- spec/support/config/database.yml.dice
|
161
181
|
- spec/command_spec.rb
|
182
|
+
- spec/template_file_spec.rb
|