This patch adds everything for the upcoming puppet device to parse its configuration file. The file describes every network device managed by this instance of puppet device with the following format:
[device.certname] type cisco url ssh://user:[email protected]:port/?enable=letmein The url of the device is the same as described in the previous interface type device_url parameter. Signed-off-by: Brice Figureau <[email protected]> --- lib/puppet/util/network_device/config.rb | 93 +++++++++++++++++++++++ spec/unit/util/network_device/config_spec.rb | 102 ++++++++++++++++++++++++++ 2 files changed, 195 insertions(+), 0 deletions(-) create mode 100644 lib/puppet/util/network_device/config.rb create mode 100644 spec/unit/util/network_device/config_spec.rb diff --git a/lib/puppet/util/network_device/config.rb b/lib/puppet/util/network_device/config.rb new file mode 100644 index 0000000..17f4e25 --- /dev/null +++ b/lib/puppet/util/network_device/config.rb @@ -0,0 +1,93 @@ +require 'ostruct' +require 'puppet/util/loadedfile' + +class Puppet::Util::NetworkDevice::Config < Puppet::Util::LoadedFile + + def self.main + @main ||= self.new + end + + def self.devices + main.devices || [] + end + + attr_reader :devices + + def exists? + FileTest.exists?(@file) + end + + def initialize() + @file = Puppet[:deviceconfig] + + raise Puppet::DevError, "No device config file defined" unless @file + return unless self.exists? + super(@file) + @devices = {} + + read(true) # force reading at start + end + + # Read the configuration file. + def read(force = false) + return unless FileTest.exists?(@file) + + parse if force or changed? + end + + private + + def parse + begin + devices = {} + device = nil + File.open(@file) { |f| + count = 1 + f.each { |line| + case line + when /^\s*#/ # skip comments + count += 1 + next + when /^\s*$/ # skip blank lines + count += 1 + next + when /^\[([\w.]+)\]\s*$/ # [device.fqdn] + name = $1 + name.chomp! + raise ConfigurationError, "Duplicate device found at line #{count}, already found at #{device.line}" if devices.include?(name) + device = OpenStruct.new + device.name = name + device.line = count + Puppet.debug "found device: #{device.name} at #{device.line}" + devices[name] = device + when /^\s*(type|url)\s+(.+)$/ + parse_directive(device, $1, $2, count) + else + raise ConfigurationError, "Invalid line #{count}: #{line}" + end + count += 1 + } + } + rescue Errno::EACCES => detail + Puppet.err "Configuration error: Cannot read #{@file}; cannot serve" + #raise Puppet::Error, "Cannot read #{@config}" + rescue Errno::ENOENT => detail + Puppet.err "Configuration error: '#{@file}' does not exit; cannot serve" + end + + @devices = devices + end + + def parse_directive(device, var, value, count) + case var + when "type" + device.provider = value + when "url" + device.url = value + else + raise ConfigurationError, + "Invalid argument '#{var}' at line #{count}" + end + end + +end \ No newline at end of file diff --git a/spec/unit/util/network_device/config_spec.rb b/spec/unit/util/network_device/config_spec.rb new file mode 100644 index 0000000..52796f3 --- /dev/null +++ b/spec/unit/util/network_device/config_spec.rb @@ -0,0 +1,102 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../../spec_helper' + +require 'puppet/util/network_device/config' + +describe Puppet::Util::NetworkDevice::Config do + before(:each) do + Puppet[:deviceconfig] = "/dummy" + FileTest.stubs(:exists?).with("/dummy").returns(true) + end + + describe "when initializing" do + before :each do + Puppet::Util::NetworkDevice::Config.any_instance.stubs(:read) + end + + it "should use the deviceconfig setting as pathname" do + Puppet.expects(:[]).with(:deviceconfig).returns("/dummy") + + Puppet::Util::NetworkDevice::Config.new + end + + it "should raise an error if no file is defined finally" do + Puppet.expects(:[]).with(:deviceconfig).returns(nil) + + lambda { Puppet::Util::NetworkDevice::Config.new }.should raise_error(Puppet::DevError) + end + + it "should read and parse the file" do + Puppet::Util::NetworkDevice::Config.any_instance.expects(:read) + + Puppet::Util::NetworkDevice::Config.new + end + end + + describe "when parsing device" do + before :each do + @config = Puppet::Util::NetworkDevice::Config.new + @config.stubs(:changed?).returns(true) + @fd = stub 'fd' + File.stubs(:open).yields(@fd) + end + + it "should skip comments" do + @fd.stubs(:each).yields(' # comment') + + OpenStruct.expects(:new).never + + @config.read + end + + it "should increment line number even on commented lines" do + @fd.stubs(:each).multiple_yields(' # comment','[router.puppetlabs.com]') + + @config.read + @config.devices.should be_include('router.puppetlabs.com') + end + + it "should skip blank lines" do + @fd.stubs(:each).yields(' ') + + @config.read + @config.devices.should be_empty + end + + it "should produce the correct line number" do + @fd.stubs(:each).multiple_yields(' ', '[router.puppetlabs.com]') + + @config.read + @config.devices['router.puppetlabs.com'].line.should == 2 + end + + it "should throw an error if the current device already exists" do + @fd.stubs(:each).multiple_yields('[router.puppetlabs.com]', '[router.puppetlabs.com]') + + lambda { @config.read }.should raise_error + end + + it "should create a new device for each found device line" do + @fd.stubs(:each).multiple_yields('[router.puppetlabs.com]', '[swith.puppetlabs.com]') + + @config.read + @config.devices.size.should == 2 + end + + it "should parse the device type" do + @fd.stubs(:each).multiple_yields('[router.puppetlabs.com]', 'type cisco') + + @config.read + @config.devices['router.puppetlabs.com'].provider.should == 'cisco' + end + + it "should parse the device url" do + @fd.stubs(:each).multiple_yields('[router.puppetlabs.com]', 'type cisco', 'url ssh://test/') + + @config.read + @config.devices['router.puppetlabs.com'].url.should == 'ssh://test/' + end + end + +end \ No newline at end of file -- 1.7.2.1 -- You received this message because you are subscribed to the Google Groups "Puppet Developers" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/puppet-dev?hl=en.
