From c8f38b7fee12eefb2bed00681b4952ac7ad3f14f Mon Sep 17 00:00:00 2001 From: luke Date: Wed, 31 Jan 2007 19:38:02 +0000 Subject: Renaming "pelement" to "resource". The old name is a holdover from before we had settled on "resource" as a term. git-svn-id: https://reductivelabs.com/svn/puppet/trunk@2137 980ebf18-57e1-0310-9a29-db15c13687c0 --- lib/puppet/client.rb | 2 +- lib/puppet/client/pelement.rb | 65 --------- lib/puppet/client/resource.rb | 65 +++++++++ lib/puppet/server.rb | 2 +- lib/puppet/server/pelement.rb | 191 --------------------------- lib/puppet/server/resource.rb | 191 +++++++++++++++++++++++++++ test/client/pelement.rb | 96 -------------- test/client/resource.rb | 96 ++++++++++++++ test/server/pelement.rb | 297 ------------------------------------------ test/server/resource.rb | 297 ++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 651 insertions(+), 651 deletions(-) delete mode 100644 lib/puppet/client/pelement.rb create mode 100644 lib/puppet/client/resource.rb delete mode 100755 lib/puppet/server/pelement.rb create mode 100755 lib/puppet/server/resource.rb delete mode 100755 test/client/pelement.rb create mode 100755 test/client/resource.rb delete mode 100755 test/server/pelement.rb create mode 100755 test/server/resource.rb diff --git a/lib/puppet/client.rb b/lib/puppet/client.rb index 4f2718b7d..de3b3eaec 100644 --- a/lib/puppet/client.rb +++ b/lib/puppet/client.rb @@ -187,7 +187,7 @@ module Puppet require 'puppet/client/runner' require 'puppet/client/status' require 'puppet/client/reporter' - require 'puppet/client/pelement' + require 'puppet/client/resource' end end diff --git a/lib/puppet/client/pelement.rb b/lib/puppet/client/pelement.rb deleted file mode 100644 index 087b61ee4..000000000 --- a/lib/puppet/client/pelement.rb +++ /dev/null @@ -1,65 +0,0 @@ -class Puppet::Client::PElement < Puppet::Client - @drivername = :PElementServer - - @handler = Puppet::Server::PElement - - def apply(bucket) - - case bucket - when Puppet::TransObject - tmp = Puppet::TransBucket.new - tmp.push bucket - bucket = tmp - bucket.name = Facter["hostname"].value - bucket.type = "pelement" - when Puppet::TransBucket - # nothing - else - raise Puppet::DevError, "You must pass a transportable object, not a %s" % - bucket.class - end - - unless @local - bucket = Base64.encode64(YAML::dump(bucket)) - end - report = @driver.apply(bucket, "yaml") - - return report - end - - def describe(type, name, retrieve = false, ignore = false) - Puppet.info "Describing %s[%s]" % [type.to_s.capitalize, name] - text = @driver.describe(type, name, retrieve, ignore, "yaml") - - object = nil - if @local - object = text - else - object = YAML::load(Base64.decode64(text)) - end - - return object - end - - def initialize(hash = {}) - if hash.include?(:PElementServer) - unless hash[:PElementServer].is_a?(Puppet::Server::PElement) - raise Puppet::DevError, "Must pass an actual PElement server object" - end - end - - super(hash) - end - - def list(type, ignore = false, base = false) - bucket = @driver.list(type, ignore, base, "yaml") - - unless @local - bucket = YAML::load(Base64.decode64(bucket)) - end - - return bucket - end -end - -# $Id$ diff --git a/lib/puppet/client/resource.rb b/lib/puppet/client/resource.rb new file mode 100644 index 000000000..6081b2b66 --- /dev/null +++ b/lib/puppet/client/resource.rb @@ -0,0 +1,65 @@ +class Puppet::Client::Resource < Puppet::Client + @drivername = :ResourceServer + + @handler = Puppet::Server::Resource + + def apply(bucket) + + case bucket + when Puppet::TransObject + tmp = Puppet::TransBucket.new + tmp.push bucket + bucket = tmp + bucket.name = Facter["hostname"].value + bucket.type = "resource" + when Puppet::TransBucket + # nothing + else + raise Puppet::DevError, "You must pass a transportable object, not a %s" % + bucket.class + end + + unless @local + bucket = Base64.encode64(YAML::dump(bucket)) + end + report = @driver.apply(bucket, "yaml") + + return report + end + + def describe(type, name, retrieve = false, ignore = false) + Puppet.info "Describing %s[%s]" % [type.to_s.capitalize, name] + text = @driver.describe(type, name, retrieve, ignore, "yaml") + + object = nil + if @local + object = text + else + object = YAML::load(Base64.decode64(text)) + end + + return object + end + + def initialize(hash = {}) + if hash.include?(:ResourceServer) + unless hash[:ResourceServer].is_a?(Puppet::Server::Resource) + raise Puppet::DevError, "Must pass an actual PElement server object" + end + end + + super(hash) + end + + def list(type, ignore = false, base = false) + bucket = @driver.list(type, ignore, base, "yaml") + + unless @local + bucket = YAML::load(Base64.decode64(bucket)) + end + + return bucket + end +end + +# $Id$ diff --git a/lib/puppet/server.rb b/lib/puppet/server.rb index 3720f25c8..aabc87b50 100644 --- a/lib/puppet/server.rb +++ b/lib/puppet/server.rb @@ -212,7 +212,7 @@ require 'puppet/server/master' require 'puppet/server/ca' require 'puppet/server/fileserver' require 'puppet/server/filebucket' -require 'puppet/server/pelement' +require 'puppet/server/resource' require 'puppet/server/runner' require 'puppet/server/logger' require 'puppet/server/report' diff --git a/lib/puppet/server/pelement.rb b/lib/puppet/server/pelement.rb deleted file mode 100755 index c97a9d4cc..000000000 --- a/lib/puppet/server/pelement.rb +++ /dev/null @@ -1,191 +0,0 @@ -require 'puppet' -require 'puppet/server' - -module Puppet - -# Serve Puppet elements. Useful for querying, copying, and, um, other stuff. -class Server::PElement < Server::Handler - attr_accessor :local - - @interface = XMLRPC::Service::Interface.new("pelementserver") { |iface| - iface.add_method("string apply(string, string)") - iface.add_method("string describe(string, string, array, array)") - iface.add_method("string list(string, array, string)") - } - - # Apply a TransBucket as a transaction. - def apply(bucket, format = "yaml", client = nil, clientip = nil) - unless @local - begin - case format - when "yaml": - bucket = YAML::load(Base64.decode64(bucket)) - else - raise Puppet::Error, "Unsupported format '%s'" % format - end - rescue => detail - raise Puppet::Error, "Could not load YAML TransBucket: %s" % detail - end - end - - component = bucket.to_type - - # Create a client, but specify the remote machine as the server - # because the class requires it, even though it's unused - client = Puppet::Client::MasterClient.new(:Server => client||"localhost") - - # Set the objects - client.objects = component - - # And then apply the configuration. This way we're reusing all - # the code in there. It should probably just be separated out, though. - transaction = client.apply - - # And then clean up - component.remove - - # It'd be nice to return some kind of report, but... at this point - # we have no such facility. - return "success" - end - - # Describe a given object. This returns the 'is' values for every state - # available on the object type. - def describe(type, name, retrieve = nil, ignore = [], format = "yaml", client = nil, clientip = nil) - Puppet.info "Describing %s[%s]" % [type.to_s.capitalize, name] - @local = true unless client - typeklass = nil - unless typeklass = Puppet.type(type) - raise Puppet::Error, "Puppet type %s is unsupported" % type - end - - obj = nil - - retrieve ||= :all - ignore ||= [] - - if obj = typeklass[name] - obj[:check] = retrieve - else - begin - obj = typeklass.create(:name => name, :check => retrieve) - rescue Puppet::Error => detail - raise Puppet::Error, "%s[%s] could not be created: %s" % - [type, name, detail] - end - end - - unless obj - raise XMLRPC::FaultException.new( - 1, "Could not create %s[%s]" % [type, name] - ) - end - - trans = obj.to_trans - - # Now get rid of any attributes they specifically don't want - ignore.each do |st| - if trans.include? st - trans.delete(st) - end - end - - # And get rid of any attributes that are nil - trans.each do |attr, value| - if value.nil? - trans.delete(attr) - end - end - - unless @local - case format - when "yaml": - trans = Base64.encode64(YAML::dump(trans)) - else - raise XMLRPC::FaultException.new( - 1, "Unavailable config format %s" % format - ) - end - end - - return trans - end - - # Create a new fileserving module. - def initialize(hash = {}) - if hash[:Local] - @local = hash[:Local] - else - @local = false - end - end - - # List all of the elements of a given type. - def list(type, ignore = [], base = nil, format = "yaml", client = nil, clientip = nil) - @local = true unless client - typeklass = nil - unless typeklass = Puppet.type(type) - raise Puppet::Error, "Puppet type %s is unsupported" % type - end - - # They can pass in false - ignore ||= [] - ignore = [ignore] unless ignore.is_a? Array - bucket = TransBucket.new - bucket.type = typeklass.name - - typeklass.list.each do |obj| - next if ignore.include? obj.name - - object = TransObject.new(obj.name, typeklass.name) - bucket << object - end - - unless @local - case format - when "yaml": - begin - bucket = Base64.encode64(YAML::dump(bucket)) - rescue => detail - Puppet.err detail - raise XMLRPC::FaultException.new( - 1, detail.to_s - ) - end - else - raise XMLRPC::FaultException.new( - 1, "Unavailable config format %s" % format - ) - end - end - - return bucket - end - - private - - def authcheck(file, mount, client, clientip) - unless mount.allowed?(client, clientip) - mount.warning "%s cannot access %s" % - [client, file] - raise Puppet::Server::AuthorizationError, "Cannot access %s" % mount - end - end - - # Deal with ignore parameters. - def handleignore(children, path, ignore) - ignore.each { |ignore| - Dir.glob(File.join(path,ignore), File::FNM_DOTMATCH) { |match| - children.delete(File.basename(match)) - } - } - return children - end - - def to_s - "pelementserver" - end -end -end - -# $Id$ diff --git a/lib/puppet/server/resource.rb b/lib/puppet/server/resource.rb new file mode 100755 index 000000000..12a188a18 --- /dev/null +++ b/lib/puppet/server/resource.rb @@ -0,0 +1,191 @@ +require 'puppet' +require 'puppet/server' + +module Puppet + +# Serve Puppet elements. Useful for querying, copying, and, um, other stuff. +class Server::Resource < Server::Handler + attr_accessor :local + + @interface = XMLRPC::Service::Interface.new("resource") { |iface| + iface.add_method("string apply(string, string)") + iface.add_method("string describe(string, string, array, array)") + iface.add_method("string list(string, array, string)") + } + + # Apply a TransBucket as a transaction. + def apply(bucket, format = "yaml", client = nil, clientip = nil) + unless @local + begin + case format + when "yaml": + bucket = YAML::load(Base64.decode64(bucket)) + else + raise Puppet::Error, "Unsupported format '%s'" % format + end + rescue => detail + raise Puppet::Error, "Could not load YAML TransBucket: %s" % detail + end + end + + component = bucket.to_type + + # Create a client, but specify the remote machine as the server + # because the class requires it, even though it's unused + client = Puppet::Client::MasterClient.new(:Server => client||"localhost") + + # Set the objects + client.objects = component + + # And then apply the configuration. This way we're reusing all + # the code in there. It should probably just be separated out, though. + transaction = client.apply + + # And then clean up + component.remove + + # It'd be nice to return some kind of report, but... at this point + # we have no such facility. + return "success" + end + + # Describe a given object. This returns the 'is' values for every state + # available on the object type. + def describe(type, name, retrieve = nil, ignore = [], format = "yaml", client = nil, clientip = nil) + Puppet.info "Describing %s[%s]" % [type.to_s.capitalize, name] + @local = true unless client + typeklass = nil + unless typeklass = Puppet.type(type) + raise Puppet::Error, "Puppet type %s is unsupported" % type + end + + obj = nil + + retrieve ||= :all + ignore ||= [] + + if obj = typeklass[name] + obj[:check] = retrieve + else + begin + obj = typeklass.create(:name => name, :check => retrieve) + rescue Puppet::Error => detail + raise Puppet::Error, "%s[%s] could not be created: %s" % + [type, name, detail] + end + end + + unless obj + raise XMLRPC::FaultException.new( + 1, "Could not create %s[%s]" % [type, name] + ) + end + + trans = obj.to_trans + + # Now get rid of any attributes they specifically don't want + ignore.each do |st| + if trans.include? st + trans.delete(st) + end + end + + # And get rid of any attributes that are nil + trans.each do |attr, value| + if value.nil? + trans.delete(attr) + end + end + + unless @local + case format + when "yaml": + trans = Base64.encode64(YAML::dump(trans)) + else + raise XMLRPC::FaultException.new( + 1, "Unavailable config format %s" % format + ) + end + end + + return trans + end + + # Create a new fileserving module. + def initialize(hash = {}) + if hash[:Local] + @local = hash[:Local] + else + @local = false + end + end + + # List all of the elements of a given type. + def list(type, ignore = [], base = nil, format = "yaml", client = nil, clientip = nil) + @local = true unless client + typeklass = nil + unless typeklass = Puppet.type(type) + raise Puppet::Error, "Puppet type %s is unsupported" % type + end + + # They can pass in false + ignore ||= [] + ignore = [ignore] unless ignore.is_a? Array + bucket = TransBucket.new + bucket.type = typeklass.name + + typeklass.list.each do |obj| + next if ignore.include? obj.name + + object = TransObject.new(obj.name, typeklass.name) + bucket << object + end + + unless @local + case format + when "yaml": + begin + bucket = Base64.encode64(YAML::dump(bucket)) + rescue => detail + Puppet.err detail + raise XMLRPC::FaultException.new( + 1, detail.to_s + ) + end + else + raise XMLRPC::FaultException.new( + 1, "Unavailable config format %s" % format + ) + end + end + + return bucket + end + + private + + def authcheck(file, mount, client, clientip) + unless mount.allowed?(client, clientip) + mount.warning "%s cannot access %s" % + [client, file] + raise Puppet::Server::AuthorizationError, "Cannot access %s" % mount + end + end + + # Deal with ignore parameters. + def handleignore(children, path, ignore) + ignore.each { |ignore| + Dir.glob(File.join(path,ignore), File::FNM_DOTMATCH) { |match| + children.delete(File.basename(match)) + } + } + return children + end + + def to_s + "resource" + end +end +end + +# $Id$ diff --git a/test/client/pelement.rb b/test/client/pelement.rb deleted file mode 100755 index 8c8e76963..000000000 --- a/test/client/pelement.rb +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/env ruby - -$:.unshift("../lib").unshift("../../lib") if __FILE__ =~ /\.rb$/ - -require 'puppet' -require 'puppet/client/pelement' -require 'puppet/server' -require 'puppettest' - -# $Id$ - -class TestPElementClient < Test::Unit::TestCase - include PuppetTest::ServerTest - - def mkpelementserver - handlers = { - :CA => {}, # so that certs autogenerate - :PElement => {}, - } - - return mkserver(handlers) - end - - def mkclient - client = nil - assert_nothing_raised { - client = Puppet::Client::PElement.new(:Server => "localhost", - :Port => @@port) - } - - return client - end - - def test_pelements - file = tempfile() - text = "yayness\n" - File.open(file, "w") { |f| f.print text } - - mkpelementserver() - - client = mkclient() - - # Test describing - tobj = nil - assert_nothing_raised { - tobj = client.describe("file", file) - } - - assert(tobj, "Did not get response") - - assert_instance_of(Puppet::TransObject, tobj) - - obj = nil - assert_nothing_raised { - obj = tobj.to_type - } - assert_events([], obj) - File.unlink(file) - assert_events([:file_created], obj) - File.unlink(file) - - # Now test applying - result = nil - assert_nothing_raised { - result = client.apply(tobj) - } - assert(FileTest.exists?(file), "File was not created on apply") - - # Lastly, test "list" - list = nil - assert_nothing_raised { - list = client.list("user") - } - - assert_instance_of(Puppet::TransBucket, list) - - count = 0 - list.each do |tobj| - break if count > 3 - assert_instance_of(Puppet::TransObject, tobj) - - tobj2 = nil - assert_nothing_raised { - tobj2 = client.describe(tobj.type, tobj.name) - } - - obj = nil - assert_nothing_raised { - obj = tobj2.to_type - } - assert_events([], obj) - - count += 1 - end - end -end diff --git a/test/client/resource.rb b/test/client/resource.rb new file mode 100755 index 000000000..51fe7ba7e --- /dev/null +++ b/test/client/resource.rb @@ -0,0 +1,96 @@ +#!/usr/bin/env ruby + +$:.unshift("../lib").unshift("../../lib") if __FILE__ =~ /\.rb$/ + +require 'puppet' +require 'puppet/client/resource' +require 'puppet/server' +require 'puppettest' + +# $Id$ + +class TestResourceClient < Test::Unit::TestCase + include PuppetTest::ServerTest + + def mkresourceserver + handlers = { + :CA => {}, # so that certs autogenerate + :Resource => {}, + } + + return mkserver(handlers) + end + + def mkclient + client = nil + assert_nothing_raised { + client = Puppet::Client::Resource.new(:Server => "localhost", + :Port => @@port) + } + + return client + end + + def test_resources + file = tempfile() + text = "yayness\n" + File.open(file, "w") { |f| f.print text } + + mkresourceserver() + + client = mkclient() + + # Test describing + tobj = nil + assert_nothing_raised { + tobj = client.describe("file", file) + } + + assert(tobj, "Did not get response") + + assert_instance_of(Puppet::TransObject, tobj) + + obj = nil + assert_nothing_raised { + obj = tobj.to_type + } + assert_events([], obj) + File.unlink(file) + assert_events([:file_created], obj) + File.unlink(file) + + # Now test applying + result = nil + assert_nothing_raised { + result = client.apply(tobj) + } + assert(FileTest.exists?(file), "File was not created on apply") + + # Lastly, test "list" + list = nil + assert_nothing_raised { + list = client.list("user") + } + + assert_instance_of(Puppet::TransBucket, list) + + count = 0 + list.each do |tobj| + break if count > 3 + assert_instance_of(Puppet::TransObject, tobj) + + tobj2 = nil + assert_nothing_raised { + tobj2 = client.describe(tobj.type, tobj.name) + } + + obj = nil + assert_nothing_raised { + obj = tobj2.to_type + } + assert_events([], obj) + + count += 1 + end + end +end diff --git a/test/server/pelement.rb b/test/server/pelement.rb deleted file mode 100755 index c86dadc11..000000000 --- a/test/server/pelement.rb +++ /dev/null @@ -1,297 +0,0 @@ -#!/usr/bin/env ruby - -$:.unshift("../lib").unshift("../../lib") if __FILE__ =~ /\.rb$/ - -require 'puppet' -require 'puppet/server/pelement' -require 'puppettest' -require 'base64' -require 'cgi' - -class TestPElementServer < Test::Unit::TestCase - include PuppetTest::ServerTest - - def verify_described(type, described) - described.each do |name, trans| - type.clear - obj = nil - assert_nothing_raised do - obj = trans.to_type - end - - assert(obj, "Could not create object") - assert_nothing_raised do - obj.retrieve - end - - if trans.type == :package - assert_equal(Puppet::Type.type(:package).defaultprovider.name, obj[:provider]) - end - end - type.clear - end - - def test_describe_file - # Make a file to describe - file = tempfile() - str = "yayness\n" - - server = nil - - assert_nothing_raised do - server = Puppet::Server::PElement.new() - end - - # The first run we create the file on the copy, the second run - # the file is already there so the object should be in sync - 2.times do |i| - [ [nil], - [[:content, :mode], []], - [[], [:content]], - [[:content], [:mode]] - ].each do |ary| - retrieve = ary[0] || [] - ignore = ary[1] || [] - - File.open(file, "w") { |f| f.print str } - - result = nil - assert_nothing_raised do - result = server.describe("file", file, *ary) - end - - assert(result, "Could not retrieve file information") - - assert_instance_of(Puppet::TransObject, result) - - # Now we have to clear, so that the server's object gets removed - Puppet::Type.type(:file).clear - - # And remove the file, so we can verify it gets recreated - if i == 0 - File.unlink(file) - end - - object = nil - assert_nothing_raised do - object = result.to_type - end - - assert(object, "Could not create type") - - retrieve.each do |state| - assert(object.should(state), "Did not retrieve %s" % state) - end - - ignore.each do |state| - assert(! object.should(state), "Incorrectly retrieved %s" % state) - end - - if i == 0 - assert_events([:file_created], object) - else - assert_nothing_raised { - object.retrieve - } - assert(object.insync?, "Object was not in sync") - end - - assert(FileTest.exists?(file), "File did not get recreated") - - if i == 0 - if object.should(:content) - assert_equal(str, File.read(file), "File contents are not the same") - else - assert_equal("", File.read(file), "File content was incorrectly made") - end - end - if FileTest.exists? file - File.unlink(file) - end - end - end - end - - def test_describe_directory - # Make a file to describe - file = tempfile() - - server = nil - - assert_nothing_raised do - server = Puppet::Server::PElement.new() - end - - [ [nil], - [[:ensure, :checksum, :mode], []], - [[], [:checksum]], - [[:ensure, :checksum], [:mode]] - ].each do |ary| - retrieve = ary[0] || [] - ignore = ary[1] || [] - - Dir.mkdir(file) - - result = nil - assert_nothing_raised do - result = server.describe("file", file, *ary) - end - - assert(result, "Could not retrieve file information") - - assert_instance_of(Puppet::TransObject, result) - - # Now we have to clear, so that the server's object gets removed - Puppet::Type.type(:file).clear - - # And remove the file, so we can verify it gets recreated - Dir.rmdir(file) - - object = nil - assert_nothing_raised do - object = result.to_type - end - - assert(object, "Could not create type") - - retrieve.each do |state| - assert(object.should(state), "Did not retrieve %s" % state) - end - - ignore.each do |state| - assert(! object.should(state), "Incorrectly retrieved %s" % state) - end - - assert_events([:directory_created], object) - - assert(FileTest.directory?(file), "Directory did not get recreated") - Dir.rmdir(file) - end - end - - def test_describe_alltypes - # Systems get pretty retarded, so I'm going to set the path to some fake - # data for ports - #Puppet::Type::ParsedType::Port.path = File.join(basedir, - # "test/data/types/ports/1") - #Puppet.err Puppet::Type::ParsedType::Port.path - server = nil - assert_nothing_raised do - server = Puppet::Server::PElement.new() - end - - require 'etc' - - # Make the example schedules, for testing - Puppet::Type.type(:schedule).mkdefaultschedules - - Puppet::Type.eachtype do |type| - unless type.respond_to? :list - Puppet.warning "%s does not respond to :list" % type.name - next - end - next unless type.name == :package - Puppet.info "Describing each %s" % type.name - - # First do a listing from the server - bucket = nil - assert_nothing_raised { - bucket = server.list(type.name) - } - - #type.clear - - count = 0 - described = {} - bucket.each do |obj| - assert_instance_of(Puppet::TransObject, obj) - break if count > 5 - described[obj.name] = server.describe(obj.type, obj.name) - count += 1 - end - - verify_described(type, described) - - count = 0 - described = {} - Puppet.info "listing again" - type.list.each do |obj| - assert_instance_of(type, obj) - - break if count > 5 - trans = nil - assert_nothing_raised do - described[obj.name] = server.describe(type.name, obj.name) - end - - count += 1 - end - - if described.empty? - Puppet.notice "Got no example objects for %s" % type.name - end - - # We separate these, in case the list operation creates objects - verify_described(type, described) - end - end - - def test_apply - server = nil - assert_nothing_raised do - server = Puppet::Server::PElement.new() - end - - file = tempfile() - str = "yayness\n" - - File.open(file, "w") { |f| f.print str } - - filetrans = nil - assert_nothing_raised { - filetrans = server.describe("file", file) - } - - Puppet::Type.type(:file).clear - - bucket = Puppet::TransBucket.new - bucket.type = "file" - bucket.push filetrans - - oldbucket = bucket.dup - File.unlink(file) - assert_nothing_raised { - server.apply(bucket) - } - - assert(FileTest.exists?(file), "File did not get recreated") - - # Now try it as a "nonlocal" server - server.local = false - yaml = nil - assert_nothing_raised { - yaml = Base64.encode64(YAML::dump(bucket)) - } - - Puppet::Type.type(:file).clear - File.unlink(file) - - if Base64.decode64(yaml) =~ /(.{20}Loglevel.{20})/ - Puppet.warning "YAML is broken on this machine" - return - end - # puts Base64.decode64(yaml) - objects = nil - assert_nothing_raised("Could not reload yaml") { - YAML::load(Base64.decode64(yaml)) - } - - # The server is supposed to accept yaml and execute it. - assert_nothing_raised { - server.apply(yaml) - } - assert(FileTest.exists?(file), "File did not get recreated from YAML") - end -end - -# $Id$ diff --git a/test/server/resource.rb b/test/server/resource.rb new file mode 100755 index 000000000..218b65f74 --- /dev/null +++ b/test/server/resource.rb @@ -0,0 +1,297 @@ +#!/usr/bin/env ruby + +$:.unshift("../lib").unshift("../../lib") if __FILE__ =~ /\.rb$/ + +require 'puppet' +require 'puppet/server/resource' +require 'puppettest' +require 'base64' +require 'cgi' + +class TestResourceServer < Test::Unit::TestCase + include PuppetTest::ServerTest + + def verify_described(type, described) + described.each do |name, trans| + type.clear + obj = nil + assert_nothing_raised do + obj = trans.to_type + end + + assert(obj, "Could not create object") + assert_nothing_raised do + obj.retrieve + end + + if trans.type == :package + assert_equal(Puppet::Type.type(:package).defaultprovider.name, obj[:provider]) + end + end + type.clear + end + + def test_describe_file + # Make a file to describe + file = tempfile() + str = "yayness\n" + + server = nil + + assert_nothing_raised do + server = Puppet::Server::Resource.new() + end + + # The first run we create the file on the copy, the second run + # the file is already there so the object should be in sync + 2.times do |i| + [ [nil], + [[:content, :mode], []], + [[], [:content]], + [[:content], [:mode]] + ].each do |ary| + retrieve = ary[0] || [] + ignore = ary[1] || [] + + File.open(file, "w") { |f| f.print str } + + result = nil + assert_nothing_raised do + result = server.describe("file", file, *ary) + end + + assert(result, "Could not retrieve file information") + + assert_instance_of(Puppet::TransObject, result) + + # Now we have to clear, so that the server's object gets removed + Puppet::Type.type(:file).clear + + # And remove the file, so we can verify it gets recreated + if i == 0 + File.unlink(file) + end + + object = nil + assert_nothing_raised do + object = result.to_type + end + + assert(object, "Could not create type") + + retrieve.each do |state| + assert(object.should(state), "Did not retrieve %s" % state) + end + + ignore.each do |state| + assert(! object.should(state), "Incorrectly retrieved %s" % state) + end + + if i == 0 + assert_events([:file_created], object) + else + assert_nothing_raised { + object.retrieve + } + assert(object.insync?, "Object was not in sync") + end + + assert(FileTest.exists?(file), "File did not get recreated") + + if i == 0 + if object.should(:content) + assert_equal(str, File.read(file), "File contents are not the same") + else + assert_equal("", File.read(file), "File content was incorrectly made") + end + end + if FileTest.exists? file + File.unlink(file) + end + end + end + end + + def test_describe_directory + # Make a file to describe + file = tempfile() + + server = nil + + assert_nothing_raised do + server = Puppet::Server::Resource.new() + end + + [ [nil], + [[:ensure, :checksum, :mode], []], + [[], [:checksum]], + [[:ensure, :checksum], [:mode]] + ].each do |ary| + retrieve = ary[0] || [] + ignore = ary[1] || [] + + Dir.mkdir(file) + + result = nil + assert_nothing_raised do + result = server.describe("file", file, *ary) + end + + assert(result, "Could not retrieve file information") + + assert_instance_of(Puppet::TransObject, result) + + # Now we have to clear, so that the server's object gets removed + Puppet::Type.type(:file).clear + + # And remove the file, so we can verify it gets recreated + Dir.rmdir(file) + + object = nil + assert_nothing_raised do + object = result.to_type + end + + assert(object, "Could not create type") + + retrieve.each do |state| + assert(object.should(state), "Did not retrieve %s" % state) + end + + ignore.each do |state| + assert(! object.should(state), "Incorrectly retrieved %s" % state) + end + + assert_events([:directory_created], object) + + assert(FileTest.directory?(file), "Directory did not get recreated") + Dir.rmdir(file) + end + end + + def test_describe_alltypes + # Systems get pretty retarded, so I'm going to set the path to some fake + # data for ports + #Puppet::Type::ParsedType::Port.path = File.join(basedir, + # "test/data/types/ports/1") + #Puppet.err Puppet::Type::ParsedType::Port.path + server = nil + assert_nothing_raised do + server = Puppet::Server::Resource.new() + end + + require 'etc' + + # Make the example schedules, for testing + Puppet::Type.type(:schedule).mkdefaultschedules + + Puppet::Type.eachtype do |type| + unless type.respond_to? :list + Puppet.warning "%s does not respond to :list" % type.name + next + end + next unless type.name == :package + Puppet.info "Describing each %s" % type.name + + # First do a listing from the server + bucket = nil + assert_nothing_raised { + bucket = server.list(type.name) + } + + #type.clear + + count = 0 + described = {} + bucket.each do |obj| + assert_instance_of(Puppet::TransObject, obj) + break if count > 5 + described[obj.name] = server.describe(obj.type, obj.name) + count += 1 + end + + verify_described(type, described) + + count = 0 + described = {} + Puppet.info "listing again" + type.list.each do |obj| + assert_instance_of(type, obj) + + break if count > 5 + trans = nil + assert_nothing_raised do + described[obj.name] = server.describe(type.name, obj.name) + end + + count += 1 + end + + if described.empty? + Puppet.notice "Got no example objects for %s" % type.name + end + + # We separate these, in case the list operation creates objects + verify_described(type, described) + end + end + + def test_apply + server = nil + assert_nothing_raised do + server = Puppet::Server::Resource.new() + end + + file = tempfile() + str = "yayness\n" + + File.open(file, "w") { |f| f.print str } + + filetrans = nil + assert_nothing_raised { + filetrans = server.describe("file", file) + } + + Puppet::Type.type(:file).clear + + bucket = Puppet::TransBucket.new + bucket.type = "file" + bucket.push filetrans + + oldbucket = bucket.dup + File.unlink(file) + assert_nothing_raised { + server.apply(bucket) + } + + assert(FileTest.exists?(file), "File did not get recreated") + + # Now try it as a "nonlocal" server + server.local = false + yaml = nil + assert_nothing_raised { + yaml = Base64.encode64(YAML::dump(bucket)) + } + + Puppet::Type.type(:file).clear + File.unlink(file) + + if Base64.decode64(yaml) =~ /(.{20}Loglevel.{20})/ + Puppet.warning "YAML is broken on this machine" + return + end + # puts Base64.decode64(yaml) + objects = nil + assert_nothing_raised("Could not reload yaml") { + YAML::load(Base64.decode64(yaml)) + } + + # The server is supposed to accept yaml and execute it. + assert_nothing_raised { + server.apply(yaml) + } + assert(FileTest.exists?(file), "File did not get recreated from YAML") + end +end + +# $Id$ -- cgit