puppet 3.5.0.rc1 → 3.5.0.rc2
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 +7 -0
- data/lib/puppet/defaults.rb +3 -2
- data/lib/puppet/indirector/catalog/compiler.rb +7 -1
- data/lib/puppet/parser/scope.rb +3 -0
- data/lib/puppet/pops/evaluator/access_operator.rb +13 -8
- data/lib/puppet/pops/issues.rb +1 -1
- data/lib/puppet/pops/types/type_calculator.rb +25 -45
- data/lib/puppet/pops/types/type_factory.rb +3 -1
- data/lib/puppet/pops/types/types.rb +25 -2
- data/lib/puppet/provider/user/directoryservice.rb +14 -0
- data/lib/puppet/settings.rb +3 -1
- data/lib/puppet/settings/file_or_directory_setting.rb +34 -0
- data/lib/puppet/type/user.rb +5 -2
- data/lib/puppet/version.rb +1 -1
- data/spec/integration/indirector/direct_file_server_spec.rb +20 -23
- data/spec/integration/parser/scope_spec.rb +41 -0
- data/spec/unit/indirector/catalog/compiler_spec.rb +6 -1
- data/spec/unit/pops/evaluator/access_ops_spec.rb +23 -3
- data/spec/unit/pops/types/type_calculator_spec.rb +10 -1
- data/spec/unit/pops/types/type_factory_spec.rb +6 -0
- data/spec/unit/provider/user/directoryservice_spec.rb +45 -4
- data/spec/unit/settings_spec.rb +32 -0
- metadata +2827 -2836
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 325fdbafac6d3a0b58e2c6ed8c297064e9b88151
|
4
|
+
data.tar.gz: d809acbac40afe5fef9f2da786f480f087e80aa3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 22fdb5d7f73a1b55b62900873ef2c0fc53b1645ee04294f1fb26d5024a1c7948ec4d5f367088a0cac41986672f09b09b8e6aecf6c6ada2239b3333f14d5dd378
|
7
|
+
data.tar.gz: eee4ae631b6941dc5545e188211df25d8e7f21a143793eb4627bad65bff15eff854190de45e0f33798dc16d877406e88e58b96afeeddcdea5506de1e1a86fb9b
|
data/lib/puppet/defaults.rb
CHANGED
@@ -870,9 +870,10 @@ EOT
|
|
870
870
|
},
|
871
871
|
:manifest => {
|
872
872
|
:default => "$manifestdir/site.pp",
|
873
|
-
:type => :
|
873
|
+
:type => :file_or_directory,
|
874
874
|
:desc => "The entry-point manifest file for puppet master or a directory of manifests
|
875
|
-
to be evaluated in alphabetical order.
|
875
|
+
to be evaluated in alphabetical order. Puppet manages this path as a directory
|
876
|
+
if it exists or if the path ends with a / or \\.",
|
876
877
|
},
|
877
878
|
:code => {
|
878
879
|
:default => "",
|
@@ -32,7 +32,13 @@ class Puppet::Resource::Catalog::Compiler < Puppet::Indirector::Code
|
|
32
32
|
end
|
33
33
|
|
34
34
|
facts.add_timestamp
|
35
|
-
|
35
|
+
|
36
|
+
options = {
|
37
|
+
:environment => request.environment,
|
38
|
+
:transaction_uuid => request.options[:transaction_uuid],
|
39
|
+
}
|
40
|
+
|
41
|
+
Puppet::Node::Facts.indirection.save(facts, nil, options)
|
36
42
|
end
|
37
43
|
end
|
38
44
|
|
data/lib/puppet/parser/scope.rb
CHANGED
@@ -538,6 +538,9 @@ class Puppet::Parser::Scope
|
|
538
538
|
def to_hash_future(recursive)
|
539
539
|
if recursive and has_enclosing_scope?
|
540
540
|
target = enclosing_scope.to_hash_future(recursive)
|
541
|
+
if !(inherited = inherited_scope).nil?
|
542
|
+
target.merge!(inherited.to_hash_future(recursive))
|
543
|
+
end
|
541
544
|
else
|
542
545
|
target = Hash.new
|
543
546
|
end
|
@@ -73,7 +73,7 @@ class Puppet::Pops::Evaluator::AccessOperator
|
|
73
73
|
def access_PRegexpType(o, scope, keys)
|
74
74
|
keys.flatten!
|
75
75
|
unless keys.size == 1
|
76
|
-
blamed = keys.size == 0 ? @semantic : @semantic.keys[
|
76
|
+
blamed = keys.size == 0 ? @semantic : @semantic.keys[1]
|
77
77
|
fail(Puppet::Pops::Issues::BAD_TYPE_SLICE_ARITY, blamed, :base_type => o, :min=>1, :actual => keys.size)
|
78
78
|
end
|
79
79
|
assert_keys(keys, o, 1, 1, String, Regexp)
|
@@ -214,7 +214,7 @@ class Puppet::Pops::Evaluator::AccessOperator
|
|
214
214
|
def assert_keys(keys, o, min, max, *allowed_classes)
|
215
215
|
size = keys.size
|
216
216
|
unless size.between?(min, max || INFINITY)
|
217
|
-
fail(Puppet::Pops::Issues::BAD_TYPE_SLICE_ARITY,
|
217
|
+
fail(Puppet::Pops::Issues::BAD_TYPE_SLICE_ARITY, @semantic, :base_type => o, :min=>1, :max => max, :actual => keys.size)
|
218
218
|
end
|
219
219
|
keys.each_with_index do |k, i|
|
220
220
|
unless allowed_classes.any? {|clazz| k.is_a?(clazz) }
|
@@ -438,10 +438,12 @@ class Puppet::Pops::Evaluator::AccessOperator
|
|
438
438
|
# Resource[File, 'foo']['bar'] # => Value of the 'bar' parameter in the File['foo'] resource
|
439
439
|
#
|
440
440
|
def access_PResourceType(o, scope, keys)
|
441
|
+
blamed = keys.size == 0 ? @semantic : @semantic.keys[0]
|
441
442
|
keys.flatten!
|
442
443
|
if keys.size == 0
|
443
|
-
|
444
|
-
|
444
|
+
max = o.type_name.nil? ? 2 : 1
|
445
|
+
fail(Puppet::Pops::Issues::BAD_TYPE_SLICE_ARITY, blamed,
|
446
|
+
:base_type => Puppet::Pops::Types::TypeCalculator.new().string(o), :min => 1, :max => max, :actual => 0)
|
445
447
|
end
|
446
448
|
if !o.title.nil?
|
447
449
|
# lookup resource and return one or more parameter values
|
@@ -500,10 +502,12 @@ class Puppet::Pops::Evaluator::AccessOperator
|
|
500
502
|
end
|
501
503
|
|
502
504
|
def access_PHostClassType(o, scope, keys)
|
505
|
+
blamed = keys.size == 0 ? @semantic : @semantic.keys[0]
|
506
|
+
|
503
507
|
keys.flatten!
|
504
508
|
if keys.size == 0
|
505
|
-
fail(Puppet::Pops::Issues::BAD_TYPE_SLICE_ARITY,
|
506
|
-
:base_type => Puppet::Pops::Types::TypeCalculator.new().string(o), :min => 1, :actual => 0)
|
509
|
+
fail(Puppet::Pops::Issues::BAD_TYPE_SLICE_ARITY, blamed,
|
510
|
+
:base_type => Puppet::Pops::Types::TypeCalculator.new().string(o), :min => 1, :max => -1, :actual => 0)
|
507
511
|
end
|
508
512
|
if ! o.class_name.nil?
|
509
513
|
# lookup class resource and return one or more parameter values
|
@@ -531,7 +535,8 @@ class Puppet::Pops::Evaluator::AccessOperator
|
|
531
535
|
result = keys.each_with_index.map do |c, i|
|
532
536
|
ctype = Puppet::Pops::Types::PHostClassType.new()
|
533
537
|
if c.is_a?(Puppet::Pops::Types::PResourceType) && !c.type_name.nil? && c.title.nil?
|
534
|
-
|
538
|
+
# Remove leading '::' since all references are global, and 3x runtime does the wrong thing
|
539
|
+
c = c.type_name.downcase.sub(/^::/, '')
|
535
540
|
end
|
536
541
|
unless c.is_a?(String)
|
537
542
|
fail(Puppet::Pops::Issues::ILLEGAL_HOSTCLASS_NAME, @semantic.keys[i], {:name => c})
|
@@ -539,7 +544,7 @@ class Puppet::Pops::Evaluator::AccessOperator
|
|
539
544
|
if c !~ Puppet::Pops::Patterns::NAME
|
540
545
|
fail(Issues::ILLEGAL_NAME, @semantic.keys[i], {:name=>c})
|
541
546
|
end
|
542
|
-
ctype.class_name = c
|
547
|
+
ctype.class_name = c.downcase.sub(/^::/,'')
|
543
548
|
ctype
|
544
549
|
end
|
545
550
|
# returns single type as type, else an array of types
|
data/lib/puppet/pops/issues.rb
CHANGED
@@ -384,7 +384,7 @@ module Puppet::Pops::Issues
|
|
384
384
|
base_type_label = base_type.is_a?(String) ? base_type : label.a_an_uc(base_type)
|
385
385
|
if max == -1 || max == 1.0 / 0.0 # Infinity
|
386
386
|
"#{base_type_label}[] accepts #{min} or more arguments. Got #{actual}"
|
387
|
-
elsif max
|
387
|
+
elsif max && max != min
|
388
388
|
"#{base_type_label}[] accepts #{min} to #{max} arguments. Got #{actual}"
|
389
389
|
else
|
390
390
|
"#{base_type_label}[] accepts #{min} #{label.plural_s(min, 'argument')}. Got #{actual}"
|
@@ -383,10 +383,8 @@ class Puppet::Pops::Types::TypeCalculator
|
|
383
383
|
def instance_of_PTupleType(t, o)
|
384
384
|
return false unless o.is_a?(Array)
|
385
385
|
# compute the tuple's min/max size, and check if that size matches
|
386
|
-
|
387
|
-
|
388
|
-
size_t.from = t.types.size - 1 + from
|
389
|
-
size_t.to = t.types.size - 1 + to
|
386
|
+
size_t = t.size_type || Puppet::Pops::Types::TypeFactory.range(*t.size_range)
|
387
|
+
|
390
388
|
# compute the array's size as type
|
391
389
|
size_t2 = size_as_type(o)
|
392
390
|
return false unless assignable?(size_t, size_t2)
|
@@ -915,39 +913,27 @@ class Puppet::Pops::Types::TypeCalculator
|
|
915
913
|
end
|
916
914
|
end
|
917
915
|
|
916
|
+
def max(a,b)
|
917
|
+
a >=b ? a : b
|
918
|
+
end
|
919
|
+
|
920
|
+
def min(a,b)
|
921
|
+
a <= b ? a : b
|
922
|
+
end
|
923
|
+
|
918
924
|
def assignable_PTupleType(t, t2)
|
919
925
|
return true if t == t2 || t.types.empty? && (t2.is_a?(Types::PArrayType))
|
920
|
-
|
921
|
-
t_ranged = t.types[-1]
|
922
|
-
t_from, t_to = size_range(t.size_type)
|
923
|
-
t_required = t_regular.size + t_from
|
926
|
+
size_t = t.size_type || Puppet::Pops::Types::TypeFactory.range(*t.size_range)
|
924
927
|
|
925
928
|
if t2.is_a?(Types::PTupleType)
|
926
|
-
|
927
|
-
t2_ranged = t2.types[-1]
|
928
|
-
t2_from, t2_to = size_range(t2.size_type)
|
929
|
-
t2_required = t2_regular.size + t2_from
|
929
|
+
size_t2 = t2.size_type || Puppet::Pops::Types::TypeFactory.range(*t2.size_range)
|
930
930
|
|
931
|
-
#
|
932
|
-
return false
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
t_required.times do |index|
|
937
|
-
t_entry = tuple_entry_at(t, t_from, t_to, index)
|
938
|
-
t2_entry = tuple_entry_at(t2, t2_from, t2_to, index)
|
939
|
-
return false if t2_entry.nil? || !assignable?(t_entry, t2_entry)
|
931
|
+
# not assignable if the number of types in t2 is outside number of types in t1
|
932
|
+
return false unless assignable?(size_t, size_t2)
|
933
|
+
max(t.types.size, t2.types.size).times do |index|
|
934
|
+
return false unless assignable?((t.types[index] || t.types[-1]), (t2.types[index] || t2.types[-1]))
|
940
935
|
end
|
941
|
-
|
942
|
-
(t2_required - t_required).times do |index|
|
943
|
-
t_entry = tuple_entry_at(t, t_from, t_to, t_required + index)
|
944
|
-
t2_entry = tuple_entry_at(t2, t2_from, t2_to, t_required + index)
|
945
|
-
return false if t2_entry.nil? || !assignable?(t_entry, t2_entry)
|
946
|
-
end
|
947
|
-
# Now only a trailing optional type remains - the last type must always be compatible
|
948
|
-
# irrespective of optionality and count
|
949
|
-
#
|
950
|
-
return assignable?(t_ranged, t2_ranged)
|
936
|
+
true
|
951
937
|
|
952
938
|
elsif t2.is_a?(Types::PArrayType)
|
953
939
|
t2_entry = t2.element_type
|
@@ -956,21 +942,15 @@ class Puppet::Pops::Types::TypeCalculator
|
|
956
942
|
# was handled at the top of this method.
|
957
943
|
#
|
958
944
|
return false if t2_entry.nil?
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
min,
|
963
|
-
|
964
|
-
return false if t_required > min
|
965
|
-
# Array with more optionally available entries can not be assigned
|
966
|
-
return false if t_regular.size + t_to < max
|
967
|
-
# each tuple type must be assignable to the element type
|
968
|
-
t_required.times do |index|
|
969
|
-
t_entry = tuple_entry_at(t, t_from, t_to, index)
|
970
|
-
return false unless assignable?(t_entry, t2_entry)
|
945
|
+
size_t = t.size_type || Puppet::Pops::Types::TypeFactory.range(*t.size_range)
|
946
|
+
size_t2 = t2.size_type || @collection_default_size_t
|
947
|
+
return false unless assignable?(size_t, size_t2)
|
948
|
+
min(t.types.size, size_t2.range()[1]).times do |index|
|
949
|
+
return false unless assignable?((t.types[index] || t.types[-1]), t2_entry)
|
971
950
|
end
|
972
|
-
|
973
|
-
|
951
|
+
true
|
952
|
+
else
|
953
|
+
false
|
974
954
|
end
|
975
955
|
end
|
976
956
|
|
@@ -221,7 +221,9 @@ module Puppet::Pops::Types::TypeFactory
|
|
221
221
|
#
|
222
222
|
def self.host_class(class_name = nil)
|
223
223
|
type = Types::PHostClassType.new()
|
224
|
-
|
224
|
+
unless class_name.nil?
|
225
|
+
type.class_name = class_name.sub(/^::/, '')
|
226
|
+
end
|
225
227
|
type
|
226
228
|
end
|
227
229
|
|
@@ -307,10 +307,33 @@ module Puppet::Pops::Types
|
|
307
307
|
# @api public
|
308
308
|
class PTupleType < PObjectType
|
309
309
|
contains_many_uni 'types', PAbstractType, :lowerBound => 1
|
310
|
-
# If set, describes
|
310
|
+
# If set, describes min and max required of the given types - if max > size of
|
311
|
+
# types, the last type entry repeats
|
312
|
+
#
|
311
313
|
contains_one_uni 'size_type', PIntegerType, :lowerBound => 0
|
312
314
|
|
313
315
|
module ClassModule
|
316
|
+
# Returns the number of elements accepted [min, max] in the tuple
|
317
|
+
def size_range
|
318
|
+
types_size = types.size
|
319
|
+
size_type.nil? ? [types_size, types_size] : size_type.range
|
320
|
+
end
|
321
|
+
|
322
|
+
# Returns the number of accepted occurrences [min, max] of the last type in the tuple
|
323
|
+
# The defaults is [1,1]
|
324
|
+
#
|
325
|
+
def repeat_last_range
|
326
|
+
types_size = types.size
|
327
|
+
if size_type.nil?
|
328
|
+
return [1, 1]
|
329
|
+
end
|
330
|
+
from, to = size_type.range()
|
331
|
+
min = from - (types_size-1)
|
332
|
+
min = min <= 0 ? 0 : min
|
333
|
+
max = to - (types_size-1)
|
334
|
+
[min, max]
|
335
|
+
end
|
336
|
+
|
314
337
|
def hash
|
315
338
|
[self.class, size_type, Set.new(types)].hash
|
316
339
|
end
|
@@ -379,7 +402,7 @@ module Puppet::Pops::Types
|
|
379
402
|
# contains_one_uni 'super_type', PHostClassType
|
380
403
|
module ClassModule
|
381
404
|
def hash
|
382
|
-
[self.class,
|
405
|
+
[self.class, class_name].hash
|
383
406
|
end
|
384
407
|
def ==(o)
|
385
408
|
self.class == o.class && class_name == o.class_name
|
@@ -370,6 +370,8 @@ Puppet::Type.type(:user).provide :directoryservice do
|
|
370
370
|
if value.length != 256
|
371
371
|
raise Puppet::Error, "OS X versions > 10.7 require a Salted SHA512 PBKDF2 password hash of 256 characters. Please check your password and try again."
|
372
372
|
end
|
373
|
+
|
374
|
+
assert_full_pbkdf2_password
|
373
375
|
end
|
374
376
|
|
375
377
|
# Methods around setting the password on OS X are the ONLY methods that
|
@@ -405,6 +407,8 @@ Puppet::Type.type(:user).provide :directoryservice do
|
|
405
407
|
# method.
|
406
408
|
def iterations=(value)
|
407
409
|
if (Puppet::Util::Package.versioncmp(self.class.get_os_version, '10.7') > 0)
|
410
|
+
assert_full_pbkdf2_password
|
411
|
+
|
408
412
|
sleep 2
|
409
413
|
flush_dscl_cache
|
410
414
|
users_plist = get_users_plist(@resource.name)
|
@@ -420,6 +424,8 @@ Puppet::Type.type(:user).provide :directoryservice do
|
|
420
424
|
# method.
|
421
425
|
def salt=(value)
|
422
426
|
if (Puppet::Util::Package.versioncmp(self.class.get_os_version, '10.7') > 0)
|
427
|
+
assert_full_pbkdf2_password
|
428
|
+
|
423
429
|
sleep 2
|
424
430
|
flush_dscl_cache
|
425
431
|
users_plist = get_users_plist(@resource.name)
|
@@ -473,6 +479,14 @@ Puppet::Type.type(:user).provide :directoryservice do
|
|
473
479
|
## Helper Methods ##
|
474
480
|
## ##
|
475
481
|
|
482
|
+
def assert_full_pbkdf2_password
|
483
|
+
missing = [:password, :salt, :iterations].select { |parameter| @resource[parameter].nil? }
|
484
|
+
|
485
|
+
if !missing.empty?
|
486
|
+
raise Puppet::Error, "OS X versions > 10\.7 use PBKDF2 password hashes, which requires all three of salt, iterations, and password hash. This resource is missing: #{missing.join(', ')}."
|
487
|
+
end
|
488
|
+
end
|
489
|
+
|
476
490
|
def users_plist_dir
|
477
491
|
'/var/db/dslocal/nodes/Default/users'
|
478
492
|
end
|
data/lib/puppet/settings.rb
CHANGED
@@ -13,6 +13,7 @@ class Puppet::Settings
|
|
13
13
|
require 'puppet/settings/enum_setting'
|
14
14
|
require 'puppet/settings/file_setting'
|
15
15
|
require 'puppet/settings/directory_setting'
|
16
|
+
require 'puppet/settings/file_or_directory_setting'
|
16
17
|
require 'puppet/settings/path_setting'
|
17
18
|
require 'puppet/settings/boolean_setting'
|
18
19
|
require 'puppet/settings/terminus_setting'
|
@@ -639,6 +640,7 @@ class Puppet::Settings
|
|
639
640
|
:string => StringSetting,
|
640
641
|
:file => FileSetting,
|
641
642
|
:directory => DirectorySetting,
|
643
|
+
:file_or_directory => FileOrDirectorySetting,
|
642
644
|
:path => PathSetting,
|
643
645
|
:boolean => BooleanSetting,
|
644
646
|
:terminus => TerminusSetting,
|
@@ -1214,7 +1216,7 @@ Generated on #{Time.now}.
|
|
1214
1216
|
return value unless value.is_a? String
|
1215
1217
|
value.gsub(/\$(\w+)|\$\{(\w+)\}/) do |value|
|
1216
1218
|
varname = $2 || $1
|
1217
|
-
if varname == "environment"
|
1219
|
+
if varname == "environment" && @environment
|
1218
1220
|
@environment
|
1219
1221
|
elsif varname == "run_mode"
|
1220
1222
|
@mode
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class Puppet::Settings::FileOrDirectorySetting < Puppet::Settings::FileSetting
|
2
|
+
|
3
|
+
def initialize(args)
|
4
|
+
super
|
5
|
+
end
|
6
|
+
|
7
|
+
def type
|
8
|
+
if Puppet::FileSystem.directory?(self.value) || @path_ends_with_slash
|
9
|
+
:directory
|
10
|
+
else
|
11
|
+
:file
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# Overrides munge to be able to read the un-munged value (the FileSetting.munch removes trailing slash)
|
16
|
+
#
|
17
|
+
def munge(value)
|
18
|
+
if value.is_a?(String) && value =~ /[\\\/]$/
|
19
|
+
@path_ends_with_slash = true
|
20
|
+
end
|
21
|
+
super
|
22
|
+
end
|
23
|
+
|
24
|
+
# @api private
|
25
|
+
def open_file(filename, option = 'r', &block)
|
26
|
+
if type == :file
|
27
|
+
super
|
28
|
+
else
|
29
|
+
controlled_access do |mode|
|
30
|
+
Puppet::FileSystem.open(filename, mode, option, &block)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/puppet/type/user.rb
CHANGED
@@ -189,6 +189,9 @@ module Puppet
|
|
189
189
|
* Mac OS X 10.7 (Lion) uses salted SHA512 hashes. The Puppet Labs [stdlib][]
|
190
190
|
module contains a `str2saltedsha512` function which can generate password
|
191
191
|
hashes for Lion.
|
192
|
+
* Mac OS X 10.8 and higher use salted SHA512 PBKDF2 hashes. When
|
193
|
+
managing passwords on these systems the salt and iterations properties
|
194
|
+
need to be specified as well as the password.
|
192
195
|
* Windows passwords can only be managed in cleartext, as there is no Windows API
|
193
196
|
for setting the password hash.
|
194
197
|
|
@@ -544,13 +547,13 @@ module Puppet
|
|
544
547
|
|
545
548
|
newproperty(:salt, :required_features => :manages_password_salt) do
|
546
549
|
desc "This is the 32 byte salt used to generate the PBKDF2 password used in
|
547
|
-
OS X"
|
550
|
+
OS X. This field is required for managing passwords on OS X >= 10.8."
|
548
551
|
end
|
549
552
|
|
550
553
|
newproperty(:iterations, :required_features => :manages_password_salt) do
|
551
554
|
desc "This is the number of iterations of a chained computation of the
|
552
555
|
password hash (http://en.wikipedia.org/wiki/PBKDF2). This parameter
|
553
|
-
is used in OS X"
|
556
|
+
is used in OS X. This field is required for managing passwords on OS X >= 10.8."
|
554
557
|
|
555
558
|
munge do |value|
|
556
559
|
if value.is_a?(String) and value =~/^[-0-9]+$/
|
data/lib/puppet/version.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
#! /usr/bin/env ruby
|
2
1
|
require 'spec_helper'
|
2
|
+
require 'matchers/include'
|
3
3
|
|
4
4
|
require 'puppet/indirector/file_content/file'
|
5
5
|
|
@@ -34,34 +34,31 @@ end
|
|
34
34
|
|
35
35
|
describe Puppet::Indirector::DirectFileServer, " when interacting with FileServing::Fileset and the model" do
|
36
36
|
include PuppetSpec::Files
|
37
|
+
include Matchers::Include
|
37
38
|
|
38
|
-
|
39
|
+
matcher :file_with_content do |name, content|
|
40
|
+
match do |actual|
|
41
|
+
actual.full_path == name && actual.content == content
|
42
|
+
end
|
43
|
+
end
|
39
44
|
|
40
|
-
|
41
|
-
|
45
|
+
matcher :directory_named do |name|
|
46
|
+
match do |actual|
|
47
|
+
actual.full_path == name
|
48
|
+
end
|
49
|
+
end
|
42
50
|
|
51
|
+
it "should return an instance for every file in the fileset" do
|
52
|
+
path = tmpdir('direct_file_server_testing')
|
43
53
|
File.open(File.join(path, "one"), "w") { |f| f.print "one content" }
|
44
54
|
File.open(File.join(path, "two"), "w") { |f| f.print "two content" }
|
45
55
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
it "should return an instance for every file in the fileset" do
|
50
|
-
result = @terminus.search(@request)
|
51
|
-
result.should be_instance_of(Array)
|
52
|
-
result.length.should == 3
|
53
|
-
result.each { |r| r.should be_instance_of(Puppet::FileServing::Content) }
|
54
|
-
end
|
56
|
+
terminus = Puppet::Indirector::FileContent::File.new
|
57
|
+
request = terminus.indirection.request(:search, "file:///#{path}", nil, :recurse => true)
|
55
58
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
when /two/; instance.content.should == "two content"
|
61
|
-
when path
|
62
|
-
else
|
63
|
-
raise "No valid key for #{instance.path.inspect}"
|
64
|
-
end
|
65
|
-
end
|
59
|
+
expect(terminus.search(request)).to include_in_any_order(
|
60
|
+
file_with_content(File.join(path, "one"), "one content"),
|
61
|
+
file_with_content(File.join(path, "two"), "two content"),
|
62
|
+
directory_named(path))
|
66
63
|
end
|
67
64
|
end
|