puppet 4.0.0 → 4.1.0

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.

Files changed (219) hide show
  1. checksums.yaml +4 -4
  2. data/ext/build_defaults.yaml +8 -35
  3. data/ext/debian/puppet.default +0 -5
  4. data/ext/debian/puppet.init +1 -15
  5. data/lib/hiera/puppet_function.rb +15 -4
  6. data/lib/puppet/application/agent.rb +5 -0
  7. data/lib/puppet/application/apply.rb +23 -2
  8. data/lib/puppet/application/device.rb +8 -3
  9. data/lib/puppet/application/master.rb +16 -5
  10. data/lib/puppet/configurer.rb +7 -5
  11. data/lib/puppet/defaults.rb +18 -0
  12. data/lib/puppet/environments.rb +1 -1
  13. data/lib/puppet/error.rb +27 -1
  14. data/lib/puppet/file_serving/metadata.rb +13 -8
  15. data/lib/puppet/file_serving/terminus_helper.rb +7 -8
  16. data/lib/puppet/file_system.rb +13 -0
  17. data/lib/puppet/file_system/file_impl.rb +4 -0
  18. data/lib/puppet/file_system/memory_impl.rb +4 -0
  19. data/lib/puppet/file_system/windows.rb +8 -0
  20. data/lib/puppet/functions.rb +33 -3
  21. data/lib/puppet/functions/defined.rb +130 -0
  22. data/lib/puppet/functions/regsubst.rb +1 -1
  23. data/lib/puppet/functions/split.rb +1 -1
  24. data/lib/puppet/indirector/catalog/compiler.rb +1 -1
  25. data/lib/puppet/indirector/facts/facter.rb +11 -0
  26. data/lib/puppet/loaders.rb +1 -0
  27. data/lib/puppet/node.rb +17 -1
  28. data/lib/puppet/node/environment.rb +4 -0
  29. data/lib/puppet/parser/ast/pops_bridge.rb +4 -0
  30. data/lib/puppet/parser/compiler.rb +9 -0
  31. data/lib/puppet/parser/functions/defined.rb +25 -1
  32. data/lib/puppet/parser/functions/file.rb +3 -1
  33. data/lib/puppet/parser/scope.rb +11 -2
  34. data/lib/puppet/parser/templatewrapper.rb +2 -1
  35. data/lib/puppet/pops.rb +4 -0
  36. data/lib/puppet/pops/evaluator/access_operator.rb +25 -5
  37. data/lib/puppet/pops/evaluator/closure.rb +28 -2
  38. data/lib/puppet/pops/evaluator/collector_transformer.rb +1 -11
  39. data/lib/puppet/pops/evaluator/collectors/catalog_collector.rb +4 -0
  40. data/lib/puppet/pops/evaluator/collectors/exported_collector.rb +4 -0
  41. data/lib/puppet/pops/evaluator/compare_operator.rb +43 -0
  42. data/lib/puppet/pops/evaluator/epp_evaluator.rb +7 -2
  43. data/lib/puppet/pops/evaluator/evaluator_impl.rb +48 -14
  44. data/lib/puppet/pops/evaluator/runtime3_support.rb +10 -5
  45. data/lib/puppet/pops/functions/dispatch.rb +6 -1
  46. data/lib/puppet/pops/functions/dispatcher.rb +7 -1
  47. data/lib/puppet/pops/issue_reporter.rb +42 -16
  48. data/lib/puppet/pops/issues.rb +116 -2
  49. data/lib/puppet/pops/loader/loader.rb +11 -0
  50. data/lib/puppet/pops/loader/loader_paths.rb +67 -6
  51. data/lib/puppet/pops/loader/module_loaders.rb +19 -8
  52. data/lib/puppet/pops/loader/puppet_function_instantiator.rb +78 -0
  53. data/lib/puppet/pops/loaders.rb +6 -4
  54. data/lib/puppet/pops/migration/migration_checker.rb +54 -0
  55. data/lib/puppet/pops/model/factory.rb +5 -1
  56. data/lib/puppet/pops/model/model_label_provider.rb +2 -0
  57. data/lib/puppet/pops/model/model_meta.rb +5 -1
  58. data/lib/puppet/pops/parser/egrammar.ra +9 -10
  59. data/lib/puppet/pops/parser/eparser.rb +1061 -1047
  60. data/lib/puppet/pops/parser/epp_support.rb +18 -9
  61. data/lib/puppet/pops/parser/evaluating_parser.rb +7 -1
  62. data/lib/puppet/pops/parser/heredoc_support.rb +12 -11
  63. data/lib/puppet/pops/parser/interpolation_support.rb +7 -1
  64. data/lib/puppet/pops/parser/lexer2.rb +29 -12
  65. data/lib/puppet/pops/parser/lexer_support.rb +52 -23
  66. data/lib/puppet/pops/parser/parser_support.rb +11 -14
  67. data/lib/puppet/pops/parser/slurp_support.rb +22 -6
  68. data/lib/puppet/pops/types/type_calculator.rb +156 -55
  69. data/lib/puppet/pops/types/type_factory.rb +66 -13
  70. data/lib/puppet/pops/types/type_parser.rb +22 -13
  71. data/lib/puppet/pops/types/types.rb +23 -4
  72. data/lib/puppet/pops/types/types_meta.rb +13 -2
  73. data/lib/puppet/pops/validation.rb +25 -2
  74. data/lib/puppet/pops/validation/checker4_0.rb +63 -31
  75. data/lib/puppet/provider/group/windows_adsi.rb +8 -4
  76. data/lib/puppet/provider/mount/parsed.rb +145 -2
  77. data/lib/puppet/provider/package/apt.rb +1 -1
  78. data/lib/puppet/provider/package/pip.rb +11 -2
  79. data/lib/puppet/provider/package/pkgng.rb +134 -0
  80. data/lib/puppet/provider/package/portage.rb +1 -1
  81. data/lib/puppet/provider/package/ports.rb +0 -3
  82. data/lib/puppet/provider/package/windows/exe_package.rb +0 -1
  83. data/lib/puppet/provider/package/windows/msi_package.rb +0 -1
  84. data/lib/puppet/provider/package/zypper.rb +50 -15
  85. data/lib/puppet/provider/scheduled_task/win32_taskscheduler.rb +32 -7
  86. data/lib/puppet/provider/service/debian.rb +1 -1
  87. data/lib/puppet/provider/service/init.rb +7 -0
  88. data/lib/puppet/provider/user/openbsd.rb +1 -0
  89. data/lib/puppet/provider/user/windows_adsi.rb +45 -2
  90. data/lib/puppet/reference/indirection.rb +1 -1
  91. data/lib/puppet/resource.rb +1 -1
  92. data/lib/puppet/resource/catalog.rb +0 -4
  93. data/lib/puppet/settings.rb +19 -0
  94. data/lib/puppet/type/file.rb +1 -0
  95. data/lib/puppet/type/file/ensure.rb +1 -1
  96. data/lib/puppet/type/mount.rb +9 -1
  97. data/lib/puppet/type/scheduled_task.rb +13 -0
  98. data/lib/puppet/type/tidy.rb +3 -1
  99. data/lib/puppet/type/user.rb +32 -0
  100. data/lib/puppet/type/yumrepo.rb +5 -5
  101. data/lib/puppet/util/log.rb +50 -8
  102. data/lib/puppet/util/log/destinations.rb +23 -2
  103. data/lib/puppet/util/logging.rb +37 -1
  104. data/lib/puppet/util/run_mode.rb +1 -14
  105. data/lib/puppet/util/windows/adsi.rb +130 -58
  106. data/lib/puppet/version.rb +1 -1
  107. data/man/man5/puppet.conf.5 +48 -6
  108. data/man/man8/extlookup2hiera.8 +1 -1
  109. data/man/man8/puppet-agent.8 +4 -1
  110. data/man/man8/puppet-apply.8 +4 -1
  111. data/man/man8/puppet-ca.8 +1 -1
  112. data/man/man8/puppet-catalog.8 +1 -1
  113. data/man/man8/puppet-cert.8 +1 -1
  114. data/man/man8/puppet-certificate.8 +1 -1
  115. data/man/man8/puppet-certificate_request.8 +1 -1
  116. data/man/man8/puppet-certificate_revocation_list.8 +1 -1
  117. data/man/man8/puppet-config.8 +1 -1
  118. data/man/man8/puppet-describe.8 +1 -1
  119. data/man/man8/puppet-device.8 +6 -3
  120. data/man/man8/puppet-doc.8 +1 -1
  121. data/man/man8/puppet-epp.8 +1 -1
  122. data/man/man8/puppet-facts.8 +1 -1
  123. data/man/man8/puppet-file.8 +1 -1
  124. data/man/man8/puppet-filebucket.8 +1 -1
  125. data/man/man8/puppet-help.8 +1 -1
  126. data/man/man8/puppet-inspect.8 +1 -1
  127. data/man/man8/puppet-key.8 +1 -1
  128. data/man/man8/puppet-man.8 +1 -1
  129. data/man/man8/puppet-master.8 +4 -1
  130. data/man/man8/puppet-module.8 +1 -1
  131. data/man/man8/puppet-node.8 +1 -1
  132. data/man/man8/puppet-parser.8 +1 -1
  133. data/man/man8/puppet-plugin.8 +1 -1
  134. data/man/man8/puppet-report.8 +1 -1
  135. data/man/man8/puppet-resource.8 +1 -1
  136. data/man/man8/puppet-resource_type.8 +1 -1
  137. data/man/man8/puppet-status.8 +1 -1
  138. data/man/man8/puppet.8 +1 -1
  139. data/spec/fixtures/unit/data_providers/environments/production/lib/puppet/functions/environment/data.rb +3 -1
  140. data/spec/fixtures/unit/data_providers/environments/production/modules/xyz/functions/data.pp +6 -0
  141. data/spec/fixtures/unit/data_providers/environments/production/modules/xyz/lib/puppet/bindings/xyz/default.rb +9 -0
  142. data/spec/fixtures/unit/data_providers/environments/production/modules/xyz/manifests/init.pp +9 -0
  143. data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/user/functions/puppetcalled.pp +3 -0
  144. data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/user/functions/puppetcaller.pp +3 -0
  145. data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/user/functions/puppetcaller4.pp +3 -0
  146. data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/user/lib/puppet/functions/user/callingpuppet.rb +5 -0
  147. data/spec/fixtures/unit/pops/loaders/loaders/module_no_lib/modules/modulea/functions/hello.pp +3 -0
  148. data/spec/fixtures/unit/pops/loaders/loaders/module_no_lib/modules/modulea/manifests/init.pp +3 -0
  149. data/spec/fixtures/unit/pops/loaders/loaders/module_no_lib/modules/modulea/metadata.json +10 -0
  150. data/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/functions/hello.pp +3 -0
  151. data/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/functions/subspace/hello.pp +3 -0
  152. data/spec/fixtures/unit/pops/loaders/loaders/single_module/modules/modulea/metadata.json +1 -10
  153. data/spec/fixtures/unit/provider/mount/parsed/aix.filesystems +93 -85
  154. data/spec/fixtures/unit/provider/mount/parsed/aix.mount +11 -7
  155. data/spec/fixtures/unit/provider/package/pkgng/pkg.info +8 -0
  156. data/spec/fixtures/unit/provider/package/pkgng/pkg.query +1 -0
  157. data/spec/fixtures/unit/provider/package/pkgng/pkg.query_absent +1 -0
  158. data/spec/fixtures/unit/provider/package/pkgng/pkg.version +3 -0
  159. data/spec/fixtures/unit/provider/package/zypper/zypper-list-updates-empty.out +3 -0
  160. data/spec/integration/application/apply_spec.rb +49 -0
  161. data/spec/integration/faces/plugin_spec.rb +0 -4
  162. data/spec/integration/indirector/facts/facter_spec.rb +59 -0
  163. data/spec/integration/parser/compiler_spec.rb +850 -0
  164. data/spec/integration/parser/resource_expressions_spec.rb +3 -0
  165. data/spec/integration/parser/scope_spec.rb +26 -5
  166. data/spec/integration/transaction_spec.rb +1 -1
  167. data/spec/integration/type/file_spec.rb +318 -41
  168. data/spec/integration/util/windows/security_spec.rb +14 -5
  169. data/spec/lib/matchers/resource.rb +22 -1
  170. data/spec/lib/puppet_spec/matchers.rb +6 -4
  171. data/spec/unit/application/master_spec.rb +33 -7
  172. data/spec/unit/data_providers/function_data_provider_spec.rb +10 -1
  173. data/spec/unit/file_serving/metadata_spec.rb +1 -1
  174. data/spec/unit/file_serving/terminus_helper_spec.rb +2 -3
  175. data/spec/unit/file_system_spec.rb +38 -0
  176. data/spec/unit/functions/defined_spec.rb +289 -0
  177. data/spec/unit/functions/hiera_spec.rb +8 -6
  178. data/spec/unit/functions/regsubst_spec.rb +4 -0
  179. data/spec/unit/functions/split_spec.rb +8 -0
  180. data/spec/unit/functions4_spec.rb +97 -2
  181. data/spec/unit/indirector/facts/facter_spec.rb +7 -0
  182. data/spec/unit/node_spec.rb +6 -0
  183. data/spec/unit/parser/functions/file_spec.rb +7 -1
  184. data/spec/unit/parser/functions/template_spec.rb +1 -1
  185. data/spec/unit/parser/scope_spec.rb +2 -2
  186. data/spec/unit/parser/templatewrapper_spec.rb +1 -1
  187. data/spec/unit/pops/evaluator/access_ops_spec.rb +19 -0
  188. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +84 -18
  189. data/spec/unit/pops/evaluator/variables_spec.rb +1 -1
  190. data/spec/unit/pops/issues_spec.rb +16 -16
  191. data/spec/unit/pops/loaders/loaders_spec.rb +106 -48
  192. data/spec/unit/pops/migration_spec.rb +53 -0
  193. data/spec/unit/pops/parser/lexer2_spec.rb +142 -1
  194. data/spec/unit/pops/parser/parse_heredoc_spec.rb +26 -0
  195. data/spec/unit/pops/types/type_calculator_spec.rb +205 -12
  196. data/spec/unit/pops/validation_spec.rb +66 -0
  197. data/spec/unit/pops/validator/validator_spec.rb +1 -1
  198. data/spec/unit/provider/group/windows_adsi_spec.rb +57 -9
  199. data/spec/unit/provider/mount/parsed_spec.rb +31 -5
  200. data/spec/unit/provider/package/apt_spec.rb +5 -0
  201. data/spec/unit/provider/package/pip_spec.rb +9 -0
  202. data/spec/unit/provider/package/pkgng_spec.rb +172 -0
  203. data/spec/unit/provider/package/windows/exe_package_spec.rb +0 -1
  204. data/spec/unit/provider/package/windows/msi_package_spec.rb +0 -1
  205. data/spec/unit/provider/package/zypper_spec.rb +50 -19
  206. data/spec/unit/provider/scheduled_task/win32_taskscheduler_spec.rb +312 -70
  207. data/spec/unit/provider/service/base_spec.rb +38 -27
  208. data/spec/unit/provider/service/debian_spec.rb +8 -0
  209. data/spec/unit/provider/service/freebsd_spec.rb +1 -0
  210. data/spec/unit/provider/service/gentoo_spec.rb +1 -0
  211. data/spec/unit/provider/service/init_spec.rb +18 -0
  212. data/spec/unit/provider/service/openbsd_spec.rb +1 -0
  213. data/spec/unit/provider/service/redhat_spec.rb +1 -0
  214. data/spec/unit/provider/user/windows_adsi_spec.rb +134 -5
  215. data/spec/unit/settings_spec.rb +11 -0
  216. data/spec/unit/util/log_spec.rb +113 -0
  217. data/spec/unit/util/windows/adsi_spec.rb +135 -41
  218. data/spec/unit/util/windows/sid_spec.rb +0 -10
  219. metadata +48 -2
@@ -126,6 +126,19 @@ module Puppet::FileSystem
126
126
  @impl.read(assert_path(path))
127
127
  end
128
128
 
129
+ # Read a file keeping the original line endings intact. This
130
+ # attempts to open files using binary mode using some encoding
131
+ # overrides and falling back to IO.read when none of the
132
+ # encodings are valid.
133
+ #
134
+ # @return [String] The contents of the file
135
+ #
136
+ # @api public
137
+ #
138
+ def self.read_preserve_line_endings(path)
139
+ @impl.read_preserve_line_endings(assert_path(path))
140
+ end
141
+
129
142
  # @return [String] The binary contents of the file
130
143
  #
131
144
  # @api public
@@ -75,6 +75,10 @@ class Puppet::FileSystem::FileImpl
75
75
  path.read
76
76
  end
77
77
 
78
+ def read_preserve_line_endings(path)
79
+ read(path)
80
+ end
81
+
78
82
  def binread(path)
79
83
  raise NotImplementedError
80
84
  end
@@ -44,6 +44,10 @@ class Puppet::FileSystem::MemoryImpl
44
44
  handle.read
45
45
  end
46
46
 
47
+ def read_preserve_line_endings(path)
48
+ read(path)
49
+ end
50
+
47
51
  def open(path, *args, &block)
48
52
  handle = assert_path(path).handle
49
53
  if block_given?
@@ -91,6 +91,14 @@ class Puppet::FileSystem::Windows < Puppet::FileSystem::Posix
91
91
  Puppet::Util::Windows::Security.set_mode(mode, path.to_s)
92
92
  end
93
93
 
94
+ def read_preserve_line_endings(path)
95
+ contents = path.read( :mode => 'rb', :encoding => Encoding::UTF_8)
96
+ contents = path.read( :mode => 'rb', :encoding => Encoding::default_external) unless contents.valid_encoding?
97
+ contents = path.read unless contents.valid_encoding?
98
+
99
+ contents
100
+ end
101
+
94
102
  private
95
103
 
96
104
  def raise_if_symlinks_unsupported
@@ -256,6 +256,14 @@ module Puppet::Functions
256
256
  end
257
257
  end
258
258
 
259
+ # Base class for all functions implemented in the puppet language
260
+ class PuppetFunction < Function
261
+ def self.init_dispatch(a_closure)
262
+ # A closure is compatible with a dispatcher - they are both callable signatures
263
+ dispatcher.add(a_closure)
264
+ end
265
+ end
266
+
259
267
  # Public api methods of the DispatcherBuilder are available within dispatch()
260
268
  # blocks declared in a Puppet::Function.create_function() call.
261
269
  #
@@ -311,7 +319,25 @@ module Puppet::Functions
311
319
  #
312
320
  # @api public
313
321
  def repeated_param(type, name)
314
- internal_param(type, name)
322
+ internal_param(type, name, true)
323
+ @max = :default
324
+ end
325
+ alias optional_repeated_param repeated_param
326
+
327
+ # Defines a repeated positional parameter with _type_ and _name_ that may occur 1 to "infinite" number of times.
328
+ # It may only appear last or just before a block parameter.
329
+ #
330
+ # @param type [String] The type specification for the parameter.
331
+ # @param name [Symbol] The name of the parameter. This is primarily used
332
+ # for error message output and does not have to match an implementation
333
+ # method parameter.
334
+ # @return [Void]
335
+ #
336
+ # @api public
337
+ def required_repeated_param(type, name)
338
+ internal_param(type, name, true)
339
+ raise ArgumentError, 'A required repeated parameter cannot be added after an optional parameter' if @min != @max
340
+ @min += 1
315
341
  @max = :default
316
342
  end
317
343
 
@@ -368,7 +394,7 @@ module Puppet::Functions
368
394
  private
369
395
 
370
396
  # @api private
371
- def internal_param(type, name)
397
+ def internal_param(type, name, repeat = false)
372
398
  raise ArgumentError, 'Parameters cannot be added after a block parameter' unless @block_type.nil?
373
399
  raise ArgumentError, 'Parameters cannot be added after a repeated parameter' if @max == :default
374
400
 
@@ -380,7 +406,11 @@ module Puppet::Functions
380
406
  @types << type
381
407
  @names << name
382
408
  # mark what should be picked for this position when dispatching
383
- @weaving << @names.size()-1
409
+ if repeat
410
+ @weaving << -@names.size()
411
+ else
412
+ @weaving << @names.size()-1
413
+ end
384
414
  else
385
415
  raise ArgumentError, "Parameter 'type' must be a String reference to a Puppet Data Type. Got #{type.class}"
386
416
  end
@@ -0,0 +1,130 @@
1
+ # Determines whether
2
+ # a given class or resource type is defined. This function can also determine whether a
3
+ # specific resource has been declared, or whether a variable has been assigned a value
4
+ # (including undef...as opposed to never having been assigned anything). Returns true
5
+ # or false. Accepts class names, type names, resource references, and variable
6
+ # reference strings of the form '$name'. When more than one argument is
7
+ # supplied, defined() returns true if any are defined.
8
+ #
9
+ # The `defined` function checks both native and defined types, including types
10
+ # provided as plugins via modules. Types and classes are both checked using their names:
11
+ #
12
+ # defined("file")
13
+ # defined("customtype")
14
+ # defined("foo")
15
+ # defined("foo::bar")
16
+ # defined('$name')
17
+ #
18
+ # Resource declarations are checked using resource references, e.g.
19
+ # `defined( File['/tmp/myfile'] )`, or `defined( Class[myclass] )`.
20
+ # Checking whether a given resource
21
+ # has been declared is, unfortunately, dependent on the evaluation order of
22
+ # the configuration, and the following code will not work:
23
+ #
24
+ # if defined(File['/tmp/foo']) {
25
+ # notify { "This configuration includes the /tmp/foo file.":}
26
+ # }
27
+ # file { "/tmp/foo":
28
+ # ensure => present,
29
+ # }
30
+ #
31
+ # However, this order requirement refers to evaluation order only, and ordering of
32
+ # resources in the configuration graph (e.g. with `before` or `require`) does not
33
+ # affect the behavior of `defined`.
34
+ #
35
+ # You may also search using types:
36
+ #
37
+ # defined(Resource['file','/some/file'])
38
+ # defined(File['/some/file'])
39
+ # defined(Class['foo'])
40
+ #
41
+ # The `defined` function does not answer if data types (e.g. `Integer`) are defined. If
42
+ # given the string 'integer' the result is false, and if given a non CatalogEntry type,
43
+ # an error is raised.
44
+ #
45
+ # The rules for asking for undef, empty strings, and the main class are different from 3.x
46
+ # (non future parser) and 4.x (with future parser or in Puppet 4.0.0 and later):
47
+ #
48
+ # defined('') # 3.x => true, 4.x => false
49
+ # defined(undef) # 3.x => true, 4.x => error
50
+ # defined('main') # 3.x => false, 4.x => true
51
+ #
52
+ # With the future parser, it is also possible to ask specifically if a name is
53
+ # a resource type (built in or defined), or a class, by giving its type:
54
+ #
55
+ # defined(Type[Class['foo']])
56
+ # defined(Type[Resource['foo']])
57
+ #
58
+ # Which is different from asking:
59
+ #
60
+ # defined('foo')
61
+ #
62
+ # Since the later returns true if 'foo' is either a class, a built-in resource type, or a user defined
63
+ # resource type, and a specific request like `Type[Class['foo']]` only returns true if `'foo'` is a class.
64
+ #
65
+ # @since 2.7.0
66
+ # @since 3.6.0 variable reference and future parser types")
67
+ # @since 3.8.1 type specific requests with future parser
68
+ #
69
+ Puppet::Functions.create_function(:'defined', Puppet::Functions::InternalFunction) do
70
+
71
+ dispatch :is_defined do
72
+ scope_param
73
+ required_repeated_param 'Variant[String, Type[CatalogEntry], Type[Type[CatalogEntry]]]', :vals
74
+ end
75
+
76
+ def is_defined(scope, *vals)
77
+ vals.any? do |val|
78
+ case val
79
+ when String
80
+ if val =~ /^\$(.+)$/
81
+ scope.exist?($1)
82
+ else
83
+ case val
84
+ when ''
85
+ next nil
86
+ when 'main'
87
+ # Find the main class (known as ''), it does not have to be in the catalog
88
+ scope.find_hostclass('')
89
+ else
90
+ # Find a resource type, definition or class definition
91
+ scope.find_resource_type(val) || scope.find_definition(val) || scope.find_hostclass(val)
92
+ #scope.compiler.findresource(:class, val)
93
+ end
94
+ end
95
+ when Puppet::Resource
96
+ # Find instance of given resource type and title that is in the catalog
97
+ scope.compiler.findresource(val.type, val.title)
98
+
99
+ when Puppet::Pops::Types::PResourceType
100
+ raise ArgumentError, 'The given resource type is a reference to all kind of types' if val.type_name.nil?
101
+ if val.title.nil?
102
+ scope.find_builtin_resource_type(val.type_name) || scope.find_definition(val.type_name)
103
+ else
104
+ scope.compiler.findresource(val.type_name, val.title)
105
+ end
106
+
107
+ when Puppet::Pops::Types::PHostClassType
108
+ raise ArgumentError, 'The given class type is a reference to all classes' if val.class_name.nil?
109
+ scope.compiler.findresource(:class, val.class_name)
110
+
111
+ when Puppet::Pops::Types::PType
112
+ case val.type
113
+ when Puppet::Pops::Types::PResourceType
114
+ # It is most reasonable to take Type[File] and Type[File[foo]] to mean the same as if not wrapped in a Type
115
+ # Since the difference between File and File[foo] already captures the distinction of type vs instance.
116
+ is_defined(scope, val.type)
117
+
118
+ when Puppet::Pops::Types::PHostClassType
119
+ # Interpreted as asking if a class (and nothing else) is defined without having to be included in the catalog
120
+ # (this is the same as asking for just the class' name, but with the added certainty that it cannot be a defined type.
121
+ #
122
+ raise ArgumentError, 'The given class type is a reference to all classes' if val.type.class_name.nil?
123
+ scope.find_hostclass(val.type.class_name)
124
+ end
125
+ else
126
+ raise ArgumentError, "Invalid argument of type '#{val.class}' to 'defined'"
127
+ end
128
+ end
129
+ end
130
+ end
@@ -68,7 +68,7 @@ Puppet::Functions.create_function(:regsubst) do
68
68
  end
69
69
 
70
70
  def regsubst_regexp(target, pattern, replacement, flags = nil)
71
- pattern = pattern.pattern if pattern.is_a?(Puppet::Pops::Types::PRegexpType)
71
+ pattern = (pattern.pattern || '') if pattern.is_a?(Puppet::Pops::Types::PRegexpType)
72
72
  inner_regsubst(target, pattern, replacement, operation = flags == 'G' ? :gsub : :sub)
73
73
  end
74
74
 
@@ -42,6 +42,6 @@ Puppet::Functions.create_function(:split) do
42
42
  end
43
43
 
44
44
  def split_RegexpType(str, pattern)
45
- str.split(pattern.pattern)
45
+ str.split(pattern.regexp)
46
46
  end
47
47
  end
@@ -78,7 +78,7 @@ class Puppet::Resource::Catalog::Compiler < Puppet::Indirector::Code
78
78
  # Add any extra data necessary to the node.
79
79
  def add_node_data(node)
80
80
  # Merge in our server-side facts, so they can be used during compilation.
81
- node.merge(@server_facts)
81
+ node.add_server_facts(@server_facts)
82
82
  end
83
83
 
84
84
  # Compile the actual catalog.
@@ -21,9 +21,20 @@ class Puppet::Node::Facts::Facter < Puppet::Indirector::Code
21
21
  # Lookup a host's facts up in Facter.
22
22
  def find(request)
23
23
  Facter.reset
24
+
25
+ # Note: we need to setup puppet's external search paths before adding the puppetversion
26
+ # fact. This is because in Facter 2.x, the first `Facter.add` causes Facter to create
27
+ # its directory loaders which cannot be changed, meaning other external facts won't
28
+ # be resolved. (PUP-4607)
24
29
  self.class.setup_external_search_paths(request) if Puppet.features.external_facts?
25
30
  self.class.setup_search_paths(request)
26
31
 
32
+ # Add the puppetversion fact; this is done before generating the hash so it is
33
+ # accessible to custom facts.
34
+ Facter.add(:puppetversion) do
35
+ setcode { Puppet.version.to_s }
36
+ end
37
+
27
38
  result = Puppet::Node::Facts.new(request.key, Facter.to_hash)
28
39
  result.add_local_facts
29
40
  result.sanitize
@@ -11,6 +11,7 @@ module Puppet
11
11
  require 'puppet/pops/loader/null_loader'
12
12
  require 'puppet/pops/loader/static_loader'
13
13
  require 'puppet/pops/loader/ruby_function_instantiator'
14
+ require 'puppet/pops/loader/puppet_function_instantiator'
14
15
  require 'puppet/pops/loader/loader_paths'
15
16
  require 'puppet/pops/loader/simple_environment_loader'
16
17
  end
@@ -16,6 +16,8 @@ class Puppet::Node
16
16
  attr_accessor :name, :classes, :source, :ipaddress, :parameters, :trusted_data, :environment_name
17
17
  attr_reader :time, :facts
18
18
 
19
+ attr_reader :server_facts
20
+
19
21
  def self.from_data_hash(data)
20
22
  raise ArgumentError, "No name provided in serialized data" unless name = data['name']
21
23
 
@@ -86,6 +88,8 @@ class Puppet::Node
86
88
 
87
89
  @facts = options[:facts]
88
90
 
91
+ @server_facts = {}
92
+
89
93
  if env = options[:environment]
90
94
  self.environment = env
91
95
  end
@@ -108,12 +112,24 @@ class Puppet::Node
108
112
  # Merge any random parameters into our parameter list.
109
113
  def merge(params)
110
114
  params.each do |name, value|
111
- @parameters[name] = value unless @parameters.include?(name)
115
+ if @parameters.include?(name)
116
+ Puppet::Util::Warnings.warnonce("The node parameter '#{name}' for node '#{@name}' was already set to '#{@parameters[name]}'. It could not be set to '#{value}'")
117
+ else
118
+ @parameters[name] = value
119
+ end
112
120
  end
113
121
 
114
122
  @parameters["environment"] ||= self.environment.name.to_s
115
123
  end
116
124
 
125
+ def add_server_facts(facts)
126
+ # Append the current environment to the list of server facts
127
+ @server_facts = facts.merge({ "environment" => self.environment.name.to_s})
128
+
129
+ # Merge the server facts into the parameters for the node
130
+ merge(facts)
131
+ end
132
+
117
133
  # Calculate the list of names we might use for looking
118
134
  # up our node. This is only used for AST nodes.
119
135
  def names
@@ -488,6 +488,10 @@ class Puppet::Node::Environment
488
488
  parser.parse
489
489
  end
490
490
  end
491
+ rescue Puppet::ParseErrorWithIssue => detail
492
+ @known_resource_types.parse_failed = true
493
+ detail.environment = self.name
494
+ raise
491
495
  rescue => detail
492
496
  @known_resource_types.parse_failed = true
493
497
 
@@ -85,6 +85,10 @@ class Puppet::Parser::AST::PopsBridge
85
85
  instantiate_ResourceTypeDefinition(d, modname)
86
86
  when Puppet::Pops::Model::NodeDefinition
87
87
  instantiate_NodeDefinition(d, modname)
88
+ when Puppet::Pops::Model::FunctionDefinition
89
+ instantiate_FunctionDefinition(d, modname)
90
+ # The 3x logic calling this will not know what to do with the result, it is compacted away at the end
91
+ next
88
92
  else
89
93
  raise Puppet::ParseError, "Internal Error: Unknown type of definition - got '#{d.class}'"
90
94
  end
@@ -32,6 +32,10 @@ class Puppet::Parser::Compiler
32
32
  end
33
33
 
34
34
  new(node).compile {|resulting_catalog| resulting_catalog.to_resource }
35
+ rescue Puppet::ParseErrorWithIssue => detail
36
+ detail.node = node.name
37
+ Puppet.log_exception(detail)
38
+ raise
35
39
  rescue => detail
36
40
  message = "#{detail} on node #{node.name}"
37
41
  Puppet.log_exception(detail, message)
@@ -556,6 +560,11 @@ class Puppet::Parser::Compiler
556
560
  catalog.client_version = node.parameters["clientversion"]
557
561
  catalog.server_version = node.parameters["serverversion"]
558
562
  @topscope.set_trusted(node.trusted_data)
563
+
564
+ if Puppet[:trusted_server_facts]
565
+ @topscope.set_server_facts(node.server_facts)
566
+ end
567
+
559
568
  facts_hash = node.facts.nil? ? {} : node.facts.values
560
569
  @topscope.set_facts(facts_hash)
561
570
  end
@@ -39,9 +39,33 @@ Puppet::Parser::Functions::newfunction(:defined, :type => :rvalue, :arity => -2,
39
39
  defined(File[\'/some/file\'])
40
40
  defined(Class[\'foo\'])
41
41
 
42
+ The `defined` function does not answer if 4.x data types (e.g. `Integer`) are defined. If
43
+ given the string 'integer' the result is false, and if given a non CatalogEntry type,
44
+ an error is raised.
45
+
46
+ The rules for asking for undef, empty strings, and the main class are different from 3.x
47
+ (non future parser) and 4.x (with future parser or in Puppet 4.0.0 and later):
48
+
49
+ defined('') # 3.x => true, 4.x => false
50
+ defined(undef) # 3.x => true, 4.x => error
51
+ defined('main') # 3.x => false, 4.x => true
52
+
53
+ With the future parser, it is also possible to ask specifically if a name is
54
+ a resource type (built in or defined), or a class, by giving its type:
55
+
56
+ defined(Type[Class['foo']])
57
+ defined(Type[Resource['foo']])
58
+
59
+ Which is different from asking:
60
+
61
+ defined('foo')
62
+
63
+ Since the later returns true if 'foo' is either a class, a built-in resource type, or a user defined
64
+ resource type, and a specific request like `Type[Class['foo']]` only returns true if `'foo'` is a class.
65
+
42
66
  - Since 2.7.0
43
67
  - Since 3.6.0 variable reference and future parser types
44
- - Since 4.0.0") do |vals|
68
+ - Since 3.8.1 type specific requests with future parser") do |vals|
45
69
  vals = [vals] unless vals.is_a?(Array)
46
70
  vals.any? do |val|
47
71
  case val
@@ -1,3 +1,5 @@
1
+ require 'puppet/file_system'
2
+
1
3
  Puppet::Parser::Functions::newfunction(
2
4
  :file, :arity => -2, :type => :rvalue,
3
5
  :doc => "Loads a file from a module and returns its contents as a string.
@@ -24,7 +26,7 @@ Puppet::Parser::Functions::newfunction(
24
26
  end
25
27
 
26
28
  if path
27
- File.read(path)
29
+ Puppet::FileSystem.read_preserve_line_endings(path)
28
30
  else
29
31
  raise Puppet::ParseError, "Could not find any files from #{vals.join(", ")}"
30
32
  end