[Pkg-puppet-devel] [SCM] Puppet packaging for Debian branch, experimental, updated. debian/2.6.8-1-844-g7ec39d5
James Turnbull
james at lovedthanlost.net
Tue May 10 08:11:44 UTC 2011
The following commit has been merged in the experimental branch:
commit 28e3db87a105eba5eddbb11167d0a6c33b18f8ce
Author: Brice Figureau <brice-puppet at daysofwonder.com>
Date: Sun Jan 2 19:26:19 2011 +0100
Add management of router/switchs global vlans
This allows to manage the global device list of vlans.
Currently supports only cisco IOS devices.
This is as easy as:
Vlan {
device_url => "ssh://user:pass@switch.domain.com/"
}
vlan {
"200": description => "R&D";
"99": description => "Management";
}
The device_url conforms to the same specs as for the interface
type.
Signed-off-by: Brice Figureau <brice-puppet at daysofwonder.com>
diff --git a/lib/puppet/provider/vlan/cisco.rb b/lib/puppet/provider/vlan/cisco.rb
new file mode 100644
index 0000000..46e172c
--- /dev/null
+++ b/lib/puppet/provider/vlan/cisco.rb
@@ -0,0 +1,34 @@
+require 'puppet/util/network_device/cisco/device'
+require 'puppet/provider/network_device'
+
+Puppet::Type.type(:vlan).provide :cisco, :parent => Puppet::Provider::NetworkDevice do
+
+ desc "Cisco switch/router provider for vlans."
+
+ mk_resource_methods
+
+ def self.lookup(url, id)
+ vlans = {}
+ device = Puppet::Util::NetworkDevice::Cisco::Device.new(url)
+ device.command do |d|
+ vlans = d.parse_vlans || {}
+ end
+ vlans[id]
+ end
+
+ def initialize(*args)
+ super
+ end
+
+ # Clear out the cached values.
+ def flush
+ device.command do |device|
+ device.update_vlan(resource[:name], former_properties, properties)
+ end
+ super
+ end
+
+ def device
+ @device ||= Puppet::Util::NetworkDevice::Cisco::Device.new(resource[:device_url])
+ end
+end
diff --git a/lib/puppet/type/vlan.rb b/lib/puppet/type/vlan.rb
new file mode 100644
index 0000000..6708ea4
--- /dev/null
+++ b/lib/puppet/type/vlan.rb
@@ -0,0 +1,24 @@
+#
+# Manages a Vlan on a given router or switch
+#
+
+Puppet::Type.newtype(:vlan) do
+ @doc = "This represents a router or switch vlan."
+
+ ensurable
+
+ newparam(:name) do
+ desc "Vlan id. It must be a number"
+ isnamevar
+
+ newvalues(/^\d+/)
+ end
+
+ newproperty(:description) do
+ desc "Vlan name"
+ end
+
+ newparam(:device_url) do
+ desc "Url to connect to a router or switch."
+ end
+end
\ No newline at end of file
diff --git a/lib/puppet/util/network_device/cisco/device.rb b/lib/puppet/util/network_device/cisco/device.rb
index 97489bd..1f35099 100644
--- a/lib/puppet/util/network_device/cisco/device.rb
+++ b/lib/puppet/util/network_device/cisco/device.rb
@@ -163,11 +163,11 @@ class Puppet::Util::NetworkDevice::Cisco::Device < Puppet::Util::NetworkDevice::
case l
# vlan name status
when /^(\d+)\s+(\w+)\s+(\w+)\s+([a-zA-Z0-9,\/. ]+)\s*$/
- vlan = { :id => $1, :name => $2, :status => $3, :interfaces => [] }
+ vlan = { :name => $1, :description => $2, :status => $3, :interfaces => [] }
if $4.strip.length > 0
vlan[:interfaces] = $4.strip.split(/\s*,\s*/).map{ |ifn| canonalize_ifname(ifn) }
end
- vlans[vlan[:id]] = vlan
+ vlans[vlan[:name]] = vlan
when /^\s+([a-zA-Z0-9,\/. ]+)\s*$/
raise "invalid sh vlan summary output" unless vlan
if $1.strip.length > 0
@@ -179,6 +179,27 @@ class Puppet::Util::NetworkDevice::Cisco::Device < Puppet::Util::NetworkDevice::
vlans
end
+ def update_vlan(id, is = {}, should = {})
+ if should[:ensure] == :absent
+ Puppet.info "Removing #{id} from device vlan"
+ transport.command("conf t")
+ transport.command("no vlan #{id}")
+ transport.command("exit")
+ return
+ end
+
+ # We're creating or updating an entry
+ transport.command("conf t")
+ transport.command("vlan #{id}")
+ [is.keys, should.keys].flatten.uniq.each do |property|
+ Puppet.debug("trying property: #{property}: #{should[property]}")
+ next if property != :description
+ transport.command("name #{should[property]}")
+ end
+ transport.command("exit")
+ transport.command("exit")
+ end
+
def parse_trunking(interface)
trunking = {}
out = transport.command("sh interface #{interface} switchport")
diff --git a/spec/unit/provider/interface/cisco_spec.rb b/spec/unit/provider/vlan/cisco_spec.rb
similarity index 50%
copy from spec/unit/provider/interface/cisco_spec.rb
copy to spec/unit/provider/vlan/cisco_spec.rb
index 7904711..0951367 100644
--- a/spec/unit/provider/interface/cisco_spec.rb
+++ b/spec/unit/provider/vlan/cisco_spec.rb
@@ -2,13 +2,13 @@
require File.dirname(__FILE__) + '/../../../spec_helper'
-require 'puppet/provider/interface/cisco'
+require 'puppet/provider/vlan/cisco'
-provider_class = Puppet::Type.type(:interface).provider(:cisco)
+provider_class = Puppet::Type.type(:vlan).provider(:cisco)
describe provider_class do
before do
- @resource = stub("resource", :name => "Fa0/1")
+ @resource = stub("resource", :name => "200")
@provider = provider_class.new(@resource)
end
@@ -29,34 +29,32 @@ describe provider_class do
it "should initialize the network device with the given url" do
Puppet::Util::NetworkDevice::Cisco::Device.expects(:new).with(:url).returns(@device)
- provider_class.lookup(:url, "Fa0/1")
+ provider_class.lookup(:url, "200")
end
- it "should delegate to the device interface fetcher" do
- @device.expects(:interface)
- provider_class.lookup("", "Fa0/1")
+ it "should delegate to the device vlans" do
+ @device.expects(:parse_vlans)
+ provider_class.lookup("", "200")
end
- it "should return the given interface data" do
- @device.expects(:interface).returns({ :description => "thisone", :mode => :access})
- provider_class.lookup("", "Fa0").should == {:description => "thisone", :mode => :access }
+ it "should return only the given vlan" do
+ @device.expects(:parse_vlans).returns({"200" => { :description => "thisone" }, "1" => { :description => "nothisone" }})
+ provider_class.lookup("", "200").should == {:description => "thisone" }
end
end
describe "when an instance is being flushed" do
- it "should call the device interface update method with current and past properties" do
- @instance = provider_class.new(:ensure => :present, :name => "Fa0/1", :description => "myinterface")
- @instance.description = "newdesc"
+ it "should call the device update_vlan method with its vlan id, current attributes, and desired attributes" do
+ @instance = provider_class.new(:ensure => :present, :name => "200", :description => "myvlan")
+ @instance.description = "myvlan2"
@instance.resource = @resource
- @resource.stubs(:[]).with(:name).returns("Fa0/1")
+ @resource.stubs(:[]).with(:name).returns("200")
device = stub_everything 'device'
@instance.stubs(:device).returns(device)
device.expects(:command).yields(device)
- interface = stub 'interface'
- device.expects(:new_interface).with("Fa0/1").returns(interface)
- interface.expects(:update).with( {:ensure => :present, :name => "Fa0/1", :description => "myinterface"},
- {:ensure => :present, :name => "Fa0/1", :description => "newdesc"})
+ device.expects(:update_vlan).with(@instance.name, {:ensure => :present, :name => "200", :description => "myvlan"},
+ {:ensure => :present, :name => "200", :description => "myvlan2"})
@instance.flush
end
diff --git a/spec/unit/type/vlan_spec.rb b/spec/unit/type/vlan_spec.rb
new file mode 100644
index 0000000..607d711
--- /dev/null
+++ b/spec/unit/type/vlan_spec.rb
@@ -0,0 +1,40 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+describe Puppet::Type.type(:vlan) do
+ it "should have a 'name' parameter'" do
+ Puppet::Type.type(:vlan).new(:name => "200")[:name].should == "200"
+ end
+
+ it "should have a 'device_url' parameter'" do
+ Puppet::Type.type(:vlan).new(:name => "200", :device_url => :device)[:device_url].should == :device
+ end
+
+ it "should have an ensure property" do
+ Puppet::Type.type(:vlan).attrtype(:ensure).should == :property
+ end
+
+ it "should have a description property" do
+ Puppet::Type.type(:vlan).attrtype(:description).should == :property
+ end
+
+ describe "when validating attribute values" do
+ before do
+ @provider = stub 'provider', :class => Puppet::Type.type(:vlan).defaultprovider, :clear => nil
+ Puppet::Type.type(:vlan).defaultprovider.stubs(:new).returns(@provider)
+ end
+
+ it "should support :present as a value to :ensure" do
+ Puppet::Type.type(:vlan).new(:name => "200", :ensure => :present)
+ end
+
+ it "should support :absent as a value to :ensure" do
+ Puppet::Type.type(:vlan).new(:name => "200", :ensure => :absent)
+ end
+
+ it "should fail if vlan name is not a number" do
+ lambda { Puppet::Type.type(:vlan).new(:name => "notanumber", :ensure => :present) }.should raise_error
+ end
+ end
+end
diff --git a/spec/unit/util/network_device/cisco/device_spec.rb b/spec/unit/util/network_device/cisco/device_spec.rb
index 9021bbd..31aec92 100644
--- a/spec/unit/util/network_device/cisco/device_spec.rb
+++ b/spec/unit/util/network_device/cisco/device_spec.rb
@@ -150,6 +150,26 @@ eos
end
end
+ describe "when updating device vlans" do
+ describe "when removing a vlan" do
+ it "should issue the no vlan command" do
+ @transport.expects(:command).with("no vlan 200")
+ @cisco.update_vlan("200", {:ensure => :present, :name => "200"}, { :ensure=> :absent})
+ end
+ end
+
+ describe "when updating a vlan" do
+ it "should issue the vlan command to enter global vlan modifications" do
+ @transport.expects(:command).with("vlan 200")
+ @cisco.update_vlan("200", {:ensure => :present, :name => "200"}, { :ensure=> :present, :name => "200"})
+ end
+
+ it "should issue the name command to modify the vlan description" do
+ @transport.expects(:command).with("name myvlan")
+ @cisco.update_vlan("200", {:ensure => :present, :name => "200"}, { :ensure=> :present, :name => "200", :description => "myvlan"})
+ end
+ end
+ end
describe "when parsing interface" do
@@ -228,7 +248,7 @@ VLAN Name Status Ports
Switch#
eos
- @cisco.parse_vlans.should == {"100"=>{:status=>"active", :interfaces=>["FastEthernet0/1", "FastEthernet0/2"], :name=>"management", :id=>"100"}, "1"=>{:status=>"active", :interfaces=>["FastEthernet0/3", "FastEthernet0/4", "FastEthernet0/5", "FastEthernet0/6", "FastEthernet0/7", "FastEthernet0/8", "FastEthernet0/9", "FastEthernet0/10", "FastEthernet0/11", "FastEthernet0/12", "FastEthernet0/13", "FastEthernet0/14", "FastEthernet0/15", "FastEthernet0/16", "FastEthernet0/17", "FastEthernet0/18", "FastEthernet0/23", "FastEthernet0/24"], :name=>"default", :id=>"1"}, "10"=>{:status=>"active", :interfaces=>[], :name=>"VLAN0010", :id=>"10"}}
+ @cisco.parse_vlans.should == {"100"=>{:status=>"active", :interfaces=>["FastEthernet0/1", "FastEthernet0/2"], :description=>"management", :name=>"100"}, "1"=>{:status=>"active", :interfaces=>["FastEthernet0/3", "FastEthernet0/4", "FastEthernet0/5", "FastEthernet0/6", "FastEthernet0/7", "FastEthernet0/8", "FastEthernet0/9", "FastEthernet0/10", "FastEthernet0/11", "FastEthernet0/12", "FastEthernet0/13", "FastEthernet0/14", "FastEthernet0/15", "FastEthernet0/16", "FastEthernet0/17", "FastEthernet0/18", "FastEthernet0/23", "FastEthernet0/24"], :description=>"default", :name=>"1"}, "10"=>{:status=>"active", :interfaces=>[], :description=>"VLAN0010", :name=>"10"}}
end
it "should parse trunk switchport information" do
--
Puppet packaging for Debian
More information about the Pkg-puppet-devel
mailing list