diff options
author | Jesse Wolfe <jes5199@gmail.com> | 2010-03-17 12:46:42 -0700 |
---|---|---|
committer | test branch <puppet-dev@googlegroups.com> | 2010-02-17 06:50:53 -0800 |
commit | eda649b6395b38dcb1a5719483222bfbfa60302c (patch) | |
tree | b248bde2ee92194a6cebe917967aedbc399fbcbe /lib/puppet | |
parent | 09b14120fe81a2955a1e4572ec0b8040ef540ade (diff) | |
download | puppet-eda649b6395b38dcb1a5719483222bfbfa60302c.tar.gz puppet-eda649b6395b38dcb1a5719483222bfbfa60302c.tar.xz puppet-eda649b6395b38dcb1a5719483222bfbfa60302c.zip |
Feature #3383 RAL over REST
ralsh --host works now, and is using REST.
A node running puppetd --listen will allow ralsh to find, search, and
modify live resources, via REST.
Signed-off-by: Jesse Wolfe <jes5199@gmail.com>
Diffstat (limited to 'lib/puppet')
-rw-r--r-- | lib/puppet/application/resource.rb | 56 | ||||
-rw-r--r-- | lib/puppet/indirector/resource/ral.rb | 48 | ||||
-rw-r--r-- | lib/puppet/indirector/resource/rest.rb | 5 | ||||
-rw-r--r-- | lib/puppet/indirector/rest.rb | 2 | ||||
-rw-r--r-- | lib/puppet/network/rest_authconfig.rb | 1 | ||||
-rw-r--r-- | lib/puppet/resource.rb | 17 | ||||
-rw-r--r-- | lib/puppet/resource/catalog.rb | 3 | ||||
-rw-r--r-- | lib/puppet/type.rb | 6 | ||||
-rw-r--r-- | lib/puppet/util/settings.rb | 1 |
9 files changed, 93 insertions, 46 deletions
diff --git a/lib/puppet/application/resource.rb b/lib/puppet/application/resource.rb index f914a1b53..0046fc1d8 100644 --- a/lib/puppet/application/resource.rb +++ b/lib/puppet/application/resource.rb @@ -71,52 +71,24 @@ Puppet::Application.new(:resource) do trans.to_manifest } - text = if @host - client = Puppet::Network::Client.resource.new(:Server => @host, :Port => Puppet[:puppetport]) - unless client.read_cert - raise "client.read_cert failed" - end - begin - # They asked for a single resource. - if name - transbucket = [client.describe(type, name)] - else - # Else, list the whole thing out. - transbucket = client.instances(type) - end - rescue Puppet::Network::XMLRPCClientError => exc - raise "client.list(#{type}) failed: #{exc.message}" - end - transbucket.sort { |a,b| a.name <=> b.name }.collect(&format) + if @host + Puppet::Resource.indirection.terminus_class = :rest + port = Puppet[:puppetport] + key = ["https://#{host}:#{port}", "production", "resources", type, name].join('/') else - if name - obj = typeobj.instances.find { |o| o.name == name } || typeobj.new(:name => name, :check => properties) - vals = obj.retrieve - - unless params.empty? - params.each do |param, value| - obj[param] = value - end - catalog = Puppet::Resource::Catalog.new - catalog.add_resource obj - begin - catalog.apply - rescue => detail - if Puppet[:trace] - puts detail.backtrace - end - end + key = [type, name].join('/') + end - end - [format.call(obj.to_trans(true))] + text = if name + if params.empty? + [ Puppet::Resource.find( key ) ] else - typeobj.instances.collect do |obj| - next if ARGV.length > 0 and ! ARGV.include? obj.name - trans = obj.to_trans(true) - format.call(trans) - end + request = Puppet::Indirector::Request.new(:resource, :save, key) # Yuck. + [ Puppet::Resource.new( type, name, params ).save( request ) ] end - end.compact.join("\n") + else + Puppet::Resource.search( key, {} ) + end.map(&format).join("\n") if options[:edit] file = "/tmp/x2puppet-#{Process.pid}.pp" diff --git a/lib/puppet/indirector/resource/ral.rb b/lib/puppet/indirector/resource/ral.rb new file mode 100644 index 000000000..f2c3f847d --- /dev/null +++ b/lib/puppet/indirector/resource/ral.rb @@ -0,0 +1,48 @@ +class Puppet::Resource::Ral < Puppet::Indirector::Code + def find( request ) + # find by name + res = type(request).instances.find { |o| o.name == resource_name(request) } + res ||= type(request).new(:name => resource_name(request), :check => type(request).properties.collect { |s| s.name }) + + return res.to_resource + end + + def search( request ) + conditions = request.options.dup + conditions[:name] = resource_name(request) if resource_name(request) + + type(request).instances.map do |res| + res.to_resource + end.find_all do |res| + conditions.all? {|property, value| res.to_resource[property].to_s == value.to_s} + end.sort do |a,b| + a.title <=> b.title + end + end + + def save( request ) + # In RAL-land, to "save" means to actually try to change machine state + res = request.instance + ral_res = res.to_ral + + catalog = Puppet::Resource::Catalog.new + catalog.add_resource ral_res + catalog.apply + + return ral_res.to_resource + end + + private + + def type_name( request ) + request.key.split('/')[0] + end + + def resource_name( request ) + request.key.split('/')[1] + end + + def type( request ) + Puppet::Type.type(type_name(request)) or raise Puppet::Error "Could not find type #{type}" + end +end diff --git a/lib/puppet/indirector/resource/rest.rb b/lib/puppet/indirector/resource/rest.rb new file mode 100644 index 000000000..7848ae65e --- /dev/null +++ b/lib/puppet/indirector/resource/rest.rb @@ -0,0 +1,5 @@ +require 'puppet/indirector/status' +require 'puppet/indirector/rest' + +class Puppet::Resource::Rest < Puppet::Indirector::REST +end diff --git a/lib/puppet/indirector/rest.rb b/lib/puppet/indirector/rest.rb index a89e98606..4fd385919 100644 --- a/lib/puppet/indirector/rest.rb +++ b/lib/puppet/indirector/rest.rb @@ -67,7 +67,7 @@ class Puppet::Indirector::REST < Puppet::Indirector::Terminus def find(request) return nil unless result = deserialize(network(request).get(indirection2uri(request), headers)) - result.name = request.key + result.name = request.key if result.respond_to?(:name=) result end diff --git a/lib/puppet/network/rest_authconfig.rb b/lib/puppet/network/rest_authconfig.rb index 01ed412cd..7c0ef9cf3 100644 --- a/lib/puppet/network/rest_authconfig.rb +++ b/lib/puppet/network/rest_authconfig.rb @@ -16,6 +16,7 @@ module Puppet { :acl => "/certificate/", :method => :find, :authenticated => false }, { :acl => "/certificate_request", :method => [:find, :save], :authenticated => false }, { :acl => "/status", :method => [:find], :authenticated => true }, + { :acl => "/resource", :method => [:find, :save, :search], :authenticated => true }, ] def self.main diff --git a/lib/puppet/resource.rb b/lib/puppet/resource.rb index e733f3ee0..bdd11fcc5 100644 --- a/lib/puppet/resource.rb +++ b/lib/puppet/resource.rb @@ -1,6 +1,6 @@ require 'puppet' require 'puppet/util/tagging' -require 'puppet/resource/reference' +#require 'puppet/resource/reference' require 'puppet/util/pson' # The simplest resource class. Eventually it will function as the @@ -12,6 +12,10 @@ class Puppet::Resource attr_accessor :file, :line, :catalog, :exported, :virtual attr_writer :type, :title + require 'puppet/indirector' + extend Puppet::Indirector + indirects :resource, :terminus_class => :ral + ATTRIBUTES = [:file, :line, :exported] def self.from_pson(pson) @@ -225,6 +229,17 @@ class Puppet::Resource return result end + def name + # this is potential namespace conflict + # between the notion of an "indirector name" + # and a "resource name" + [ type, title ].join('/') + end + + def to_resource + self + end + private # Produce a canonical method name. diff --git a/lib/puppet/resource/catalog.rb b/lib/puppet/resource/catalog.rb index c5ae8f52d..6e064a9a1 100644 --- a/lib/puppet/resource/catalog.rb +++ b/lib/puppet/resource/catalog.rb @@ -1,3 +1,4 @@ +require 'puppet/resource' require 'puppet/node' require 'puppet/indirector' require 'puppet/simple_graph' @@ -79,7 +80,7 @@ class Puppet::Resource::Catalog < Puppet::SimpleGraph # If the name and title differ, set up an alias - if resource.respond_to?(:name) and resource.respond_to?(:title) and resource.name != resource.title + if resource.respond_to?(:name) and resource.respond_to?(:title) and resource.respond_to?(:isomorphic?) and resource.name != resource.title self.alias(resource, resource.name) if resource.isomorphic? end diff --git a/lib/puppet/type.rb b/lib/puppet/type.rb index 1df84f2df..2fb4abca8 100644 --- a/lib/puppet/type.rb +++ b/lib/puppet/type.rb @@ -2025,6 +2025,12 @@ class Type return trans end + def to_resource + # this 'type instance' versus 'resource' distinction seems artificial + # I'd like to see it collapsed someday ~JW + self.to_trans.to_resource + end + %w{exported virtual}.each do |m| define_method(m+"?") do self.send(m) diff --git a/lib/puppet/util/settings.rb b/lib/puppet/util/settings.rb index 08d42d913..ad1b947b3 100644 --- a/lib/puppet/util/settings.rb +++ b/lib/puppet/util/settings.rb @@ -1,6 +1,5 @@ require 'puppet' require 'sync' -require 'puppet/transportable' require 'getoptlong' require 'puppet/external/event-loop' |