[Pkg-puppet-devel] [facter] 43/180: (FACT-185) Update ec2 facts to use new ec2 query classes
Stig Sandbeck Mathisen
ssm at debian.org
Mon Jun 30 15:06:29 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 07f5dfbeee62aaab2c6028c21b5b308b13b3f267
Author: Adrien Thebo <git at somethingsinistral.net>
Date: Wed Apr 2 16:33:10 2014 -0700
(FACT-185) Update ec2 facts to use new ec2 query classes
---
lib/facter/ec2.rb | 59 +++++++------
spec/unit/ec2_spec.rb | 228 +++++++++++++++++---------------------------------
2 files changed, 112 insertions(+), 175 deletions(-)
diff --git a/lib/facter/ec2.rb b/lib/facter/ec2.rb
index 09e0109..2e57592 100644
--- a/lib/facter/ec2.rb
+++ b/lib/facter/ec2.rb
@@ -1,37 +1,44 @@
-require 'facter/util/ec2'
-require 'open-uri'
+require 'facter/ec2/rest'
-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)
+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
end
end
-rescue => details
- Facter.warn "Could not retrieve ec2 metadata: #{details.message}"
end
-def userdata()
- Facter.add(:ec2_userdata) do
+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
+
setcode do
- if userdata = Facter::Util::EC2.userdata
- userdata.split
- end
+ @querier.fetch
end
end
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"
+# 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
end
diff --git a/spec/unit/ec2_spec.rb b/spec/unit/ec2_spec.rb
index f26a613..bf2aa2f 100755
--- a/spec/unit/ec2_spec.rb
+++ b/spec/unit/ec2_spec.rb
@@ -1,187 +1,117 @@
-#! /usr/bin/env ruby
-
require 'spec_helper'
-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
-
- 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"))
+require 'facter/ec2/rest'
- Object.any_instance.expects(:open).
- with("#{api_prefix}/2008-02-01/meta-data/foo").
- at_least_once.returns(StringIO.new("bar"))
+describe "ec2_metadata" do
+ let(:querier) { stub('EC2 metadata querier') }
- Facter.collection.internal_loader.load(:ec2)
-
- Facter.fact(:ec2_foo).value.should == "bar"
- end
+ before do
+ Facter::EC2::Metadata.stubs(:new).returns querier
+ Facter.collection.internal_loader.load(:ec2)
+ 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"))
+ subject { Facter.fact(:ec2_metadata).resolution(:rest) }
- Object.any_instance.expects(:open).
- with("#{api_prefix}/2008-02-01/meta-data/foo").
- at_least_once.returns(StringIO.new("bar\nbaz"))
+ 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.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
+ end
- Facter.fact(:ec2_foo).value.should == "bar,baz"
+ describe "when the ec2 endpoint is reachable" do
+ before do
+ querier.stubs(:reachable?).returns true
end
- 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"))
+ it "is suitable if the virtual fact is xen" do
+ Facter.fact(:virtual).stubs(:value).returns "xen"
+ subject.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"
+ expect(subject).to be_suitable
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(""))
-
- 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"]
+ it "is suitable if the virtual fact is xenu" do
+ Facter.fact(:virtual).stubs(:value).returns "xenu"
+ expect(subject).to be_suitable
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)
-
- # Assume we can connect
- Facter::Util::EC2.stubs(:can_connect?).returns(true)
- 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
- 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(""))
+describe "ec2_userdata" do
+ let(:querier) { stub('EC2 metadata querier') }
- Facter::Util::EC2.stubs(:read_uri).
- with("#{api_prefix}/latest/user-data/").
- returns("test")
+ before do
+ Facter::EC2::Userdata.stubs(:new).returns querier
+ Facter.collection.internal_loader.load(:ec2)
+ end
- # Force a fact load
- Facter.collection.internal_loader.load(:ec2)
+ subject { Facter.fact(:ec2_userdata).resolution(:rest) }
- Facter.fact(:ec2_userdata).value.should == ["test"]
- end
+ 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
- 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)
+ 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
- # Assume we can connect
- Facter::Util::EC2.stubs(:can_connect?).returns(true)
+ describe "when the ec2 endpoint is reachable" do
+ before do
+ querier.stubs(:reachable?).returns true
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(""))
-
- 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"]
+ it "is suitable if the virtual fact is xen" do
+ Facter.fact(:virtual).stubs(:value).returns "xen"
+ expect(subject).to be_suitable
end
- 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
+ it "is suitable if the virtual fact is xenu" do
+ Facter.fact(:virtual).stubs(:value).returns "xenu"
+ expect(subject).to be_suitable
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 "when api connect test fails" do
- before :each do
- Facter.stubs(:warnonce)
- 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.
- 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)
+ it "unpacks the ec2_metadata fact" do
+ Facter.define_fact(:ec2_metadata).stubs(:value).returns({"hello" => "world"})
+ Facter.collection.internal_loader.load(:ec2)
- # 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
+ expect(Facter.value("ec2_hello")).to eq "world"
+ end
- # Force a fact load
- Facter.collection.internal_loader.load(:ec2)
+ 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)
- Facter.fact(:ec2_userdata).should == nil
- end
+ Facter.collection.internal_loader.load(:ec2)
- it "should rescue the exception" do
- Facter::Util::EC2.expects(:open).with("#{api_prefix}:80/").raises(Timeout::Error)
+ all_facts = Facter.collection.to_hash
- Facter::Util::EC2.should_not be_can_connect
- end
+ ec2_facts = all_facts.keys.select { |k| k =~ /^ec2_/ }
+ expect(ec2_facts).to be_empty
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