diff --git a/lib/puppet/type/host.rb b/lib/puppet/type/host.rb index 2a04474e8..3e34c0b60 100755 --- a/lib/puppet/type/host.rb +++ b/lib/puppet/type/host.rb @@ -1,103 +1,101 @@ -require 'ipaddr' - module Puppet newtype(:host) do ensurable newproperty(:ip) do desc "The host's IP address, IPv4 or IPv6." validate do |value| unless value =~ /((([0-9a-fA-F]+:){7}[0-9a-fA-F]+)|(([0-9a-fA-F]+:)*[0-9a-fA-F]+)?::(([0-9a-fA-F]+:)*[0-9a-fA-F]+)?)|((25[0-5]|2[0-4][\d]|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})/ raise Puppet::Error, "Invalid IP address" end end end newproperty(:alias) do desc "Any alias the host might have. Multiple values must be specified as an array. Note that this state has the same name as one of the metaparams; using this state to set aliases will make those aliases available in your Puppet scripts and also on disk." def insync?(is) is == @should end def is_to_s(currentvalue = @is) currentvalue = [currentvalue] unless currentvalue.is_a? Array currentvalue.join(" ") end def retrieve is = super case is when String is = is.split(/\s*,\s*/) when Symbol: is = [is] when Array # nothing else raise Puppet::DevError, "Invalid @is type %s" % is.class end return is end # We actually want to return the whole array here, not just the first # value. def should if defined? @should if @should == [:absent] return :absent else return @should end else return nil end end def should_to_s(newvalue = @should) newvalue.join(" ") end validate do |value| if value =~ /\s/ raise Puppet::Error, "Aliases cannot include whitespace" end end end newproperty(:target) do desc "The file in which to store service information. Only used by those providers that write to disk (i.e., not NetInfo)." defaultto { if @resource.class.defaultprovider.ancestors.include?(Puppet::Provider::ParsedFile) @resource.class.defaultprovider.default_target else nil end } end newparam(:name) do desc "The host name." isnamevar validate do |value| - unless value =~ /^([a-z0-9]([-a-z0-9]*[a-z0-9])?\.)+((a[cdefgilmnoqrstuwxz]|aero|arpa)|(b[abdefghijmnorstvwyz]|biz)|(c[acdfghiklmnorsuvxyz]|cat|com|coop)|d[ejkmoz]|(e[ceghrstu]|edu)|f[ijkmor]|(g[abdefghilmnpqrstuwy]|gov)|h[kmnrtu]|(i[delmnoqrst]|info|int)|(j[emop]|jobs)|k[eghimnprwyz]|l[abcikrstuvy]|(m[acdghklmnopqrstuvwxyz]|mil|mobi|museum)|(n[acefgilopruz]|name|net)|(om|org)|(p[aefghklmnrstwy]|pro)|qa|r[eouw]|s[abcdeghijklmnortvyz]|(t[cdfghjklmnoprtvwz]|travel)|u[agkmsyz]|v[aceginu]|w[fs]|y[etu]|z[amw])$/ + unless value =~ /^\w+-?[\w+]?\.?[\w+.{1}]*\w+$/ raise Puppet::Error, "Invalid host name" end end end @doc = "Installs and manages host entries. For most systems, these entries will just be in ``/etc/hosts``, but some systems (notably OS X) will have different solutions." end end diff --git a/test/ral/types/host.rb b/test/ral/types/host.rb index 088f93c1f..16ed20bd4 100755 --- a/test/ral/types/host.rb +++ b/test/ral/types/host.rb @@ -1,165 +1,174 @@ #!/usr/bin/env ruby require File.dirname(__FILE__) + '/../../lib/puppettest' require 'puppettest' require 'test/unit' require 'facter' class TestHost < Test::Unit::TestCase include PuppetTest def setup super @hosttype = Puppet::Type.type(:host) @provider = @hosttype.defaultprovider # Make sure they aren't using something funky like netinfo unless @provider.name == :parsed @hosttype.defaultprovider = @hosttype.provider(:parsed) end cleanup do @hosttype.defaultprovider = nil end if @provider.respond_to?(:default_target=) @default_file = @provider.default_target cleanup do @provider.default_target = @default_file end @target = tempfile() @provider.default_target = @target end end def mkhost if defined? @hcount @hcount += 1 else @hcount = 1 end @catalog ||= mk_catalog host = nil assert_nothing_raised { host = Puppet.type(:host).create( :name => "fakehost%s" % @hcount, :ip => "192.168.27.%s" % @hcount, :alias => "alias%s" % @hcount, :catalog => @catalog ) } return host end def test_list assert_nothing_raised do @hosttype.defaultprovider.prefetch end count = 0 @hosttype.each do |h| count += 1 end assert_equal(0, count, "Found hosts in empty file somehow") end # Darwin will actually write to netinfo here. if Facter.value(:operatingsystem) != "Darwin" or Process.uid == 0 def test_simplehost host = nil # We want to actually use the netinfo provider on darwin if Facter.value(:operatingsystem) == "Darwin" Puppet::Type.type(:host).defaultprovider = nil end assert_nothing_raised { host = Puppet.type(:host).create( :name => "culain", :ip => "192.168.0.3" ) } current_values = nil assert_nothing_raised { current_values = host.retrieve } assert_events([:host_created], host) assert_nothing_raised { current_values = host.retrieve } assert_equal(:present, current_values[host.property(:ensure)]) host[:ensure] = :absent assert_events([:host_removed], host) assert_nothing_raised { current_values = host.retrieve } assert_equal(:absent, current_values[host.property(:ensure)]) end def test_moddinghost # We want to actually use the netinfo provider on darwin if Facter.value(:operatingsystem) == "Darwin" Puppet::Type.type(:host).defaultprovider = nil end host = mkhost() if Facter.value(:operatingsystem) == "Darwin" assert_equal(:netinfo, host[:provider], "Got incorrect provider") end cleanup do host[:ensure] = :absent assert_apply(host) end assert_events([:host_created], host) current_values = nil assert_nothing_raised { current_values = host.retrieve } # This was a hard bug to track down. assert_instance_of(String, current_values[host.property(:ip)]) host[:alias] = %w{madstop kirby yayness} assert_events([:host_changed], host) assert_nothing_raised { current_values = host.retrieve } assert_equal(%w{madstop kirby yayness}, current_values[host.property(:alias)]) host[:ensure] = :absent assert_events([:host_removed], host) end + + def test_invalid_ipaddress + host = mkhost() + + assert_raise(Puppet::Error) { + host[:ip] = "abc.def.ghi.jkl" + } end + end + def test_aliasisproperty assert_equal(:property, @hosttype.attrtype(:alias)) end def test_multivalues host = mkhost assert_raise(Puppet::Error) { host[:alias] = "puppetmasterd yayness" } end def test_puppetalias host = mkhost() assert_nothing_raised { host[:alias] = "testing" } same = host.class["testing"] assert(same, "Could not retrieve by alias") end end