summaryrefslogtreecommitdiffstats
path: root/lib/puppet/face
diff options
context:
space:
mode:
authorMax Martin <max@puppetlabs.com>2011-04-13 17:30:44 -0700
committerMax Martin <max@puppetlabs.com>2011-04-13 17:30:44 -0700
commit3dde838ac992571e13262ea29ba3a0eb8152e753 (patch)
tree90520cf62bfa2f1bb9c992bbfe1bc47ae10471f2 /lib/puppet/face
parentfe45c2417af580597cd39adec96a30a05a7cd66a (diff)
parent3ab44c7ce01ab86a995deb66228f5be95239c92a (diff)
downloadpuppet-3dde838ac992571e13262ea29ba3a0eb8152e753.tar.gz
puppet-3dde838ac992571e13262ea29ba3a0eb8152e753.tar.xz
puppet-3dde838ac992571e13262ea29ba3a0eb8152e753.zip
Merge branch 'next'
* next: (204 commits) Revert "(#6928) Removed --ignoreimport" Updated CHANGELOG for 2.6.8rc1 (#6928) Removed --ignoreimport (#6928) Remove --parseonly (#6928) Add a Parser face with Validate action (#6830) Fix sha1 to digest/sha1 require issue for Ruby 1.9 (#6830) Fix UTF-8 encoding issue for Ruby 1.9 (#6830) Fix string method sub call on a symbol for Ruby 1.9 (#2331) Remove darwinports pkg provider, replace with rewritten macports provider (#7059) handle inherited action binding scope maint: ensure we handle '-foo=' options correctly in faces. (#2150) Fix File const lookup when configuring routes Fixed #7082 - Added system support for groups maint: install erb templates under lib/ maint: clean up the spec test headers in bulk. (#7056) Use 'face' rather than 'faces' in the production code. maint: eliminate deprecated since 2008 code from Puppet. (#6117) Add POST support to indirector requests (#6962) Move option handling into #parse_options, not #preinit. maint: whitespace cleanup for puppet/util/command_line. ...
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/parser.rb17
-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
21 files changed, 432 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/parser.rb b/lib/puppet/face/parser.rb
new file mode 100644
index 000000000..c44810b99
--- /dev/null
+++ b/lib/puppet/face/parser.rb
@@ -0,0 +1,17 @@
+require 'puppet/face'
+require 'puppet/parser'
+
+Puppet::Face.define(:parser, '0.0.1') do
+ action :validate do
+ when_invoked do |*args|
+ args.pop
+ files = args
+ files << Puppet[:manifest] if files.empty?
+ files.each do |file|
+ Puppet[:manifest] = file
+ Puppet::Node::Environment.new(Puppet[:environment]).known_resource_types.clear
+ end
+ nil
+ end
+ end
+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