class Tengine::ResourceEc2::DummyConnection

EC2に実際には接続しないであたかも接続しているかのように見せるためのダミーです。

環境変数EC2_DUMMYがtrueの場合に、RightAws::Ec2の代わりにこのクラスからインスタンスが生成されます。 起動してから環境変数EC2_DUMMY_INTERVALで指定された秒数が経過したインスタンス(のダミー)はちゃんとrunningになるようになっています。

10/08/19 13:06:41

akimatter: モックはtestでしか使えません。

10/08/19 13:08:47

akimatter: developmentでは、RightAws::Ec2のインスタンスの代わりのダミー(一般的にはモックって言うけど、specのモックと区別して敢えてダミーします)を使うようにするべきかも。

10/08/19 13:09:19

akimatter: ただし、developmentでもダミーではなくEC2にちゃんと繋ぎたい場合もあるので、

10/08/19 13:09:41

akimatter: 環境変数か何かの設定でこれらの動作が変わる方が良いかと思います。

Constants

STATIC_ATTRS
UPDATE_INTERVAL

Public Class Methods

instances() click to toggle source

クラス変数で生成しているインスタンスを保持したいところですが、 それだとdevelopmentモードでクラスがロードされる度に保持している内容がクリア されてしまうのでNGでした。 他に影響を与えないように実装する手段が他に思いつかなかったので、グローバル変数を使います。 cattr_accessor :instances @@instances = {}

# File lib/tengine/resource_ec2/dummy_connection.rb, line 20
def self.instances
  $ec2_dummy_instances ||= {}
end
instances=(value) click to toggle source
# File lib/tengine/resource_ec2/dummy_connection.rb, line 23
def self.instances=(value)
  $ec2_dummy_instances = value
end
new(access_key, secret_access_key, options = {}) click to toggle source
# File lib/tengine/resource_ec2/dummy_connection.rb, line 31
def initialize(access_key, secret_access_key, options = {})
  @access_key, @secret_access_key = access_key, secret_access_key
  @options = options || {}
end

Public Instance Methods

describe_availability_zones(*args) click to toggle source
# File lib/tengine/resource_ec2/dummy_connection.rb, line 116
def describe_availability_zones(*args)
  [
    {:region_name=>"us-east-1", :zone_name=>"us-east-1a", :zone_state=>"available"},
    {:region_name=>"us-east-1", :zone_name=>"us-east-1b", :zone_state=>"available"},
    {:region_name=>"us-east-1", :zone_name=>"us-east-1c", :zone_state=>"available"},
    {:region_name=>"us-east-1", :zone_name=>"us-east-1d", :zone_state=>"available"}
  ]
end
describe_images(*args) click to toggle source
# File lib/tengine/resource_ec2/dummy_connection.rb, line 129
def describe_images(*args)
  []
end
describe_images_by_owner(*args) click to toggle source
# File lib/tengine/resource_ec2/dummy_connection.rb, line 125
def describe_images_by_owner(*args)
  []
end
describe_instances(instance_ids = []) click to toggle source
# File lib/tengine/resource_ec2/dummy_connection.rb, line 79
def describe_instances(instance_ids = [])
  update_instances
  if instance_ids.empty?
    instances.values.sort_by{|hash| hash[:aws_instance_id]}
  else
    instance_ids.map{|id| instances[id]}
  end
end
instances() click to toggle source
# File lib/tengine/resource_ec2/dummy_connection.rb, line 27
def instances
  self.class.instances
end
launch_instances(image_id, options) click to toggle source
# File lib/tengine/resource_ec2/dummy_connection.rb, line 49
def launch_instances(image_id, options)
  launch_time = Time.zone.now
  count = options.delete(:min_count) || 1
  options.delete(:max_count) # :max_countは無視
  idx = 0
  result = []
  count.times do
    instance_index = (self.class.last_instance_index += 1)
    instanceid = "i-DMY%05d" % instance_index
    instance_hash = {
      :aws_instance_id => instanceid,
      :aws_image_id => image_id,
      :state_reason_code=>"pending",
      :ssh_key_name => options[:key_name],
      :aws_groups => options[:group_ids],
      :state_reason_message=>"pending",
      :aws_state_code=>0,
      :dns_name=>"",
      :private_dns_name => "",
      :aws_launch_time => launch_time.iso8601,
      :aws_state => "pending",
      :ami_launch_index => idx.to_s,
    }.update(STATIC_ATTRS.dup)
    idx += 1
    result << instance_hash
    instances[instanceid] = instance_hash
  end
  result
end
terminate_instances(instance_ids) click to toggle source
# File lib/tengine/resource_ec2/dummy_connection.rb, line 88
def terminate_instances(instance_ids)
  update_instances
  instance_ids.each do |instance_id|
    update_status_running(instance_id) # 停止する前に一度はrunningにしておく
    hash = instances[instance_id]
    hash.update(
      :state_reason_code=>"Client.UserInitiatedShutdown",
      :state_reason_message=>"Client.UserInitiatedShutdown: User initiated shutdown",
      :aws_state_code=>48,
      :dns_name=>"",
      :private_dns_name=>"",
      :aws_state=>"terminated"
      )
    hash.delete(:ip_address)
    hash.delete(:private_ip_address)
  end
  instance_ids.map do |instance_id|
    {
      :aws_prev_state_name => "running",
      :aws_instance_id => instance_id,
      :aws_current_state_code => 32,
      :aws_current_state_name => "shutting-down",
      :aws_prev_state_code => 16
    }
  end
end

Private Instance Methods

update_instances() click to toggle source
# File lib/tengine/resource_ec2/dummy_connection.rb, line 137
def update_instances
  t = (Time.zone || Time).now
  instances.each do |instanceid, hash|
    next unless hash[:aws_state] == "pending"
    launch_time = Time.zone.parse(hash[:aws_launch_time])
    next if (t - launch_time) < UPDATE_INTERVAL
    update_status_running(instanceid)
  end
end
update_status_running(instance_id) click to toggle source
# File lib/tengine/resource_ec2/dummy_connection.rb, line 147
def update_status_running(instance_id)
  hash = instances[instance_id]
  unless hash
    raise ArgumentError, "No instance found for #{instance_id.inspect}. " << instances.keys.map(&:to_s).join("\n") << " exist."
  end
  instance_index = hash[:aws_instance_id].sub(/^i\-DMY/, '').to_i
  hash.update(
    :aws_state_code=>16,
    :dns_name=>"ec2-184-72-20-#{instance_index}.us-west-1.compute.amazonaws.com",
    :ip_address=>"184.72.20.#{instance_index}",
    :private_dns_name=>"ip-10-162-153-#{instance_index}.us-west-1.compute.internal",
    :private_ip_address=>"10.162.153.#{instance_index}",
    :aws_state=>"running",
    :architecture=>"i386"
    )
  hash.delete(:state_reason_message)
  hash.delete(:state_reason_code)
end