[Pkg-puppet-devel] [facter] 102/180: Revert "Merge pull request #661 from adrienthebo/feature/facter-2/fact-185-structured-ec2-metadata"
Stig Sandbeck Mathisen
ssm at debian.org
Mon Jun 30 15:06:36 UTC 2014
This is an automated email from the git hooks/post-receive script.
ssm pushed a commit to branch master
in repository facter.
commit 75402bee698cc5c8d5049af5ce0e15b928f5021b
Author: Kylo Ginsberg <kylo at puppetlabs.com>
Date: Fri May 23 13:15:27 2014 -0700
Revert "Merge pull request #661 from adrienthebo/feature/facter-2/fact-185-structured-ec2-metadata"
This reverts commit e3da03097164fd973aef79bef507426edb7e5ced, reversing
changes made to 2ce8849b75339f577f08375adabfdbf50d932c71.
---
lib/facter/core/suitable.rb | 6 +-
lib/facter/ec2.rb | 59 ++++----
lib/facter/ec2/rest.rb | 129 ----------------
lib/facter/util/ec2.rb | 5 -
lib/facter/util/values.rb | 29 ----
spec/fixtures/unit/ec2/rest/meta-data/root | 20 ---
spec/unit/core/suitable_spec.rb | 10 --
spec/unit/ec2/rest_spec.rb | 140 ------------------
spec/unit/ec2_spec.rb | 228 +++++++++++++++++++----------
spec/unit/util/ec2_spec.rb | 4 -
spec/unit/util/values_spec.rb | 40 -----
11 files changed, 180 insertions(+), 490 deletions(-)
diff --git a/lib/facter/core/suitable.rb b/lib/facter/core/suitable.rb
index 0262470..1b3c04f 100644
--- a/lib/facter/core/suitable.rb
+++ b/lib/facter/core/suitable.rb
@@ -108,6 +108,10 @@ module Facter::Core::Suitable
#
# @api private
def suitable?
- @confines.all? { |confine| confine.true? }
+ unless defined? @suitable
+ @suitable = ! @confines.detect { |confine| ! confine.true? }
+ end
+
+ return @suitable
end
end
diff --git a/lib/facter/ec2.rb b/lib/facter/ec2.rb
index 2e57592..09e0109 100644
--- a/lib/facter/ec2.rb
+++ b/lib/facter/ec2.rb
@@ -1,44 +1,37 @@
-require 'facter/ec2/rest'
+require 'facter/util/ec2'
+require 'open-uri'
-Facter.define_fact(:ec2_metadata) do
- define_resolution(:rest) do
- confine do
- Facter.value(:virtual).match /^xen/
- end
-
- @querier = Facter::EC2::Metadata.new
- confine do
- @querier.reachable?
- end
-
- setcode do
- @querier.fetch
+def metadata(id = "")
+ open("http://169.254.169.254/2008-02-01/meta-data/#{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.
+ split("\n")
+ symbol = "ec2_#{key.gsub(/\-|\//, '_')}".to_sym
+ Facter.add(symbol) { setcode { value.join(',') } }
+ else
+ metadata(key)
end
end
+rescue => details
+ Facter.warn "Could not retrieve ec2 metadata: #{details.message}"
end
-Facter.define_fact(:ec2_userdata) do
- define_resolution(:rest) do
- confine do
- Facter.value(:virtual).match /^xen/
- end
-
- @querier = Facter::EC2::Userdata.new
- confine do
- @querier.reachable?
- end
-
+def userdata()
+ Facter.add(:ec2_userdata) do
setcode do
- @querier.fetch
+ if userdata = Facter::Util::EC2.userdata
+ userdata.split
+ end
end
end
end
-# The flattened version of the EC2 facts are deprecated and will be removed in
-# a future release of Facter.
-if (ec2_metadata = Facter.value(:ec2_metadata))
- ec2_facts = Facter::Util::Values.flatten_structure("ec2", ec2_metadata)
- ec2_facts.each_pair do |factname, factvalue|
- Facter.add(factname, :value => factvalue)
- end
+if (Facter::Util::EC2.has_euca_mac? || Facter::Util::EC2.has_openstack_mac? ||
+ Facter::Util::EC2.has_ec2_arp?) && Facter::Util::EC2.can_connect?
+ metadata
+ userdata
+else
+ Facter.debug "Not an EC2 host"
end
diff --git a/lib/facter/ec2/rest.rb b/lib/facter/ec2/rest.rb
deleted file mode 100644
index e9c1fca..0000000
--- a/lib/facter/ec2/rest.rb
+++ /dev/null
@@ -1,129 +0,0 @@
-require 'timeout'
-require 'open-uri'
-
-module Facter
- module EC2
- CONNECTION_ERRORS = [
- Errno::EHOSTDOWN,
- Errno::EHOSTUNREACH,
- Errno::ENETUNREACH,
- Errno::ECONNABORTED,
- Errno::ECONNREFUSED,
- Errno::ECONNRESET,
- Errno::ETIMEDOUT,
- ]
-
- class Base
- def reachable?(retry_limit = 3)
- timeout = 0.2
- able_to_connect = false
- attempts = 0
-
- begin
- Timeout.timeout(timeout) do
- open(@baseurl).read
- end
- able_to_connect = true
- rescue OpenURI::HTTPError => e
- if e.message.match /404 Not Found/i
- able_to_connect = false
- else
- retry if attempts < retry_limit
- end
- rescue Timeout::Error
- retry if attempts < retry_limit
- rescue *CONNECTION_ERRORS
- retry if attempts < retry_limit
- ensure
- attempts = attempts + 1
- end
-
- able_to_connect
- end
- end
-
- class Metadata < Base
-
- DEFAULT_URI = "http://169.254.169.254/latest/meta-data/"
-
- def initialize(uri = DEFAULT_URI)
- @baseurl = uri
- end
-
- def fetch(path = '')
- results = {}
-
- keys = fetch_endpoint(path)
- keys.each do |key|
- if key.match(%r[/$])
- # If a metadata key is suffixed with '/' then it's a general metadata
- # resource, so we have to recursively look up all the keys in the given
- # collection.
- name = key[0..-2]
- results[name] = fetch("#{path}#{key}")
- else
- # This is a simple key/value pair, we can just query the given endpoint
- # and store the results.
- ret = fetch_endpoint("#{path}#{key}")
- results[key] = ret.size > 1 ? ret : ret.first
- end
- end
-
- results
- end
-
- # @param path [String] The path relative to the object base url
- #
- # @return [Array, NilClass]
- def fetch_endpoint(path)
- uri = @baseurl + path
- body = open(uri).read
- parse_results(body)
- rescue OpenURI::HTTPError => e
- if e.message.match /404 Not Found/i
- return nil
- else
- Facter.log_exception(e, "Failed to fetch ec2 uri #{uri}: #{e.message}")
- return nil
- end
- rescue *CONNECTION_ERRORS => e
- Facter.log_exception(e, "Failed to fetch ec2 uri #{uri}: #{e.message}")
- return nil
- end
-
- private
-
- def parse_results(body)
- lines = body.split("\n")
- lines.map do |line|
- if (match = line.match(/^(\d+)=.*$/))
- # Metadata arrays are formatted like '<index>=<associated key>/', so
- # we need to extract the index from that output.
- "#{match[1]}/"
- else
- line
- end
- end
- end
- end
-
- class Userdata < Base
- DEFAULT_URI = "http://169.254.169.254/latest/user-data/"
-
- def initialize(uri = DEFAULT_URI)
- @baseurl = uri
- end
-
- def fetch
- open(@baseurl).read
- rescue OpenURI::HTTPError => e
- if e.message.match /404 Not Found/i
- return nil
- else
- Facter.log_exception(e, "Failed to fetch ec2 uri #{uri}: #{e.message}")
- return nil
- end
- end
- end
- end
-end
diff --git a/lib/facter/util/ec2.rb b/lib/facter/util/ec2.rb
index b81c8fe..c6e5dca 100644
--- a/lib/facter/util/ec2.rb
+++ b/lib/facter/util/ec2.rb
@@ -11,7 +11,6 @@ module Facter::Util::EC2
# The +wait_sec+ parameter provides you with an adjustable timeout.
#
def can_connect?(wait_sec=2)
- Facter.warnonce("#{self}.#{__method__} is deprecated; see the Facter::EC2 classes instead")
url = "http://169.254.169.254:80/"
Timeout::timeout(wait_sec) {open(url)}
return true
@@ -24,7 +23,6 @@ module Facter::Util::EC2
# Test if this host has a mac address used by Eucalyptus clouds, which
# normally is +d0:0d+.
def has_euca_mac?
- Facter.warnonce("#{self}.#{__method__} is deprecated; see the Facter::EC2 classes instead")
!!(Facter.value(:macaddress) =~ %r{^[dD]0:0[dD]:})
end
@@ -32,14 +30,12 @@ module Facter::Util::EC2
# normally starts with FA:16:3E (older versions of OpenStack
# may generate mac addresses starting with 02:16:3E)
def has_openstack_mac?
- Facter.warnonce("#{self}.#{__method__} is deprecated; see the Facter::EC2 classes instead")
!!(Facter.value(:macaddress) =~ %r{^(02|[fF][aA]):16:3[eE]})
end
# Test if the host has an arp entry in its cache that matches the EC2 arp,
# which is normally +fe:ff:ff:ff:ff:ff+.
def has_ec2_arp?
- Facter.warnonce("#{self}.#{__method__} is deprecated; see the Facter::EC2 classes instead")
kernel = Facter.value(:kernel)
mac_address_re = case kernel
@@ -77,7 +73,6 @@ module Facter::Util::EC2
#
# @return [String] containing the response body or `nil`
def self.userdata(version="latest")
- Facter.warnonce("#{self}.#{__method__} is deprecated; see the Facter::EC2 classes instead")
uri = "http://169.254.169.254/#{version}/user-data/"
begin
read_uri(uri)
diff --git a/lib/facter/util/values.rb b/lib/facter/util/values.rb
index 1fbb1b6..a7048d5 100644
--- a/lib/facter/util/values.rb
+++ b/lib/facter/util/values.rb
@@ -1,4 +1,3 @@
-
module Facter
module Util
# A util module for facter containing helper methods
@@ -76,34 +75,6 @@ module Facter
value = value.downcase if value.is_a?(String)
value
end
-
- # Flatten the given data structure to something that's suitable to return
- # as flat facts.
- #
- # @param path [String] The fact path to be prefixed to the given value.
- # @param structure [Object] The data structure to flatten. Nested hashes
- # will be recursively flattened, everything else will be returned as-is.
- #
- # @return [Hash] The given data structure prefixed with the given path
- def flatten_structure(path, structure)
- results = {}
-
- if structure.is_a? Hash
- structure.each_pair do |name, value|
- new_path = "#{path}_#{name}".gsub(/\-|\//, '_')
- results.merge! flatten_structure(new_path, value)
- end
- elsif structure.is_a? Array
- structure.each_with_index do |value, index|
- new_path = "#{path}_#{index}"
- results.merge! flatten_structure(new_path, value)
- end
- else
- results[path] = structure
- end
-
- results
- end
end
end
end
diff --git a/spec/fixtures/unit/ec2/rest/meta-data/root b/spec/fixtures/unit/ec2/rest/meta-data/root
deleted file mode 100644
index 9ec3bbe..0000000
--- a/spec/fixtures/unit/ec2/rest/meta-data/root
+++ /dev/null
@@ -1,20 +0,0 @@
-ami-id
-ami-launch-index
-ami-manifest-path
-block-device-mapping/
-hostname
-instance-action
-instance-id
-instance-type
-kernel-id
-local-hostname
-local-ipv4
-mac
-metrics/
-network/
-placement/
-profile
-public-hostname
-public-ipv4
-public-keys/
-reservation-id
diff --git a/spec/unit/core/suitable_spec.rb b/spec/unit/core/suitable_spec.rb
index 8277408..4c0b1fd 100644
--- a/spec/unit/core/suitable_spec.rb
+++ b/spec/unit/core/suitable_spec.rb
@@ -92,15 +92,5 @@ describe Facter::Core::Suitable do
expect(subject).to_not be_suitable
end
-
- it "recalculates suitability on every invocation" do
- subject.confine :kernel => 'Linux'
-
- subject.confines.first.stubs(:true?).returns false
- expect(subject).to_not be_suitable
- subject.confines.first.unstub(:true?)
- subject.confines.first.stubs(:true?).returns true
- expect(subject).to be_suitable
- end
end
end
diff --git a/spec/unit/ec2/rest_spec.rb b/spec/unit/ec2/rest_spec.rb
deleted file mode 100644
index 5c74b49..0000000
--- a/spec/unit/ec2/rest_spec.rb
+++ /dev/null
@@ -1,140 +0,0 @@
-require 'spec_helper'
-require 'facter/ec2/rest'
-
-shared_examples_for "an ec2 rest querier" do
- describe "determining if the uri is reachable" do
- it "retries if the connection times out" do
- subject.stubs(:open).returns(stub(:read => nil))
- Timeout.expects(:timeout).with(0.2).twice.raises(Timeout::Error).returns(true)
- expect(subject).to be_reachable
- end
-
- it "retries if the connection is reset" do
- subject.expects(:open).twice.raises(Errno::ECONNREFUSED).returns(StringIO.new("woo"))
- expect(subject).to be_reachable
- end
-
- it "is false if the given uri returns a 404" do
- subject.expects(:open).with(anything).once.raises(OpenURI::HTTPError.new("404 Not Found", StringIO.new("woo")))
- expect(subject).to_not be_reachable
- end
- end
-
-end
-
-describe Facter::EC2::Metadata do
-
- subject { described_class.new('http://0.0.0.0/latest/meta-data/') }
-
- let(:response) { StringIO.new }
-
- describe "fetching a metadata endpoint" do
- it "splits the body into an array" do
- response.string = my_fixture_read("meta-data/root")
- subject.stubs(:open).with("http://0.0.0.0/latest/meta-data/").returns response
- output = subject.fetch_endpoint('')
-
- expect(output).to eq %w[
- ami-id ami-launch-index ami-manifest-path block-device-mapping/ hostname
- instance-action instance-id instance-type kernel-id local-hostname
- local-ipv4 mac metrics/ network/ placement/ profile public-hostname
- public-ipv4 public-keys/ reservation-id
- ]
- end
-
- it "reformats keys that are array indices" do
- response.string = "0=adrien at grey/"
- subject.stubs(:open).with("http://0.0.0.0/latest/meta-data/public-keys/").returns response
- output = subject.fetch_endpoint("public-keys/")
-
- expect(output).to eq %w[0/]
- end
-
- it "returns nil if the endpoint returns a 404" do
- Facter.expects(:log_exception).never
- subject.stubs(:open).with("http://0.0.0.0/latest/meta-data/public-keys/1/").raises OpenURI::HTTPError.new("404 Not Found", response)
- output = subject.fetch_endpoint('public-keys/1/')
-
- expect(output).to be_nil
- end
-
- it "logs an error if the endpoint raises a non-404 HTTPError" do
- Facter.expects(:log_exception).with(instance_of(OpenURI::HTTPError), anything)
-
- subject.stubs(:open).with("http://0.0.0.0/latest/meta-data/").raises OpenURI::HTTPError.new("418 I'm a Teapot", response)
- output = subject.fetch_endpoint("")
-
- expect(output).to be_nil
- end
-
- it "logs an error if the endpoint raises a connection error" do
- Facter.expects(:log_exception).with(instance_of(Errno::ECONNREFUSED), anything)
-
- subject.stubs(:open).with("http://0.0.0.0/latest/meta-data/").raises Errno::ECONNREFUSED
- output = subject.fetch_endpoint('')
-
- expect(output).to be_nil
- end
- end
-
- describe "recursively fetching the EC2 metadata API" do
- it "queries the given endpoint for metadata keys" do
- subject.expects(:fetch_endpoint).with("").returns([])
- subject.fetch
- end
-
- it "fetches the value for a simple metadata key" do
- subject.expects(:fetch_endpoint).with("").returns(['indexthing'])
- subject.expects(:fetch_endpoint).with("indexthing").returns(['first', 'second'])
-
- output = subject.fetch
- expect(output).to eq({'indexthing' => ['first', 'second']})
- end
-
- it "unwraps metadata values that are in single element arrays" do
- subject.expects(:fetch_endpoint).with("").returns(['ami-id'])
- subject.expects(:fetch_endpoint).with("ami-id").returns(['i-12x'])
-
- output = subject.fetch
- expect(output).to eq({'ami-id' => 'i-12x'})
- end
-
- it "recursively queries an endpoint if the key ends with '/'" do
- subject.expects(:fetch_endpoint).with("").returns(['metrics/'])
- subject.expects(:fetch_endpoint).with("metrics/").returns(['vhostmd'])
- subject.expects(:fetch_endpoint).with("metrics/vhostmd").returns(['woo'])
-
- output = subject.fetch
- expect(output).to eq({'metrics' => {'vhostmd' => 'woo'}})
- end
- end
-
- it_behaves_like "an ec2 rest querier"
-end
-
-describe Facter::EC2::Userdata do
-
- subject { described_class.new('http://0.0.0.0/latest/user-data/') }
-
- let(:response) { StringIO.new }
-
- describe "reaching the userdata" do
- it "queries the userdata URI" do
- subject.expects(:open).with('http://0.0.0.0/latest/user-data/').returns(response)
- subject.fetch
- end
-
- it "returns the result of the query without modification" do
- response.string = "clooouuuuud"
- subject.expects(:open).with('http://0.0.0.0/latest/user-data/').returns(response)
- expect(subject.fetch).to eq "clooouuuuud"
- end
-
- it "is nil if the URI returned a 404" do
- subject.expects(:open).with('http://0.0.0.0/latest/user-data/').once.raises(OpenURI::HTTPError.new("404 Not Found", StringIO.new("woo")))
- expect(subject.fetch).to be_nil
- end
- end
-
- it_behaves_like "an ec2 rest querier"
-end
diff --git a/spec/unit/ec2_spec.rb b/spec/unit/ec2_spec.rb
index bf2aa2f..f26a613 100755
--- a/spec/unit/ec2_spec.rb
+++ b/spec/unit/ec2_spec.rb
@@ -1,117 +1,187 @@
+#! /usr/bin/env ruby
+
require 'spec_helper'
-require 'facter/ec2/rest'
+require 'facter/util/ec2'
+
+describe "ec2 facts" do
+ # This is the standard prefix for making an API call in EC2 (or fake)
+ # environments.
+ let(:api_prefix) { "http://169.254.169.254" }
+
+ describe "when running on ec2" do
+ before :each do
+ # This is an ec2 instance, not a eucalyptus instance
+ Facter::Util::EC2.stubs(:has_euca_mac?).returns(false)
+ Facter::Util::EC2.stubs(:has_openstack_mac?).returns(false)
+ Facter::Util::EC2.stubs(:has_ec2_arp?).returns(true)
+
+ # Assume we can connect
+ Facter::Util::EC2.stubs(:can_connect?).returns(true)
+ end
-describe "ec2_metadata" do
- let(:querier) { stub('EC2 metadata querier') }
+ it "should create flat meta-data facts" do
+ Object.any_instance.expects(:open).
+ with("#{api_prefix}/2008-02-01/meta-data/").
+ at_least_once.returns(StringIO.new("foo"))
- before do
- Facter::EC2::Metadata.stubs(:new).returns querier
- Facter.collection.internal_loader.load(:ec2)
- end
+ Object.any_instance.expects(:open).
+ with("#{api_prefix}/2008-02-01/meta-data/foo").
+ at_least_once.returns(StringIO.new("bar"))
- subject { Facter.fact(:ec2_metadata).resolution(:rest) }
+ Facter.collection.internal_loader.load(:ec2)
- it "is unsuitable if the virtual fact is not xen" do
- Facter.fact(:virtual).stubs(:value).returns "kvm"
- expect(subject).to_not be_suitable
- end
+ Facter.fact(:ec2_foo).value.should == "bar"
+ end
- it "is unsuitable if ec2 endpoint is not reachable" do
- Facter.fact(:virtual).stubs(:value).returns "xen"
- querier.stubs(:reachable?).returns false
- expect(subject).to_not be_suitable
- end
+ it "should create flat meta-data facts with comma seperation" do
+ Object.any_instance.expects(:open).
+ with("#{api_prefix}/2008-02-01/meta-data/").
+ at_least_once.returns(StringIO.new("foo"))
+
+ Object.any_instance.expects(:open).
+ with("#{api_prefix}/2008-02-01/meta-data/foo").
+ at_least_once.returns(StringIO.new("bar\nbaz"))
- describe "when the ec2 endpoint is reachable" do
- before do
- querier.stubs(:reachable?).returns true
+ Facter.collection.internal_loader.load(:ec2)
+
+ Facter.fact(:ec2_foo).value.should == "bar,baz"
end
- it "is suitable if the virtual fact is xen" do
- Facter.fact(:virtual).stubs(:value).returns "xen"
- subject.suitable?
+ it "should create structured meta-data facts" do
+ Object.any_instance.expects(:open).
+ with("#{api_prefix}/2008-02-01/meta-data/").
+ at_least_once.returns(StringIO.new("foo/"))
+
+ Object.any_instance.expects(:open).
+ with("#{api_prefix}/2008-02-01/meta-data/foo/").
+ at_least_once.returns(StringIO.new("bar"))
- expect(subject).to be_suitable
+ Object.any_instance.expects(:open).
+ with("#{api_prefix}/2008-02-01/meta-data/foo/bar").
+ at_least_once.returns(StringIO.new("baz"))
+
+ Facter.collection.internal_loader.load(:ec2)
+
+ Facter.fact(:ec2_foo_bar).value.should == "baz"
end
- it "is suitable if the virtual fact is xenu" do
- Facter.fact(:virtual).stubs(:value).returns "xenu"
- expect(subject).to be_suitable
+ it "should create ec2_user_data fact" do
+ # No meta-data
+ Object.any_instance.expects(:open).
+ with("#{api_prefix}/2008-02-01/meta-data/").
+ at_least_once.returns(StringIO.new(""))
+
+ Facter::Util::EC2.stubs(:read_uri).
+ with("#{api_prefix}/latest/user-data/").
+ returns("test")
+
+ Facter.collection.internal_loader.load(:ec2)
+ Facter.fact(:ec2_userdata).value.should == ["test"]
end
end
- it "resolves the value by recursively querying the rest endpoint" do
- querier.expects(:fetch).returns({"hello" => "world"})
- expect(subject.value).to eq({"hello" => "world"})
- end
-end
+ describe "when running on eucalyptus" do
+ before :each do
+ # Return false for ec2, true for eucalyptus
+ Facter::Util::EC2.stubs(:has_euca_mac?).returns(true)
+ Facter::Util::EC2.stubs(:has_openstack_mac?).returns(false)
+ Facter::Util::EC2.stubs(:has_ec2_arp?).returns(false)
-describe "ec2_userdata" do
- let(:querier) { stub('EC2 metadata querier') }
+ # Assume we can connect
+ Facter::Util::EC2.stubs(:can_connect?).returns(true)
+ end
- before do
- Facter::EC2::Userdata.stubs(:new).returns querier
- Facter.collection.internal_loader.load(:ec2)
- end
+ it "should create ec2_user_data fact" do
+ # No meta-data
+ Object.any_instance.expects(:open).\
+ with("#{api_prefix}/2008-02-01/meta-data/").\
+ at_least_once.returns(StringIO.new(""))
- subject { Facter.fact(:ec2_userdata).resolution(:rest) }
+ Facter::Util::EC2.stubs(:read_uri).
+ with("#{api_prefix}/latest/user-data/").
+ returns("test")
- it "is unsuitable if the virtual fact is not xen" do
- Facter.fact(:virtual).stubs(:value).returns "kvm"
- expect(subject).to_not be_suitable
- end
+ # Force a fact load
+ Facter.collection.internal_loader.load(:ec2)
- it "is unsuitable if ec2 endpoint is not reachable" do
- Facter.fact(:virtual).stubs(:value).returns "xen"
- querier.stubs(:reachable?).returns false
- expect(subject).to_not be_suitable
+ Facter.fact(:ec2_userdata).value.should == ["test"]
+ end
end
- describe "when the ec2 endpoint is reachable" do
- before do
- querier.stubs(:reachable?).returns true
+ describe "when running on openstack" do
+ before :each do
+ # Return false for ec2, true for eucalyptus
+ Facter::Util::EC2.stubs(:has_openstack_mac?).returns(true)
+ Facter::Util::EC2.stubs(:has_euca_mac?).returns(false)
+ Facter::Util::EC2.stubs(:has_ec2_arp?).returns(false)
+
+ # Assume we can connect
+ Facter::Util::EC2.stubs(:can_connect?).returns(true)
end
- it "is suitable if the virtual fact is xen" do
- Facter.fact(:virtual).stubs(:value).returns "xen"
- expect(subject).to be_suitable
+ it "should create ec2_user_data fact" do
+ # No meta-data
+ Object.any_instance.expects(:open).\
+ with("#{api_prefix}/2008-02-01/meta-data/").\
+ at_least_once.returns(StringIO.new(""))
+
+ Facter::Util::EC2.stubs(:read_uri).
+ with("#{api_prefix}/latest/user-data/").
+ returns("test")
+
+ # Force a fact load
+ Facter.collection.internal_loader.load(:ec2)
+
+ Facter.fact(:ec2_userdata).value.should == ["test"]
end
- it "is suitable if the virtual fact is xenu" do
- Facter.fact(:virtual).stubs(:value).returns "xenu"
- expect(subject).to be_suitable
+ it "should return nil if open fails" do
+ Facter.stubs(:warn) # do not pollute test output
+ Facter.expects(:warn).with('Could not retrieve ec2 metadata: host unreachable')
+
+ Object.any_instance.expects(:open).
+ with("#{api_prefix}/2008-02-01/meta-data/").
+ at_least_once.raises(RuntimeError, 'host unreachable')
+
+ Facter::Util::EC2.stubs(:read_uri).
+ with("#{api_prefix}/latest/user-data/").
+ raises(RuntimeError, 'host unreachable')
+
+ # Force a fact load
+ Facter.collection.internal_loader.load(:ec2)
+
+ Facter.fact(:ec2_userdata).value.should be_nil
end
- end
- it "resolves the value by fetching the rest endpoint" do
- querier.expects(:fetch).returns "user data!"
- expect(subject.value).to eq "user data!"
end
-end
-describe "flattened versions of ec2 facts" do
- # These facts are tricky to test because they are dynamic facts, and they are
- # generated from a fact that is defined in the same file. In order to pull
- # this off we need to define the ec2_metadata fact ahead of time so that we
- # can stub the value, and then manually load the correct files.
+ describe "when api connect test fails" do
+ before :each do
+ Facter.stubs(:warnonce)
+ end
- it "unpacks the ec2_metadata fact" do
- Facter.define_fact(:ec2_metadata).stubs(:value).returns({"hello" => "world"})
- Facter.collection.internal_loader.load(:ec2)
+ it "should not populate ec2_userdata" do
+ # Emulate ec2 for now as it matters little to this test
+ Facter::Util::EC2.stubs(:has_euca_mac?).returns(true)
+ Facter::Util::EC2.stubs(:has_ec2_arp?).never
+ Facter::Util::EC2.expects(:can_connect?).at_least_once.returns(false)
- expect(Facter.value("ec2_hello")).to eq "world"
- end
+ # The API should never be called at this point
+ Object.any_instance.expects(:open).
+ with("#{api_prefix}/2008-02-01/meta-data/").never
+ Object.any_instance.expects(:open).
+ with("#{api_prefix}/2008-02-01/user-data/").never
- it "does not set any flat ec2 facts if the ec2_metadata fact is nil" do
- Facter.define_fact(:ec2_metadata).stubs(:value)
- Facter.define_fact(:ec2_userdata).stubs(:value).returns(nil)
+ # Force a fact load
+ Facter.collection.internal_loader.load(:ec2)
- Facter.collection.internal_loader.load(:ec2)
+ Facter.fact(:ec2_userdata).should == nil
+ end
- all_facts = Facter.collection.to_hash
+ it "should rescue the exception" do
+ Facter::Util::EC2.expects(:open).with("#{api_prefix}:80/").raises(Timeout::Error)
- ec2_facts = all_facts.keys.select { |k| k =~ /^ec2_/ }
- expect(ec2_facts).to be_empty
+ Facter::Util::EC2.should_not be_can_connect
+ end
end
-
end
diff --git a/spec/unit/util/ec2_spec.rb b/spec/unit/util/ec2_spec.rb
index 7af59d8..f963db6 100755
--- a/spec/unit/util/ec2_spec.rb
+++ b/spec/unit/util/ec2_spec.rb
@@ -4,10 +4,6 @@ require 'spec_helper'
require 'facter/util/ec2'
describe Facter::Util::EC2 do
- before do
- # Squelch deprecation notices
- Facter.stubs(:warnonce)
- end
# This is the standard prefix for making an API call in EC2 (or fake)
# environments.
let(:api_prefix) { "http://169.254.169.254" }
diff --git a/spec/unit/util/values_spec.rb b/spec/unit/util/values_spec.rb
index bc347c4..557eb19 100644
--- a/spec/unit/util/values_spec.rb
+++ b/spec/unit/util/values_spec.rb
@@ -128,44 +128,4 @@ describe Facter::Util::Values do
end
end
end
-
- describe "flatten_structure" do
- it "converts a string to a hash containing that string" do
- input = "foo"
- output = described_class.flatten_structure("path", input)
- expect(output).to eq({"path" => "foo"})
- end
-
- it "converts an array to a hash with the array elements with indexes" do
- input = ["foo"]
- output = described_class.flatten_structure("path", input)
- expect(output).to eq({"path_0" => "foo"})
- end
-
- it "prefixes a non-nested hash with the given path" do
- input = {"foo" => "bar"}
- output = described_class.flatten_structure("path", input)
- expect(output).to eq({"path_foo" => "bar"})
- end
-
- it "flattens elements till it reaches the first non-flattenable structure" do
- input = {
- "first" => "second",
- "arr" => ["zero", "one"],
- "nested_array" => [
- "hash" => "string",
- ],
- "top" => {"middle" => ['bottom']},
- }
- output = described_class.flatten_structure("path", input)
-
- expect(output).to eq({
- "path_first" => "second",
- "path_arr_0" => "zero",
- "path_arr_1" => "one",
- "path_nested_array_0_hash" => "string",
- "path_top_middle_0" => "bottom"
- })
- end
- end
end
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-puppet/facter.git
More information about the Pkg-puppet-devel
mailing list