summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorJames Turnbull <james@lovedthanlost.net>2011-03-08 21:24:54 +1100
committerJames Turnbull <james@lovedthanlost.net>2011-03-17 07:56:07 +1100
commitd62e079489c07201cb343f2ca109fecd62d6e567 (patch)
tree33f3271f79702d2fb521031a52bee057159b6430 /lib
parent0411d2eacbfad9d07977dea8975b604b7cdd1aa5 (diff)
downloadfacter-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.rb82
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