summaryrefslogtreecommitdiffstats
path: root/lib/puppet
diff options
context:
space:
mode:
Diffstat (limited to 'lib/puppet')
-rw-r--r--lib/puppet/application/agent.rb8
-rw-r--r--lib/puppet/application/apply.rb7
-rw-r--r--lib/puppet/application/ca.rb5
-rw-r--r--lib/puppet/application/device.rb8
-rw-r--r--lib/puppet/defaults.rb2
-rw-r--r--lib/puppet/face/ca.rb233
-rw-r--r--lib/puppet/interface.rb5
-rw-r--r--lib/puppet/interface/action.rb3
-rw-r--r--lib/puppet/interface/face_collection.rb49
-rw-r--r--lib/puppet/interface/option_manager.rb3
-rw-r--r--lib/puppet/module.rb5
-rw-r--r--lib/puppet/ssl/inventory.rb2
-rwxr-xr-xlib/puppet/type/file/source.rb2
-rw-r--r--lib/puppet/util.rb1
-rw-r--r--lib/puppet/util/settings.rb2
15 files changed, 271 insertions, 64 deletions
diff --git a/lib/puppet/application/agent.rb b/lib/puppet/application/agent.rb
index f0442648b..ea7cbdfb5 100644
--- a/lib/puppet/application/agent.rb
+++ b/lib/puppet/application/agent.rb
@@ -187,10 +187,10 @@ configuration options can also be generated by running puppet agent with
should always at least contain MD5, MD2, SHA1 and SHA256.
* --detailed-exitcodes:
- Provide transaction information via exit codes. If this is enabled, an
- exit code of '2' means there were changes, and an exit code of '4'
- means that there were failures during the transaction. This option
- only makes sense in conjunction with --onetime.
+ Provide transaction information via exit codes. If this is enabled, an exit
+ code of '2' means there were changes, an exit code of '4' means there were
+ failures during the transaction, and an exit code of '6' means there were both
+ changes and failures.
* --disable:
Disable working on the local system. This puts a lock file in place,
diff --git a/lib/puppet/application/apply.rb b/lib/puppet/application/apply.rb
index 5562a9b09..200309b7d 100644
--- a/lib/puppet/application/apply.rb
+++ b/lib/puppet/application/apply.rb
@@ -82,9 +82,10 @@ configuration options can also be generated by running puppet with
Enable full debugging.
* --detailed-exitcodes:
- Provide transaction information via exit codes. If this is enabled, an
- exit code of '2' means there were changes, and an exit code of '4'
- means that there were failures during the transaction.
+ Provide transaction information via exit codes. If this is enabled, an exit
+ code of '2' means there were changes, an exit code of '4' means there were
+ failures during the transaction, and an exit code of '6' means there were both
+ changes and failures.
* --help:
Print this help message
diff --git a/lib/puppet/application/ca.rb b/lib/puppet/application/ca.rb
new file mode 100644
index 000000000..d1ec2502e
--- /dev/null
+++ b/lib/puppet/application/ca.rb
@@ -0,0 +1,5 @@
+require 'puppet/application/face_base'
+
+class Puppet::Application::Ca < Puppet::Application::FaceBase
+ run_mode :master
+end
diff --git a/lib/puppet/application/device.rb b/lib/puppet/application/device.rb
index 3e2dec98c..977c5c023 100644
--- a/lib/puppet/application/device.rb
+++ b/lib/puppet/application/device.rb
@@ -113,10 +113,10 @@ parameter, so you can specify '--server <servername>' as an argument.
Enable full debugging.
* --detailed-exitcodes:
- Provide transaction information via exit codes. If this is enabled, an
- exit code of '2' means there were changes, and an exit code of '4' means
- that there were failures during the transaction. This option only makes
- sense in conjunction with --onetime.
+ Provide transaction information via exit codes. If this is enabled, an exit
+ code of '2' means there were changes, an exit code of '4' means there were
+ failures during the transaction, and an exit code of '6' means there were both
+ changes and failures.
* --help:
Print this help message
diff --git a/lib/puppet/defaults.rb b/lib/puppet/defaults.rb
index e6beb512e..637ee8fdd 100644
--- a/lib/puppet/defaults.rb
+++ b/lib/puppet/defaults.rb
@@ -472,7 +472,7 @@ module Puppet
:desc => "The directory in which to store reports
received from the client. Each client gets a separate
subdirectory."},
- :reporturl => ["http://localhost:3000/reports",
+ :reporturl => ["http://localhost:3000/reports/upload",
"The URL used by the http reports processor to send reports"],
:fileserverconfig => ["$confdir/fileserver.conf", "Where the fileserver configuration is stored."],
:strict_hostname_checking => [false, "Whether to only search for the complete
diff --git a/lib/puppet/face/ca.rb b/lib/puppet/face/ca.rb
new file mode 100644
index 000000000..e643530f0
--- /dev/null
+++ b/lib/puppet/face/ca.rb
@@ -0,0 +1,233 @@
+require 'puppet/face'
+
+Puppet::Face.define(:ca, '0.1.0') do
+ copyright "Puppet Labs", 2011
+ license "Apache 2 license; see COPYING"
+
+ summary "Local Puppet Certificate Authority management."
+
+ description <<TEXT
+This provides local management of the Puppet Certificate Authority.
+
+You can use this subcommand to sign outstanding certificate requests, list
+and manage local certificates, and inspect the state of the CA.
+TEXT
+
+ action :list do
+ summary "List certificates and/or certificate requests."
+
+ description <<-end
+This will list the current certificates and certificate signing requests
+in the Puppet CA. You will also get the fingerprint, and any certificate
+verification failure reported.
+ end
+
+ option "--[no-]all" do
+ summary "Include all certificates and requests."
+ end
+
+ option "--[no-]pending" do
+ summary "Include pending certificate signing requests."
+ end
+
+ option "--[no-]signed" do
+ summary "Include signed certificates."
+ end
+
+ option "--subject PATTERN" do
+ summary "Only list if the subject matches PATTERN."
+
+ description <<TEXT
+Only include certificates or requests where subject matches PATTERN.
+
+PATTERN is interpreted as a regular expression, allowing complex
+filtering of the content.
+TEXT
+ end
+
+ when_invoked do |options|
+ raise "Not a CA" unless Puppet::SSL::CertificateAuthority.ca?
+ unless ca = Puppet::SSL::CertificateAuthority.instance
+ raise "Unable to fetch the CA"
+ end
+
+ pattern = options[:subject].nil? ? nil :
+ Regexp.new(options[:subject], Regexp::IGNORECASE)
+
+ pending = options[:pending].nil? ? options[:all] : options[:pending]
+ signed = options[:signed].nil? ? options[:all] : options[:signed]
+
+ # By default we list pending, so if nothing at all was requested...
+ unless pending or signed then pending = true end
+
+ hosts = []
+
+ pending and hosts += ca.waiting?
+ signed and hosts += ca.list
+
+ pattern and hosts = hosts.select {|hostname| pattern.match hostname }
+
+ hosts.sort.map {|host| Puppet::SSL::Host.new(host) }
+ end
+
+ when_rendering :console do |hosts|
+ unless ca = Puppet::SSL::CertificateAuthority.instance
+ raise "Unable to fetch the CA"
+ end
+
+ length = hosts.map{|x| x.name.length }.max + 1
+
+ hosts.map do |host|
+ name = host.name.ljust(length)
+ if host.certificate_request then
+ " #{name} (#{host.certificate_request.fingerprint})"
+ else
+ begin
+ ca.verify(host.certificate)
+ "+ #{name} (#{host.certificate.fingerprint})"
+ rescue Puppet::SSL::CertificateAuthority::CertificateVerificationError => e
+ "- #{name} (#{host.certificate.fingerprint}) (#{e.to_s})"
+ end
+ end
+ end.join("\n")
+ end
+ end
+
+ action :destroy do
+ when_invoked do |host, options|
+ raise "Not a CA" unless Puppet::SSL::CertificateAuthority.ca?
+ unless ca = Puppet::SSL::CertificateAuthority.instance
+ raise "Unable to fetch the CA"
+ end
+
+ ca.destroy host
+ end
+ end
+
+ action :revoke do
+ when_invoked do |host, options|
+ raise "Not a CA" unless Puppet::SSL::CertificateAuthority.ca?
+ unless ca = Puppet::SSL::CertificateAuthority.instance
+ raise "Unable to fetch the CA"
+ end
+
+ begin
+ ca.revoke host
+ rescue ArgumentError => e
+ # This is a bit naff, but it makes the behaviour consistent with the
+ # destroy action. The underlying tools could be nicer for that sort
+ # of thing; they have fairly inconsistent reporting of failures.
+ raise unless e.to_s =~ /Could not find a serial number for /
+ "Nothing was revoked"
+ end
+ end
+ end
+
+ action :generate do
+ when_invoked do |host, options|
+ raise "Not a CA" unless Puppet::SSL::CertificateAuthority.ca?
+ unless ca = Puppet::SSL::CertificateAuthority.instance
+ raise "Unable to fetch the CA"
+ end
+
+ begin
+ ca.generate host
+ rescue RuntimeError => e
+ if e.to_s =~ /already has a requested certificate/
+ "#{host} already has a certificate request; use sign instead"
+ else
+ raise
+ end
+ rescue ArgumentError => e
+ if e.to_s =~ /A Certificate already exists for /
+ "#{host} already has a certificate"
+ else
+ raise
+ end
+ end
+ end
+ end
+
+ action :sign do
+ when_invoked do |host, options|
+ raise "Not a CA" unless Puppet::SSL::CertificateAuthority.ca?
+ unless ca = Puppet::SSL::CertificateAuthority.instance
+ raise "Unable to fetch the CA"
+ end
+
+ begin
+ ca.sign host
+ rescue ArgumentError => e
+ if e.to_s =~ /Could not find certificate request/
+ e.to_s
+ else
+ raise
+ end
+ end
+ end
+ end
+
+ action :print do
+ when_invoked do |host, options|
+ raise "Not a CA" unless Puppet::SSL::CertificateAuthority.ca?
+ unless ca = Puppet::SSL::CertificateAuthority.instance
+ raise "Unable to fetch the CA"
+ end
+
+ ca.print host
+ end
+ end
+
+ action :fingerprint do
+ option "--digest ALGORITHM" do
+ summary "The hash algorithm to use when displaying the fingerprint"
+ end
+
+ when_invoked do |host, options|
+ raise "Not a CA" unless Puppet::SSL::CertificateAuthority.ca?
+ unless ca = Puppet::SSL::CertificateAuthority.instance
+ raise "Unable to fetch the CA"
+ end
+
+ begin
+ # I want the default from the CA, not to duplicate it, but passing
+ # 'nil' explicitly means that we don't get that. This works...
+ if options.has_key? :digest
+ ca.fingerprint host, options[:digest]
+ else
+ ca.fingerprint host
+ end
+ rescue ArgumentError => e
+ raise unless e.to_s =~ /Could not find a certificate or csr for/
+ nil
+ end
+ end
+ end
+
+ action :verify do
+ when_invoked do |host, options|
+ raise "Not a CA" unless Puppet::SSL::CertificateAuthority.ca?
+ unless ca = Puppet::SSL::CertificateAuthority.instance
+ raise "Unable to fetch the CA"
+ end
+
+ begin
+ ca.verify host
+ { :host => host, :valid => true }
+ rescue ArgumentError => e
+ raise unless e.to_s =~ /Could not find a certificate for/
+ { :host => host, :valid => false, :error => e.to_s }
+ rescue Puppet::SSL::CertificateAuthority::CertificateVerificationError => e
+ { :host => host, :valid => false, :error => e.to_s }
+ end
+ end
+
+ when_rendering :console do |value|
+ if value[:valid]
+ nil
+ else
+ "Could not verify #{value[:host]}: #{value[:error]}"
+ end
+ end
+ end
+end
diff --git a/lib/puppet/interface.rb b/lib/puppet/interface.rb
index 6be8b6930..6c288f3c0 100644
--- a/lib/puppet/interface.rb
+++ b/lib/puppet/interface.rb
@@ -2,6 +2,7 @@ require 'puppet'
require 'puppet/util/autoload'
require 'puppet/interface/documentation'
require 'prettyprint'
+require 'semver'
class Puppet::Interface
include FullDocs
@@ -84,12 +85,12 @@ class Puppet::Interface
attr_reader :name, :version
def initialize(name, version, &block)
- unless Puppet::Interface::FaceCollection.validate_version(version)
+ unless SemVer.valid?(version)
raise ArgumentError, "Cannot create face #{name.inspect} with invalid version number '#{version}'!"
end
@name = Puppet::Interface::FaceCollection.underscorize(name)
- @version = version
+ @version = SemVer.new(version)
# The few bits of documentation we actually demand. The default license
# is a favour to our end users; if you happen to get that in a core face
diff --git a/lib/puppet/interface/action.rb b/lib/puppet/interface/action.rb
index 185302b07..fe77a9658 100644
--- a/lib/puppet/interface/action.rb
+++ b/lib/puppet/interface/action.rb
@@ -227,8 +227,9 @@ WRAPPER
end
end
+ @options << option.name
+
option.aliases.each do |name|
- @options << name
@options_hash[name] = option
end
diff --git a/lib/puppet/interface/face_collection.rb b/lib/puppet/interface/face_collection.rb
index 12d3c56b1..4522824fd 100644
--- a/lib/puppet/interface/face_collection.rb
+++ b/lib/puppet/interface/face_collection.rb
@@ -1,8 +1,6 @@
require 'puppet/interface'
module Puppet::Interface::FaceCollection
- SEMVER_VERSION = /^(\d+)\.(\d+)\.(\d+)([A-Za-z][0-9A-Za-z-]*|)$/
-
@faces = Hash.new { |hash, key| hash[key] = {} }
def self.faces
@@ -17,55 +15,18 @@ module Puppet::Interface::FaceCollection
@faces.keys.select {|name| @faces[name].length > 0 }
end
- def self.validate_version(version)
- !!(SEMVER_VERSION =~ version.to_s)
- end
-
- def self.semver_to_array(v)
- parts = SEMVER_VERSION.match(v).to_a[1..4]
- parts[0..2] = parts[0..2].map { |e| e.to_i }
- parts
- end
-
- def self.cmp_semver(a, b)
- a, b = [a, b].map do |x| semver_to_array(x) end
-
- cmp = a[0..2] <=> b[0..2]
- if cmp == 0
- cmp = a[3] <=> b[3]
- cmp = +1 if a[3].empty? && !b[3].empty?
- cmp = -1 if b[3].empty? && !a[3].empty?
- end
- cmp
- end
-
- def self.prefix_match?(desired, target)
- # Can't meaningfully do a prefix match with current on either side.
- return false if desired == :current
- return false if target == :current
-
- # REVISIT: Should probably fail if the matcher is not valid.
- prefix = desired.split('.').map {|x| x =~ /^\d+$/ and x.to_i }
- have = semver_to_array(target)
-
- while want = prefix.shift do
- return false unless want == have.shift
- end
- return true
- end
-
def self.[](name, version)
name = underscorize(name)
get_face(name, version) or load_face(name, version)
end
# get face from memory, without loading.
- def self.get_face(name, desired_version)
+ def self.get_face(name, pattern)
return nil unless @faces.has_key? name
+ return @faces[name][:current] if pattern == :current
- return @faces[name][:current] if desired_version == :current
-
- found = @faces[name].keys.select {|v| prefix_match?(desired_version, v) }.sort.last
+ versions = @faces[name].keys - [ :current ]
+ found = SemVer.find_matching(pattern, versions)
return @faces[name][found]
end
@@ -108,7 +69,7 @@ module Puppet::Interface::FaceCollection
# versions here and return the last item in that set.
#
# --daniel 2011-04-06
- latest_ver = @faces[name].keys.sort {|a, b| cmp_semver(a, b) }.last
+ latest_ver = @faces[name].keys.sort.last
@faces[name][:current] = @faces[name][latest_ver]
end
rescue LoadError => e
diff --git a/lib/puppet/interface/option_manager.rb b/lib/puppet/interface/option_manager.rb
index 326a91d92..a1f300e8e 100644
--- a/lib/puppet/interface/option_manager.rb
+++ b/lib/puppet/interface/option_manager.rb
@@ -26,8 +26,9 @@ module Puppet::Interface::OptionManager
end
end
+ @options << option.name
+
option.aliases.each do |name|
- @options << name
@options_hash[name] = option
end
diff --git a/lib/puppet/module.rb b/lib/puppet/module.rb
index 059591ed8..00468df96 100644
--- a/lib/puppet/module.rb
+++ b/lib/puppet/module.rb
@@ -42,7 +42,10 @@ class Puppet::Module
def has_metadata?
return false unless metadata_file
- FileTest.exist?(metadata_file)
+ return false unless FileTest.exist?(metadata_file)
+
+ metadata = PSON.parse File.read(metadata_file)
+ return metadata.is_a?(Hash) && !metadata.keys.empty?
end
def initialize(name, environment = nil)
diff --git a/lib/puppet/ssl/inventory.rb b/lib/puppet/ssl/inventory.rb
index e094da100..c210fdc35 100644
--- a/lib/puppet/ssl/inventory.rb
+++ b/lib/puppet/ssl/inventory.rb
@@ -48,5 +48,7 @@ class Puppet::SSL::Inventory
return Integer($1)
end
+
+ return nil
end
end
diff --git a/lib/puppet/type/file/source.rb b/lib/puppet/type/file/source.rb
index 76c646baf..49e885865 100755
--- a/lib/puppet/type/file/source.rb
+++ b/lib/puppet/type/file/source.rb
@@ -42,7 +42,7 @@ module Puppet
on the local host, whereas `agent` will connect to the
puppet server that it received the manifest from.
- See the [fileserver configuration documentation](http://projects.puppetlabs.com/projects/puppet/wiki/File_Serving_Configuration) for information on how to configure
+ See the [fileserver configuration documentation](http://docs.puppetlabs.com/guides/file_serving.html) for information on how to configure
and use file services within Puppet.
If you specify multiple file sources for a file, then the first
diff --git a/lib/puppet/util.rb b/lib/puppet/util.rb
index ce9d4642b..ff09221a2 100644
--- a/lib/puppet/util.rb
+++ b/lib/puppet/util.rb
@@ -30,7 +30,6 @@ module Util
end
end
-
def self.synchronize_on(x,type)
sync_object,users = 0,1
begin
diff --git a/lib/puppet/util/settings.rb b/lib/puppet/util/settings.rb
index f243b8691..4559e9af3 100644
--- a/lib/puppet/util/settings.rb
+++ b/lib/puppet/util/settings.rb
@@ -721,7 +721,7 @@ if @config.include?(:run_mode)
end
Puppet::Util::SUIDManager.asuser(*chown) do
- mode = obj.mode || 0640
+ mode = obj.mode ? obj.mode.to_i : 0640
args << "w" if args.empty?
args << mode