114 lines
3.3 KiB
Ruby
114 lines
3.3 KiB
Ruby
include Opscode::Aws::Ec2
|
|
|
|
# Support whyrun
|
|
def whyrun_supported?
|
|
true
|
|
end
|
|
|
|
action :associate do
|
|
ip = new_resource.ip || node['aws']['elastic_ip'][new_resource.name]['ip']
|
|
addr = address(ip)
|
|
|
|
if addr.nil?
|
|
raise "Elastic IP #{ip} does not exist"
|
|
elsif addr[:instance_id] == instance_id
|
|
Chef::Log.debug("Elastic IP #{ip} is already attached to the instance")
|
|
else
|
|
converge_by("attach Elastic IP #{ip} to the instance") do
|
|
Chef::Log.info("Attaching Elastic IP #{ip} to the instance")
|
|
attach(ip, new_resource.timeout)
|
|
node.set['aws']['elastic_ip'][new_resource.name]['ip'] = ip
|
|
node.save unless Chef::Config[:solo]
|
|
end
|
|
end
|
|
end
|
|
|
|
action :disassociate do
|
|
ip = new_resource.ip || node['aws']['elastic_ip'][new_resource.name]['ip']
|
|
addr = address(ip)
|
|
|
|
if addr.nil?
|
|
Chef::Log.debug("Elastic IP #{ip} does not exist, so there is nothing to detach")
|
|
elsif addr[:instance_id] != instance_id
|
|
Chef::Log.debug("Elastic IP #{ip} is already detached from the instance")
|
|
else
|
|
converge_by("detach Elastic IP #{ip} from the instance") do
|
|
Chef::Log.info("Detaching Elastic IP #{ip} from the instance")
|
|
detach(ip, new_resource.timeout)
|
|
end
|
|
end
|
|
end
|
|
|
|
action :allocate do
|
|
current_elastic_ip = node['aws']['elastic_ip'][new_resource.name]['ip']
|
|
if current_elastic_ip
|
|
Chef::Log.info("An Elastic IP was already allocated for #{new_resource.name} #{current_elastic_ip} from the instance")
|
|
else
|
|
converge_by("allocate new Elastic IP for #{new_resource.name}") do
|
|
addr = ec2.allocate_address
|
|
Chef::Log.info("Allocated Elastic IP #{addr[:public_ip]} from the instance")
|
|
node.set['aws']['elastic_ip'][new_resource.name]['ip'] = addr[:public_ip]
|
|
node.save unless Chef::Config[:solo]
|
|
end
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def address(ip)
|
|
ec2.describe_addresses.find { |a| a[:public_ip] == ip }
|
|
end
|
|
|
|
def attach(ip, timeout)
|
|
addr = address(ip)
|
|
if addr[:domain] == 'vpc'
|
|
ec2.associate_address(instance_id, {:allocation_id => addr[:allocation_id]})
|
|
else
|
|
ec2.associate_address(instance_id, {:public_ip => addr[:public_ip]})
|
|
end
|
|
|
|
# block until attached
|
|
begin
|
|
Timeout::timeout(timeout) do
|
|
while true
|
|
addr = address(ip)
|
|
if addr.nil?
|
|
raise "Elastic IP has been deleted while waiting for attachment"
|
|
elsif addr[:instance_id] == instance_id
|
|
Chef::Log.debug("Elastic IP is attached to this instance")
|
|
break
|
|
else
|
|
Chef::Log.debug("Elastic IP is currently attached to #{addr[:instance_id]}")
|
|
end
|
|
sleep 3
|
|
end
|
|
end
|
|
rescue Timeout::Error
|
|
raise "Timed out waiting for attachment after #{timeout} seconds"
|
|
end
|
|
end
|
|
|
|
def detach(ip, timeout)
|
|
ec2.disassociate_address({:public_ip => ip})
|
|
|
|
# block until detached
|
|
begin
|
|
Timeout::timeout(timeout) do
|
|
while true
|
|
addr = address(ip)
|
|
if addr.nil?
|
|
Chef::Log.debug("Elastic IP has been deleted while waiting for detachment")
|
|
elsif addr[:instance_id] != instance_id
|
|
Chef::Log.debug("Elastic IP is detached from this instance")
|
|
break
|
|
else
|
|
Chef::Log.debug("Elastic IP is still attached")
|
|
end
|
|
sleep 3
|
|
end
|
|
end
|
|
rescue Timeout::Error
|
|
raise "Timed out waiting for detachment after #{timeout} seconds"
|
|
end
|
|
end
|