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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1d13bb21d8c45b24fefad1d7057fe6aea3d3961921cdfc6a94da8868dd4042ed
4
- data.tar.gz: 0f3ea599215049c844f2e778c28418d61484f9287ffa079f388bb5732142d653
3
+ metadata.gz: e5bb488ea8f0b38b938b9fd4ac13a69a1f60a8df544d546c123478bb31bb25ae
4
+ data.tar.gz: 7a351f59b04eaa6703e00608c2e9f90a3c53199529536ffe0ce3eb01f49d698e
5
5
  SHA512:
6
- metadata.gz: 93c35b5e5b5050f373043f672623577ba9a6eb29b9c0f88d3b9baa3274133034b1bba99d1d7380729663aa8cf91ee34a552db74c879bed28371833489b0df124
7
- data.tar.gz: 4400a06336890c10107a9e222b54dc0af98142baa91c318db6c8cac6be831f3d6c347b508885de6c00e59698af3149fa111964bb67b1379dbe93ec1f5ff54335
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 ||= begin
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)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "dice_bag/available_templates"
2
4
  require "dice_bag/project"
3
5
  require "dice_bag/config_file"
@@ -1,4 +1,6 @@
1
- require "dice_bag/dice_bag_file.rb"
1
+ # frozen_string_literal: true
2
+
3
+ require "dice_bag/dice_bag_file"
2
4
  require "dice_bag/project"
3
5
 
4
6
  # this class encapsulate a configuration file of the project
@@ -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.exists?(@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.exists?(file)
24
+ return true if @@overwrite_all || !File.exist?(file)
24
25
  return false if diff(file, new_contents).empty?
25
26
 
26
- while true
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
@@ -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
- OpenSSL::PKey::RSA.new @private_key
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-----".freeze
31
- FOOTER = "-----END RSA PRIVATE KEY-----".freeze
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, "")
@@ -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(Bundler.settings[:path], "/**/*")) if defined?(Bundler) && Bundler.settings[:path]
28
+ fl.exclude(File.join(bundle_path, "/**/*"))
25
29
  end
26
30
  end
27
31
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DiceBag
2
4
  class Railtie < Rails::Railtie
3
5
  rake_tasks do
@@ -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".freeze
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 :config => ["config:all"]
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(:deploy => true)
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 |t, args|
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 (use config:generate_all:force to replace all without asking for input)"
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 |t, args|
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', set the env variable '#{FORCE_ENV_VAR}' to overwrite the templates without asking for confirmation)"
47
- task :generate_from_gems, :names do |t, args|
48
- ARGV.each { |a| task a.to_sym do ; end }
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
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  load "dice_bag/tasks/config.rake"
@@ -1,4 +1,6 @@
1
- require "dice_bag/dice_bag_file.rb"
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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DiceBag
2
- VERSION = "1.4.0"
4
+ VERSION = "1.6.1"
3
5
  end
@@ -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 :as_yaml_comment :as_ruby_comment
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
- "'#@template_filename' template file.",
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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative "dice_bag/available_templates"
2
4
  module DiceBag
3
5
  require "dice_bag/railtie" if defined?(Rails)
data/spec/command_spec.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "spec_helper"
2
4
  require "dice_bag/project"
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "spec_helper"
2
4
  require "dice_bag/configuration"
3
5
 
data/spec/spec_helper.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Require this file using `require "spec_helper"` to ensure that it is only
2
4
  # loaded once.
3
5
  # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
@@ -0,0 +1,4 @@
1
+ development:
2
+ database: development
3
+ username: <%= configured.database_username || 'root' %>
4
+ password: <%= configured.database_password %>
@@ -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.0
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: 2020-05-19 00:00:00.000000000 Z
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: diff-lcs
57
+ name: aruba
44
58
  requirement: !ruby/object:Gem::Requirement
45
59
  requirements:
46
60
  - - "~>"
47
61
  - !ruby/object:Gem::Version
48
- version: '1.0'
49
- type: :runtime
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: '1.0'
69
+ version: 0.6.0
56
70
  - !ruby/object:Gem::Dependency
57
- name: aruba
71
+ name: bundler
58
72
  requirement: !ruby/object:Gem::Requirement
59
73
  requirements:
60
- - - "~>"
74
+ - - ">="
61
75
  - !ruby/object:Gem::Version
62
- version: 0.6.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.6.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: bundler
99
+ name: rubocop
86
100
  requirement: !ruby/object:Gem::Requirement
87
101
  requirements:
88
- - - ">="
102
+ - - "~>"
89
103
  - !ruby/object:Gem::Version
90
- version: '0'
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: '0'
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.3.0
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