Class: CemAcpt::Config::Base
- Inherits:
-
Object
- Object
- CemAcpt::Config::Base
- Defined in:
- lib/cem_acpt/config/base.rb
Overview
Base class for other config classes Child classes should provide the following constant:
- VALID_KEYS - provide an array of valid top-level keys for the config as symbols
Child classes should implement the following methods:
- defaults - provide a hash of default values for the config
- env_var_prefix - provide a string to prefix environment variables with (defaults to 'CEM_ACPT').
This will be converted to uppercase, have all non-alphanumeric characters replaced with
underscores, and be joined with the key name with an underscore to form the environment
variable name.
However, they can override any of the methods in this class.
Direct Known Subclasses
Constant Summary collapse
- BASE_VALID_KEYS =
%i[ ci_mode config_file log_level log_file log_format no_destroy_nodes no_ephemeral_ssh_key platform provisioner puppet quiet secrets terraform user_config verbose ].freeze
- DEEP_MERGE_OPTS =
{ overwrite_arrays: true, merge_nil_values: true, }.freeze
Instance Attribute Summary collapse
-
#config ⇒ Object
(also: #to_h)
readonly
Returns the value of attribute config.
-
#env_vars ⇒ Object
readonly
Returns the value of attribute env_vars.
Class Method Summary collapse
- .inherited(subclass) ⇒ Object
-
.load_hook(&block) ⇒ Object
Add a block to be called after the config is loaded but before it is validated and frozen.
Instance Method Summary collapse
- #[](key) ⇒ Object
- #ci_mode? ⇒ Boolean (also: #ci?)
- #debug_mode? ⇒ Boolean (also: #debug?)
-
#defaults ⇒ Hash
The default configuration.
- #empty? ⇒ Boolean
-
#env_var_prefix ⇒ String
The prefix for environment variables.
-
#explain ⇒ Object
Returns a string representation of how the config was loaded.
- #get(dot_key) ⇒ Object (also: #dget)
- #has?(dot_key) ⇒ Boolean
-
#initialize(opts: {}, config_file: nil, load_user_config: true) ⇒ Base
constructor
A new instance of Base.
- #inspect ⇒ Object
-
#load(opts: {}, config_file: nil) ⇒ self
Load the configuration from the environment variables, config file, and opts The order of precedence is: 1.
- #quiet_mode? ⇒ Boolean (also: #quiet?)
- #to_json(*args, expose_secrets: false) ⇒ Object
- #to_yaml(expose_secrets: false) ⇒ Object
-
#valid_keys ⇒ Array<Symbol>
Valid top-level keys for the config.
- #verbose_mode? ⇒ Boolean (also: #verbose?)
Constructor Details
#initialize(opts: {}, config_file: nil, load_user_config: true) ⇒ Base
Returns a new instance of Base.
85 86 87 88 89 |
# File 'lib/cem_acpt/config/base.rb', line 85 def initialize(opts: {}, config_file: nil, load_user_config: true) @load_user_config = load_user_config @explanation = {} load(opts: opts, config_file: config_file) end |
Instance Attribute Details
#config ⇒ Object Also known as: to_h
Returns the value of attribute config.
83 84 85 |
# File 'lib/cem_acpt/config/base.rb', line 83 def config @config end |
#env_vars ⇒ Object (readonly)
Returns the value of attribute env_vars.
83 84 85 |
# File 'lib/cem_acpt/config/base.rb', line 83 def env_vars @env_vars end |
Class Method Details
.inherited(subclass) ⇒ Object
69 70 71 |
# File 'lib/cem_acpt/config/base.rb', line 69 def self.inherited(subclass) subclass.instance_variable_set(:@load_hook, nil) end |
.load_hook(&block) ⇒ Object
Add a block to be called after the config is loaded but before it is validated and frozen. The block will be passed the config hash and can be used to modify the config before it is finalized.
75 76 77 78 79 80 81 |
# File 'lib/cem_acpt/config/base.rb', line 75 def self.load_hook(&block) if block_given? @load_hook = block else @load_hook end end |
Instance Method Details
#[](key) ⇒ Object
165 166 167 168 169 170 171 172 173 |
# File 'lib/cem_acpt/config/base.rb', line 165 def [](key) if key.is_a?(Symbol) @config[key].dup elsif key.is_a?(String) get(key) else raise ArgumentError, "Invalid key type '#{key.class}'" end end |
#ci_mode? ⇒ Boolean Also known as: ci?
188 189 190 |
# File 'lib/cem_acpt/config/base.rb', line 188 def ci_mode? !!get('ci_mode') || !!(ENV['GITHUB_ACTIONS'] || ENV['CI']) end |
#debug_mode? ⇒ Boolean Also known as: debug?
193 194 195 |
# File 'lib/cem_acpt/config/base.rb', line 193 def debug_mode? get('log_level') == 'debug' end |
#defaults ⇒ Hash
Returns The default configuration.
110 111 112 |
# File 'lib/cem_acpt/config/base.rb', line 110 def defaults {} end |
#empty? ⇒ Boolean
184 185 186 |
# File 'lib/cem_acpt/config/base.rb', line 184 def empty? @config.empty? end |
#env_var_prefix ⇒ String
Returns The prefix for environment variables.
96 97 98 |
# File 'lib/cem_acpt/config/base.rb', line 96 def env_var_prefix 'CEM_ACPT' end |
#explain ⇒ Object
Returns a string representation of how the config was loaded
159 160 161 162 163 |
# File 'lib/cem_acpt/config/base.rb', line 159 def explain @explanation.each_with_object([]) { |(key, values), ary| ary << "#{key}:\n -->#{values.join("\n -->")}" }.join("\n") end |
#get(dot_key) ⇒ Object Also known as: dget
175 176 177 |
# File 'lib/cem_acpt/config/base.rb', line 175 def get(dot_key) @dot_key_cache[dot_key] ||= @config.dget(dot_key).dup end |
#has?(dot_key) ⇒ Boolean
180 181 182 |
# File 'lib/cem_acpt/config/base.rb', line 180 def has?(dot_key) !!get(dot_key) end |
#inspect ⇒ Object
91 92 93 |
# File 'lib/cem_acpt/config/base.rb', line 91 def inspect "#<#{self.class}:#{object_id.to_s(16)}>" end |
#load(opts: {}, config_file: nil) ⇒ self
Load the configuration from the environment variables, config file, and opts The order of precedence is:
1. static options (set in this class)
2. Runtime options
3. Runtime config file
4. User config file
5. Environment variables
6. Defaults
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/cem_acpt/config/base.rb', line 125 def load(opts: {}, config_file: nil) create_config_dirs! init_config!(opts: opts, config_file: config_file) add_env_vars!(@config) @config.deep_merge!(user_config, **DEEP_MERGE_OPTS) if user_config && @load_user_config @config.deep_merge!(config_from_file, **DEEP_MERGE_OPTS) if config_from_file if @options @config.deep_merge!(@options, **DEEP_MERGE_OPTS) @options.each do |key, _value| add_config_explanation(key, "runtime option") end end (@config) # Run the load hook if it is defined. This allows child classes to modify the config after it has been loaded # but before it is validated and frozen. block = self.class.load_hook instance_eval(&block) if block @config.format! # Symbolize keys of all hashes # Remove any keys that are not in the valid keys list for this config. This prevents invalid config options # from being set. @config.select! { |key, _| valid_keys.include?(key) } # Wrap secrets in the config with the Secret class to prevent them from being accidentally printed in logs # or error messages. WARNING: Secrets can leak from Terraform logging. wrap_secrets! validate_config! @dot_key_cache = {} # Freeze the config so it can't be modified # This helps with thread safety and deterministic behavior @config.freeze self end |
#quiet_mode? ⇒ Boolean Also known as: quiet?
203 204 205 |
# File 'lib/cem_acpt/config/base.rb', line 203 def quiet_mode? !!get('quiet') end |
#to_json(*args, expose_secrets: false) ⇒ Object
215 216 217 218 219 220 |
# File 'lib/cem_acpt/config/base.rb', line 215 def to_json(*args, expose_secrets: false) return @config.to_json(*args) unless @config.key?(:secrets) serializable_secrets = @config[:secrets].transform_values { |v| v.is_a?(Secret) ? (expose_secrets ? v.value : v.to_s) : v } @config.merge(secrets: serializable_secrets).to_json(*args) end |
#to_yaml(expose_secrets: false) ⇒ Object
208 209 210 211 212 213 |
# File 'lib/cem_acpt/config/base.rb', line 208 def to_yaml(expose_secrets: false) return @config.to_yaml unless @config.key?(:secrets) serializable_secrets = @config[:secrets].transform_values { |v| v.is_a?(Secret) ? (expose_secrets ? v.value : v.to_s) : v } @config.merge(secrets: serializable_secrets).to_yaml end |
#valid_keys ⇒ Array<Symbol>
Returns Valid top-level keys for the config.
101 102 103 104 105 106 107 |
# File 'lib/cem_acpt/config/base.rb', line 101 def valid_keys if self.class.const_defined?(:VALID_KEYS) (BASE_VALID_KEYS + self.class.const_get(:VALID_KEYS)).uniq else BASE_VALID_KEYS end end |
#verbose_mode? ⇒ Boolean Also known as: verbose?
198 199 200 |
# File 'lib/cem_acpt/config/base.rb', line 198 def verbose_mode? !!get('verbose') end |