puppet 2.7.1 → 2.7.3
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puppet might be problematic. Click here for more details.
- data/CHANGELOG +225 -1
- data/CONTRIBUTING.md +299 -0
- data/README.md +0 -1
- data/conf/redhat/puppet.spec +132 -25
- data/conf/solaris/pkginfo +1 -1
- data/conf/suse/puppet.spec +5 -2
- data/ext/envpuppet +56 -3
- data/ext/vim/README +2 -1
- data/ext/vim/ftplugin/puppet.vim +94 -0
- data/ext/vim/indent/puppet.vim +76 -0
- data/lib/puppet.rb +2 -3
- data/lib/puppet/application/agent.rb +7 -7
- data/lib/puppet/application/apply.rb +20 -8
- data/lib/puppet/application/ca.rb +5 -0
- data/lib/puppet/application/cert.rb +2 -1
- data/lib/puppet/application/certificate.rb +0 -5
- data/lib/puppet/application/device.rb +4 -4
- data/lib/puppet/application/doc.rb +23 -12
- data/lib/puppet/application/face_base.rb +2 -1
- data/lib/puppet/application/inspect.rb +5 -2
- data/lib/puppet/configurer.rb +60 -56
- data/lib/puppet/configurer/fact_handler.rb +6 -1
- data/lib/puppet/defaults.rb +20 -1
- data/lib/puppet/face/ca.rb +233 -0
- data/lib/puppet/face/certificate.rb +15 -11
- data/lib/puppet/face/certificate_request.rb +9 -11
- data/lib/puppet/face/certificate_revocation_list.rb +5 -7
- data/lib/puppet/face/node/clean.rb +154 -0
- data/lib/puppet/face/status.rb +1 -0
- data/lib/puppet/file_serving/configuration/parser.rb +6 -13
- data/lib/puppet/indirector/exec.rb +3 -3
- data/lib/puppet/indirector/face.rb +17 -7
- data/lib/puppet/indirector/report/processor.rb +29 -16
- data/lib/puppet/indirector/rest.rb +42 -7
- data/lib/puppet/indirector/yaml.rb +5 -0
- data/lib/puppet/interface.rb +7 -2
- data/lib/puppet/interface/action.rb +57 -23
- data/lib/puppet/interface/action_manager.rb +10 -5
- data/lib/puppet/interface/face_collection.rb +43 -52
- data/lib/puppet/interface/option.rb +19 -0
- data/lib/puppet/interface/option_builder.rb +13 -0
- data/lib/puppet/interface/option_manager.rb +2 -1
- data/lib/puppet/metatype/manager.rb +7 -20
- data/lib/puppet/module.rb +4 -1
- data/lib/puppet/network/authconfig.rb +3 -1
- data/lib/puppet/network/authstore.rb +14 -5
- data/lib/puppet/network/handler/fileserver.rb +3 -0
- data/lib/puppet/network/http/webrick.rb +1 -1
- data/lib/puppet/network/rest_authconfig.rb +6 -1
- data/lib/puppet/network/rest_authorization.rb +1 -1
- data/lib/puppet/parser/compiler.rb +8 -11
- data/lib/puppet/parser/functions.rb +1 -6
- data/lib/puppet/parser/functions/create_resources.rb +6 -5
- data/lib/puppet/parser/functions/regsubst.rb +26 -0
- data/lib/puppet/parser/functions/shellquote.rb +26 -0
- data/lib/puppet/parser/functions/sprintf.rb +26 -0
- data/lib/puppet/parser/grammar.ra +34 -60
- data/lib/puppet/parser/lexer.rb +5 -5
- data/lib/puppet/parser/parser.rb +913 -1196
- data/lib/puppet/parser/resource.rb +18 -1
- data/lib/puppet/parser/scope.rb +2 -2
- data/lib/puppet/provider/augeas/augeas.rb +42 -17
- data/lib/puppet/provider/mount/parsed.rb +19 -1
- data/lib/puppet/provider/naginator.rb +9 -1
- data/lib/puppet/provider/nameservice/directoryservice.rb +11 -8
- data/lib/puppet/provider/network_device.rb +1 -1
- data/lib/puppet/provider/package/aptitude.rb +1 -0
- data/lib/puppet/provider/package/pacman.rb +94 -0
- data/lib/puppet/provider/ssh_authorized_key/parsed.rb +0 -6
- data/lib/puppet/rails/host.rb +7 -0
- data/lib/puppet/reports/store.rb +15 -0
- data/lib/puppet/resource/catalog.rb +15 -6
- data/lib/puppet/ssl/certificate.rb +6 -0
- data/lib/puppet/ssl/inventory.rb +2 -0
- data/lib/puppet/transaction.rb +9 -17
- data/lib/puppet/transaction/report.rb +3 -3
- data/lib/puppet/type.rb +13 -24
- data/lib/puppet/type/file.rb +8 -2
- data/lib/puppet/type/file/source.rb +2 -2
- data/lib/puppet/type/service.rb +20 -24
- data/lib/puppet/type/ssh_authorized_key.rb +12 -0
- data/lib/puppet/type/user.rb +8 -0
- data/lib/puppet/util.rb +0 -1
- data/lib/puppet/util/network_device.rb +3 -3
- data/lib/puppet/util/settings.rb +1 -1
- data/lib/puppet/util/settings/file_setting.rb +1 -0
- data/lib/semver.rb +65 -0
- data/spec/integration/defaults_spec.rb +23 -1
- data/spec/integration/network/rest_authconfig_spec.rb +145 -0
- data/spec/integration/node/facts_spec.rb +1 -1
- data/spec/integration/parser/functions_spec.rb +1 -1
- data/spec/integration/parser/parser_spec.rb +31 -0
- data/spec/integration/provider/ssh_authorized_key_spec.rb +207 -0
- data/spec/integration/type_spec.rb +11 -0
- data/spec/lib/puppet/face/1.0.0/huzzah.rb +8 -0
- data/spec/lib/puppet/face/huzzah.rb +1 -0
- data/spec/lib/puppet/face/huzzah/obsolete.rb +6 -0
- data/spec/shared_behaviours/things_that_declare_options.rb +115 -3
- data/spec/unit/application/agent_spec.rb +2 -2
- data/spec/unit/application/apply_spec.rb +74 -56
- data/spec/unit/application/cert_spec.rb +10 -0
- data/spec/unit/application/device_spec.rb +2 -3
- data/spec/unit/application/face_base_spec.rb +1 -0
- data/spec/unit/application/facts_spec.rb +1 -0
- data/spec/unit/application/inspect_spec.rb +5 -0
- data/spec/unit/configurer/fact_handler_spec.rb +45 -37
- data/spec/unit/configurer_spec.rb +405 -327
- data/spec/unit/face/ca_spec.rb +355 -0
- data/spec/unit/face/certificate_spec.rb +16 -4
- data/spec/unit/face/node_spec.rb +261 -1
- data/spec/unit/file_serving/configuration/parser_spec.rb +8 -0
- data/spec/unit/indirector/certificate/rest_spec.rb +1 -0
- data/spec/unit/indirector/certificate_status/file_spec.rb +4 -0
- data/spec/unit/indirector/exec_spec.rb +4 -4
- data/spec/unit/indirector/face_spec.rb +3 -1
- data/spec/unit/indirector/facts/couch_spec.rb +2 -2
- data/spec/unit/indirector/facts/network_device_spec.rb +2 -6
- data/spec/unit/indirector/node/exec_spec.rb +1 -1
- data/spec/unit/indirector/report/processor_spec.rb +31 -8
- data/spec/unit/indirector/rest_spec.rb +53 -5
- data/spec/unit/indirector/yaml_spec.rb +18 -0
- data/spec/unit/interface/action_spec.rb +112 -8
- data/spec/unit/interface/face_collection_spec.rb +46 -36
- data/spec/unit/interface/option_spec.rb +44 -0
- data/spec/unit/interface_spec.rb +11 -6
- data/spec/unit/module_spec.rb +38 -9
- data/spec/unit/network/authconfig_spec.rb +23 -0
- data/spec/unit/network/authstore_spec.rb +36 -4
- data/spec/unit/network/handler/fileserver_spec.rb +32 -0
- data/spec/unit/network/rest_authconfig_spec.rb +1 -1
- data/spec/unit/node_spec.rb +1 -0
- data/spec/unit/parser/compiler_spec.rb +8 -46
- data/spec/unit/parser/lexer_spec.rb +27 -17
- data/spec/unit/parser/resource_spec.rb +61 -3
- data/spec/unit/parser/scope_spec.rb +5 -1
- data/spec/unit/provider/augeas/augeas_spec.rb +106 -1
- data/spec/unit/provider/cisco_spec.rb +3 -4
- data/spec/unit/provider/interface/cisco_spec.rb +1 -2
- data/spec/unit/provider/mount/parsed_spec.rb +41 -0
- data/spec/unit/provider/nameservice/directoryservice_spec.rb +60 -0
- data/spec/unit/provider/network_device_spec.rb +1 -2
- data/spec/unit/provider/package/pacman_spec.rb +237 -0
- data/spec/unit/provider/package/pkgutil_spec.rb +2 -3
- data/spec/unit/provider/ssh_authorized_key/parsed_spec.rb +21 -32
- data/spec/unit/provider/vlan/cisco_spec.rb +1 -2
- data/spec/unit/rails/host_spec.rb +8 -0
- data/spec/unit/resource/catalog_spec.rb +55 -8
- data/spec/unit/semver_spec.rb +187 -0
- data/spec/unit/ssl/certificate_spec.rb +25 -0
- data/spec/unit/transaction/report_spec.rb +3 -3
- data/spec/unit/transaction_spec.rb +8 -2
- data/spec/unit/type/file_spec.rb +57 -0
- data/spec/unit/type/interface_spec.rb +1 -2
- data/spec/unit/type/schedule_spec.rb +73 -42
- data/spec/unit/type/ssh_authorized_key_spec.rb +180 -70
- data/spec/unit/type/user_spec.rb +8 -0
- data/spec/unit/type/vlan_spec.rb +1 -2
- data/spec/unit/type_spec.rb +66 -0
- data/spec/unit/util/network_device/cisco/device_spec.rb +1 -2
- data/spec/unit/util/network_device/cisco/facts_spec.rb +2 -3
- data/spec/unit/util/network_device/cisco/interface_spec.rb +1 -2
- data/spec/unit/util/network_device/config_spec.rb +3 -4
- data/spec/unit/util/network_device/ipcalc_spec.rb +1 -2
- data/spec/unit/util/network_device/transport/base_spec.rb +1 -2
- data/spec/unit/util/network_device/transport/ssh_spec.rb +1 -2
- data/spec/unit/util/network_device/transport/telnet_spec.rb +1 -2
- data/spec/unit/util/network_device_spec.rb +2 -2
- data/spec/unit/util/settings/file_setting_spec.rb +4 -0
- data/spec/unit/util/settings_spec.rb +11 -0
- data/test/lib/puppettest/railstesting.rb +0 -34
- metadata +19 -4
@@ -0,0 +1,154 @@
|
|
1
|
+
Puppet::Face.define(:node, '0.0.1') do
|
2
|
+
action(:clean) do
|
3
|
+
option "--[no-]unexport" do
|
4
|
+
summary "Unexport exported resources"
|
5
|
+
end
|
6
|
+
|
7
|
+
summary "Clean up everything a puppetmaster knows about a node"
|
8
|
+
arguments "<host1> [<host2> ...]"
|
9
|
+
description <<-EOT
|
10
|
+
This includes
|
11
|
+
|
12
|
+
* Signed certificates ($vardir/ssl/ca/signed/node.domain.pem)
|
13
|
+
* Cached facts ($vardir/yaml/facts/node.domain.yaml)
|
14
|
+
* Cached node stuff ($vardir/yaml/node/node.domain.yaml)
|
15
|
+
* Reports ($vardir/reports/node.domain)
|
16
|
+
* Stored configs: it can either remove all data from an host in your
|
17
|
+
storedconfig database, or with --unexport turn every exported resource
|
18
|
+
supporting ensure to absent so that any other host checking out their
|
19
|
+
config can remove those exported configurations.
|
20
|
+
|
21
|
+
This will unexport exported resources of a
|
22
|
+
host, so that consumers of these resources can remove the exported
|
23
|
+
resources and we will safely remove the node from our
|
24
|
+
infrastructure.
|
25
|
+
EOT
|
26
|
+
|
27
|
+
when_invoked do |*args|
|
28
|
+
nodes = args[0..-2]
|
29
|
+
options = args.last
|
30
|
+
raise "At least one node should be passed" if nodes.empty? || nodes == options
|
31
|
+
|
32
|
+
# TODO: this is a hack and should be removed if faces provide the proper
|
33
|
+
# infrastructure to set the run mode.
|
34
|
+
require 'puppet/util/run_mode'
|
35
|
+
$puppet_application_mode = Puppet::Util::RunMode[:master]
|
36
|
+
|
37
|
+
if Puppet::SSL::CertificateAuthority.ca?
|
38
|
+
Puppet::SSL::Host.ca_location = :local
|
39
|
+
else
|
40
|
+
Puppet::SSL::Host.ca_location = :none
|
41
|
+
end
|
42
|
+
|
43
|
+
Puppet::Node::Facts.indirection.terminus_class = :yaml
|
44
|
+
Puppet::Node::Facts.indirection.cache_class = :yaml
|
45
|
+
Puppet::Node.indirection.terminus_class = :yaml
|
46
|
+
Puppet::Node.indirection.cache_class = :yaml
|
47
|
+
|
48
|
+
nodes.each { |node| cleanup(node.downcase, options[:unexport]) }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def cleanup(node, unexport)
|
53
|
+
clean_cert(node)
|
54
|
+
clean_cached_facts(node)
|
55
|
+
clean_cached_node(node)
|
56
|
+
clean_reports(node)
|
57
|
+
|
58
|
+
# This is roughly functional, but seems to introduce order-dependent test
|
59
|
+
# failures; this can be re-added when those issues are resolved.
|
60
|
+
# clean_storeconfigs(node, unexport)
|
61
|
+
end
|
62
|
+
|
63
|
+
# clean signed cert for +host+
|
64
|
+
def clean_cert(node)
|
65
|
+
if Puppet::SSL::CertificateAuthority.ca?
|
66
|
+
Puppet::Face[:ca, :current].revoke(node)
|
67
|
+
Puppet::Face[:ca, :current].destroy(node)
|
68
|
+
Puppet.info "#{node} certificates removed from ca"
|
69
|
+
else
|
70
|
+
Puppet.info "Not managing #{node} certs as this host is not a CA"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# clean facts for +host+
|
75
|
+
def clean_cached_facts(node)
|
76
|
+
Puppet::Node::Facts.indirection.destroy(node)
|
77
|
+
Puppet.info "#{node}'s facts removed"
|
78
|
+
end
|
79
|
+
|
80
|
+
# clean cached node +host+
|
81
|
+
def clean_cached_node(node)
|
82
|
+
Puppet::Node.indirection.destroy(node)
|
83
|
+
Puppet.info "#{node}'s cached node removed"
|
84
|
+
end
|
85
|
+
|
86
|
+
# clean node reports for +host+
|
87
|
+
def clean_reports(node)
|
88
|
+
Puppet::Transaction::Report.indirection.destroy(node)
|
89
|
+
Puppet.info "#{node}'s reports removed"
|
90
|
+
end
|
91
|
+
|
92
|
+
# clean storeconfig for +node+
|
93
|
+
def clean_storeconfigs(node, do_unexport=false)
|
94
|
+
return unless Puppet[:storeconfigs] && Puppet.features.rails?
|
95
|
+
require 'puppet/rails'
|
96
|
+
Puppet::Rails.connect
|
97
|
+
unless rails_node = Puppet::Rails::Host.find_by_name(node)
|
98
|
+
Puppet.notice "No entries found for #{node} in storedconfigs."
|
99
|
+
return
|
100
|
+
end
|
101
|
+
|
102
|
+
if do_unexport
|
103
|
+
unexport(rails_node)
|
104
|
+
Puppet.notice "Force #{node}'s exported resources to absent"
|
105
|
+
Puppet.warning "Please wait until all other hosts have checked out their configuration before finishing the cleanup with:"
|
106
|
+
Puppet.warning "$ puppet node clean #{node}"
|
107
|
+
else
|
108
|
+
rails_node.destroy
|
109
|
+
Puppet.notice "#{node} storeconfigs removed"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def unexport(node)
|
114
|
+
# fetch all exported resource
|
115
|
+
query = {:include => {:param_values => :param_name}}
|
116
|
+
query[:conditions] = [ "exported=? AND host_id=?", true, node.id ]
|
117
|
+
Puppet::Rails::Resource.find(:all, query).each do |resource|
|
118
|
+
if type_is_ensurable(resource)
|
119
|
+
line = 0
|
120
|
+
param_name = Puppet::Rails::ParamName.find_or_create_by_name("ensure")
|
121
|
+
|
122
|
+
if ensure_param = resource.param_values.find(
|
123
|
+
:first,
|
124
|
+
:conditions => [ 'param_name_id = ?', param_name.id ]
|
125
|
+
)
|
126
|
+
line = ensure_param.line.to_i
|
127
|
+
Puppet::Rails::ParamValue.delete(ensure_param.id);
|
128
|
+
end
|
129
|
+
|
130
|
+
# force ensure parameter to "absent"
|
131
|
+
resource.param_values.create(
|
132
|
+
:value => "absent",
|
133
|
+
:line => line,
|
134
|
+
:param_name => param_name
|
135
|
+
)
|
136
|
+
Puppet.info("#{resource.name} has been marked as \"absent\"")
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def environment
|
142
|
+
@environment ||= Puppet::Node::Environment.new
|
143
|
+
end
|
144
|
+
|
145
|
+
def type_is_ensurable(resource)
|
146
|
+
if (type = Puppet::Type.type(resource.restype)) && type.validattr?(:ensure)
|
147
|
+
return true
|
148
|
+
else
|
149
|
+
type = environment.known_resource_types.find_definition('', resource.restype)
|
150
|
+
return true if type && type.arguments.keys.include?('ensure')
|
151
|
+
end
|
152
|
+
return false
|
153
|
+
end
|
154
|
+
end
|
data/lib/puppet/face/status.rb
CHANGED
@@ -12,6 +12,7 @@ Puppet::Indirector::Face.define(:status, '0.0.1') do
|
|
12
12
|
get_action(:search).summary "Invalid for this subcommand."
|
13
13
|
|
14
14
|
find = get_action(:find)
|
15
|
+
find.default = true
|
15
16
|
find.summary "Check status of puppet master server."
|
16
17
|
find.arguments "<dummy_text>"
|
17
18
|
find.returns <<-'EOT'
|
@@ -24,9 +24,10 @@ class Puppet::FileServing::Configuration::Parser < Puppet::Util::LoadedFile
|
|
24
24
|
when /^\s*$/; next # skip blank lines
|
25
25
|
when /\[([-\w]+)\]/
|
26
26
|
mount = newmount($1)
|
27
|
-
when /^\s*(\w+)\s+(
|
27
|
+
when /^\s*(\w+)\s+(.+?)(\s*#.*)?$/
|
28
28
|
var = $1
|
29
29
|
value = $2
|
30
|
+
value.strip!
|
30
31
|
raise(ArgumentError, "Fileserver configuration file does not use '=' as a separator") if value =~ /^=/
|
31
32
|
case var
|
32
33
|
when "path"
|
@@ -58,12 +59,8 @@ class Puppet::FileServing::Configuration::Parser < Puppet::Util::LoadedFile
|
|
58
59
|
begin
|
59
60
|
mount.info "allowing #{val} access"
|
60
61
|
mount.allow(val)
|
61
|
-
rescue AuthStoreError => detail
|
62
|
-
|
63
|
-
raise ArgumentError.new(
|
64
|
-
detail.to_s,
|
65
|
-
|
66
|
-
@count, file)
|
62
|
+
rescue Puppet::AuthStoreError => detail
|
63
|
+
raise ArgumentError.new(detail.to_s, @count, file)
|
67
64
|
end
|
68
65
|
}
|
69
66
|
end
|
@@ -75,12 +72,8 @@ class Puppet::FileServing::Configuration::Parser < Puppet::Util::LoadedFile
|
|
75
72
|
begin
|
76
73
|
mount.info "denying #{val} access"
|
77
74
|
mount.deny(val)
|
78
|
-
rescue AuthStoreError => detail
|
79
|
-
|
80
|
-
raise ArgumentError.new(
|
81
|
-
detail.to_s,
|
82
|
-
|
83
|
-
@count, file)
|
75
|
+
rescue Puppet::AuthStoreError => detail
|
76
|
+
raise ArgumentError.new(detail.to_s, @count, file)
|
84
77
|
end
|
85
78
|
}
|
86
79
|
end
|
@@ -16,8 +16,8 @@ class Puppet::Indirector::Exec < Puppet::Indirector::Terminus
|
|
16
16
|
private
|
17
17
|
|
18
18
|
# Proxy the execution, so it's easier to test.
|
19
|
-
def execute(command)
|
20
|
-
Puppet::Util.execute(command)
|
19
|
+
def execute(command, arguments)
|
20
|
+
Puppet::Util.execute(command,arguments)
|
21
21
|
end
|
22
22
|
|
23
23
|
# Call the external command and see if it returns our output.
|
@@ -33,7 +33,7 @@ class Puppet::Indirector::Exec < Puppet::Indirector::Terminus
|
|
33
33
|
# Add our name to it.
|
34
34
|
external_command << name
|
35
35
|
begin
|
36
|
-
output = execute(external_command)
|
36
|
+
output = execute(external_command, :combine => false)
|
37
37
|
rescue Puppet::ExecutionFailure => detail
|
38
38
|
raise Puppet::Error, "Failed to find #{name} via exec: #{detail}"
|
39
39
|
end
|
@@ -48,16 +48,26 @@ class Puppet::Indirector::Face < Puppet::Face
|
|
48
48
|
return result
|
49
49
|
end
|
50
50
|
|
51
|
+
option "--extra HASH" do
|
52
|
+
summary "Extra arguments to pass to the indirection request"
|
53
|
+
description <<-end
|
54
|
+
A terminus can take additional arguments to refine the operation, which
|
55
|
+
are passed as an arbitrary hash to the back-end. Anything passed as
|
56
|
+
the extra value is just send direct to the back-end.
|
57
|
+
end
|
58
|
+
default_to do Hash.new end
|
59
|
+
end
|
60
|
+
|
51
61
|
action :destroy do
|
52
62
|
summary "Delete an object."
|
53
63
|
arguments "<key>"
|
54
|
-
when_invoked {
|
64
|
+
when_invoked {|key, options| call_indirection_method :destroy, key, options[:extra] }
|
55
65
|
end
|
56
66
|
|
57
67
|
action :find do
|
58
68
|
summary "Retrieve an object by name."
|
59
69
|
arguments "<key>"
|
60
|
-
when_invoked {
|
70
|
+
when_invoked {|key, options| call_indirection_method :find, key, options[:extra] }
|
61
71
|
end
|
62
72
|
|
63
73
|
action :save do
|
@@ -68,13 +78,13 @@ class Puppet::Indirector::Face < Puppet::Face
|
|
68
78
|
currently accept data from STDIN, save actions cannot currently be invoked
|
69
79
|
from the command line.
|
70
80
|
EOT
|
71
|
-
when_invoked {
|
81
|
+
when_invoked {|key, options| call_indirection_method :save, key, options[:extra] }
|
72
82
|
end
|
73
83
|
|
74
84
|
action :search do
|
75
85
|
summary "Search for an object or retrieve multiple objects."
|
76
86
|
arguments "<query>"
|
77
|
-
when_invoked {
|
87
|
+
when_invoked {|key, options| call_indirection_method :search, key, options[:extra] }
|
78
88
|
end
|
79
89
|
|
80
90
|
# Print the configuration for the current terminus class
|
@@ -86,11 +96,11 @@ class Puppet::Indirector::Face < Puppet::Face
|
|
86
96
|
run mode with the '--mode' option.
|
87
97
|
EOT
|
88
98
|
|
89
|
-
when_invoked do
|
99
|
+
when_invoked do |options|
|
90
100
|
if t = indirection.terminus_class
|
91
|
-
|
101
|
+
"Run mode '#{Puppet.run_mode.name}': #{t}"
|
92
102
|
else
|
93
|
-
|
103
|
+
"No default terminus class for run mode '#{Puppet.run_mode.name}'"
|
94
104
|
end
|
95
105
|
end
|
96
106
|
end
|
@@ -14,28 +14,30 @@ class Puppet::Transaction::Report::Processor < Puppet::Indirector::Code
|
|
14
14
|
process(request.instance)
|
15
15
|
end
|
16
16
|
|
17
|
+
def destroy(request)
|
18
|
+
processors do |mod|
|
19
|
+
mod.destroy(request.key) if mod.respond_to?(:destroy)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
17
23
|
private
|
18
24
|
|
19
25
|
# Process the report with each of the configured report types.
|
20
26
|
# LAK:NOTE This isn't necessarily the best design, but it's backward
|
21
27
|
# compatible and that's good enough for now.
|
22
28
|
def process(report)
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
Puppet.err "Report #{name} failed: #{detail}"
|
36
|
-
end
|
37
|
-
else
|
38
|
-
Puppet.warning "No report named '#{name}'"
|
29
|
+
Puppet.debug "Recieved report to process from #{report.host}"
|
30
|
+
processors do |mod|
|
31
|
+
Puppet.debug "Processing report from #{report.host} with processor #{mod}"
|
32
|
+
# We have to use a dup because we're including a module in the
|
33
|
+
# report.
|
34
|
+
newrep = report.dup
|
35
|
+
begin
|
36
|
+
newrep.extend(mod)
|
37
|
+
newrep.process
|
38
|
+
rescue => detail
|
39
|
+
puts detail.backtrace if Puppet[:trace]
|
40
|
+
Puppet.err "Report #{name} failed: #{detail}"
|
39
41
|
end
|
40
42
|
end
|
41
43
|
end
|
@@ -45,4 +47,15 @@ class Puppet::Transaction::Report::Processor < Puppet::Indirector::Code
|
|
45
47
|
# LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
|
46
48
|
x = Puppet[:reports].gsub(/(^\s+)|(\s+$)/, '').split(/\s*,\s*/)
|
47
49
|
end
|
50
|
+
|
51
|
+
def processors(&blk)
|
52
|
+
return if Puppet[:reports] == "none"
|
53
|
+
reports.each do |name|
|
54
|
+
if mod = Puppet::Reports.report(name)
|
55
|
+
yield(mod)
|
56
|
+
else
|
57
|
+
Puppet.warning "No report named '#{name}'"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
48
61
|
end
|
@@ -71,16 +71,51 @@ class Puppet::Indirector::REST < Puppet::Indirector::Terminus
|
|
71
71
|
Puppet::Network::HttpPool.http_instance(request.server || self.class.server, request.port || self.class.port)
|
72
72
|
end
|
73
73
|
|
74
|
+
[:get, :post, :head, :delete, :put].each do |method|
|
75
|
+
define_method "http_#{method}" do |request, *args|
|
76
|
+
http_request(method, request, *args)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def http_request(method, request, *args)
|
81
|
+
http_connection = network(request)
|
82
|
+
peer_certs = []
|
83
|
+
|
84
|
+
# We add the callback to collect the certificates for use in constructing
|
85
|
+
# the error message if the verification failed. This is necessary since we
|
86
|
+
# don't have direct access to the cert that we expected the connection to
|
87
|
+
# use otherwise.
|
88
|
+
#
|
89
|
+
http_connection.verify_callback = proc do |preverify_ok, ssl_context|
|
90
|
+
peer_certs << Puppet::SSL::Certificate.from_s(ssl_context.current_cert.to_pem)
|
91
|
+
preverify_ok
|
92
|
+
end
|
93
|
+
|
94
|
+
http_connection.send(method, *args)
|
95
|
+
rescue OpenSSL::SSL::SSLError => error
|
96
|
+
if error.message.include? "certificate verify failed"
|
97
|
+
raise Puppet::Error, "#{error.message}. This is often because the time is out of sync on the server or client"
|
98
|
+
elsif error.message.include? "hostname was not match"
|
99
|
+
raise unless cert = peer_certs.find { |c| c.name !~ /^puppet ca/i }
|
100
|
+
|
101
|
+
valid_certnames = [cert.name, *cert.alternate_names].uniq
|
102
|
+
msg = valid_certnames.length > 1 ? "one of #{valid_certnames.join(', ')}" : valid_certnames.first
|
103
|
+
|
104
|
+
raise Puppet::Error, "Server hostname '#{http_connection.address}' did not match server certificate; expected #{msg}"
|
105
|
+
else
|
106
|
+
raise
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
74
110
|
def find(request)
|
75
111
|
uri, body = request_to_uri_and_body(request)
|
76
112
|
uri_with_query_string = "#{uri}?#{body}"
|
77
|
-
http_connection = network(request)
|
78
113
|
# WEBrick in Ruby 1.9.1 only supports up to 1024 character lines in an HTTP request
|
79
114
|
# http://redmine.ruby-lang.org/issues/show/3991
|
80
115
|
response = if "GET #{uri_with_query_string} HTTP/1.1\r\n".length > 1024
|
81
|
-
|
116
|
+
http_post(request, uri, body, headers)
|
82
117
|
else
|
83
|
-
|
118
|
+
http_get(request, uri_with_query_string, headers)
|
84
119
|
end
|
85
120
|
result = deserialize response
|
86
121
|
result.name = request.key if result.respond_to?(:name=)
|
@@ -88,7 +123,7 @@ class Puppet::Indirector::REST < Puppet::Indirector::Terminus
|
|
88
123
|
end
|
89
124
|
|
90
125
|
def head(request)
|
91
|
-
response =
|
126
|
+
response = http_head(request, indirection2uri(request), headers)
|
92
127
|
case response.code
|
93
128
|
when "404"
|
94
129
|
return false
|
@@ -101,7 +136,7 @@ class Puppet::Indirector::REST < Puppet::Indirector::Terminus
|
|
101
136
|
end
|
102
137
|
|
103
138
|
def search(request)
|
104
|
-
unless result = deserialize(
|
139
|
+
unless result = deserialize(http_get(request, indirection2uri(request), headers), true)
|
105
140
|
return []
|
106
141
|
end
|
107
142
|
result
|
@@ -109,12 +144,12 @@ class Puppet::Indirector::REST < Puppet::Indirector::Terminus
|
|
109
144
|
|
110
145
|
def destroy(request)
|
111
146
|
raise ArgumentError, "DELETE does not accept options" unless request.options.empty?
|
112
|
-
deserialize
|
147
|
+
deserialize http_delete(request, indirection2uri(request), headers)
|
113
148
|
end
|
114
149
|
|
115
150
|
def save(request)
|
116
151
|
raise ArgumentError, "PUT does not accept options" unless request.options.empty?
|
117
|
-
deserialize
|
152
|
+
deserialize http_put(request, indirection2uri(request), request.instance.render, headers.merge({ "Content-Type" => request.instance.mime }))
|
118
153
|
end
|
119
154
|
|
120
155
|
private
|
@@ -47,6 +47,11 @@ class Puppet::Indirector::Yaml < Puppet::Indirector::Terminus
|
|
47
47
|
File.join(base, self.class.indirection_name.to_s, name.to_s + ext)
|
48
48
|
end
|
49
49
|
|
50
|
+
def destroy(request)
|
51
|
+
file_path = path(request.key)
|
52
|
+
File.unlink(file_path) if File.exists?(file_path)
|
53
|
+
end
|
54
|
+
|
50
55
|
def search(request)
|
51
56
|
Dir.glob(path(request.key,'')).collect do |file|
|
52
57
|
YAML.load_file(file)
|
data/lib/puppet/interface.rb
CHANGED
@@ -2,6 +2,7 @@ require 'puppet'
|
|
2
2
|
require 'puppet/util/autoload'
|
3
3
|
require 'puppet/interface/documentation'
|
4
4
|
require 'prettyprint'
|
5
|
+
require 'semver'
|
5
6
|
|
6
7
|
class Puppet::Interface
|
7
8
|
include FullDocs
|
@@ -63,6 +64,10 @@ class Puppet::Interface
|
|
63
64
|
end
|
64
65
|
face
|
65
66
|
end
|
67
|
+
|
68
|
+
def find_action(name, action, version = :current)
|
69
|
+
Puppet::Interface::FaceCollection.get_action_for_face(name, action, version)
|
70
|
+
end
|
66
71
|
end
|
67
72
|
|
68
73
|
def set_default_format(format)
|
@@ -84,12 +89,12 @@ class Puppet::Interface
|
|
84
89
|
attr_reader :name, :version
|
85
90
|
|
86
91
|
def initialize(name, version, &block)
|
87
|
-
unless
|
92
|
+
unless SemVer.valid?(version)
|
88
93
|
raise ArgumentError, "Cannot create face #{name.inspect} with invalid version number '#{version}'!"
|
89
94
|
end
|
90
95
|
|
91
96
|
@name = Puppet::Interface::FaceCollection.underscorize(name)
|
92
|
-
@version = version
|
97
|
+
@version = SemVer.new(version)
|
93
98
|
|
94
99
|
# The few bits of documentation we actually demand. The default license
|
95
100
|
# is a favour to our end users; if you happen to get that in a core face
|