Class: Rubber::Configuration::Environment

Inherits:
Object
  • Object
show all
Defined in:
lib/rubber/environment.rb

Overview

Contains the configuration defined in rubber.yml Handles selecting of correct config values based on the host/role passed into bind

Defined Under Namespace

Classes: BoundEnv, HashValueProxy

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config_root, env) ⇒ Environment

Returns a new instance of Environment.



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/rubber/environment.rb', line 19

def initialize(config_root, env)
  @config_root = config_root
  @config_env = env
  
  @config_files = ["#{@config_root}/rubber.yml"]
  @config_files += Dir["#{@config_root}/rubber-*.yml"].sort

  # add a config file for current env only so that you can override
  #things for specific envs
  @config_files -= Dir["#{@config_root}/rubber-*-env.yml"]
  env_yml = "#{@config_root}/rubber-#{Rubber.env}-env.yml"
  @config_files << env_yml if File.exist?(env_yml)
  
  @items = {}
  @config_files.each { |file| read_config(file) }

  read_secret_config
end

Instance Attribute Details

#config_envObject (readonly)

Returns the value of attribute config_env.



15
16
17
# File 'lib/rubber/environment.rb', line 15

def config_env
  @config_env
end

#config_filesObject (readonly)

Returns the value of attribute config_files.



16
17
18
# File 'lib/rubber/environment.rb', line 16

def config_files
  @config_files
end

#config_rootObject (readonly)

Returns the value of attribute config_root.



14
15
16
# File 'lib/rubber/environment.rb', line 14

def config_root
  @config_root
end

#config_secretObject (readonly)

Returns the value of attribute config_secret.



17
18
19
# File 'lib/rubber/environment.rb', line 17

def config_secret
  @config_secret
end

Class Method Details

.combine(old, new) ⇒ Object

combine old and new into a single value: non-nil wins if other is nil arrays just get unioned hashes also get unioned, but the values of conflicting keys get combined All else, the new value wins



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/rubber/environment.rb', line 115

def self.combine(old, new)
  return old if new.nil?
  return new if old.nil?
  value = old
  if old.is_a?(Hash) && new.is_a?(Hash)
    value = old.clone
    new.each do |nk, nv|
      if nk.to_s[0..0] == '^'
        nk = nk[1..-1]
        value[nk] = combine(nil, nv)
      else
        value[nk] = combine(value[nk], nv)
      end
    end
  elsif old.is_a?(Array) && new.is_a?(Array)
    value = old | new
  else
    value = new
  end

  value
end

Instance Method Details

#bind(roles = nil, host = nil) ⇒ Object



106
107
108
# File 'lib/rubber/environment.rb', line 106

def bind(roles = nil, host = nil)
  BoundEnv.new(@items, roles, host, config_env)
end

#current_full_hostObject



102
103
104
# File 'lib/rubber/environment.rb', line 102

def current_full_host
  Socket::gethostname
end

#current_hostObject



98
99
100
# File 'lib/rubber/environment.rb', line 98

def current_host
  Socket::gethostname.gsub(/\..*/, '')
end

#known_rolesObject



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/rubber/environment.rb', line 77

def known_roles
  return @known_roles if @known_roles
  
  roles = []
  # all the roles known about in config directory
  roles.concat Dir["#{@config_root}/role/*"].collect {|f| File.basename(f) }
  
  # all the roles known about in script directory
  roles.concat Dir["#{Rubber.root}/script/*/role/*"].collect {|f| File.basename(f) }
  
  # all the roles known about in yml files
  Dir["#{@config_root}/rubber*.yml"].each do |yml|
    rubber_yml = YAML::load(ERB.new(IO.read(yml)).result) rescue {}
    roles.concat(rubber_yml['roles'].keys) rescue nil
    roles.concat(rubber_yml['role_dependencies'].keys) rescue nil
    roles.concat(rubber_yml['role_dependencies'].values) rescue nil
  end
  
  @known_roles = roles.flatten.uniq.sort
end

#read_config(file) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/rubber/environment.rb', line 38

def read_config(file)
  Rubber.logger.debug{"Reading rubber configuration from #{file}"}
  if File.exist?(file)
    begin
      data = IO.read(file)
      data = yield(data) if block_given?
      @items = Environment.combine(@items, YAML::load(ERB.new(data).result) || {})
    rescue Exception => e
      Rubber.logger.error{"Unable to read rubber configuration from #{file}"}
      raise
    end
  end
end

#read_secret_configObject



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/rubber/environment.rb', line 52

def read_secret_config
  bound = bind()
  @config_secret = bound.rubber_secret
  if @config_secret

    # The config_secret value should point to a file outside of the project directory. When run locally, rubber
    # will be able to read this file directly. In order to support deploys without having to commit this file,
    # rubber will SCP the file up as part of the deploy. In that case, the file can be found in config_root and
    # will have the same base name. If the file doesn't exist locally, we'll assume it's a deployed location
    # and read the file from config_root.
    @config_secret = "#{@config_root}/#{File.basename(@config_secret)}" unless File.exist?(@config_secret)

    obfuscation_key = bound.rubber_secret_key
    if obfuscation_key
      require 'rubber/encryption'

      read_config(@config_secret) do |data|
        Rubber::Encryption.decrypt(data, obfuscation_key)
      end
    else
      read_config(@config_secret)
    end
  end
end