Module: Rudy::Huxtable

Overview

Rudy::Huxtable

Huxtable gives access to instances for config, global, and logger to any class that includes it.

class Rudy::Hello
  include Rudy::Huxtable

  def print_config
    p @@config.defaults  # {:nocolor => true, ...}
    p @@global.verbose   # => 1
    p @@logger.class     # => StringIO
  end

end

Constant Summary collapse

@@debug =

TODO: investigate @@debug bug. When this is true, Caesars.debug? returns true too. It’s possible this is intentional but probably not.

false
@@abort =
false
@@config =
Rudy::Config.new
@@global =
Rudy::Global.new
@@logger =

BUG: memory-leak for long-running apps

StringIO.new
@@sacred_params =
[:accesskey, :secretkey, :cert, :privatekey]

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.change_environment(v) ⇒ Object



74
# File 'lib/rudy/huxtable.rb', line 74

def self.change_environment(v); @@global.environment = v; end

.change_position(v) ⇒ Object



75
# File 'lib/rudy/huxtable.rb', line 75

def self.change_position(v); @@global.position = v; end

.change_region(v) ⇒ Object



73
# File 'lib/rudy/huxtable.rb', line 73

def self.change_region(v); @@global.region = v; end

.change_role(v) ⇒ Object



72
# File 'lib/rudy/huxtable.rb', line 72

def self.change_role(v); @@global.role = v; end

.change_zone(v) ⇒ Object



71
# File 'lib/rudy/huxtable.rb', line 71

def self.change_zone(v); @@global.zone = v; end

.create_domainObject



57
58
59
60
# File 'lib/rudy/huxtable.rb', line 57

def self.create_domain
  @sdb = Rudy::AWS::SDB.new(@@global.accesskey, @@global.secretkey, @@global.region)
  @sdb.create_domain Rudy::DOMAIN
end

.debug?Boolean

Returns:

  • (Boolean)


78
# File 'lib/rudy/huxtable.rb', line 78

def Huxtable.debug?; @@debug == true; end

.domainObject



67
68
69
# File 'lib/rudy/huxtable.rb', line 67

def self.domain
  Rudy::DOMAIN
end

.domain_exists?Boolean

Returns:

  • (Boolean)


62
63
64
65
# File 'lib/rudy/huxtable.rb', line 62

def self.domain_exists?
  @sdb = Rudy::AWS::SDB.new(@@global.accesskey, @@global.secretkey, @@global.region)
  (@sdb.list_domains || []).member? Rudy::DOMAIN
end

.keypair_path_to_name(kp) ⇒ Object



228
229
230
231
232
# File 'lib/rudy/huxtable.rb', line 228

def self.keypair_path_to_name(kp)
  return nil unless kp
  name = File.basename kp
  #name.gsub(/key-/, '')   # We keep the key- now
end

.update_config(path = nil) ⇒ Object

NOTE: These methods conflict with Drydock::Command classes. It’s probably a good idea to not expose these anyway since it can be done via Rudy::Huxtable.update_global etc… def config; @@config; end def global; @@global; end def logger; @@logger; end



42
43
44
45
46
47
# File 'lib/rudy/huxtable.rb', line 42

def self.update_config(path=nil)
  @@config.verbose = (@@global.verbose > 0)
  # nil and bad paths sent to look_and_load are ignored
  @@config.look_and_load(path || @@global.config)
  @@global.apply_config(@@config)
end

.update_global(ghash = {}) ⇒ Object



49
50
51
# File 'lib/rudy/huxtable.rb', line 49

def self.update_global(ghash={})
  @@global.update(ghash)
end

.update_logger(logger) ⇒ Object



53
54
55
# File 'lib/rudy/huxtable.rb', line 53

def self.update_logger(logger)
  @@logger = logger
end

Instance Method Details

#check_keysObject



79
80
81
82
83
# File 'lib/rudy/huxtable.rb', line 79

def check_keys
  raise "No EC2 .pem keys provided" unless has_pem_keys?
  raise "No SSH key provided for #{current_user}!" unless has_keypair?
  raise "No SSH key provided for root!" unless has_keypair?(:root)
end

#config_dirnameObject



94
95
96
97
98
99
# File 'lib/rudy/huxtable.rb', line 94

def config_dirname
  raise "No config paths defined" unless @@config.is_a?(Rudy::Config) && @@config.paths.is_a?(Array)
  base_dir = File.dirname @@config.paths.first
  raise "Config directory doesn't exist #{base_dir}" unless File.exists?(base_dir)
  base_dir
end

#current_group_nameObject



166
167
168
# File 'lib/rudy/huxtable.rb', line 166

def current_group_name
  "g-#{current_machine_group}"
end

#current_machine_address(position = '01') ⇒ Object

Raises:



195
196
197
198
199
200
201
# File 'lib/rudy/huxtable.rb', line 195

def current_machine_address(position='01')
  raise NoConfig unless @@config
  raise NoMachinesConfig unless @@config.machines
  raise "Position cannot be nil" if position.nil?
  addresses = [fetch_machine_param(:addresses)].flatten.compact
  addresses[position.to_i-1]
end

#current_machine_countObject



170
171
172
# File 'lib/rudy/huxtable.rb', line 170

def current_machine_count
  fetch_machine_param(:positions) || 1
end

#current_machine_groupObject



162
163
164
# File 'lib/rudy/huxtable.rb', line 162

def current_machine_group
  [@@global.environment, @@global.role].join(Rudy::DELIM)
end

#current_machine_hostnameObject



174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/rudy/huxtable.rb', line 174

def current_machine_hostname
  # NOTE: There is an issue with Caesars that a keyword that has been
  # defined as forced_array (or forced_hash, etc...) is like that for
  # all subclasses of Caesars. There is a conflict between "hostname" 
  # in the machines config and routines config. The routines config 
  # parses hostname with forced_array because it's a shell command
  # in Rye::Cmd. Machines config expects just a symbol. The issue
  # is with Caesars so this is a workaround to return a symbol.
  hn = fetch_machine_param(:hostname) || :rudy
  hn = hn.flatten.compact.first if hn.is_a?(Array)
  hn
end

#current_machine_imageObject



187
188
189
# File 'lib/rudy/huxtable.rb', line 187

def current_machine_image
  fetch_machine_param(:ami)
end

#current_machine_nameObject

TODO: fix machine_group to include zone



204
205
206
# File 'lib/rudy/huxtable.rb', line 204

def current_machine_name
  [@@global.zone, current_machine_group, @@global.position].join(Rudy::DELIM)
end

#current_machine_sizeObject



191
192
193
# File 'lib/rudy/huxtable.rb', line 191

def current_machine_size
  fetch_machine_param(:size) || 'm1.small'
end

#current_userObject



155
156
157
# File 'lib/rudy/huxtable.rb', line 155

def current_user
  @@global.user
end

#current_user_keypairpathObject



158
159
160
# File 'lib/rudy/huxtable.rb', line 158

def current_user_keypairpath
  user_keypairpath(current_user)
end

#debug?Boolean

Returns:

  • (Boolean)


77
# File 'lib/rudy/huxtable.rb', line 77

def debug?; Rudy::Huxtable.debug?; end

#group_metadata(env = @@global.environment, role = @@global.role) ⇒ Object



223
224
225
226
# File 'lib/rudy/huxtable.rb', line 223

def (env=@@global.environment, role=@@global.role)
  query = "['environment' = '#{env}'] intersection ['role' = '#{role}']"
  @sdb.query_with_attributes(Rudy::DOMAIN, query)
end

#has_keypair?(name = nil) ⇒ Boolean

Returns:

  • (Boolean)


101
102
103
104
# File 'lib/rudy/huxtable.rb', line 101

def has_keypair?(name=nil)
  kp = user_keypairpath(name)
  (!kp.nil? && File.exists?(kp))
end

#has_keys?Boolean

Returns:

  • (Boolean)


90
91
92
# File 'lib/rudy/huxtable.rb', line 90

def has_keys?
  (@@global.accesskey && !@@global.accesskey.empty? && @@global.secretkey && !@@global.secretkey.empty?)
end

#has_pem_keys?Boolean

Returns:

  • (Boolean)


85
86
87
88
# File 'lib/rudy/huxtable.rb', line 85

def has_pem_keys?
  (@@global.cert       && File.exists?(@@global.cert) && 
   @@global.privatekey && File.exists?(@@global.privatekey))
end

#has_root_keypair?Boolean

Returns:

  • (Boolean)


150
151
152
153
# File 'lib/rudy/huxtable.rb', line 150

def has_root_keypair?
  path = user_keypairpath(:root)
  (!path.nil? && !path.empty?)
end

#known_machine_group?Boolean

Looks for ENV-ROLE configuration in machines. There must be at least one definition in the config for this to return true That’s how Rudy knows the current group is defined.

Returns:

  • (Boolean)

Raises:



238
239
240
241
242
243
244
245
246
# File 'lib/rudy/huxtable.rb', line 238

def known_machine_group?
  raise NoConfig unless @@config
  raise NoMachinesConfig unless @@config.machines
  return false if !@@config && !@@global
  zon, env, rol = @@global.zone, @@global.environment, @@global.role
  conf = @@config.machines.find_deferred(@@global.region, zon, [env, rol])
  conf ||= @@config.machines.find_deferred(zon, [env, rol])
  !conf.nil?
end

#root_keypairnameObject



121
122
123
# File 'lib/rudy/huxtable.rb', line 121

def root_keypairname
  user_keypairname :root
end

#root_keypairpathObject



146
147
148
# File 'lib/rudy/huxtable.rb', line 146

def root_keypairpath
  user_keypairpath :root
end

#switch_user(name = nil) ⇒ Object

name the name of the remote user to use for the remainder of the command (or until switched again). If no name is provided, the user will be revert to whatever it was before the previous switch. TODO: deprecate



212
213
214
215
216
217
218
219
220
221
# File 'lib/rudy/huxtable.rb', line 212

def switch_user(name=nil)
  if name == nil && @switch_user_previous
    @@global.user = @switch_user_previous
  elsif @@global.user != name
    raise "No root keypair defined for #{name}!" unless has_keypair?(name)
    @@logger.puts "Remote commands will be run as #{name} user"
    @switch_user_previous = @@global.user
    @@global.user = name
  end
end

#user_keypairname(user) ⇒ Object

Returns the name of the current keypair for the given user. If there’s a private key path in the config this will return the basename (it’s assumed the Amazon KeyPair has the same name as the file). Otherwise this returns the Rudy style name: key-ZONE-ENV-ROLE-USER. Or if this the user is root: key-ZONE-ENV-ROLE



112
113
114
115
116
117
118
119
120
# File 'lib/rudy/huxtable.rb', line 112

def user_keypairname(user)
  kp = user_keypairpath(user)
  if kp
    kp = Huxtable.keypair_path_to_name(kp)
  else
    n = (user.to_s == 'root') ? '' : "-#{user}"
    "key-%s-%s%s" % [@@global.zone, current_machine_group, n]
  end    
end

#user_keypairpath(name) ⇒ Object

Raises:



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/rudy/huxtable.rb', line 126

def user_keypairpath(name)
  raise Rudy::Error, "No user provided" unless name
  raise NoConfig unless @@config
  raise NoMachinesConfig unless @@config.machines
  raise NoGlobal unless @@global
  zon, env, rol = @@global.zone, @@global.environment, @@global.role
  #Caesars.enable_debug
  path = @@config.machines.find_deferred(zon, env, rol, [:users, name, :keypair])
  path ||= @@config.machines.find_deferred(env, rol, [:users, name, :keypair])
  path ||= @@config.machines.find_deferred(rol, [:users, name, :keypair])
  
  # EC2 Keypairs that were created are intended for starting the machine instances. 
  # These are used as the root SSH keys. If we can find a user defined key, we'll 
  # check the config path for a generated one. 
  if !path && name.to_s == 'root'
    path = File.join(self.config_dirname, "key-#{@@global.zone}-#{current_machine_group}")
  end
  path = File.expand_path(path) if path && File.exists?(path)
  path
end