diff options
author | Brice Figureau <brice-puppet@daysofwonder.com> | 2011-01-03 19:45:51 +0100 |
---|---|---|
committer | James Turnbull <james@lovedthanlost.net> | 2011-04-08 18:19:53 +1000 |
commit | 596571fd2b03957e7ed185856ee649c1e610716c (patch) | |
tree | bd483ba28d9380d82d1de8c9cb9e5976e5e0aa4a | |
parent | 6560da52674dfce10a622b633a9ed511f75b0a89 (diff) | |
download | puppet-596571fd2b03957e7ed185856ee649c1e610716c.tar.gz puppet-596571fd2b03957e7ed185856ee649c1e610716c.tar.xz puppet-596571fd2b03957e7ed185856ee649c1e610716c.zip |
Base class for network device based providers
This is the common bits of all future network device providers
that are using prefetching/flushing to limit the number of
calls to the remote network device.
The idea is that we need one transaction to prefetch and one
to flush each instance.
Implementors needs to implement lookup which returns a hash
of the found entity, and flush to update the remote device.
Signed-off-by: Brice Figureau <brice-puppet@daysofwonder.com>
-rw-r--r-- | lib/puppet/provider/network_device.rb | 59 | ||||
-rw-r--r-- | spec/unit/provider/network_device_spec.rb | 148 |
2 files changed, 207 insertions, 0 deletions
diff --git a/lib/puppet/provider/network_device.rb b/lib/puppet/provider/network_device.rb new file mode 100644 index 000000000..58865fddc --- /dev/null +++ b/lib/puppet/provider/network_device.rb @@ -0,0 +1,59 @@ + +# This is the base class of all prefetched network device provider +class Puppet::Provider::NetworkDevice < Puppet::Provider + + def self.lookup(url, name) + raise "This provider doesn't implement the necessary lookup method" + end + + def self.prefetch(resources) + resources.each do |name, resource| + if result = lookup(resource[:device_url], name) + result[:ensure] = :present + resource.provider = new(result) + else + resource.provider = new(:ensure => :absent) + end + end + end + + def exists? + @property_hash[:ensure] != :absent + end + + def initialize(*args) + super + + # Make a duplicate, so that we have a copy for comparison + # at the end. + @properties = @property_hash.dup + end + + def create + @property_hash[:ensure] = :present + self.class.resource_type.validproperties.each do |property| + if val = resource.should(property) + @property_hash[property] = val + end + end + end + + def destroy + @property_hash[:ensure] = :absent + end + + def flush + @property_hash.clear + end + + def self.instances + end + + def former_properties + @properties.dup + end + + def properties + @property_hash.dup + end +end
\ No newline at end of file diff --git a/spec/unit/provider/network_device_spec.rb b/spec/unit/provider/network_device_spec.rb new file mode 100644 index 000000000..3e6d382ee --- /dev/null +++ b/spec/unit/provider/network_device_spec.rb @@ -0,0 +1,148 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../spec_helper' + +require 'puppet/provider/network_device' + +Puppet::Type.type(:vlan).provide :test, :parent => Puppet::Provider::NetworkDevice do + mk_resource_methods + def self.lookup(device_url, name) + end +end + +provider_class = Puppet::Type.type(:vlan).provider(:test) + +describe provider_class do + before do + @resource = stub("resource", :name => "test") + @provider = provider_class.new(@resource) + end + + it "should be able to prefetch instances from the device" do + provider_class.should respond_to(:prefetch) + end + + it "should have an instances method" do + provider_class.should respond_to(:instances) + end + + describe "when prefetching" do + before do + @resource = stub_everything 'resource' + @resources = {"200" => @resource} + provider_class.stubs(:lookup) + end + + it "should lookup an entry for each passed resource" do + provider_class.expects(:lookup).with(nil, "200").returns nil + + provider_class.stubs(:new) + @resource.stubs(:provider=) + provider_class.prefetch(@resources) + end + + describe "resources that do not exist" do + it "should create a provider with :ensure => :absent" do + provider_class.stubs(:lookup).returns(nil) + provider_class.expects(:new).with(:ensure => :absent).returns "myprovider" + @resource.expects(:provider=).with("myprovider") + provider_class.prefetch(@resources) + end + end + + describe "resources that exist" do + it "should create a provider with the results of the find and ensure at present" do + provider_class.stubs(:lookup).returns({ :name => "200", :description => "myvlan"}) + + provider_class.expects(:new).with(:name => "200", :description => "myvlan", :ensure => :present).returns "myprovider" + @resource.expects(:provider=).with("myprovider") + + provider_class.prefetch(@resources) + end + end + end + + describe "when being initialized" do + describe "with a hash" do + before do + @resource_class = mock 'resource_class' + provider_class.stubs(:resource_type).returns @resource_class + + @property_class = stub 'property_class', :array_matching => :all, :superclass => Puppet::Property + @resource_class.stubs(:attrclass).with(:one).returns(@property_class) + @resource_class.stubs(:valid_parameter?).returns true + end + + it "should store a copy of the hash as its vlan_properties" do + instance = provider_class.new(:one => :two) + instance.former_properties.should == {:one => :two} + end + end + end + + describe "when an instance" do + before do + @instance = provider_class.new + + @property_class = stub 'property_class', :array_matching => :all, :superclass => Puppet::Property + @resource_class = stub 'resource_class', :attrclass => @property_class, :valid_parameter? => true, :validproperties => [:description] + provider_class.stubs(:resource_type).returns @resource_class + end + + it "should have a method for creating the instance" do + @instance.should respond_to(:create) + end + + it "should have a method for removing the instance" do + @instance.should respond_to(:destroy) + end + + it "should indicate when the instance already exists" do + @instance = provider_class.new(:ensure => :present) + @instance.exists?.should be_true + end + + it "should indicate when the instance does not exist" do + @instance = provider_class.new(:ensure => :absent) + @instance.exists?.should be_false + end + + describe "is being flushed" do + it "should flush properties" do + @instance = provider_class.new(:ensure => :present, :name => "200", :description => "myvlan") + @instance.flush + @instance.properties.should be_empty + end + end + + describe "is being created" do + before do + @rclass = mock 'resource_class' + @rclass.stubs(:validproperties).returns([:description]) + @resource = stub_everything 'resource' + @resource.stubs(:class).returns @rclass + @resource.stubs(:should).returns nil + @instance.stubs(:resource).returns @resource + end + + it "should set its :ensure value to :present" do + @instance.create + @instance.properties[:ensure].should == :present + end + + it "should set all of the other attributes from the resource" do + @resource.expects(:should).with(:description).returns "myvlan" + + @instance.create + @instance.properties[:description].should == "myvlan" + end + end + + describe "is being destroyed" do + it "should set its :ensure value to :absent" do + @instance.destroy + @instance.properties[:ensure].should == :absent + end + end + end +end |