puppet 4.3.1 → 4.3.2
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.
- checksums.yaml +4 -4
- data/ext/build_defaults.yaml +1 -1
- data/lib/hiera/scope.rb +1 -1
- data/lib/puppet/application/lookup.rb +41 -43
- data/lib/puppet/data_providers/lookup_adapter.rb +73 -26
- data/lib/puppet/functions/lookup.rb +126 -150
- data/lib/puppet/functions/match.rb +1 -0
- data/lib/puppet/indirector/hiera.rb +3 -1
- data/lib/puppet/indirector/indirection.rb +6 -2
- data/lib/puppet/indirector/json.rb +2 -2
- data/lib/puppet/module.rb +3 -2
- data/lib/puppet/node.rb +11 -2
- data/lib/puppet/parser/compiler.rb +1 -8
- data/lib/puppet/parser/functions/lookup.rb +128 -149
- data/lib/puppet/parser/functions/match.rb +1 -0
- data/lib/puppet/plugins/data_providers/data_provider.rb +3 -2
- data/lib/puppet/pops/adapters.rb +43 -0
- data/lib/puppet/pops/evaluator/access_operator.rb +3 -3
- data/lib/puppet/pops/evaluator/closure.rb +51 -51
- data/lib/puppet/pops/evaluator/collector_transformer.rb +16 -0
- data/lib/puppet/pops/evaluator/runtime3_support.rb +11 -2
- data/lib/puppet/pops/functions/function.rb +6 -2
- data/lib/puppet/pops/issues.rb +16 -0
- data/lib/puppet/pops/loader/puppet_function_instantiator.rb +3 -2
- data/lib/puppet/pops/lookup.rb +3 -0
- data/lib/puppet/pops/lookup/explainer.rb +73 -3
- data/lib/puppet/pops/lookup/invocation.rb +21 -19
- data/lib/puppet/pops/model/factory.rb +153 -155
- data/lib/puppet/pops/model/model.rb +9 -0
- data/lib/puppet/pops/model/model_label_provider.rb +1 -0
- data/lib/puppet/pops/parser/evaluating_parser.rb +3 -3
- data/lib/puppet/pops/parser/lexer2.rb +411 -393
- data/lib/puppet/pops/parser/slurp_support.rb +5 -1
- data/lib/puppet/pops/types/type_calculator.rb +2 -6
- data/lib/puppet/pops/types/types.rb +3 -9
- data/lib/puppet/pops/validation/checker4_0.rb +36 -12
- data/lib/puppet/provider/group/windows_adsi.rb +2 -2
- data/lib/puppet/provider/package/pip.rb +11 -1
- data/lib/puppet/provider/package/rpm.rb +0 -1
- data/lib/puppet/provider/package/yum.rb +1 -1
- data/lib/puppet/provider/service/debian.rb +5 -18
- data/lib/puppet/provider/service/init.rb +7 -0
- data/lib/puppet/provider/service/launchd.rb +6 -0
- data/lib/puppet/provider/service/systemd.rb +1 -1
- data/lib/puppet/provider/user/windows_adsi.rb +2 -2
- data/lib/puppet/provider/yumrepo/inifile.rb +6 -3
- data/lib/puppet/resource/type.rb +2 -1
- data/lib/puppet/transaction/additional_resource_generator.rb +17 -3
- data/lib/puppet/type/group.rb +6 -2
- data/lib/puppet/util/windows.rb +4 -0
- data/lib/puppet/util/windows/adsi.rb +61 -24
- data/lib/puppet/util/windows/principal.rb +181 -0
- data/lib/puppet/util/windows/registry.rb +21 -15
- data/lib/puppet/util/windows/sid.rb +42 -11
- data/lib/puppet/version.rb +1 -1
- data/spec/fixtures/unit/application/environments/production/data/common.yaml +4 -0
- data/spec/fixtures/unit/application/environments/production/manifests/site.pp +1 -0
- data/spec/fixtures/unit/application/environments/puppet_func_provider/environment.conf +1 -0
- data/spec/fixtures/unit/application/environments/puppet_func_provider/functions/data.pp +10 -0
- data/spec/fixtures/unit/application/environments/puppet_func_provider/manifests/site.pp +1 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_module_config/data/common.yaml +4 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_module_config/data/specific.yaml +4 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_module_config/hiera.yaml +7 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_modules/data/common.yaml +4 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_modules/data/specific.yaml +4 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_modules/environment.conf +2 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_modules/hiera.yaml +7 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_modules/manifests/site.pp +1 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_modules/modules/one/data/common.yaml +6 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_modules/modules/one/hiera.yaml +5 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_modules/modules/one/manifests/init.pp +2 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_modules/modules/one/metadata.json +9 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_modules/modules/two/data/common.yaml +4 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_modules/modules/two/hiera.yaml +5 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_modules/modules/two/manifests/init.pp +3 -0
- data/spec/fixtures/unit/data_providers/environments/hiera_modules/modules/two/metadata.json +9 -0
- data/spec/fixtures/unit/pops/loaders/loaders/dependent_modules_with_metadata/modules/usee/functions/usee_puppet.pp +3 -0
- data/spec/fixtures/unit/pops/loaders/loaders/dependent_modules_with_metadata/{usee → modules/usee}/lib/puppet/functions/usee/callee.rb +0 -0
- data/spec/fixtures/unit/pops/loaders/loaders/dependent_modules_with_metadata/modules/usee/lib/puppet/functions/usee/usee_ruby.rb +6 -0
- data/spec/fixtures/unit/pops/loaders/loaders/dependent_modules_with_metadata/modules/usee/manifests/init.pp +6 -0
- data/spec/fixtures/unit/pops/loaders/loaders/dependent_modules_with_metadata/modules/usee2/lib/puppet/functions/usee2/callee.rb +5 -0
- data/spec/fixtures/unit/pops/loaders/loaders/dependent_modules_with_metadata/modules/user/functions/puppet_calling_puppet.pp +5 -0
- data/spec/fixtures/unit/pops/loaders/loaders/dependent_modules_with_metadata/modules/user/functions/puppet_calling_puppet_init.pp +5 -0
- data/spec/fixtures/unit/pops/loaders/loaders/dependent_modules_with_metadata/modules/user/functions/puppet_calling_ruby.pp +5 -0
- data/spec/fixtures/unit/pops/loaders/loaders/dependent_modules_with_metadata/{user → modules/user}/lib/puppet/functions/user/caller.rb +0 -0
- data/spec/fixtures/unit/pops/loaders/loaders/dependent_modules_with_metadata/modules/user/lib/puppet/functions/user/caller2.rb +5 -0
- data/spec/fixtures/unit/pops/loaders/loaders/dependent_modules_with_metadata/modules/user/lib/puppet/functions/user/ruby_calling_puppet.rb +5 -0
- data/spec/fixtures/unit/pops/loaders/loaders/dependent_modules_with_metadata/modules/user/lib/puppet/functions/user/ruby_calling_puppet_init.rb +5 -0
- data/spec/fixtures/unit/pops/loaders/loaders/dependent_modules_with_metadata/modules/user/lib/puppet/functions/user/ruby_calling_ruby.rb +5 -0
- data/spec/fixtures/unit/pops/loaders/loaders/dependent_modules_with_metadata/modules/user/manifests/init.pp +81 -0
- data/spec/fixtures/unit/pops/loaders/loaders/dependent_modules_with_metadata/{user → modules/user}/metadata.json +2 -1
- data/spec/integration/parser/collection_spec.rb +8 -0
- data/spec/integration/util/windows/principal_spec.rb +115 -0
- data/spec/{unit → integration}/util/windows/registry_spec.rb +91 -1
- data/spec/integration/util/windows/security_spec.rb +2 -2
- data/spec/unit/application/lookup_spec.rb +138 -28
- data/spec/unit/data_providers/hiera_data_provider_spec.rb +182 -5
- data/spec/unit/face/epp_face_spec.rb +2 -2
- data/spec/unit/functions/epp_spec.rb +6 -6
- data/spec/unit/functions/inline_epp_spec.rb +4 -4
- data/spec/unit/functions/lookup_spec.rb +30 -3
- data/spec/unit/functions4_spec.rb +1 -1
- data/spec/unit/hiera/scope_spec.rb +5 -2
- data/spec/unit/indirector/json_spec.rb +1 -1
- data/spec/unit/node_spec.rb +8 -0
- data/spec/unit/parser/compiler_spec.rb +0 -18
- data/spec/unit/pops/evaluator/access_ops_spec.rb +4 -4
- data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +1 -1
- data/spec/unit/pops/loaders/loaders_spec.rb +84 -2
- data/spec/unit/pops/parser/lexer2_spec.rb +6 -0
- data/spec/unit/pops/parser/parser_rspec_helper.rb +5 -0
- data/spec/unit/pops/types/type_calculator_spec.rb +0 -17
- data/spec/unit/pops/validator/validator_spec.rb +87 -0
- data/spec/unit/provider/group/windows_adsi_spec.rb +8 -8
- data/spec/unit/provider/package/pip_spec.rb +41 -13
- data/spec/unit/provider/package/rpm_spec.rb +2 -25
- data/spec/unit/provider/package/yum_spec.rb +1 -1
- data/spec/unit/provider/service/debian_spec.rb +6 -24
- data/spec/unit/provider/service/init_spec.rb +11 -1
- data/spec/unit/provider/service/launchd_spec.rb +11 -0
- data/spec/unit/provider/service/systemd_spec.rb +18 -12
- data/spec/unit/provider/service/upstart_spec.rb +57 -0
- data/spec/unit/provider/user/windows_adsi_spec.rb +5 -5
- data/spec/unit/provider/yumrepo/inifile_spec.rb +16 -0
- data/spec/unit/resource_spec.rb +12 -2
- data/spec/unit/util/windows/adsi_spec.rb +44 -36
- data/spec/unit/util/windows/sid_spec.rb +47 -10
- metadata +77 -10
@@ -67,6 +67,10 @@ module Puppet::Pops::Parser::SlurpSupport
|
|
67
67
|
def slurp(scanner, pattern, escapes, ignore_invalid_escapes)
|
68
68
|
str = scanner.scan_until(pattern) || return
|
69
69
|
|
70
|
+
return str unless str.include?('\\')
|
71
|
+
|
72
|
+
return str.gsub!(/\\(\\|')/m, '\1') || str if escapes.equal?(SQ_ESCAPES)
|
73
|
+
|
70
74
|
# Process unicode escapes first as they require getting 4 hex digits
|
71
75
|
# If later a \u is found it is warned not to be a unicode escape
|
72
76
|
if escapes.include?('u')
|
@@ -83,7 +87,7 @@ module Puppet::Pops::Parser::SlurpSupport
|
|
83
87
|
when 'r' ; "\r"
|
84
88
|
when 'n' ; "\n"
|
85
89
|
when 't' ; "\t"
|
86
|
-
when 's' ;
|
90
|
+
when 's' ; ' '
|
87
91
|
when 'u'
|
88
92
|
lex_warning(Puppet::Pops::Issues::ILLEGAL_UNICODE_ESCAPE)
|
89
93
|
"\\u"
|
@@ -708,12 +708,8 @@ class Puppet::Pops::Types::TypeCalculator
|
|
708
708
|
from = range.from
|
709
709
|
to = range.to
|
710
710
|
x = from.nil? ? 1 : from
|
711
|
-
y = to.nil? ?
|
712
|
-
|
713
|
-
[x, y]
|
714
|
-
else
|
715
|
-
[y, x]
|
716
|
-
end
|
711
|
+
y = to.nil? ? TheInfinity : to
|
712
|
+
[x, y]
|
717
713
|
end
|
718
714
|
|
719
715
|
# @api private
|
@@ -423,15 +423,9 @@ module Puppet::Pops
|
|
423
423
|
def initialize(from, to = Float::INFINITY)
|
424
424
|
from = -Float::INFINITY if from.nil? || from == :default
|
425
425
|
to = Float::INFINITY if to.nil? || to == :default
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
@from = from
|
430
|
-
@to = to
|
431
|
-
else
|
432
|
-
@to = from
|
433
|
-
@from = to
|
434
|
-
end
|
426
|
+
raise ArgumentError, "'from' must be less or equal to 'to'. Got (#{from}, #{to}" if from.is_a?(Numeric) && to.is_a?(Numeric) && from > to
|
427
|
+
@from = from
|
428
|
+
@to = to
|
435
429
|
end
|
436
430
|
|
437
431
|
# Returns the lower bound of the numeric range or `nil` if no lower bound is set.
|
@@ -213,11 +213,24 @@ class Puppet::Pops::Validation::Checker4_0
|
|
213
213
|
rvalue(o.right_expr)
|
214
214
|
end
|
215
215
|
|
216
|
+
def resource_without_title?(o)
|
217
|
+
if o.instance_of?(Puppet::Pops::Model::BlockExpression)
|
218
|
+
statements = o.statements
|
219
|
+
statements.length == 2 && statements[0].instance_of?(Puppet::Pops::Model::QualifiedName) && statements[1].instance_of?(Puppet::Pops::Model::LiteralHash)
|
220
|
+
else
|
221
|
+
false
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
216
225
|
def check_BlockExpression(o)
|
217
|
-
o
|
218
|
-
|
219
|
-
|
220
|
-
|
226
|
+
if resource_without_title?(o)
|
227
|
+
acceptor.accept(Issues::RESOURCE_WITHOUT_TITLE, o, :name => o.statements[0].value)
|
228
|
+
else
|
229
|
+
o.statements[0..-2].each do |statement|
|
230
|
+
if idem(statement)
|
231
|
+
acceptor.accept(Issues::IDEM_EXPRESSION_NOT_LAST, statement)
|
232
|
+
break # only flag the first
|
233
|
+
end
|
221
234
|
end
|
222
235
|
end
|
223
236
|
end
|
@@ -264,6 +277,7 @@ class Puppet::Pops::Validation::Checker4_0
|
|
264
277
|
def check_EppExpression(o)
|
265
278
|
if o.eContainer.is_a?(Puppet::Pops::Model::LambdaExpression)
|
266
279
|
internal_check_no_capture(o.eContainer, o)
|
280
|
+
internal_check_parameter_name_uniqueness(o.eContainer)
|
267
281
|
end
|
268
282
|
end
|
269
283
|
|
@@ -352,16 +366,13 @@ class Puppet::Pops::Validation::Checker4_0
|
|
352
366
|
end
|
353
367
|
|
354
368
|
def check_FunctionDefinition(o)
|
355
|
-
# TODO PUP-2080: more strict rule for top - can only be contained in Program (for now)
|
356
|
-
# sticking functions in classes would create functions in the class name space
|
357
|
-
# but not be special in any other way
|
358
|
-
#
|
359
369
|
check_NamedDefinition(o)
|
360
370
|
end
|
361
371
|
|
362
372
|
def check_HostClassDefinition(o)
|
363
373
|
check_NamedDefinition(o)
|
364
374
|
internal_check_no_capture(o)
|
375
|
+
internal_check_parameter_name_uniqueness(o)
|
365
376
|
internal_check_reserved_params(o)
|
366
377
|
internal_check_no_idem_last(o)
|
367
378
|
end
|
@@ -369,13 +380,14 @@ class Puppet::Pops::Validation::Checker4_0
|
|
369
380
|
def check_ResourceTypeDefinition(o)
|
370
381
|
check_NamedDefinition(o)
|
371
382
|
internal_check_no_capture(o)
|
383
|
+
internal_check_parameter_name_uniqueness(o)
|
372
384
|
internal_check_reserved_params(o)
|
373
385
|
internal_check_no_idem_last(o)
|
374
386
|
end
|
375
387
|
|
376
388
|
def internal_check_no_idem_last(o)
|
377
389
|
if violator = ends_with_idem(o.body)
|
378
|
-
acceptor.accept(Issues::IDEM_NOT_ALLOWED_LAST, violator, {:container => o})
|
390
|
+
acceptor.accept(Issues::IDEM_NOT_ALLOWED_LAST, violator, {:container => o}) unless resource_without_title?(violator)
|
379
391
|
end
|
380
392
|
end
|
381
393
|
|
@@ -409,6 +421,13 @@ class Puppet::Pops::Validation::Checker4_0
|
|
409
421
|
end
|
410
422
|
end
|
411
423
|
|
424
|
+
def internal_check_parameter_name_uniqueness(o)
|
425
|
+
unique = Set.new
|
426
|
+
o.parameters.each do |p|
|
427
|
+
acceptor.accept(Issues::DUPLICATE_PARAMETER, p, {:param_name => p.name}) unless unique.add?(p.name)
|
428
|
+
end
|
429
|
+
end
|
430
|
+
|
412
431
|
def check_IfExpression(o)
|
413
432
|
rvalue(o.test)
|
414
433
|
end
|
@@ -433,7 +452,7 @@ class Puppet::Pops::Validation::Checker4_0
|
|
433
452
|
hostname(o.host_matches, o)
|
434
453
|
top(o.eContainer, o)
|
435
454
|
if violator = ends_with_idem(o.body)
|
436
|
-
acceptor.accept(Issues::IDEM_NOT_ALLOWED_LAST, violator, {:container => o})
|
455
|
+
acceptor.accept(Issues::IDEM_NOT_ALLOWED_LAST, violator, {:container => o}) unless resource_without_title?(violator)
|
437
456
|
end
|
438
457
|
unless o.parent.nil?
|
439
458
|
acceptor.accept(Issues::ILLEGAL_NODE_INHERITANCE, o.parent)
|
@@ -700,8 +719,13 @@ class Puppet::Pops::Validation::Checker4_0
|
|
700
719
|
end
|
701
720
|
|
702
721
|
def top_BlockExpression(o, definition)
|
703
|
-
|
704
|
-
|
722
|
+
if definition.is_a?(Model::FunctionDefinition) && !o.eContainer.is_a?(Model::Program)
|
723
|
+
# not ok if the definition is a FunctionDefinition. It can never be nested in a block
|
724
|
+
acceptor.accept(Issues::NOT_ABSOLUTE_TOP_LEVEL, definition)
|
725
|
+
else
|
726
|
+
# ok, if this is a block representing the body of a class, or is top level
|
727
|
+
top o.eContainer, definition
|
728
|
+
end
|
705
729
|
end
|
706
730
|
|
707
731
|
def top_HostClassDefinition(o, definition)
|
@@ -28,7 +28,7 @@ Puppet::Type.type(:group).provide :windows_adsi do
|
|
28
28
|
specified_users = Puppet::Util::Windows::ADSI::Group.name_sid_hash(should)
|
29
29
|
|
30
30
|
if @resource[:auth_membership]
|
31
|
-
current_users == specified_users
|
31
|
+
current_users.keys.to_a == specified_users.keys.to_a
|
32
32
|
else
|
33
33
|
(specified_users.keys.to_a & current_users.keys.to_a) == specified_users.keys.to_a
|
34
34
|
end
|
@@ -48,7 +48,7 @@ Puppet::Type.type(:group).provide :windows_adsi do
|
|
48
48
|
else
|
49
49
|
account = sid.account
|
50
50
|
end
|
51
|
-
resource.debug("#{sid.domain}\\#{account} (#{sid.
|
51
|
+
resource.debug("#{sid.domain}\\#{account} (#{sid.sid})")
|
52
52
|
"#{sid.domain}\\#{account}"
|
53
53
|
end
|
54
54
|
return users.join(',')
|
@@ -3,6 +3,7 @@
|
|
3
3
|
|
4
4
|
require 'puppet/provider/package'
|
5
5
|
require 'xmlrpc/client'
|
6
|
+
require 'puppet/util/http_proxy'
|
6
7
|
|
7
8
|
Puppet::Type.type(:package).provide :pip,
|
8
9
|
:parent => ::Puppet::Provider::Package do
|
@@ -60,7 +61,16 @@ Puppet::Type.type(:package).provide :pip,
|
|
60
61
|
# cache of PyPI's package list so this operation will always have to
|
61
62
|
# ask the web service.
|
62
63
|
def latest
|
63
|
-
|
64
|
+
http_proxy_host = Puppet::Util::HttpProxy.http_proxy_host
|
65
|
+
http_proxy_port = Puppet::Util::HttpProxy.http_proxy_port
|
66
|
+
if http_proxy_host && http_proxy_port
|
67
|
+
proxy = "#{http_proxy_host}:#{http_proxy_port}"
|
68
|
+
else
|
69
|
+
# nil is acceptable
|
70
|
+
proxy = http_proxy_host
|
71
|
+
end
|
72
|
+
|
73
|
+
client = XMLRPC::Client.new2("http://pypi.python.org/pypi", proxy)
|
64
74
|
client.http_header_extra = {"Content-Type" => "text/xml"}
|
65
75
|
client.timeout = 10
|
66
76
|
result = client.call("package_releases", @resource[:name])
|
@@ -281,7 +281,6 @@ Puppet::Type.type(:package).provide :rpm, :source => :rpm, :parent => Puppet::Pr
|
|
281
281
|
self::NEVRA_FIELDS.zip(match.captures) { |f, v| hash[f] = v }
|
282
282
|
hash[:provider] = self.name
|
283
283
|
hash[:ensure] = "#{hash[:version]}-#{hash[:release]}"
|
284
|
-
hash[:ensure].prepend("#{hash[:epoch]}:") if hash[:epoch] != '0'
|
285
284
|
else
|
286
285
|
Puppet.debug("Failed to match rpm line #{line}")
|
287
286
|
end
|
@@ -80,7 +80,7 @@ Puppet::Type.type(:package).provide :yum, :parent => :rpm, :source => :rpm do
|
|
80
80
|
elsif output.exitstatus == 0
|
81
81
|
self.debug "#{command(:cmd)} check-update exited with 0; no package updates available."
|
82
82
|
else
|
83
|
-
self.
|
83
|
+
self.warning "Could not check for updates, '#{command(:cmd)} check-update' exited with #{output.exitstatus}"
|
84
84
|
end
|
85
85
|
updates
|
86
86
|
end
|
@@ -15,6 +15,7 @@ Puppet::Type.type(:service).provide :debian, :parent => :init do
|
|
15
15
|
# http://projects.reductivelabs.com/issues/2538
|
16
16
|
# is resolved.
|
17
17
|
commands :invoke_rc => "/usr/sbin/invoke-rc.d"
|
18
|
+
commands :service => "/usr/sbin/service"
|
18
19
|
|
19
20
|
defaultfor :operatingsystem => :cumuluslinux
|
20
21
|
defaultfor :operatingsystem => :debian, :operatingsystemmajrelease => ['5','6','7']
|
@@ -65,23 +66,9 @@ Puppet::Type.type(:service).provide :debian, :parent => :init do
|
|
65
66
|
end
|
66
67
|
|
67
68
|
def statuscmd
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
else
|
73
|
-
majversion = Facter.value(:operatingsystemmajrelease).split('.')[0].to_i
|
74
|
-
end
|
75
|
-
|
76
|
-
|
77
|
-
if ((os == 'debian' && majversion >= 8) || (os == 'ubuntu' && majversion >= 15))
|
78
|
-
# SysVInit scripts will always return '0' for status when the service is masked,
|
79
|
-
# even if the service is actually stopped. Use the SysVInit-Systemd compatibility
|
80
|
-
# layer to determine the actual status. This is only necessary when the SysVInit
|
81
|
-
# version of a service is queried. I.e, 'ntp' instead of 'ntp.service'.
|
82
|
-
(@resource[:hasstatus] == :true) && ["systemctl", "is-active", @resource[:name]]
|
83
|
-
else
|
84
|
-
super
|
85
|
-
end
|
69
|
+
# /usr/sbin/service provides an abstraction layer which is able to query services
|
70
|
+
# independent of the init system used.
|
71
|
+
# See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=775795
|
72
|
+
(@resource[:hasstatus] == :true) && [command(:service), @resource[:name], "status"]
|
86
73
|
end
|
87
74
|
end
|
@@ -49,6 +49,13 @@ Puppet::Type.type(:service).provide :init, :parent => :base do
|
|
49
49
|
excludes += %w{wait-for-state portmap-wait}
|
50
50
|
# these excludes were found with grep -r -L start /etc/init.d
|
51
51
|
excludes += %w{rcS module-init-tools}
|
52
|
+
# Prevent puppet failing on unsafe scripts from Yocto Linux
|
53
|
+
if Facter.value(:osfamily) == "cisco-wrlinux"
|
54
|
+
excludes += %w{banner.sh bootmisc.sh checkroot.sh devpts.sh dmesg.sh
|
55
|
+
hostname.sh mountall.sh mountnfs.sh populate-volatile.sh
|
56
|
+
rmnologin.sh save-rtc.sh sendsigs sysfs.sh umountfs
|
57
|
+
umountnfs.sh}
|
58
|
+
end
|
52
59
|
# Prevent puppet failing to get status of the new service introduced
|
53
60
|
# by the fix for this (bug https://bugs.launchpad.net/ubuntu/+source/lightdm/+bug/982889)
|
54
61
|
# due to puppet's inability to deal with upstart services with instances.
|
@@ -193,6 +193,12 @@ Puppet::Type.type(:service).provide :launchd, :parent => :base do
|
|
193
193
|
# Read a plist, whether its format is XML or in Apple's "binary1"
|
194
194
|
# format.
|
195
195
|
def self.read_plist(path)
|
196
|
+
begin
|
197
|
+
return Plist::parse_xml(path)
|
198
|
+
rescue ArgumentError => detail
|
199
|
+
Puppet.debug("Error reading #{path}: #{detail}. Retrying with plutil.")
|
200
|
+
end
|
201
|
+
|
196
202
|
begin
|
197
203
|
Plist::parse_xml(plutil('-convert', 'xml1', '-o', '/dev/stdout', path))
|
198
204
|
rescue Puppet::ExecutionFailure => detail
|
@@ -12,7 +12,7 @@ Puppet::Type.type(:service).provide :systemd, :parent => :base do
|
|
12
12
|
defaultfor :osfamily => :redhat, :operatingsystem => :fedora
|
13
13
|
defaultfor :osfamily => :suse
|
14
14
|
defaultfor :operatingsystem => :debian, :operatingsystemmajrelease => "8"
|
15
|
-
defaultfor :operatingsystem => :ubuntu, :operatingsystemmajrelease => "15.04"
|
15
|
+
defaultfor :operatingsystem => :ubuntu, :operatingsystemmajrelease => ["15.04","15.10"]
|
16
16
|
|
17
17
|
def self.instances
|
18
18
|
i = []
|
@@ -40,7 +40,7 @@ Puppet::Type.type(:user).provide :windows_adsi do
|
|
40
40
|
specified_users = Puppet::Util::Windows::ADSI::Group.name_sid_hash(should)
|
41
41
|
|
42
42
|
if @resource[:membership] == :inclusive
|
43
|
-
current_users == specified_users
|
43
|
+
current_users.keys.to_a == specified_users.keys.to_a
|
44
44
|
else
|
45
45
|
(specified_users.keys.to_a & current_users.keys.to_a) == specified_users.keys.to_a
|
46
46
|
end
|
@@ -55,7 +55,7 @@ Puppet::Type.type(:user).provide :windows_adsi do
|
|
55
55
|
else
|
56
56
|
account = sid.account
|
57
57
|
end
|
58
|
-
resource.debug("#{sid.domain}\\#{account} (#{sid.
|
58
|
+
resource.debug("#{sid.domain}\\#{account} (#{sid.sid})")
|
59
59
|
"#{sid.domain}\\#{account}"
|
60
60
|
end
|
61
61
|
return groups.join(',')
|
@@ -74,9 +74,12 @@ Puppet::Type.type(:yumrepo).provide(:inifile) do
|
|
74
74
|
def self.reposdir(conf='/etc/yum.conf', dirs=['/etc/yum.repos.d', '/etc/yum/repos.d'])
|
75
75
|
reposdir = find_conf_value('reposdir', conf)
|
76
76
|
# Use directories in reposdir if they are set instead of default
|
77
|
-
|
78
|
-
|
79
|
-
|
77
|
+
if reposdir
|
78
|
+
# Follow the code from the yum/config.py
|
79
|
+
dirs = reposdir.gsub!("\n", ' ')
|
80
|
+
dirs = reposdir.gsub!(',', ' ')
|
81
|
+
dirs = reposdir.split
|
82
|
+
end
|
80
83
|
dirs.select! { |dir| Puppet::FileSystem.exist?(dir) }
|
81
84
|
if dirs.empty?
|
82
85
|
Puppet.debug('No yum directories were found on the local filesystem')
|
data/lib/puppet/resource/type.rb
CHANGED
@@ -387,7 +387,8 @@ class Puppet::Resource::Type
|
|
387
387
|
parameters = resource.parameters
|
388
388
|
arguments.each do |param_name, _|
|
389
389
|
name = param_name.to_sym
|
390
|
-
|
390
|
+
param = parameters[name]
|
391
|
+
next unless param.nil? || param.value.nil?
|
391
392
|
value = lookup_external_default_for(param_name, scope)
|
392
393
|
resource[name] = value unless value.nil?
|
393
394
|
end
|
@@ -138,10 +138,10 @@ class Puppet::Transaction::AdditionalResourceGenerator
|
|
138
138
|
def add_generated_directed_dependency(parent, child, label=nil)
|
139
139
|
if parent.depthfirst?
|
140
140
|
source = child
|
141
|
-
target = parent
|
141
|
+
target = parent
|
142
142
|
else
|
143
143
|
source = parent
|
144
|
-
target = child
|
144
|
+
target = child
|
145
145
|
end
|
146
146
|
|
147
147
|
# For each potential relationship metaparam, check if parent or
|
@@ -170,8 +170,22 @@ class Puppet::Transaction::AdditionalResourceGenerator
|
|
170
170
|
}
|
171
171
|
|
172
172
|
if not edge_exists
|
173
|
+
# We *cannot* use target.to_resource here!
|
174
|
+
#
|
175
|
+
# For reasons that are beyond my (and, perhaps, human)
|
176
|
+
# comprehension, to_resource will call retrieve. This is
|
177
|
+
# problematic if a generated resource needs the system to be
|
178
|
+
# changed by a previous resource (think a file on a path
|
179
|
+
# controlled by a mount resource).
|
180
|
+
#
|
181
|
+
# Instead of using to_resource, we just construct a resource as
|
182
|
+
# if the arguments to the Type instance had been passed to a
|
183
|
+
# Resource instead.
|
184
|
+
resource = ::Puppet::Resource.new(target.class, target.title,
|
185
|
+
:parameters => target.original_parameters)
|
186
|
+
|
173
187
|
source[:before] ||= []
|
174
|
-
source[:before] <<
|
188
|
+
source[:before] << resource
|
175
189
|
end
|
176
190
|
end
|
177
191
|
|
data/lib/puppet/type/group.rb
CHANGED
@@ -80,7 +80,9 @@ module Puppet
|
|
80
80
|
|
81
81
|
newproperty(:members, :array_matching => :all, :required_features => :manages_members) do
|
82
82
|
desc "The members of the group. For directory services where group
|
83
|
-
membership is stored in the group objects, not the users.
|
83
|
+
membership is stored in the group objects, not the users. Use
|
84
|
+
with auth_membership to determine whether the specified members
|
85
|
+
are inclusive or the minimum."
|
84
86
|
|
85
87
|
def change_to_s(currentvalue, newvalue)
|
86
88
|
currentvalue = currentvalue.join(",") if currentvalue != :absent
|
@@ -116,7 +118,9 @@ module Puppet
|
|
116
118
|
end
|
117
119
|
|
118
120
|
newparam(:auth_membership, :boolean => true, :parent => Puppet::Parameter::Boolean) do
|
119
|
-
desc "
|
121
|
+
desc "Whether the provider is authoritative for group membership. This
|
122
|
+
must be set to true to allow setting the group to no members with
|
123
|
+
`members => [],`."
|
120
124
|
defaultto false
|
121
125
|
end
|
122
126
|
|
data/lib/puppet/util/windows.rb
CHANGED
@@ -6,6 +6,9 @@ module Puppet::Util::Windows
|
|
6
6
|
end
|
7
7
|
module Registry
|
8
8
|
end
|
9
|
+
module SID
|
10
|
+
class Principal; end
|
11
|
+
end
|
9
12
|
|
10
13
|
if Puppet::Util::Platform.windows?
|
11
14
|
# these reference platform specific gems
|
@@ -14,6 +17,7 @@ module Puppet::Util::Windows
|
|
14
17
|
require 'puppet/util/windows/error'
|
15
18
|
require 'puppet/util/windows/com'
|
16
19
|
require 'puppet/util/windows/sid'
|
20
|
+
require 'puppet/util/windows/principal'
|
17
21
|
require 'puppet/util/windows/file'
|
18
22
|
require 'puppet/util/windows/security'
|
19
23
|
require 'puppet/util/windows/user'
|
@@ -56,21 +56,30 @@ module Puppet::Util::Windows::ADSI
|
|
56
56
|
"winmgmts:{impersonationLevel=impersonate}!//#{host}/root/cimv2"
|
57
57
|
end
|
58
58
|
|
59
|
+
# This method should *only* be used to generate WinNT://<SID> style monikers
|
60
|
+
# used for IAdsGroup::Add / IAdsGroup::Remove. These URIs are not useable
|
61
|
+
# to resolve an account with WIN32OLE.connect
|
62
|
+
# Valid input is a SID::Principal, S-X-X style SID string or any valid
|
63
|
+
# account name with or without domain prefix
|
59
64
|
# @api private
|
60
65
|
def sid_uri_safe(sid)
|
61
|
-
return sid_uri(sid) if sid.kind_of?(
|
66
|
+
return sid_uri(sid) if sid.kind_of?(Puppet::Util::Windows::SID::Principal)
|
62
67
|
|
63
68
|
begin
|
64
|
-
sid =
|
69
|
+
sid = Puppet::Util::Windows::SID.name_to_sid_object(sid)
|
65
70
|
sid_uri(sid)
|
66
|
-
rescue
|
71
|
+
rescue Puppet::Util::Windows::Error, Puppet::Error
|
67
72
|
nil
|
68
73
|
end
|
69
74
|
end
|
70
75
|
|
76
|
+
# This method should *only* be used to generate WinNT://<SID> style monikers
|
77
|
+
# used for IAdsGroup::Add / IAdsGroup::Remove. These URIs are not useable
|
78
|
+
# to resolve an account with WIN32OLE.connect
|
71
79
|
def sid_uri(sid)
|
72
|
-
raise Puppet::Error.new( "Must use a valid SID
|
73
|
-
|
80
|
+
raise Puppet::Error.new( "Must use a valid SID::Principal" ) if !sid.kind_of?(Puppet::Util::Windows::SID::Principal)
|
81
|
+
|
82
|
+
"WinNT://#{sid.sid}"
|
74
83
|
end
|
75
84
|
|
76
85
|
def uri(resource_name, resource_type, host = '.')
|
@@ -99,8 +108,6 @@ module Puppet::Util::Windows::ADSI
|
|
99
108
|
|
100
109
|
module Shared
|
101
110
|
def uri(name, host = '.')
|
102
|
-
if sid_uri = Puppet::Util::Windows::ADSI.sid_uri_safe(name) then return sid_uri end
|
103
|
-
|
104
111
|
host = '.' if ['NT AUTHORITY', 'BUILTIN', Socket.gethostname].include?(host)
|
105
112
|
|
106
113
|
# group or user
|
@@ -136,7 +143,7 @@ module Puppet::Util::Windows::ADSI
|
|
136
143
|
sids = names.map do |name|
|
137
144
|
sid = Puppet::Util::Windows::SID.name_to_sid_object(name)
|
138
145
|
raise Puppet::Error.new( "Could not resolve name: #{name}" ) if !sid
|
139
|
-
[sid.
|
146
|
+
[sid.sid, sid]
|
140
147
|
end
|
141
148
|
|
142
149
|
Hash[ sids ]
|
@@ -247,20 +254,12 @@ module Puppet::Util::Windows::ADSI
|
|
247
254
|
|
248
255
|
|
249
256
|
def add_group_sids(*sids)
|
250
|
-
group_names =
|
251
|
-
sids.each do |sid|
|
252
|
-
group_names << Puppet::Util::Windows::SID.sid_to_name(sid)
|
253
|
-
end
|
254
|
-
|
257
|
+
group_names = sids.map { |s| s.domain_account }
|
255
258
|
add_to_groups(*group_names)
|
256
259
|
end
|
257
260
|
|
258
261
|
def remove_group_sids(*sids)
|
259
|
-
group_names =
|
260
|
-
sids.each do |sid|
|
261
|
-
group_names << Puppet::Util::Windows::SID.sid_to_name(sid)
|
262
|
-
end
|
263
|
-
|
262
|
+
group_names = sids.map { |s| s.domain_account }
|
264
263
|
remove_from_groups(*group_names)
|
265
264
|
end
|
266
265
|
|
@@ -273,7 +272,7 @@ module Puppet::Util::Windows::ADSI
|
|
273
272
|
|
274
273
|
desired_groups = desired_groups.split(',').map(&:strip)
|
275
274
|
|
276
|
-
current_hash = Hash[ self.group_sids.map { |sid| [sid.
|
275
|
+
current_hash = Hash[ self.group_sids.map { |sid| [sid.sid, sid] } ]
|
277
276
|
desired_hash = self.class.name_sid_hash(desired_groups)
|
278
277
|
|
279
278
|
# First we add the user to all the groups it should be in but isn't
|
@@ -321,10 +320,30 @@ module Puppet::Util::Windows::ADSI
|
|
321
320
|
user_name
|
322
321
|
end
|
323
322
|
|
324
|
-
def self.exists?(
|
325
|
-
|
323
|
+
def self.exists?(name_or_sid)
|
324
|
+
well_known = false
|
325
|
+
if (sid = Puppet::Util::Windows::SID.name_to_sid_object(name_or_sid))
|
326
|
+
return true if sid.account_type == :SidTypeUser
|
327
|
+
|
328
|
+
# 'well known group' is special as it can be a group like Everyone OR a user like SYSTEM
|
329
|
+
# so try to resolve it
|
330
|
+
# https://msdn.microsoft.com/en-us/library/cc234477.aspx
|
331
|
+
well_known = sid.account_type == :SidTypeWellKnownGroup
|
332
|
+
return false if sid.account_type != :SidTypeAlias && !well_known
|
333
|
+
name_or_sid = "#{sid.domain}\\#{sid.account}"
|
334
|
+
end
|
335
|
+
|
336
|
+
user = Puppet::Util::Windows::ADSI.connect(User.uri(*User.parse_name(name_or_sid)))
|
337
|
+
# otherwise, verify that the account is actually a User account
|
338
|
+
user.Class == 'User'
|
339
|
+
rescue
|
340
|
+
# special accounts like SYSTEM cannot resolve via moniker like WinNT://./SYSTEM,user
|
341
|
+
# and thus fail to connect - so given a validly resolved SID, this failure is ambiguous as it
|
342
|
+
# may indicate either a group like Service or an account like SYSTEM
|
343
|
+
well_known
|
326
344
|
end
|
327
345
|
|
346
|
+
|
328
347
|
def self.delete(name)
|
329
348
|
Puppet::Util::Windows::ADSI.delete(name, 'user')
|
330
349
|
end
|
@@ -437,7 +456,7 @@ module Puppet::Util::Windows::ADSI
|
|
437
456
|
def set_members(desired_members, inclusive = true)
|
438
457
|
return if desired_members.nil?
|
439
458
|
|
440
|
-
current_hash = Hash[ self.member_sids.map { |sid| [sid.
|
459
|
+
current_hash = Hash[ self.member_sids.map { |sid| [sid.sid, sid] } ]
|
441
460
|
desired_hash = self.class.name_sid_hash(desired_members)
|
442
461
|
|
443
462
|
# First we add all missing members
|
@@ -464,8 +483,26 @@ module Puppet::Util::Windows::ADSI
|
|
464
483
|
new(name, Puppet::Util::Windows::ADSI.create(name, 'group'))
|
465
484
|
end
|
466
485
|
|
467
|
-
def self.exists?(
|
468
|
-
|
486
|
+
def self.exists?(name_or_sid)
|
487
|
+
well_known = false
|
488
|
+
if (sid = Puppet::Util::Windows::SID.name_to_sid_object(name_or_sid))
|
489
|
+
return true if sid.account_type == :SidTypeGroup
|
490
|
+
|
491
|
+
# 'well known group' is special as it can be a group like Everyone OR a user like SYSTEM
|
492
|
+
# so try to resolve it
|
493
|
+
# https://msdn.microsoft.com/en-us/library/cc234477.aspx
|
494
|
+
well_known = sid.account_type == :SidTypeWellKnownGroup
|
495
|
+
return false if sid.account_type != :SidTypeAlias && !well_known
|
496
|
+
name_or_sid = "#{sid.domain}\\#{sid.account}"
|
497
|
+
end
|
498
|
+
|
499
|
+
user = Puppet::Util::Windows::ADSI.connect(Group.uri(*Group.parse_name(name_or_sid)))
|
500
|
+
user.Class == 'Group'
|
501
|
+
rescue
|
502
|
+
# special groups like Authenticated Users cannot resolve via moniker like WinNT://./Authenticated Users,group
|
503
|
+
# and thus fail to connect - so given a validly resolved SID, this failure is ambiguous as it
|
504
|
+
# may indicate either a group like Service or an account like SYSTEM
|
505
|
+
well_known
|
469
506
|
end
|
470
507
|
|
471
508
|
def self.delete(name)
|