Class: Invar::Reality
- Inherits:
-
Object
- Object
- Invar::Reality
- Includes:
- TestExtension::RealityMethods
- Defined in:
- lib/invar/reality.rb,
lib/invar/test.rb
Overview
Stores application config, secrets, and environmental variables. Environment variables come from ENV at the time of instantiation, while configs and secrets are loaded from respective files in the appropriate location. The secrets file is kept encrypted at rest.
Fetch information from a Reality by using the slash operator or square brackets:
invar = Invar::Reality.new(namespace: 'test-app')
puts invar / :config / :database / :host
puts invar[:config][:database][:host] # same as above
puts invar / :secrets / :database / :user
Note: ‘Invar.new` is a shorthand for Invar::Reality.new
Information known by a Reality is immutable. You may use the ‘#pretend` method to simulate different values during testing.
# In your tests, define an after_load hook
require 'invar/test'
Invar.after_load do |reality|
reality[:config][:database][:host].pretend 'example.com'
end
# then later, in your app, it will use the pretend value
invar = Invar.new namespace: 'my-app'
puts invar / :config / :database / :host # prints example.com
Defined Under Namespace
Classes: RealityValidator
Constant Summary collapse
- DEFAULT_KEY_FILE_NAME =
Name of the default key file to be searched for within config directories
'master_key'
Instance Method Summary collapse
-
#fetch(base_scope) ⇒ Object
(also: #/, #[])
Fetch from one of the two base scopes: :config or :secret.
-
#initialize(namespace:, decryption_keyfile: nil, configs_schema: nil, secrets_schema: nil) ⇒ Reality
constructor
Constructs a new Invar.
Constructor Details
#initialize(namespace:, decryption_keyfile: nil, configs_schema: nil, secrets_schema: nil) ⇒ Reality
Constructs a new Invar.
It will search for config, secrets, and decryption key files using the XDG specification.
The secrets file is decrypted using Lockbox. The key will be requested from these locations in order:
1. the Lockbox.master_key variable
2. the LOCKBOX_MASTER_KEY environment variable.
3. saved in a secure key file (recommended)
4. manual terminal prompt entry (recommended)
The :decryption_keyfile argument specifies the filename to read for option 3. It will be searched for in the same XDG locations as the secrets file. The decryption keyfile will be checked for safe permission modes.
NEVER hardcode your encryption key. This class intentionally does not accept a raw string of your decryption key to discourage hardcoding your encryption key and committing it to version control.
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/invar/reality.rb', line 67 def initialize(namespace:, decryption_keyfile: nil, configs_schema: nil, secrets_schema: nil) locator = FileLocator.new(namespace) search_paths = locator.search_paths.join(', ') begin @configs = Scope.new(load_configs(locator)) rescue FileLocator::FileNotFoundError raise MissingConfigFileError, "No Invar config file found. Create config.yml in one of these locations: #{ search_paths }" end begin @secrets = Scope.new(load_secrets(locator, decryption_keyfile || DEFAULT_KEY_FILE_NAME)) rescue FileLocator::FileNotFoundError hint = "Create encrypted secrets.yml in one of these locations: #{ search_paths }" raise MissingSecretsFileError, "No Invar secrets file found. #{ hint }" end freeze RealityValidator.new(configs_schema, secrets_schema).validate(@configs, @secrets) end |
Instance Method Details
#fetch(base_scope) ⇒ Object Also known as: /, []
Fetch from one of the two base scopes: :config or :secret. Plural names are also accepted (ie. :configs and :secrets).
95 96 97 98 99 100 101 102 103 104 |
# File 'lib/invar/reality.rb', line 95 def fetch(base_scope) case base_scope when /configs?/i @configs when /secrets?/i @secrets else raise ArgumentError, 'The root scope name must be either :config or :secret.' end end |