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