container_config 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/workflows/main.yml +35 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.rubocop.yml +28 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +64 -0
- data/LICENSE.txt +21 -0
- data/README.md +116 -0
- data/Rakefile +12 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/container_config.gemspec +37 -0
- data/lib/container_config.rb +185 -0
- data/lib/container_config/coercer.rb +61 -0
- data/lib/container_config/coercer/base.rb +39 -0
- data/lib/container_config/coercer/boolean.rb +34 -0
- data/lib/container_config/coercer/float.rb +33 -0
- data/lib/container_config/coercer/integer.rb +33 -0
- data/lib/container_config/coercer/ssl_certificate.rb +47 -0
- data/lib/container_config/coercer/ssl_key.rb +45 -0
- data/lib/container_config/coercer/ssl_verify_mode.rb +42 -0
- data/lib/container_config/coercer/string.rb +31 -0
- data/lib/container_config/coercer/symbol.rb +33 -0
- data/lib/container_config/logger.rb +9 -0
- data/lib/container_config/provider.rb +66 -0
- data/lib/container_config/provider/base.rb +39 -0
- data/lib/container_config/provider/default.rb +30 -0
- data/lib/container_config/provider/env.rb +29 -0
- data/lib/container_config/provider/rails_credential.rb +31 -0
- data/lib/container_config/provider/secret_volume.rb +58 -0
- data/lib/container_config/rails.rb +10 -0
- data/lib/container_config/rails/mailer.rb +81 -0
- data/lib/container_config/redis.rb +95 -0
- data/lib/container_config/version.rb +6 -0
- metadata +167 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a335fbf082edd704a0fad5393a1211ad20b0533611f688a174112533469c43e9
|
4
|
+
data.tar.gz: 71cde1c1a6a7f539ff6d9359ea98b594d35a39d19d06148e32c0a2ad1fff25a9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bbb9e521366c1f740a76d9d473c2eb95a6c9e9a5be2c09856523ec63112a03e6c509cd1820bd7886522de4286bc276b7b9508a4f6120225b2c7082945e37c09c
|
7
|
+
data.tar.gz: ebd3318980dfe673eb1b4c526f7b5ffb9b7741709376a323a7d01ca521a7f9fbfb93f6b253213cfa1bf75372fed65d13a528a430aa4dbe6b3d14784e380d5802
|
@@ -0,0 +1,35 @@
|
|
1
|
+
name: Ruby
|
2
|
+
|
3
|
+
on: [push,pull_request]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
build:
|
7
|
+
runs-on: ubuntu-latest
|
8
|
+
steps:
|
9
|
+
- uses: actions/checkout@v2
|
10
|
+
- name: Set up Ruby
|
11
|
+
uses: ruby/setup-ruby@v1
|
12
|
+
with:
|
13
|
+
ruby-version: 2.7.2
|
14
|
+
- name: Run unit tests and code linting
|
15
|
+
run: |
|
16
|
+
gem install bundler -v 2.2.9
|
17
|
+
bundle install
|
18
|
+
bundle exec rake
|
19
|
+
bundle exec yard
|
20
|
+
|
21
|
+
- name: Deploy documentation
|
22
|
+
if: github.ref == 'refs/heads/main'
|
23
|
+
uses: crazy-max/ghaction-github-pages@v2.2.0
|
24
|
+
with:
|
25
|
+
target_branch: gh-pages
|
26
|
+
build_dir: doc
|
27
|
+
env:
|
28
|
+
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
29
|
+
|
30
|
+
- name: Release Gem
|
31
|
+
if: contains(github.ref, 'refs/tags/v')
|
32
|
+
uses: dawidd6/action-publish-gem@v1.2.0
|
33
|
+
with:
|
34
|
+
github_token: ${{secrets.GITHUB_TOKEN}}
|
35
|
+
api_key: ${{secrets.RUBYGEMS_API_KEY}}
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 2.4
|
3
|
+
NewCops: enable
|
4
|
+
|
5
|
+
Style/StringLiterals:
|
6
|
+
Enabled: true
|
7
|
+
EnforcedStyle: double_quotes
|
8
|
+
|
9
|
+
Style/StringLiteralsInInterpolation:
|
10
|
+
Enabled: true
|
11
|
+
EnforcedStyle: double_quotes
|
12
|
+
|
13
|
+
Layout/LineLength:
|
14
|
+
Max: 150
|
15
|
+
|
16
|
+
Metrics/BlockLength:
|
17
|
+
Exclude:
|
18
|
+
- spec/**/*.rb
|
19
|
+
|
20
|
+
Metrics/AbcSize:
|
21
|
+
Max: 25
|
22
|
+
|
23
|
+
Metrics/MethodLength:
|
24
|
+
Max: 20
|
25
|
+
|
26
|
+
Lint/BooleanSymbol:
|
27
|
+
Exclude:
|
28
|
+
- spec/container_config/coercer/symbol_spec.rb
|
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
container_config (0.1.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
ast (2.4.2)
|
10
|
+
diff-lcs (1.4.4)
|
11
|
+
parallel (1.20.1)
|
12
|
+
parser (3.0.0.0)
|
13
|
+
ast (~> 2.4.1)
|
14
|
+
rainbow (3.0.0)
|
15
|
+
rake (13.0.3)
|
16
|
+
regexp_parser (2.1.1)
|
17
|
+
rexml (3.2.4)
|
18
|
+
rspec (3.10.0)
|
19
|
+
rspec-core (~> 3.10.0)
|
20
|
+
rspec-expectations (~> 3.10.0)
|
21
|
+
rspec-mocks (~> 3.10.0)
|
22
|
+
rspec-core (3.10.1)
|
23
|
+
rspec-support (~> 3.10.0)
|
24
|
+
rspec-expectations (3.10.1)
|
25
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
26
|
+
rspec-support (~> 3.10.0)
|
27
|
+
rspec-mocks (3.10.2)
|
28
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
29
|
+
rspec-support (~> 3.10.0)
|
30
|
+
rspec-support (3.10.2)
|
31
|
+
rubocop (1.11.0)
|
32
|
+
parallel (~> 1.10)
|
33
|
+
parser (>= 3.0.0.0)
|
34
|
+
rainbow (>= 2.2.2, < 4.0)
|
35
|
+
regexp_parser (>= 1.8, < 3.0)
|
36
|
+
rexml
|
37
|
+
rubocop-ast (>= 1.2.0, < 2.0)
|
38
|
+
ruby-progressbar (~> 1.7)
|
39
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
40
|
+
rubocop-ast (1.4.1)
|
41
|
+
parser (>= 2.7.1.5)
|
42
|
+
rubocop-rake (0.5.1)
|
43
|
+
rubocop
|
44
|
+
rubocop-rspec (2.2.0)
|
45
|
+
rubocop (~> 1.0)
|
46
|
+
rubocop-ast (>= 1.1.0)
|
47
|
+
ruby-progressbar (1.11.0)
|
48
|
+
unicode-display_width (2.0.0)
|
49
|
+
yard (0.9.26)
|
50
|
+
|
51
|
+
PLATFORMS
|
52
|
+
x86_64-linux
|
53
|
+
|
54
|
+
DEPENDENCIES
|
55
|
+
container_config!
|
56
|
+
rake (~> 13.0)
|
57
|
+
rspec (~> 3.0)
|
58
|
+
rubocop (~> 1.7)
|
59
|
+
rubocop-rake (~> 0.5)
|
60
|
+
rubocop-rspec (~> 2.2)
|
61
|
+
yard (~> 0.9)
|
62
|
+
|
63
|
+
BUNDLED WITH
|
64
|
+
2.2.9
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2021 Matthew Newell
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
# Container Config
|
2
|
+
|
3
|
+
`ContainerConfig` loads values from environment variables, secrets, application credentials, and any other desired value sources within Ruby applications. Rails is not required, but this gem will integrate with Rails if it is available.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application"s Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem "container_config"
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle install
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install container_config
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
# Retrieve the value of the POSTGRES_USER environment variable, secret mount, or Rails credential
|
25
|
+
ConfigLoader.load("POSTGRES_USER")
|
26
|
+
|
27
|
+
# Retrieve the value of the POSTGRES_PORT environment variable, secret mount, or Rails credential as an integer with a default value of 5432
|
28
|
+
ConfigLoader.load("POSTGRES_PORT", type: :integer, default: 5432)
|
29
|
+
|
30
|
+
# Retrieve the value of the POSTGRES_PASSWORD environment variable, secret mount, or Rails credential and raise an exception if it cannot be found
|
31
|
+
ConfigLoader.load("POSTGRES_PASSWORD", required: true)
|
32
|
+
```
|
33
|
+
|
34
|
+
Full documentation is available in the [ContainerConfig GitHub Pages](https://wheatevo.github.io/container_config/).
|
35
|
+
|
36
|
+
### Extending ContainerConfig
|
37
|
+
|
38
|
+
`ContainerConfig` may be extended by adding more value providers to gather configuration data or by adding more type coercers to coerce retrieved data into desired types.
|
39
|
+
|
40
|
+
#### Value Providers
|
41
|
+
|
42
|
+
More value providers may be added by creating a new class that inherits from `ContainerConfig::Provider::Base` and implementing the `name` and `load` methods. The `name` method should return a `String` name for your value provider and the `load` method should receive a `String` `key`, `*dig_keys`, and `**options` and return the found value or `nil`.
|
43
|
+
|
44
|
+
You may optionally call `super` from `load` to enable logging by default.
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
# Define a new value provider that returns the abstract from a DuckDuckGo instant result search (https://duckduckgo.com/api)
|
48
|
+
require "container_config"
|
49
|
+
require "uri"
|
50
|
+
require "net/http"
|
51
|
+
require "json"
|
52
|
+
|
53
|
+
class DuckDuckGoAbstractProvider < ContainerConfig::Provider::Base
|
54
|
+
def name
|
55
|
+
"DuckDuckGo Wikipedia abstract provider"
|
56
|
+
end
|
57
|
+
|
58
|
+
def load(key, *dig_keys, **options)
|
59
|
+
super
|
60
|
+
|
61
|
+
response = Net::HTTP.get(URI.parse("https://api.duckduckgo.com/?q=#{URI.encode_www_form([key])}&format=json"))
|
62
|
+
JSON.parse(response)["Abstract"]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Add the DuckDuckGo value provider to the array of existing providers
|
67
|
+
ContainerConfig.providers << DuckDuckGoAbstractProvider.new
|
68
|
+
|
69
|
+
# Use the DuckDuckGo value provider
|
70
|
+
ContainerConfig.load("rockhopper penguins")
|
71
|
+
# => "The rockhopper penguins are three closely related taxa of crested penguins..."
|
72
|
+
```
|
73
|
+
|
74
|
+
#### Type Coercers
|
75
|
+
|
76
|
+
More supported types may be added by creating a new class that inherits from `ContainerConfig::Coercer::Base` and implementing the `name`, `type`, and `coerce` methods. The `name` method should return a `String` name for your type coercer, the `type` method should return a `Symbol` type for your type coercer, and the `coerce` method should receive a single `Object` `value` and return your coerced type.
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
# Define a new type coercer that simply prepends "MyType: " to the string representation of a value
|
80
|
+
require "container_config"
|
81
|
+
|
82
|
+
class MyTypeCoercer < ContainerConfig::Coercer::Base
|
83
|
+
def name
|
84
|
+
"My Type"
|
85
|
+
end
|
86
|
+
|
87
|
+
def type
|
88
|
+
:my_type
|
89
|
+
end
|
90
|
+
|
91
|
+
def coerce(value)
|
92
|
+
"MyType: #{value}"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# Add the type coercer to the array of existing type coercers
|
97
|
+
ContainerConfig.coercers << MyTypeCoercer.new
|
98
|
+
|
99
|
+
# Use the type coercer (KEY has value "key_value")
|
100
|
+
ContainerConfig.load("KEY", type: :my_type)
|
101
|
+
# => "MyType: key_value"
|
102
|
+
```
|
103
|
+
|
104
|
+
## Development
|
105
|
+
|
106
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
107
|
+
|
108
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
109
|
+
|
110
|
+
## Contributing
|
111
|
+
|
112
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/wheatevo/container_config.
|
113
|
+
|
114
|
+
## License
|
115
|
+
|
116
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "bundler/setup"
|
5
|
+
require "container_config"
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
# require "pry"
|
12
|
+
# Pry.start
|
13
|
+
|
14
|
+
require "irb"
|
15
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/container_config/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "container_config"
|
7
|
+
spec.version = ContainerConfig::VERSION
|
8
|
+
spec.authors = ["Matthew Newell"]
|
9
|
+
spec.email = ["matthewtnewell@gmail.com"]
|
10
|
+
|
11
|
+
spec.summary = "Loads container configuration values from environment variables, secrets, and credentials."
|
12
|
+
spec.description = "Loads container configuration values from environment variables, secrets, and credentials."
|
13
|
+
spec.homepage = "https://github.com/wheatevo/container_config"
|
14
|
+
spec.license = "MIT"
|
15
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
|
16
|
+
|
17
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
18
|
+
spec.metadata["source_code_uri"] = "https://github.com/wheatevo/container_config"
|
19
|
+
spec.metadata["changelog_uri"] = "https://github.com/wheatevo/container_config/blob/master/CHANGELOG.md"
|
20
|
+
|
21
|
+
# Specify which files should be added to the gem when it is released.
|
22
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
23
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
24
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
|
25
|
+
end
|
26
|
+
spec.bindir = "exe"
|
27
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
28
|
+
spec.require_paths = ["lib"]
|
29
|
+
|
30
|
+
# Development dependencies
|
31
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
32
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
33
|
+
spec.add_development_dependency "rubocop", "~> 1.7"
|
34
|
+
spec.add_development_dependency "rubocop-rake", "~> 0.5"
|
35
|
+
spec.add_development_dependency "rubocop-rspec", "~> 2.2"
|
36
|
+
spec.add_development_dependency "yard", "~> 0.9"
|
37
|
+
end
|
@@ -0,0 +1,185 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "container_config/version"
|
4
|
+
require "container_config/logger"
|
5
|
+
require "container_config/provider"
|
6
|
+
require "container_config/coercer"
|
7
|
+
require "container_config/redis"
|
8
|
+
|
9
|
+
# Contains methods for loading and parsing container configuration
|
10
|
+
module ContainerConfig
|
11
|
+
#
|
12
|
+
# Loads a configuration setting from environment variables, mounted secrets, or the application credentials
|
13
|
+
#
|
14
|
+
# @param [String] key Configuration key to load
|
15
|
+
# @param [Array] dig_keys Variable keys to use to load from providers that accept a dig structure
|
16
|
+
# defaults to the lowercase key split by underscores
|
17
|
+
# "MY_PASSWORD" => ["my", "password"]
|
18
|
+
# @param [Hash] options Options Hash
|
19
|
+
# @option options [Boolean] :required whether to raise an exception if the setting cannot be found
|
20
|
+
# @option options [String] :default default value if the configuration setting cannot be found
|
21
|
+
# @option options [String] :secret_mount_directory directory where secret files are mounted
|
22
|
+
# @option options [Boolean] :coerce_nil where to coerce nil values (defaults to true)
|
23
|
+
# @option options [Boolean] :cache whether to cache the retrieved value and to return that value in future calls
|
24
|
+
# future calls must also specify cache: true to prevent the value from being re-read
|
25
|
+
# @option options [Symbol] :type type to use such as :boolean, :integer, :string, :symbol,
|
26
|
+
# :ssl_verify_mode, :ssl_certificate, or :ssl_key
|
27
|
+
# @option options [Array] :enum valid values for the configuration parameter, raises an exception
|
28
|
+
# if the value is not in the enum
|
29
|
+
#
|
30
|
+
# @return [Object] configuration setting value
|
31
|
+
#
|
32
|
+
def self.load(key, *dig_keys, **options)
|
33
|
+
logger.debug { "Loading configuration value for #{key}" }
|
34
|
+
options[:required] ||= options[:raise] || false
|
35
|
+
dig_keys = key.downcase.split("_") if dig_keys.empty?
|
36
|
+
|
37
|
+
return cache[key] if options[:cache] && cache.key?(key)
|
38
|
+
|
39
|
+
config_value = ContainerConfig::Provider.load_value(key, *dig_keys, **options)
|
40
|
+
handle_empty_value(config_value, key, **options)
|
41
|
+
config_value = ContainerConfig::Coercer.coerce_value(config_value, options[:type], **options)
|
42
|
+
handle_enum(config_value, **options)
|
43
|
+
|
44
|
+
cache[key] = config_value if options[:cache]
|
45
|
+
|
46
|
+
config_value
|
47
|
+
end
|
48
|
+
|
49
|
+
#
|
50
|
+
# Clears all entries from the configuration cache
|
51
|
+
#
|
52
|
+
def self.clear_cache
|
53
|
+
@cache = {}
|
54
|
+
end
|
55
|
+
|
56
|
+
#
|
57
|
+
# Gets the configuration cache
|
58
|
+
#
|
59
|
+
# @return [Hash] configuration cache
|
60
|
+
#
|
61
|
+
def self.cache
|
62
|
+
@cache ||= {}
|
63
|
+
end
|
64
|
+
|
65
|
+
#
|
66
|
+
# Gets the list of configuration value coercers
|
67
|
+
#
|
68
|
+
# @return [Array<ContainerConfig::Coercer::Base>] current value coercers
|
69
|
+
#
|
70
|
+
def self.coercers
|
71
|
+
@coercers ||= ContainerConfig::Coercer.default_coercers
|
72
|
+
end
|
73
|
+
|
74
|
+
#
|
75
|
+
# Sets the list of configuration value coercers
|
76
|
+
#
|
77
|
+
# @param [Array<ContainerConfig::Coercer::Base>] coercers new value coercers
|
78
|
+
#
|
79
|
+
def self.coercers=(coercers)
|
80
|
+
@coercers = coercers
|
81
|
+
end
|
82
|
+
|
83
|
+
#
|
84
|
+
# Gets the list of configuration value providers
|
85
|
+
#
|
86
|
+
# @return [Array<ContainerConfig::Provider::Base>] current value providers
|
87
|
+
#
|
88
|
+
def self.providers
|
89
|
+
@providers ||= ContainerConfig::Provider.default_providers
|
90
|
+
end
|
91
|
+
|
92
|
+
#
|
93
|
+
# Sets the list of configuration value providers
|
94
|
+
#
|
95
|
+
# @param [Array<ContainerConfig::Provider::Base>] providers new value providers
|
96
|
+
#
|
97
|
+
def self.providers=(providers)
|
98
|
+
@providers = providers
|
99
|
+
end
|
100
|
+
|
101
|
+
#
|
102
|
+
# Gets the container config logger
|
103
|
+
#
|
104
|
+
# @return [ContainerConfig::Logger] current logger
|
105
|
+
#
|
106
|
+
def self.logger
|
107
|
+
@logger ||= ContainerConfig::Logger.new($stdout, level: Logger::INFO)
|
108
|
+
end
|
109
|
+
|
110
|
+
#
|
111
|
+
# Sets the container config logger
|
112
|
+
#
|
113
|
+
# @param [::Logger] logger logger to set
|
114
|
+
#
|
115
|
+
def self.logger=(logger)
|
116
|
+
if logger.nil?
|
117
|
+
self.logger.level = Logger::FATAL
|
118
|
+
return self.logger
|
119
|
+
end
|
120
|
+
@logger = logger
|
121
|
+
end
|
122
|
+
|
123
|
+
#
|
124
|
+
# Gets the container config log formatter
|
125
|
+
#
|
126
|
+
# @return [::Logger::Formatter] current log formatter
|
127
|
+
#
|
128
|
+
def self.log_formatter
|
129
|
+
@log_formatter ||= logger.formatter
|
130
|
+
end
|
131
|
+
|
132
|
+
#
|
133
|
+
# Sets the container config log formatter
|
134
|
+
#
|
135
|
+
# @param [::Logger::Formatter] log_formatter new log formatter
|
136
|
+
#
|
137
|
+
def self.log_formatter=(log_formatter)
|
138
|
+
@log_formatter = log_formatter
|
139
|
+
logger.formatter = log_formatter
|
140
|
+
end
|
141
|
+
|
142
|
+
#
|
143
|
+
# Whether this is in the context of a Rails application
|
144
|
+
#
|
145
|
+
# @return [Boolean] true if in a Rails application, false otherwise
|
146
|
+
#
|
147
|
+
def self.rails_app?
|
148
|
+
defined?(::Rails) && ::Rails.respond_to?(:application)
|
149
|
+
end
|
150
|
+
|
151
|
+
class << self
|
152
|
+
private
|
153
|
+
|
154
|
+
def handle_empty_value(config_value, key, **options)
|
155
|
+
if config_value.nil? || config_value.to_s.empty?
|
156
|
+
provider_list = providers.map(&:name).join(", ")
|
157
|
+
logger.warn { "Could not find value for #{key} in providers: #{provider_list}" }
|
158
|
+
raise MissingRequiredValue, "Could not find value for #{key} in providers: #{provider_list}!" if options[:required]
|
159
|
+
else
|
160
|
+
logger.debug { "Configuration value for #{key} loaded" }
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def handle_enum(config_value, **options)
|
165
|
+
return if !options[:enum] || options[:enum].include?(config_value)
|
166
|
+
|
167
|
+
valid_values = options[:enum].join(", ")
|
168
|
+
raise InvalidEnumValue, "Config value #{config_value.inspect} is invalid. Valid values: #{valid_values}"
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
# General ContainerConfig error
|
173
|
+
class Error < StandardError; end
|
174
|
+
|
175
|
+
# Error raised when a required value is missing when loading a configuration value
|
176
|
+
class MissingRequiredValue < Error; end
|
177
|
+
|
178
|
+
# Error raised when a derived class is missing an override method
|
179
|
+
class MissingOverride < Error; end
|
180
|
+
|
181
|
+
# Error raised when a configuration value is not within the provided enum
|
182
|
+
class InvalidEnumValue < Error; end
|
183
|
+
end
|
184
|
+
|
185
|
+
require "container_config/rails" if ContainerConfig.rails_app?
|