summaryrefslogtreecommitdiffstats
path: root/lib/puppet/face
diff options
context:
space:
mode:
authorDaniel Pittman <daniel@puppetlabs.com>2011-04-13 00:17:57 -0700
committerDaniel Pittman <daniel@puppetlabs.com>2011-04-13 00:17:57 -0700
commit4dd6a77481400b7eeac3377267d092d4c6d22da3 (patch)
treef95d292596144832805a9b57a55bc440f7cfaa43 /lib/puppet/face
parent941c56a283265cdf5a951ecaae63580b60486c52 (diff)
downloadpuppet-4dd6a77481400b7eeac3377267d092d4c6d22da3.tar.gz
puppet-4dd6a77481400b7eeac3377267d092d4c6d22da3.tar.xz
puppet-4dd6a77481400b7eeac3377267d092d4c6d22da3.zip
(#7056) Use 'face' rather than 'faces' in the production code.
After some discussion we decided that most uses of the Puppet Face infrastructure were about single faces on their own, not about the collection, and so we were better referring to Puppet::Face[...] in code. This implements that by translating names and references in the Ruby code to the new, s-less, name.
Diffstat (limited to 'lib/puppet/face')
-rw-r--r--lib/puppet/face/catalog.rb40
-rw-r--r--lib/puppet/face/catalog/select.rb10
-rw-r--r--lib/puppet/face/certificate.rb46
-rw-r--r--lib/puppet/face/certificate_request.rb4
-rw-r--r--lib/puppet/face/certificate_revocation_list.rb4
-rw-r--r--lib/puppet/face/config.rb12
-rw-r--r--lib/puppet/face/configurer.rb12
-rw-r--r--lib/puppet/face/facts.rb18
-rw-r--r--lib/puppet/face/file.rb5
-rw-r--r--lib/puppet/face/help.rb104
-rw-r--r--lib/puppet/face/help/action.erb3
-rw-r--r--lib/puppet/face/help/face.erb7
-rw-r--r--lib/puppet/face/help/global.erb20
-rw-r--r--lib/puppet/face/indirector.rb94
-rw-r--r--lib/puppet/face/key.rb4
-rw-r--r--lib/puppet/face/node.rb5
-rw-r--r--lib/puppet/face/report.rb15
-rw-r--r--lib/puppet/face/resource.rb4
-rw-r--r--lib/puppet/face/resource_type.rb4
-rw-r--r--lib/puppet/face/status.rb4
20 files changed, 415 insertions, 0 deletions
diff --git a/lib/puppet/face/catalog.rb b/lib/puppet/face/catalog.rb
new file mode 100644
index 000000000..0dcde3591
--- /dev/null
+++ b/lib/puppet/face/catalog.rb
@@ -0,0 +1,40 @@
+require 'puppet/face/indirector'
+
+Puppet::Face::Indirector.define(:catalog, '0.0.1') do
+ action(:apply) do
+ when_invoked do |catalog, options|
+ report = Puppet::Transaction::Report.new("apply")
+ report.configuration_version = catalog.version
+
+ Puppet::Util::Log.newdestination(report)
+
+ begin
+ benchmark(:notice, "Finished catalog run") do
+ catalog.apply(:report => report)
+ end
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Failed to apply catalog: #{detail}"
+ end
+
+ report.finalize_report
+ report
+ end
+ end
+
+ action(:download) do
+ when_invoked do |certname, facts, options|
+ Puppet::Resource::Catalog.indirection.terminus_class = :rest
+ facts_to_upload = {:facts_format => :b64_zlib_yaml, :facts => CGI.escape(facts.render(:b64_zlib_yaml))}
+ catalog = nil
+ retrieval_duration = thinmark do
+ catalog = Puppet::Face[:catalog, '0.0.1'].find(certname, facts_to_upload)
+ end
+ catalog = catalog.to_ral
+ catalog.finalize
+ catalog.retrieval_duration = retrieval_duration
+ catalog.write_class_file
+ catalog
+ end
+ end
+end
diff --git a/lib/puppet/face/catalog/select.rb b/lib/puppet/face/catalog/select.rb
new file mode 100644
index 000000000..ba27117bc
--- /dev/null
+++ b/lib/puppet/face/catalog/select.rb
@@ -0,0 +1,10 @@
+# Select and show a list of resources of a given type.
+Puppet::Face.define(:catalog, '0.0.1') do
+ action :select do
+ when_invoked do |host, type, options|
+ catalog = Puppet::Resource::Catalog.indirection.find(host)
+
+ catalog.resources.reject { |res| res.type != type }.each { |res| puts res }
+ end
+ end
+end
diff --git a/lib/puppet/face/certificate.rb b/lib/puppet/face/certificate.rb
new file mode 100644
index 000000000..77e80f099
--- /dev/null
+++ b/lib/puppet/face/certificate.rb
@@ -0,0 +1,46 @@
+require 'puppet/face/indirector'
+require 'puppet/ssl/host'
+
+Puppet::Face::Indirector.define(:certificate, '0.0.1') do
+ # REVISIT: This should use a pre-invoke hook to run the common code that
+ # needs to happen before we invoke any action; that would be much nicer than
+ # the "please repeat yourself" stuff found in here right now.
+ #
+ # option "--ca-location LOCATION" do
+ # type [:whatever, :location, :symbols]
+ # hook :before do |value|
+ # Puppet::SSL::Host.ca_location = value
+ # end
+ # end
+ #
+ # ...but should I pass the arguments as well?
+ # --daniel 2011-04-05
+ option "--ca-location LOCATION"
+
+ action :generate do
+ when_invoked do |name, options|
+ Puppet::SSL::Host.ca_location = options[:ca_location].to_sym
+ host = Puppet::SSL::Host.new(name)
+ host.generate_certificate_request
+ host.certificate_request.class.indirection.save(host.certificate_request)
+ end
+ end
+
+ action :list do
+ when_invoked do |options|
+ Puppet::SSL::Host.ca_location = options[:ca_location].to_sym
+ Puppet::SSL::Host.indirection.search("*", {
+ :for => :certificate_request,
+ }).map { |h| h.inspect }
+ end
+ end
+
+ action :sign do
+ when_invoked do |name, options|
+ Puppet::SSL::Host.ca_location = options[:ca_location].to_sym
+ host = Puppet::SSL::Host.new(name)
+ host.desired_state = 'signed'
+ Puppet::SSL::Host.indirection.save(host)
+ end
+ end
+end
diff --git a/lib/puppet/face/certificate_request.rb b/lib/puppet/face/certificate_request.rb
new file mode 100644
index 000000000..1feba25ab
--- /dev/null
+++ b/lib/puppet/face/certificate_request.rb
@@ -0,0 +1,4 @@
+require 'puppet/face/indirector'
+
+Puppet::Face::Indirector.define(:certificate_request, '0.0.1') do
+end
diff --git a/lib/puppet/face/certificate_revocation_list.rb b/lib/puppet/face/certificate_revocation_list.rb
new file mode 100644
index 000000000..6a75aa578
--- /dev/null
+++ b/lib/puppet/face/certificate_revocation_list.rb
@@ -0,0 +1,4 @@
+require 'puppet/face/indirector'
+
+Puppet::Face::Indirector.define(:certificate_revocation_list, '0.0.1') do
+end
diff --git a/lib/puppet/face/config.rb b/lib/puppet/face/config.rb
new file mode 100644
index 000000000..45cb6b156
--- /dev/null
+++ b/lib/puppet/face/config.rb
@@ -0,0 +1,12 @@
+require 'puppet/face'
+
+Puppet::Face.define(:config, '0.0.1') do
+ action(:print) do
+ when_invoked do |*args|
+ options = args.pop
+ Puppet.settings[:configprint] = args.join(",")
+ Puppet.settings.print_config_options
+ nil
+ end
+ end
+end
diff --git a/lib/puppet/face/configurer.rb b/lib/puppet/face/configurer.rb
new file mode 100644
index 000000000..74dfb854e
--- /dev/null
+++ b/lib/puppet/face/configurer.rb
@@ -0,0 +1,12 @@
+require 'puppet/face'
+
+Puppet::Face.define(:configurer, '0.0.1') do
+ action(:synchronize) do
+ when_invoked do |certname, options|
+ facts = Puppet::Face[:facts, '0.0.1'].find(certname)
+ catalog = Puppet::Face[:catalog, '0.0.1'].download(certname, facts)
+ report = Puppet::Face[:catalog, '0.0.1'].apply(catalog)
+ report
+ end
+ end
+end
diff --git a/lib/puppet/face/facts.rb b/lib/puppet/face/facts.rb
new file mode 100644
index 000000000..8668b2531
--- /dev/null
+++ b/lib/puppet/face/facts.rb
@@ -0,0 +1,18 @@
+require 'puppet/face/indirector'
+require 'puppet/node/facts'
+
+Puppet::Face::Indirector.define(:facts, '0.0.1') do
+ set_default_format :yaml
+
+ # Upload our facts to the server
+ action(:upload) do
+ when_invoked do |options|
+ Puppet::Node::Facts.indirection.terminus_class = :facter
+ facts = Puppet::Node::Facts.indirection.find(Puppet[:certname])
+ Puppet::Node::Facts.indirection.terminus_class = :rest
+ Puppet::Node::Facts.indirection.save(facts)
+ Puppet.notice "Uploaded facts for '#{Puppet[:certname]}'"
+ nil
+ end
+ end
+end
diff --git a/lib/puppet/face/file.rb b/lib/puppet/face/file.rb
new file mode 100644
index 000000000..1aa9462dd
--- /dev/null
+++ b/lib/puppet/face/file.rb
@@ -0,0 +1,5 @@
+require 'puppet/face/indirector'
+
+Puppet::Face::Indirector.define(:file, '0.0.1') do
+ set_indirection_name :file_bucket_file
+end
diff --git a/lib/puppet/face/help.rb b/lib/puppet/face/help.rb
new file mode 100644
index 000000000..1c2da9e83
--- /dev/null
+++ b/lib/puppet/face/help.rb
@@ -0,0 +1,104 @@
+require 'puppet/face'
+require 'puppet/util/command_line'
+require 'pathname'
+require 'erb'
+
+Puppet::Face.define(:help, '0.0.1') do
+ summary "Displays help about puppet subcommands"
+
+ action(:help) do
+ summary "Display help about faces and their actions."
+
+ option "--version VERSION" do
+ desc "Which version of the interface to show help for"
+ end
+
+ when_invoked do |*args|
+ # Check our invocation, because we want varargs and can't do defaults
+ # yet. REVISIT: when we do option defaults, and positional options, we
+ # should rewrite this to use those. --daniel 2011-04-04
+ options = args.pop
+ if options.nil? or args.length > 2 then
+ raise ArgumentError, "help only takes two (optional) arguments, a face name, and an action"
+ end
+
+ version = :current
+ if options.has_key? :version then
+ if options[:version].to_s !~ /^current$/i then
+ version = options[:version]
+ else
+ if args.length == 0 then
+ raise ArgumentError, "version only makes sense when a face is given"
+ end
+ end
+ end
+
+ # Name those parameters...
+ facename, actionname = args
+
+ if facename then
+ if legacy_applications.include? facename then
+ actionname and raise ArgumentError, "Legacy subcommands don't take actions"
+ return Puppet::Application[facename].help
+ else
+ face = Puppet::Face[facename.to_sym, version]
+ actionname and action = face.get_action(actionname.to_sym)
+ end
+ end
+
+ case args.length
+ when 0 then
+ template = erb 'global.erb'
+ when 1 then
+ face or fail ArgumentError, "Unable to load face #{facename}"
+ template = erb 'face.erb'
+ when 2 then
+ face or fail ArgumentError, "Unable to load face #{facename}"
+ action or fail ArgumentError, "Unable to load action #{actionname} from #{face}"
+ template = erb 'action.erb'
+ else
+ fail ArgumentError, "Too many arguments to help action"
+ end
+
+ # Run the ERB template in our current binding, including all the local
+ # variables we established just above. --daniel 2011-04-11
+ return template.result(binding)
+ end
+ end
+
+ def erb(name)
+ template = (Pathname(__FILE__).dirname + "help" + name)
+ erb = ERB.new(template.read, nil, '%')
+ erb.filename = template.to_s
+ return erb
+ end
+
+ def legacy_applications
+ # The list of applications, less those that are duplicated as a face.
+ Puppet::Util::CommandLine.available_subcommands.reject do |appname|
+ Puppet::Face.face? appname.to_sym, :current or
+ # ...this is a nasty way to exclude non-applications. :(
+ %w{face_base indirection_base}.include? appname
+ end.sort
+ end
+
+ def horribly_extract_summary_from(appname)
+ begin
+ require "puppet/application/#{appname}"
+ help = Puppet::Application[appname].help.split("\n")
+ # Now we find the line with our summary, extract it, and return it. This
+ # depends on the implementation coincidence of how our pages are
+ # formatted. If we can't match the pattern we expect we return the empty
+ # string to ensure we don't blow up in the summary. --daniel 2011-04-11
+ while line = help.shift do
+ if md = /^puppet-#{appname}\([^\)]+\) -- (.*)$/.match(line) then
+ return md[1]
+ end
+ end
+ rescue Exception
+ # Damn, but I hate this: we just ignore errors here, no matter what
+ # class they are. Meh.
+ end
+ return ''
+ end
+end
diff --git a/lib/puppet/face/help/action.erb b/lib/puppet/face/help/action.erb
new file mode 100644
index 000000000..eaf131464
--- /dev/null
+++ b/lib/puppet/face/help/action.erb
@@ -0,0 +1,3 @@
+Use: puppet <%= face.name %> [options] <%= action.name %> [options]
+
+Summary: <%= action.summary %>
diff --git a/lib/puppet/face/help/face.erb b/lib/puppet/face/help/face.erb
new file mode 100644
index 000000000..efe5fd809
--- /dev/null
+++ b/lib/puppet/face/help/face.erb
@@ -0,0 +1,7 @@
+Use: puppet <%= face.name %> [options] <action> [options]
+
+Available actions:
+% face.actions.each do |actionname|
+% action = face.get_action(actionname)
+ <%= action.name.to_s.ljust(16) %> <%= action.summary %>
+% end
diff --git a/lib/puppet/face/help/global.erb b/lib/puppet/face/help/global.erb
new file mode 100644
index 000000000..f4c761b2b
--- /dev/null
+++ b/lib/puppet/face/help/global.erb
@@ -0,0 +1,20 @@
+puppet <subcommand> [options] <action> [options]
+
+Available subcommands, from Puppet Faces:
+% Puppet::Face.faces.sort.each do |name|
+% face = Puppet::Face[name, :current]
+ <%= face.name.to_s.ljust(16) %> <%= face.summary %>
+% end
+
+% unless legacy_applications.empty? then # great victory when this is true!
+Available applications, soon to be ported to Faces:
+% legacy_applications.each do |appname|
+% summary = horribly_extract_summary_from appname
+ <%= appname.to_s.ljust(16) %> <%= summary %>
+% end
+% end
+
+See 'puppet help <subcommand> <action>' for help on a specific subcommand action.
+See 'puppet help <subcommand>' for help on a specific subcommand.
+See 'puppet man <subcommand>' for the full man page.
+Puppet v<%= Puppet::PUPPETVERSION %>
diff --git a/lib/puppet/face/indirector.rb b/lib/puppet/face/indirector.rb
new file mode 100644
index 000000000..f48611e4b
--- /dev/null
+++ b/lib/puppet/face/indirector.rb
@@ -0,0 +1,94 @@
+require 'puppet'
+require 'puppet/face'
+
+class Puppet::Face::Indirector < Puppet::Face
+ option "--terminus TERMINUS" do
+ desc "REVISIT: You can select a terminus, which has some bigger effect
+that we should describe in this file somehow."
+ end
+
+ def self.indirections
+ Puppet::Indirector::Indirection.instances.collect { |t| t.to_s }.sort
+ end
+
+ def self.terminus_classes(indirection)
+ Puppet::Indirector::Terminus.terminus_classes(indirection.to_sym).collect { |t| t.to_s }.sort
+ end
+
+ def call_indirection_method(method, *args)
+ options = args.last
+ options.has_key?(:terminus) and set_terminus(options[:terminus])
+
+ begin
+ result = indirection.__send__(method, *args)
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ raise "Could not call '#{method}' on '#{indirection_name}': #{detail}"
+ end
+
+ indirection.reset_terminus_class
+ return result
+ end
+
+ action :destroy do
+ when_invoked { |*args| call_indirection_method(:destroy, *args) }
+ end
+
+ action :find do
+ when_invoked { |*args| call_indirection_method(:find, *args) }
+ end
+
+ action :save do
+ when_invoked { |*args| call_indirection_method(:save, *args) }
+ end
+
+ action :search do
+ when_invoked { |*args| call_indirection_method(:search, *args) }
+ end
+
+ # Print the configuration for the current terminus class
+ action :info do
+ when_invoked do |*args|
+ options = args.pop
+ options.has_key?(:terminus) and set_terminus(options[:terminus])
+
+ if t = indirection.terminus_class
+ puts "Run mode '#{Puppet.run_mode.name}': #{t}"
+ else
+ $stderr.puts "No default terminus class for run mode '#{Puppet.run_mode.name}'"
+ end
+
+ indirection.reset_terminus_class
+ end
+ end
+
+ attr_accessor :from
+
+ def indirection_name
+ @indirection_name || name.to_sym
+ end
+
+ # Here's your opportunity to override the indirection name. By default it
+ # will be the same name as the face.
+ def set_indirection_name(name)
+ @indirection_name = name
+ end
+
+ # Return an indirection associated with a face, if one exists;
+ # One usually does.
+ def indirection
+ unless @indirection
+ @indirection = Puppet::Indirector::Indirection.instance(indirection_name)
+ @indirection or raise "Could not find terminus for #{indirection_name}"
+ end
+ @indirection
+ end
+
+ def set_terminus(from)
+ begin
+ indirection.terminus_class = from
+ rescue => detail
+ raise "Could not set '#{indirection.name}' terminus to '#{from}' (#{detail}); valid terminus types are #{self.class.terminus_classes(indirection.name).join(", ") }"
+ end
+ end
+end
diff --git a/lib/puppet/face/key.rb b/lib/puppet/face/key.rb
new file mode 100644
index 000000000..3a11ddb03
--- /dev/null
+++ b/lib/puppet/face/key.rb
@@ -0,0 +1,4 @@
+require 'puppet/face/indirector'
+
+Puppet::Face::Indirector.define(:key, '0.0.1') do
+end
diff --git a/lib/puppet/face/node.rb b/lib/puppet/face/node.rb
new file mode 100644
index 000000000..fd1a548d6
--- /dev/null
+++ b/lib/puppet/face/node.rb
@@ -0,0 +1,5 @@
+require 'puppet/face/indirector'
+
+Puppet::Face::Indirector.define(:node, '0.0.1') do
+ set_default_format :yaml
+end
diff --git a/lib/puppet/face/report.rb b/lib/puppet/face/report.rb
new file mode 100644
index 000000000..6e6f0b335
--- /dev/null
+++ b/lib/puppet/face/report.rb
@@ -0,0 +1,15 @@
+require 'puppet/face/indirector'
+
+Puppet::Face::Indirector.define(:report, '0.0.1') do
+ action(:submit) do
+ when_invoked do |report, options|
+ begin
+ Puppet::Transaction::Report.terminus_class = :rest
+ report.save
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Could not send report: #{detail}"
+ end
+ end
+ end
+end
diff --git a/lib/puppet/face/resource.rb b/lib/puppet/face/resource.rb
new file mode 100644
index 000000000..d162f728a
--- /dev/null
+++ b/lib/puppet/face/resource.rb
@@ -0,0 +1,4 @@
+require 'puppet/face/indirector'
+
+Puppet::Face::Indirector.define(:resource, '0.0.1') do
+end
diff --git a/lib/puppet/face/resource_type.rb b/lib/puppet/face/resource_type.rb
new file mode 100644
index 000000000..0cdbd719f
--- /dev/null
+++ b/lib/puppet/face/resource_type.rb
@@ -0,0 +1,4 @@
+require 'puppet/face/indirector'
+
+Puppet::Face::Indirector.define(:resource_type, '0.0.1') do
+end
diff --git a/lib/puppet/face/status.rb b/lib/puppet/face/status.rb
new file mode 100644
index 000000000..7085e7cd7
--- /dev/null
+++ b/lib/puppet/face/status.rb
@@ -0,0 +1,4 @@
+require 'puppet/face/indirector'
+
+Puppet::Face::Indirector.define(:status, '0.0.1') do
+end