diff options
author | James Turnbull <james@lovedthanlost.net> | 2011-03-08 21:24:54 +1100 |
---|---|---|
committer | James Turnbull <james@lovedthanlost.net> | 2011-03-17 07:56:07 +1100 |
commit | d62e079489c07201cb343f2ca109fecd62d6e567 (patch) | |
tree | 33f3271f79702d2fb521031a52bee057159b6430 /lib | |
parent | 0411d2eacbfad9d07977dea8975b604b7cdd1aa5 (diff) | |
download | facter-d62e079489c07201cb343f2ca109fecd62d6e567.tar.gz facter-d62e079489c07201cb343f2ca109fecd62d6e567.tar.xz facter-d62e079489c07201cb343f2ca109fecd62d6e567.zip |
Fixed #2346 - A much cleverer EC2 fact
The fact now checks for an EC2 ARP or in the EU Zone for an EC2 MAC
This should mean the fact's return is much more robust
The fact also now supports returning userdata (which is a bit ugly
given Facter returns strings but a good bookmark for refactor in 2.0)
Diffstat (limited to 'lib')
-rw-r--r-- | lib/facter/ec2.rb | 82 |
1 files changed, 64 insertions, 18 deletions
diff --git a/lib/facter/ec2.rb b/lib/facter/ec2.rb index ea29d14..29b2a1c 100644 --- a/lib/facter/ec2.rb +++ b/lib/facter/ec2.rb @@ -1,27 +1,46 @@ -# Changelog: -# Original facts - Tim Dysinger -# Updated and added can_connect? function - KurtBe +# Original fact Tim Dysinger +# Additional work from KurtBe +# Additional work for Paul Nasrat +# Additional work modelled on Ohai EC2 fact require 'open-uri' -require 'timeout' - -def can_connect?(ip,port,wait_sec=2) - url = "http://#{ip}:#{port}/" - Timeout::timeout(wait_sec) {open(url)} - return true -rescue Timeout::Error - return false -rescue - return false -end +require 'socket' + +EC2_ADDR = "169.254.169.254" +EC2_METADATA_URL = "http://#{EC2_ADDR}/2008-02-01/meta-data" +EC2_USERDATA_URL = "http://#{EC2_ADDR}/2008-02-01/user-data" +def can_metadata_connect?(addr, port, timeout=2) + t = Socket.new(Socket::Constants::AF_INET, Socket::Constants::SOCK_STREAM, 0) + saddr = Socket.pack_sockaddr_in(port, addr) + connected = false + + begin + t.connect_nonblock(saddr) + rescue Errno::EINPROGRESS + r,w,e = IO::select(nil,[t],nil,timeout) + if !w.nil? + connected = true + else + begin + t.connect_nonblock(saddr) + rescue Errno::EISCONN + t.close + connected = true + rescue SystemCallError + end + end + rescue SystemCallError + end + connected +end def metadata(id = "") - open("http://169.254.169.254/2008-02-01/meta-data/#{id||=''}").read. + open("#{EC2_METADATA_URL}/#{id||=''}").read. split("\n").each do |o| key = "#{id}#{o.gsub(/\=.*$/, '/')}" if key[-1..-1] != '/' - value = open("http://169.254.169.254/2008-02-01/meta-data/#{key}").read. + value = open("#{EC2_METADATA_URL}/#{key}").read. split("\n") value = value.size>1 ? value : value.first symbol = "ec2_#{key.gsub(/\-|\//, '_')}".to_sym @@ -32,7 +51,34 @@ def metadata(id = "") end end -if can_connect?("169.254.169.254","80") - metadata +def userdata() + # assumes the only expected error is the 404 if there's no user-data + begin + value = OpenURI.open_uri("#{EC2_USERDATA_URL}/").read.split + Facter.add(:ec2_userdata) { setcode { value } } + rescue OpenURI::HTTPError + end end +def has_euca_mac? + if Facter.value(:macaddress) =~ /^[dD]0:0[dD]:/ + return true + else + return false + end +end + +def has_ec2_arp? + if Facter.value(:arp) == 'fe:ff:ff:ff:ff:ff' + return true + else + return false + end +end + +if (has_euca_mac? || has_ec2_arp?) && can_metadata_connect?(EC2_ADDR,80) + metadata + userdata +else + Facter.debug "Not an EC2 host" +end |