diff --git a/lib/puppet/face/catalog.rb b/lib/puppet/face/catalog.rb index 3e964c7fe..660574ea3 100644 --- a/lib/puppet/face/catalog.rb +++ b/lib/puppet/face/catalog.rb @@ -1,63 +1,108 @@ require 'puppet/indirector/face' Puppet::Indirector::Face.define(:catalog, '0.0.1') do copyright "Puppet Labs", 2011 license "Apache 2 license; see COPYING" summary "Compile, save, view, and convert catalogs." - description <<-EOT -This face primarily interacts with the compiling subsystem. -By default, it compiles a catalog using the default manifest and the -hostname from 'certname', but you can choose to retrieve a catalog from -the server by specifying '--from rest'. You can also choose to print any -catalog in 'dot' format (for easy graph viewing with OmniGraffle or Graphviz) -with '--format dot'. +This face primarily interacts with the compiling subsystem. By default, +it compiles a catalog using the default manifest and the hostname from +`certname`, but you can choose to retrieve a catalog from the server by +specifying `--terminus rest`. You can also choose to print any catalog +in 'dot' format (for easy graph viewing with OmniGraffle or Graphviz) +with '--render-as dot'. + EOT + notes <<-EOT +This is an indirector face, which exposes find, search, save, and +destroy actions for an indirected subsystem of Puppet. Valid terminuses +for this face include: + +* `active_record` +* `compiler` +* `queue` +* `rest` +* `yaml` EOT action(:apply) do - summary "apply a Puppet::Resource::Catalog object" + summary "Apply a Puppet::Resource::Catalog object" + description <<-EOT +Applies a catalog object retrieved with the `download` action. This +action cannot consume a serialized catalog, and is not intended for +command-line use." + EOT + notes <<-EOT +This action returns a Puppet::Transaction::Report object. + EOT + examples <<-EOT +From `secret_agent.rb`: + + Puppet::Face[:plugin, '0.0.1'].download + + 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) + + Puppet::Face[:report, '0.0.1'].submit(report) + EOT when_invoked do |options| catalog = Puppet::Face[:catalog, "0.0.1"].find(Puppet[:certname]) or raise "Could not find catalog for #{Puppet[:certname]}" catalog = catalog.to_ral 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 - summary "Download the catalog for the certname to the local filesystem." + summary "Download this node's catalog from the puppet master server" + description <<-EOT +Retrieves a catalog from the puppet master. Unlike the `find` action, +`download` submits facts to the master as part of the request. This +action is not intended for command-line use. + EOT + notes "This action returns a Puppet::Resource::Catalog object." + examples <<-EOT +From `secret_agent.rb`: + + Puppet::Face[:plugin, '0.0.1'].download + + 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) + Puppet::Face[:report, '0.0.1'].submit(report) + EOT when_invoked do |options| Puppet::Resource::Catalog.indirection.terminus_class = :rest Puppet::Resource::Catalog.indirection.cache_class = nil catalog = nil retrieval_duration = thinmark do catalog = Puppet::Face[:catalog, '0.0.1'].find(Puppet[:certname]) end catalog.retrieval_duration = retrieval_duration catalog.write_class_file Puppet::Resource::Catalog.indirection.terminus_class = :yaml Puppet::Face[:catalog, "0.0.1"].save(catalog) Puppet.notice "Saved catalog for #{Puppet[:certname]} to yaml" nil end end end diff --git a/lib/puppet/face/catalog/select.rb b/lib/puppet/face/catalog/select.rb index a68a8e0f3..c5d37eb66 100644 --- a/lib/puppet/face/catalog/select.rb +++ b/lib/puppet/face/catalog/select.rb @@ -1,26 +1,42 @@ # Select and show a list of resources of a given type. Puppet::Face.define(:catalog, '0.0.1') do action :select do + summary "Select and show a list of resources of a given type" + description <<-EOT +Retrieves a catalog for the specified host and returns an array of +resources of the given type. This action is not intended for +command-line use. + EOT + notes <<-NOTES +The type name for this action must be given in its capitalized form. +That is, calling `catalog select mynode file` will return an empty +array, whereas calling it with 'File' will return a list of the node's +file resources. + +By default, this action will retrieve a catalog from Puppet's compiler +subsystem; you must call the action with `--terminus rest` if you wish +to retrieve a catalog from the puppet master. + NOTES when_invoked do |host, type, options| # REVISIT: Eventually, type should have a default value that triggers # the non-specific behaviour. For now, though, this will do. # --daniel 2011-05-03 catalog = Puppet::Resource::Catalog.indirection.find(host) if type == '*' catalog.resources else type = type.downcase catalog.resources.reject { |res| res.type.downcase != type } end end when_rendering :console do |value| if value.nil? then "no matching resources found" else value.map {|x| x.to_s }.join("\n") end end end end diff --git a/lib/puppet/face/certificate.rb b/lib/puppet/face/certificate.rb index 0018c5fd3..d1bdbec9d 100644 --- a/lib/puppet/face/certificate.rb +++ b/lib/puppet/face/certificate.rb @@ -1,45 +1,76 @@ require 'puppet/indirector/face' require 'puppet/ssl/host' Puppet::Indirector::Face.define(:certificate, '0.0.1') do copyright "Puppet Labs", 2011 license "Apache 2 license; see COPYING" - summary "provide access to the CA for certificate management" + summary "Provide access to the CA for certificate management" + description <<-EOT +This face interacts with a local or remote Puppet certificate +authority. Currently, its behavior is not a full superset of puppet +cert; specifically, it is unable to mimic puppet cert's "clean" option, +and its "generate" action submits a CSR rather than creating a +signed certificate. + EOT + notes <<-EOT +This is an indirector face, which exposes find, search, save, and +destroy actions for an indirected subsystem of Puppet. Valid terminuses +for this face include: + +* `ca` +* `file` +* `rest` + EOT option "--ca-location LOCATION" do + summary "The certificate authority to query" + description <<-EOT +Whether to act on the local certificate authority or one provided by a +remote puppet master. Allowed values are 'local' and 'remote.' + EOT + before_action do |action, args, options| Puppet::SSL::Host.ca_location = options[:ca_location].to_sym end end action :generate do - summary "Generate a new Certificate Signing Request for HOST" + summary "Generate a new certificate signing request for HOST" + description <<-EOT +Generates and submits a certificate signing request (CSR) for the +provided host identifier. This CSR will then have to be signed by a user +with the proper authorization on the certificate authority. + +Puppet agent handles CSR submission automatically. This action is +primarily useful for requesting certificates for individual users and +external applications. + EOT when_invoked do |name, options| host = Puppet::SSL::Host.new(name) host.generate_certificate_request host.certificate_request.class.indirection.save(host.certificate_request) end end action :list do - summary "List all Certificate Signing Requests" + summary "List all certificate signing requests" when_invoked do |options| Puppet::SSL::Host.indirection.search("*", { :for => :certificate_request, }).map { |h| h.inspect } end end action :sign do - summary "Sign a Certificate Signing Request for HOST" + summary "Sign a certificate signing request for HOST" when_invoked do |name, options| 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 index 809758423..907bed18b 100644 --- a/lib/puppet/face/certificate_request.rb +++ b/lib/puppet/face/certificate_request.rb @@ -1,8 +1,32 @@ require 'puppet/indirector/face' Puppet::Indirector::Face.define(:certificate_request, '0.0.1') do copyright "Puppet Labs", 2011 license "Apache 2 license; see COPYING" summary "Manage certificate requests." + description <<-EOT +Retrieves and submits certificate signing requests (CSRs). Invoke +`search` with an unread key to retrieve all outstanding CSRs, invoke +`find` with a node certificate name to retrieve a specific request, and +invoke `save` to submit a CSR. + EOT + notes <<-EOT +This is an indirector face, which exposes find, search, save, and +destroy actions for an indirected subsystem of Puppet. Valid terminuses +for this face include: + +* `ca` +* `file` +* `rest` + EOT + examples <<-EOT +Retrieve all CSRs from the local CA: + + puppet certificate_request search no_key --terminus ca + +Retrieve a single CSR from the puppet master's CA: + + puppet certificate_request find mynode.puppetlabs.lan --terminus rest + EOT end diff --git a/lib/puppet/face/certificate_revocation_list.rb b/lib/puppet/face/certificate_revocation_list.rb index 9913fad4b..4d5e26f76 100644 --- a/lib/puppet/face/certificate_revocation_list.rb +++ b/lib/puppet/face/certificate_revocation_list.rb @@ -1,8 +1,29 @@ require 'puppet/indirector/face' Puppet::Indirector::Face.define(:certificate_revocation_list, '0.0.1') do copyright "Puppet Labs", 2011 license "Apache 2 license; see COPYING" summary "Manage the list of revoked certificates." + description <<-EOT +TK This is just for retrieving the CRL, right? Do the +search/save/destroy methods do anything? + EOT + notes <<-EOT +Although the find action must be given an argument, this argument is +never read, and can contain the descriptive text of your choice. + +This is an indirector face, which exposes find, search, save, and +destroy actions for an indirected subsystem of Puppet. Valid terminuses +for this face include: + +* `ca` +* `file` +* `rest` + EOT + examples <<-EXAMPLES +Retrieve the CRL: + + puppet certificate_revocation_list find crl + EXAMPLES end diff --git a/lib/puppet/face/config.rb b/lib/puppet/face/config.rb index fc685202c..6b4131f56 100644 --- a/lib/puppet/face/config.rb +++ b/lib/puppet/face/config.rb @@ -1,17 +1,48 @@ require 'puppet/face' Puppet::Face.define(:config, '0.0.1') do copyright "Puppet Labs", 2011 license "Apache 2 license; see COPYING" - summary "Interact with Puppet configuration options." + summary "Interact with Puppet configuration options" action(:print) do + summary "Examine Puppet's current configuration options" + description <<-EOT +Prints the value of a single configuration option or a list of +configuration options. + +This action is an alternate interface to the information available with +`puppet agent --configprint`. + EOT + notes <<-EOT +The return data of this action varies depending on its arguments. When +called with "all," `print` will return a complete list of option names +and values. When called with a single configuration option name, it will +return the value of that option. When called with a list of +configuration option names, it will return the corresponding list of +option names and values. + +By default, this action retrieves its configuration information in agent +mode. To examine the master's configuration, supply Puppet's global +`--mode master` option. To examine configurations from a specific +environment, you can use the `--environment` option. + EOT + examples <<-EOT +Get puppet's runfile directory: + + puppet config print rundir + +Get a list of important directories from the master's config: + + puppet config print all --mode master | grep -E "(path|dir)" + EOT + 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/facts.rb b/lib/puppet/face/facts.rb index 9add63dd0..12dbded91 100644 --- a/lib/puppet/face/facts.rb +++ b/lib/puppet/face/facts.rb @@ -1,24 +1,49 @@ require 'puppet/indirector/face' require 'puppet/node/facts' Puppet::Indirector::Face.define(:facts, '0.0.1') do copyright "Puppet Labs", 2011 license "Apache 2 license; see COPYING" summary "Retrieve, store, and view facts." + notes <<-EOT +This is an indirector face, which exposes find, search, save, and +destroy actions for an indirected subsystem of Puppet. Valid terminuses +for this face include: + +* `active_record` +* `couch` +* `facter` +* `inventory_active_record` +* `memory` +* `network_device` +* `rest` +* `yaml` + EOT action(:upload) do - summary "upload our facts to the server." + summary "Upload our facts to the puppet master." + description <<-EOT +Retrieves facts for the local system and saves them to the puppet master +server. This is essentially a shortcut action: it calls the `find` +action with the facter terminus, then passes the returned facts object +to the `save` action, which uses the rest terminus. + EOT + notes <<-EOT +This action uses the save action, which requires the puppet master's +auth.conf to allow save access to the `facts` REST terminus. See +`http://docs.puppetlabs.com/guides/rest_auth_conf.html` for more details. + EOT render_as :yaml 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 index 1f2fc9f55..9c66f66a7 100644 --- a/lib/puppet/face/file.rb +++ b/lib/puppet/face/file.rb @@ -1,10 +1,21 @@ require 'puppet/indirector/face' Puppet::Indirector::Face.define(:file, '0.0.1') do copyright "Puppet Labs", 2011 license "Apache 2 license; see COPYING" summary "Retrieve and store files in a filebucket" + # TK this needs a description of how to find files in a filebucket, and + # some good use cases for retrieving/storing them. I can't write either + # of these yet. + notes <<-EOT +This is an indirector face, which exposes find, search, save, and +destroy actions for an indirected subsystem of Puppet. Valid terminuses +for this face include: + +* `file` +* `rest` + EOT set_indirection_name :file_bucket_file end diff --git a/lib/puppet/face/key.rb b/lib/puppet/face/key.rb index 148dc06c2..79c08b7a3 100644 --- a/lib/puppet/face/key.rb +++ b/lib/puppet/face/key.rb @@ -1,14 +1,23 @@ require 'puppet/indirector/face' Puppet::Indirector::Face.define(:key, '0.0.1') do copyright "Puppet Labs", 2011 license "Apache 2 license; see COPYING" - summary "Create, save, and remove certificate keys." + summary "Create, save, and remove certificate keys" description <<-EOT -Keys are created for you automatically when certificate -requests are generated with 'puppet certificate generate'. +Keys are created for you automatically when certificate requests are +generated with 'puppet certificate generate'. You should not have to use +this action directly from the command line. + EOT + notes <<-EOT +This is an indirector face, which exposes find, search, save, and +destroy actions for an indirected subsystem of Puppet. Valid terminuses +for this face include: + +* `ca` +* `file` EOT end diff --git a/lib/puppet/face/node.rb b/lib/puppet/face/node.rb index c4cf30b98..64002909e 100644 --- a/lib/puppet/face/node.rb +++ b/lib/puppet/face/node.rb @@ -1,11 +1,24 @@ require 'puppet/indirector/face' Puppet::Indirector::Face.define(:node, '0.0.1') do copyright "Puppet Labs", 2011 license "Apache 2 license; see COPYING" - summary "View and manage nodes" + summary "View and manage node definitions" description <<-EOT -It defaults to using whatever your node terminus is set as. +This face interacts with node objects, which are what Puppet uses to build a catalog. A node object consists of the node's facts, environment, additional top-scope variables, and classes. TK need this fact-checked. + EOT + notes <<-EOT +This is an indirector face, which exposes find, search, save, and +destroy actions for an indirected subsystem of Puppet. Valid terminuses +for this face include: + +* `active_record` +* `exec` +* `ldap` +* `memory` +* `plain` +* `rest` +* `yaml` EOT end diff --git a/lib/puppet/face/parser.rb b/lib/puppet/face/parser.rb index c4c3fb55e..26035d0ef 100644 --- a/lib/puppet/face/parser.rb +++ b/lib/puppet/face/parser.rb @@ -1,25 +1,31 @@ require 'puppet/face' require 'puppet/parser' Puppet::Face.define(:parser, '0.0.1') do copyright "Puppet Labs", 2011 license "Apache 2 license; see COPYING" summary "Interact directly with the parser" action :validate do + summary "Validate the syntax of one or more Puppet manifests" + description <<-EOT +This action validates Puppet DSL syntax without compiling a catalog or +syncing any resources. If no manifest files are provided, it will +validate the default site manifest. + EOT when_invoked do |*args| args.pop files = args if files.empty? files << Puppet[:manifest] Puppet.notice "No manifest specified. Validating the default manifest #{Puppet[:manifest]}" end 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/plugin.rb b/lib/puppet/face/plugin.rb index 8a2559405..f55bd3b28 100644 --- a/lib/puppet/face/plugin.rb +++ b/lib/puppet/face/plugin.rb @@ -1,31 +1,47 @@ require 'puppet/face' Puppet::Face.define(:plugin, '0.0.1') do copyright "Puppet Labs", 2011 license "Apache 2 license; see COPYING" summary "Interact with the Puppet plugin system" + description <<-EOT +This face provides network access to the puppet master's store of +plugins. It is intended for use in other faces, rather than for direct +command line access. + EOT + notes <<-EOT +The puppet master can serve Ruby code collected from the lib directories +of its modules. These plugins can be used on agent nodes to extend +Facter and implement custom types and providers. + EOT action :download do summary "Download plugins from the configured master" returns <<-EOT An array containing the files actually downloaded. This will be empty array when everything was in sync. EOT + notes "This action modifies files on disk without returning any data." + examples <<-EOT +Retrieve plugins from the puppet master: + + Puppet::Face[:plugin, '0.0.1'].download + EOT when_invoked do |options| require 'puppet/configurer/downloader' Puppet::Configurer::Downloader.new("plugin", Puppet[:plugindest], Puppet[:pluginsource], Puppet[:pluginsignore]).evaluate end when_rendering :console do |value| if value.empty? then "No plugins downloaded." else "Downloaded these plugins: #{value.join(', ')}" end end end end diff --git a/lib/puppet/face/report.rb b/lib/puppet/face/report.rb index f5b6d08ff..7143d45be 100644 --- a/lib/puppet/face/report.rb +++ b/lib/puppet/face/report.rb @@ -1,21 +1,48 @@ require 'puppet/indirector/face' Puppet::Indirector::Face.define(:report, '0.0.1') do copyright "Puppet Labs", 2011 license "Apache 2 license; see COPYING" summary "Create, display, and submit reports" + notes <<-EOT +This is an indirector face, which exposes find, search, save, and +destroy actions for an indirected subsystem of Puppet. Valid terminuses +for this face include: + +* `processor` +* `rest` +* `yaml` + + EOT action(:submit) do + summary "Submit a report object to the puppet master" + description <<-EOT +This action is essentially a shortcut and wrapper for the `save` action +with a terminus of `rest`. It also can provide additional details in the +event of a report submission failure. It is not intended for use from +a command line. + EOT + examples <<-EOT +From secret_agent.rb: + Puppet::Face[:plugin, '0.0.1'].download + + 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) + + Puppet::Face[:report, '0.0.1'].submit(report) + EOT when_invoked do |report, options| begin Puppet::Transaction::Report.indirection.terminus_class = :rest Puppet::Face[:report, "0.0.1"].save(report) Puppet.notice "Uploaded report for #{report.name}" 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 index 9ded46c0c..72e9a2a3f 100644 --- a/lib/puppet/face/resource.rb +++ b/lib/puppet/face/resource.rb @@ -1,8 +1,23 @@ require 'puppet/indirector/face' Puppet::Indirector::Face.define(:resource, '0.0.1') do copyright "Puppet Labs", 2011 license "Apache 2 license; see COPYING" summary "Interact directly with resources via the RAL, like ralsh" + description <<-EOT +This face provides a Ruby API with functionality similar to the puppet +resource (née ralsh) command line application. It is not intended to be +used from the command line. + EOT + notes <<-EOT +This is an indirector face, which exposes find, search, save, and +destroy actions for an indirected subsystem of Puppet. Valid terminuses +for this face include: + +* `ral` +* `rest` + EOT + + examples "TK we really need some examples for this one." end diff --git a/lib/puppet/face/resource_type.rb b/lib/puppet/face/resource_type.rb index 648cf1191..c4004379e 100644 --- a/lib/puppet/face/resource_type.rb +++ b/lib/puppet/face/resource_type.rb @@ -1,8 +1,17 @@ require 'puppet/indirector/face' Puppet::Indirector::Face.define(:resource_type, '0.0.1') do copyright "Puppet Labs", 2011 license "Apache 2 license; see COPYING" summary "View resource types, classes, and nodes from all manifests" + description "TK I have no idea what this does." + notes <<-EOT +This is an indirector face, which exposes find, search, save, and +destroy actions for an indirected subsystem of Puppet. Valid terminuses +for this face include: + +* `parser` +* `rest` + EOT end diff --git a/lib/puppet/face/secret_agent.rb b/lib/puppet/face/secret_agent.rb index 99208b545..2ddc5c9c9 100644 --- a/lib/puppet/face/secret_agent.rb +++ b/lib/puppet/face/secret_agent.rb @@ -1,26 +1,39 @@ require 'puppet/face' Puppet::Face.define(:secret_agent, '0.0.1') do copyright "Puppet Labs", 2011 license "Apache 2 license; see COPYING" - summary "Provides agent-like behavior, with no plugin downloading or reporting." + summary "Provides agent-like behavior, with no plugin downloading or reporting" + description <<-EOT +This face currently functions as a proof of concept, demonstrating how +Faces allows the separation of application logic from Puppet's internal +systems; compare the code for puppet agent. It will eventually replace +puppet agent entirely, and can provide a template for users who wish to +implement agent-like functionality with drastically different +application logic. + EOT action(:synchronize) do - summary "run the secret agent, which makes the catalog and system match..." + summary "Retrieve and apply a catalog from the puppet master" + description <<-EOT +This action mimics the behavior of the puppet agent application. It does +not currently daemonize, but can download plugins, submit facts, +retrieve and apply a catalog, and submit a report to the puppet master. + EOT when_invoked do |options| Puppet::Face[:plugin, '0.0.1'].download Puppet::Face[:facts, '0.0.1'].upload Puppet::Face[:catalog, '0.0.1'].download report = Puppet::Face[:catalog, '0.0.1'].apply Puppet::Face[:report, '0.0.1'].submit(report) return report end end end diff --git a/lib/puppet/face/status.rb b/lib/puppet/face/status.rb index 7ef05fa0e..0b53bef84 100644 --- a/lib/puppet/face/status.rb +++ b/lib/puppet/face/status.rb @@ -1,8 +1,30 @@ require 'puppet/indirector/face' Puppet::Indirector::Face.define(:status, '0.0.1') do copyright "Puppet Labs", 2011 license "Apache 2 license; see COPYING" - summary "View status information" + summary "View puppet server status" + description <<-EOT +This subcommand is only useful for determining whether a puppet master +server (or an agent node, if puppet was started with the `--listen` +option) is responding to requests. + +Only the `find` action is valid. If the server is responding to +requests, `find` will retrieve a status object; if not, the connection +will be refused. When invoked with the `local` terminus, `find` will +always return true. + +If you wish to query a server other than the master configured in +puppet.conf, you must set the `--server` and `--masterport` options on +the command line. + EOT + notes <<-EOT +This is an indirector face, which exposes find, search, save, and +destroy actions for an indirected subsystem of Puppet. Valid terminuses +for this face include: + +* `local` +* `rest` + EOT end diff --git a/lib/puppet/indirector/face.rb b/lib/puppet/indirector/face.rb index 0fd44dfea..3140ce2a0 100644 --- a/lib/puppet/indirector/face.rb +++ b/lib/puppet/indirector/face.rb @@ -1,94 +1,122 @@ require 'puppet/face' class Puppet::Indirector::Face < Puppet::Face option "--terminus TERMINUS" do - description %q{ -REVISIT: You can select a terminus, which has some bigger effect -that we should describe in this file somehow. -}.strip + summary "The indirector terminus to use for this action" + description <<-EOT +Indirector faces expose indirected subsystems of Puppet. These +subsystems are each able to retrieve and alter a specific type of data +(with the familiar actions of `find`, `search`, `save`, and `destroy`) +from an arbitrary number of pluggable backends. In Puppet parlance, +these backends are called terminuses. + +Almost all indirected subsystems have a `rest` terminus that interacts +with the puppet master's data. Most of them have additional terminuses +for various local data models, which are in turn used by the indirected +subsystem on the puppet master whenever it receives a remote request. + +The terminus for an action is often determined by context, but +occasionally needs to be set explicitly. See the "Notes" section of this +face's manpage for more details. + EOT before_action do |action, args, options| set_terminus(options[:terminus]) end after_action do |action, args, options| indirection.reset_terminus_class end 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, key, options) begin result = indirection.__send__(method, key, options) rescue => detail puts detail.backtrace if Puppet[:trace] raise "Could not call '#{method}' on '#{indirection_name}': #{detail}" end return result end action :destroy do + summary "Delete an object" when_invoked { |key, options| call_indirection_method(:destroy, key, options) } end action :find do + summary "Retrieve an object by name" when_invoked { |key, options| call_indirection_method(:find, key, options) } end action :save do + summary "Create or modify an object" + notes <<-EOT +Save actions cannot currently be invoked from the command line, and are +for API use only. + EOT when_invoked { |key, options| call_indirection_method(:save, key, options) } end action :search do + summary "Search for an object" when_invoked { |key, options| call_indirection_method(:search, key, options) } end # Print the configuration for the current terminus class action :info do + summary "Print the default terminus class for this face" + description <<-EOT +TK So this is per-face, right? No way to tell what the default terminus +is per-action, for subsystems that switch to REST for save but query +locally for find? + EOT + when_invoked do |*args| 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 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