class Constancy::Config
Constants
- CONFIG_FILENAMES
- DEFAULT_CONSUL_TOKEN_SOURCE
- DEFAULT_CONSUL_URL
- DEFAULT_VAULT_CONSUL_TOKEN_FIELD
- VALID_CONFIG_KEYS
- VALID_CONFIG_KEY_PATTERNS
- VALID_CONSTANCY_CONFIG_KEYS
- VALID_CONSUL_CONFIG_KEYS
- VALID_VAULT_CONFIG_KEYS
- VALID_VAULT_KEY_PATTERNS
Attributes
base_dir[RW]
call_external_apis[RW]
config_file[RW]
consul_token_sources[RW]
consul_url[RW]
default_consul_token_source[RW]
sync_targets[RW]
target_allowlist[RW]
Public Class Methods
discover(dir: nil)
click to toggle source
discover the nearest config file
# File lib/constancy/config.rb, line 28 def discover(dir: nil) dir ||= Dir.pwd CONFIG_FILENAMES.each do |filename| full_path = File.join(dir, filename) if File.exist?(full_path) return full_path end end dir == "/" ? nil : self.discover(dir: File.dirname(dir)) end
new(path: nil, targets: nil, call_external_apis: true)
click to toggle source
# File lib/constancy/config.rb, line 51 def initialize(path: nil, targets: nil, call_external_apis: true) if path.nil? or File.directory?(path) self.config_file = Constancy::Config.discover(dir: path) elsif File.exist?(path) self.config_file = path else raise Constancy::ConfigFileNotFound.new end if self.config_file.nil? or not File.exist?(self.config_file) or not File.readable?(self.config_file) raise Constancy::ConfigFileNotFound.new end self.config_file = File.expand_path(self.config_file) self.base_dir = File.dirname(self.config_file) self.target_allowlist = targets self.call_external_apis = call_external_apis parse! end
only_valid_config_keys!(keylist)
click to toggle source
# File lib/constancy/config.rb, line 41 def only_valid_config_keys!(keylist) (keylist - VALID_CONFIG_KEYS).each do |key| if not VALID_CONFIG_KEY_PATTERNS.find { |pattern| key =~ pattern } raise Constancy::ConfigFileInvalid.new("'#{key}' is not a valid configuration key") end end true end
Public Instance Methods
chomp?()
click to toggle source
# File lib/constancy/config.rb, line 75 def chomp? @do_chomp end
color?()
click to toggle source
# File lib/constancy/config.rb, line 83 def color? @use_color end
delete?()
click to toggle source
# File lib/constancy/config.rb, line 79 def delete? @do_delete end
parse!()
click to toggle source
# File lib/constancy/config.rb, line 93 def parse! raw = {} begin raw = YAML.load(ERB.new(File.read(self.config_file)).result) rescue raise Constancy::ConfigFileInvalid.new("Unable to parse config file as YAML") end if raw.is_a? FalseClass # this generally means an empty config file raw = {} end if not raw.is_a? Hash raise Constancy::ConfigFileInvalid.new("Config file must form a hash") end Constancy::Config.only_valid_config_keys!(raw.keys) self.consul_token_sources = { "none" => Constancy::PassiveTokenSource.new, "env" => Constancy::EnvTokenSource.new, }.merge( self.parse_vault_token_sources!(raw), ) raw['consul'] ||= {} if not raw['consul'].is_a? Hash raise Constancy::ConfigFileInvalid.new("'consul' must be a hash") end if (raw['consul'].keys - VALID_CONSUL_CONFIG_KEYS) != [] raise Constancy::ConfigFileInvalid.new("Only the following keys are valid in the consul config: #{VALID_CONSUL_CONFIG_KEYS.join(", ")}") end self.consul_url = raw['consul']['url'] || DEFAULT_CONSUL_URL srcname = raw['consul']['token_source'] || DEFAULT_CONSUL_TOKEN_SOURCE self.default_consul_token_source = self.consul_token_sources[srcname].tap do |src| if src.nil? raise Constancy::ConfigFileInvalid.new("Consul token source '#{consul_token_source}' is not defined") end end raw['constancy'] ||= {} if not raw['constancy'].is_a? Hash raise Constancy::ConfigFileInvalid.new("'constancy' must be a hash") end if (raw['constancy'].keys - VALID_CONSTANCY_CONFIG_KEYS) != [] raise Constancy::ConfigFileInvalid.new("Only the following keys are valid in the 'constancy' config block: #{VALID_CONSTANCY_CONFIG_KEYS.join(", ")}") end # verbose: default false @is_verbose = raw['constancy']['verbose'] ? true : false if ENV['CONSTANCY_VERBOSE'] @is_verbose = true end # chomp: default true if raw['constancy'].has_key?('chomp') @do_chomp = raw['constancy']['chomp'] ? true : false else @do_chomp = true end # delete: default false @do_delete = raw['constancy']['delete'] ? true : false raw['sync'] ||= [] if not raw['sync'].is_a? Array raise Constancy::ConfigFileInvalid.new("'sync' must be an array") end # color: default true if raw['constancy'].has_key?('color') @use_color = raw['constancy']['color'] ? true : false else @use_color = true end self.sync_targets = [] raw['sync'].each do |target| token_source = self.default_consul_token_source if target.is_a? Hash target['datacenter'] ||= raw['consul']['datacenter'] if target['chomp'].nil? target['chomp'] = self.chomp? end if target['delete'].nil? target['delete'] = self.delete? end if not target['token_source'].nil? token_source = self.consul_token_sources[target['token_source']] if token_source.nil? raise Constancy::ConfigFileInvalid.new("Consul token source '#{target['token_source']}' is not defined") end target.delete('token_source') end end if not self.target_allowlist.nil? # unnamed targets cannot be allowlisted next if target['name'].nil? # named targets must be on the allowlist next if not self.target_allowlist.include?(target['name']) end # only try to fetch consul tokens if we are actually going to do work consul_token = if self.call_external_apis token_source.consul_token else "" end self.sync_targets << Constancy::SyncTarget.new(config: target, consul_url: consul_url, token_source: token_source, base_dir: self.base_dir, call_external_apis: self.call_external_apis) end end
parse_vault_token_sources!(raw)
click to toggle source
# File lib/constancy/config.rb, line 87 def parse_vault_token_sources!(raw) raw.keys.select { |key| VALID_VAULT_KEY_PATTERNS.find { |pattern| key =~ pattern } }.collect do |key| [key, Constancy::VaultTokenSource.new(name: key, config: raw[key])] end.to_h end
verbose?()
click to toggle source
# File lib/constancy/config.rb, line 71 def verbose? @is_verbose end