Class: ZZSharedLib::Amazon

Inherits:
Object
  • Object
show all
Defined in:
lib/zzsharedlib/amazon.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeAmazon

Returns a new instance of Amazon.



40
41
42
43
44
45
# File 'lib/zzsharedlib/amazon.rb', line 40

def initialize
  connection = RightAws::ActiveSdb.establish_connection(Amazon.access_key, Amazon.secret_key, :logger => Amazon.logger)
  @ec2 = Amazon.ec2
  @elb = Amazon.elb
  @force_tags = true
end

Instance Attribute Details

#ec2Object (readonly)

Returns the value of attribute ec2.



7
8
9
# File 'lib/zzsharedlib/amazon.rb', line 7

def ec2
  @ec2
end

#elbObject (readonly)

Returns the value of attribute elb.



7
8
9
# File 'lib/zzsharedlib/amazon.rb', line 7

def elb
  @elb
end

Class Method Details

.access_keyObject



21
22
23
# File 'lib/zzsharedlib/amazon.rb', line 21

def self.access_key
  Options.get(:access_key) || ENV['AWS_ACCESS_KEY_ID']
end

.ec2Object



9
10
11
# File 'lib/zzsharedlib/amazon.rb', line 9

def self.ec2
  @@ec2 ||= RightAws::Ec2.new(access_key, secret_key, :endpoint_url => 'https://ec2.us-east-1.amazonaws.com/', :logger => Amazon.logger)
end

.elbObject



13
14
15
# File 'lib/zzsharedlib/amazon.rb', line 13

def self.elb
  @@elb ||= RightAws::ElbInterface.new(access_key, secret_key, :logger => Amazon.logger)
end

.log_levelObject



25
26
27
# File 'lib/zzsharedlib/amazon.rb', line 25

def self.log_level
  Options.get(:log_level) || Logger::Severity::WARN
end

.loggerObject



36
37
38
# File 'lib/zzsharedlib/amazon.rb', line 36

def self.logger
  @@logger ||= make_logger
end

.make_loggerObject



29
30
31
32
33
34
# File 'lib/zzsharedlib/amazon.rb', line 29

def self.make_logger
  # need to pass in a logdev for this to work...
  logger = Logger.new(STDOUT)
  logger.level = log_level
  logger
end

.secret_keyObject



17
18
19
# File 'lib/zzsharedlib/amazon.rb', line 17

def self.secret_key
  Options.get(:secret_key) || ENV['AWS_SECRET_ACCESS_KEY']
end

Instance Method Details

#describe_tagsObject

does a describe and returns the map, if we already have it and not doing force return what we already have we filter out any terminated instances



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/zzsharedlib/amazon.rb', line 67

def describe_tags
  return @describe_tags if @force_tag == false && !@describe_tags.nil?
  @force_tags = false   # use from cache next time unless somebody resets flag
  # grab it all and filter later
  all_tags = ec2.describe_tags

  # filter out any terminated instances
  instances = ec2.describe_instances
  ignore_instances = Set.new
  instances.each do |instance|
    if instance[:aws_state] != 'running'
      ignore_instances << instance[:aws_instance_id]
    end
  end
  filtered_tags = []
  all_tags.each do |tag|
    resource_id = tag[:resource_id]
    filtered_tags << tag unless ignore_instances.include?(resource_id)
  end

  return @describe_tags = filtered_tags
end

#find_and_sort_named_instances(group = nil, role = nil, ready_only = true) ⇒ Object

find with filters and sort by Name, returns array of maps with

=> inst_id, :Name => “Instance Name”,…


143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/zzsharedlib/amazon.rb', line 143

def find_and_sort_named_instances(group = nil, role = nil, ready_only = true)
  instances = {}
  describe_tags.each do |tag|
    if "instance" == tag[:resource_type]
      resource_id = tag[:resource_id]
      inst = instances[resource_id]
      if inst.nil?
        inst = { :resource_id => resource_id }
        instances[resource_id] = inst
      end
      key = tag[:key].to_sym
      value = tag[:value]
      inst[key] = value
    end
  end

  # ok, we've collected the data now we need to filter it
  filtered_instances = []
  need_describe = []
  instances.each_value do |inst|
    next if inst[:group].nil? ||(group.nil? == false && inst[:group] != group.to_s)
    next if inst[:role].nil? || (role.nil? == false && inst[:role] != role.to_s)
    next if ready_only && inst[:state] != "ready"
    filtered_instances << inst
    need_describe << inst[:resource_id]
  end
  filtered_instances.sort! { |a,b| a[:Name] <=> b[:Name] }

  # last step is to describe the instances we care about to get
  # more info and add that to each instance returned
  az_instances = ec2.describe_instances(need_describe)
  az_hash = {}
  az_instances.each do |instance|
    key = instance[:aws_instance_id]
    az_hash[key] = instance
  end
  # now update the info on filtered instances
  ready_instances = []
  filtered_instances.each do |instance|
    inst_id = instance[:resource_id]
    detail = az_hash[inst_id]
    if !detail.nil?
      instance[:public_hostname] = detail[:dns_name]
      instance[:local_hostname] = detail[:private_dns_name]
      ready_instances << instance
    end
  end
  return ready_instances
end

#find_by_role(group, role) ⇒ Object

finds instances within a group/app by a role



132
133
134
135
136
137
# File 'lib/zzsharedlib/amazon.rb', line 132

def find_by_role(group, role)
  match_role = find_typed_resource("instance", :role, role)
  match_group = find_typed_resource("instance", :group, group)
  # find the ones that match all three
  match = match_role & match_group
end

#find_deploy_group(group_name) ⇒ Object

get the deploy group object from the simple db



48
49
50
51
52
53
54
55
56
57
# File 'lib/zzsharedlib/amazon.rb', line 48

def find_deploy_group(group_name)
  # first see if already exists
  deploy_group = DeployGroupSimpleDB.find_by_zz_object_type_and_group(DeployGroupSimpleDB.object_type, group_name, :auto_load => true)

  if deploy_group.nil? || deploy_group[:group] != group_name
    raise "Deploy group not found.  Make sure you specified the correct deploy group name."
  end

  deploy_group
end

#find_named_instances(group = nil, role = nil, ready_only = true) ⇒ Object

similar to find_and_sort_named_instances but returns a hash with the instance id as the key for each element

=> { :Name => “Instance Name”, :role => role,…}



199
200
201
202
203
204
205
206
207
# File 'lib/zzsharedlib/amazon.rb', line 199

def find_named_instances(group = nil, role = nil, ready_only = true)
  remapped = {}
  instances = find_and_sort_named_instances(group, role)
  instances.each do |instance|
    key = instance[:resource_id].to_sym
    remapped[key] = instance
  end
  return remapped
end

#find_typed_resource(type, key, value) ⇒ Object

find an exact match for a given resource type, key, and value returns a list of the resource_ids that matched



117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/zzsharedlib/amazon.rb', line 117

def find_typed_resource(type, key, value)
  ids = []
  type = type.to_s
  key = key.to_s
  value = value.to_s
  describe_tags.each do |tag|
    if type == tag[:resource_type] && key == tag[:key] && value == tag[:value]
      ids << tag[:resource_id]
    end
  end

  return ids
end

#flat_tags_for_resource(id) ⇒ Object

flatten the key/values into a top level hash assumes all tags are for the same resource id



103
104
105
106
107
108
109
110
111
112
113
# File 'lib/zzsharedlib/amazon.rb', line 103

def flat_tags_for_resource(id)
  tags = tags_for_resource(id)
  flat = {}
  tags.each do |tag|
    key = tag[:key]
    value = tag[:value]
    flat[key.to_sym] = value
  end

  return flat
end

#flush_tagsObject

call this to ensure the tags come from amazon next time



60
61
62
# File 'lib/zzsharedlib/amazon.rb', line 60

def flush_tags
  @force_tags = true
end

#tags_for_resource(id) ⇒ Object

return all the tags that match a given resource id



91
92
93
94
95
96
97
98
99
# File 'lib/zzsharedlib/amazon.rb', line 91

def tags_for_resource(id)
  tags = []
  id = id.to_s
  describe_tags.each do |tag|
    tags << tag if id == tag[:resource_id]
  end

  return tags
end