Project

General

Profile

Download (3.58 KB) Statistics
| Branch: | Tag: | Revision:
module Foreman::Model
class EC2 < ComputeResource
has_one :key_pair, :foreign_key => :compute_resource_id, :dependent => :destroy

delegate :subnets, :to => :client
validates :user, :password, :presence => true

after_create :setup_key_pair
after_destroy :destroy_key_pair

alias_attribute :access_key, :user
alias_attribute :region, :url

def to_label
"#{name} (#{region}-#{provider_friendly_name})"
end

def provided_attributes
super.merge({ :ip => :vm_ip_address })
end

def self.model_name
ComputeResource.model_name
end

def capabilities
[:image]
end

def find_vm_by_uuid uuid
client.servers.get(uuid)
rescue Fog::Compute::AWS::Error
raise(ActiveRecord::RecordNotFound)
end

def create_vm args = { }
args = vm_instance_defaults.merge(args.to_hash.symbolize_keys)
if (name = args[:name])
args.merge!(:tags => {:Name => name})
end
if (image_id = args[:image_id])
image = images.find_by_uuid(image_id)
iam_hash = image.iam_role.present? ? {:iam_instance_profile_name => image.iam_role} : {}
args.merge!(iam_hash)
end
args[:groups].reject!(&:empty?) if args.has_key?(:groups)
args[:security_group_ids].reject!(&:empty?) if args.has_key?(:security_group_ids)
super(args)
end

def security_groups vpc=nil
groups = client.security_groups
groups.reject! { |sg| sg.vpc_id != vpc } if vpc
groups
end

def regions
return [] if user.blank? or password.blank?
@regions ||= client.describe_regions.body["regionInfo"].map { |r| r["regionName"] }
end

def zones
@zones ||= client.describe_availability_zones.body["availabilityZoneInfo"].map { |r| r["zoneName"] if r["regionName"] == region }.compact
end

def flavors
client.flavors
end

def test_connection options = {}
super
errors[:user].empty? and errors[:password].empty? and regions
rescue Fog::Compute::AWS::Error => e
errors[:base] << e.message
end

def console(uuid)
vm = find_vm_by_uuid(uuid)
vm.console_output.body.merge(:type=>'log', :name=>vm.name)
end

def destroy_vm(uuid)
vm = find_vm_by_uuid(uuid)
vm.destroy if vm
true
end

# not supporting update at the moment
def update_required?(old_attrs, new_attrs)
false
end

def associated_host(vm)
Host.authorized(:view_hosts, Host).where(:ip => [vm.public_ip_address, vm.private_ip_address]).first
end

private

def client
@client ||= ::Fog::Compute.new(:provider => "AWS", :aws_access_key_id => user, :aws_secret_access_key => password, :region => region)
end

# this method creates a new key pair for each new ec2 compute resource
# it should create the key and upload it to AWS
def setup_key_pair
key = client.key_pairs.create :name => "foreman-#{id}#{Foreman.uuid}"
KeyPair.create! :name => key.name, :compute_resource_id => self.id, :secret => key.private_key
rescue => e
logger.warn "failed to generate key pair"
destroy_key_pair
raise
end

def destroy_key_pair
return unless key_pair
logger.info "removing AWS key #{key_pair.name}"
key = client.key_pairs.get(key_pair.name)
key.destroy if key
key_pair.destroy
true
rescue => e
logger.warn "failed to delete key pair from AWS, you might need to cleanup manually : #{e}"
end

def vm_instance_defaults
super.merge(
:flavor_id => "m1.small",
:key_pair => key_pair
)
end
end
end
(1-1/7)