puppet 3.7.5-x86-mingw32 → 3.8.1-x86-mingw32

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 (108) hide show
  1. checksums.yaml +4 -4
  2. data/ext/build_defaults.yaml +5 -5
  3. data/lib/hiera/puppet_function.rb +15 -4
  4. data/lib/puppet.rb +5 -2
  5. data/lib/puppet/application/agent.rb +5 -0
  6. data/lib/puppet/application/apply.rb +5 -0
  7. data/lib/puppet/application/device.rb +8 -3
  8. data/lib/puppet/application/master.rb +5 -0
  9. data/lib/puppet/defaults.rb +8 -0
  10. data/lib/puppet/error.rb +27 -1
  11. data/lib/puppet/file_system.rb +13 -0
  12. data/lib/puppet/file_system/file19windows.rb +8 -0
  13. data/lib/puppet/file_system/file_impl.rb +4 -0
  14. data/lib/puppet/file_system/memory_impl.rb +4 -0
  15. data/lib/puppet/functions.rb +25 -3
  16. data/lib/puppet/functions/defined.rb +130 -0
  17. data/lib/puppet/functions/hiera_include.rb +1 -1
  18. data/lib/puppet/node/environment.rb +4 -0
  19. data/lib/puppet/parser/compiler.rb +5 -2
  20. data/lib/puppet/parser/functions/defined.rb +26 -1
  21. data/lib/puppet/parser/functions/file.rb +3 -1
  22. data/lib/puppet/parser/templatewrapper.rb +2 -1
  23. data/lib/puppet/pops.rb +5 -0
  24. data/lib/puppet/pops/evaluator/access_operator.rb +25 -5
  25. data/lib/puppet/pops/evaluator/collector_transformer.rb +1 -11
  26. data/lib/puppet/pops/evaluator/compare_operator.rb +43 -0
  27. data/lib/puppet/pops/evaluator/evaluator_impl.rb +43 -28
  28. data/lib/puppet/pops/evaluator/runtime3_support.rb +9 -5
  29. data/lib/puppet/pops/functions/dispatch.rb +6 -1
  30. data/lib/puppet/pops/issue_reporter.rb +42 -16
  31. data/lib/puppet/pops/issues.rb +96 -0
  32. data/lib/puppet/pops/loader/module_loaders.rb +3 -1
  33. data/lib/puppet/pops/loaders.rb +6 -4
  34. data/lib/puppet/pops/migration/migration_checker.rb +45 -0
  35. data/lib/puppet/pops/model/factory.rb +1 -1
  36. data/lib/puppet/pops/model/model_meta.rb +1 -1
  37. data/lib/puppet/pops/parser/egrammar.ra +1 -1
  38. data/lib/puppet/pops/parser/eparser.rb +1 -1
  39. data/lib/puppet/pops/parser/epp_support.rb +18 -9
  40. data/lib/puppet/pops/parser/evaluating_parser.rb +7 -1
  41. data/lib/puppet/pops/parser/heredoc_support.rb +12 -11
  42. data/lib/puppet/pops/parser/interpolation_support.rb +7 -1
  43. data/lib/puppet/pops/parser/lexer2.rb +8 -8
  44. data/lib/puppet/pops/parser/lexer_support.rb +46 -20
  45. data/lib/puppet/pops/parser/parser_support.rb +11 -14
  46. data/lib/puppet/pops/parser/slurp_support.rb +22 -6
  47. data/lib/puppet/pops/types/type_calculator.rb +156 -55
  48. data/lib/puppet/pops/types/type_factory.rb +67 -14
  49. data/lib/puppet/pops/types/type_parser.rb +22 -13
  50. data/lib/puppet/pops/types/types.rb +21 -3
  51. data/lib/puppet/pops/types/types_meta.rb +13 -2
  52. data/lib/puppet/pops/validation.rb +25 -2
  53. data/lib/puppet/pops/validation/checker4_0.rb +25 -5
  54. data/lib/puppet/provider/group/windows_adsi.rb +18 -6
  55. data/lib/puppet/provider/mount/parsed.rb +145 -2
  56. data/lib/puppet/provider/package/pip.rb +4 -5
  57. data/lib/puppet/provider/package/zypper.rb +17 -7
  58. data/lib/puppet/provider/scheduled_task/win32_taskscheduler.rb +35 -10
  59. data/lib/puppet/provider/service/init.rb +7 -0
  60. data/lib/puppet/provider/user/windows_adsi.rb +8 -1
  61. data/lib/puppet/provider/zpool/zpool.rb +7 -2
  62. data/lib/puppet/resource.rb +1 -1
  63. data/lib/puppet/type/group.rb +1 -1
  64. data/lib/puppet/type/mount.rb +14 -3
  65. data/lib/puppet/type/scheduled_task.rb +21 -6
  66. data/lib/puppet/util/log.rb +50 -8
  67. data/lib/puppet/util/log/destinations.rb +23 -2
  68. data/lib/puppet/util/logging.rb +37 -1
  69. data/lib/puppet/util/windows/adsi.rb +36 -11
  70. data/lib/puppet/version.rb +1 -1
  71. data/spec/fixtures/unit/provider/mount/parsed/aix.filesystems +93 -85
  72. data/spec/fixtures/unit/provider/mount/parsed/aix.mount +11 -7
  73. data/spec/integration/parser/collector_spec.rb +7 -0
  74. data/spec/integration/parser/future_compiler_spec.rb +9 -0
  75. data/spec/integration/parser/resource_expressions_spec.rb +3 -0
  76. data/spec/unit/file_system_spec.rb +38 -0
  77. data/spec/unit/functions/defined_spec.rb +291 -0
  78. data/spec/unit/functions/hiera_spec.rb +8 -6
  79. data/spec/unit/functions4_spec.rb +97 -2
  80. data/spec/unit/parser/functions/file_spec.rb +8 -2
  81. data/spec/unit/parser/functions/template_spec.rb +1 -1
  82. data/spec/unit/parser/templatewrapper_spec.rb +1 -1
  83. data/spec/unit/pops/evaluator/access_ops_spec.rb +19 -0
  84. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +61 -8
  85. data/spec/unit/pops/issues_spec.rb +16 -16
  86. data/spec/unit/pops/loaders/module_loaders_spec.rb +5 -0
  87. data/spec/unit/pops/migration_spec.rb +180 -0
  88. data/spec/unit/pops/parser/lexer2_spec.rb +152 -1
  89. data/spec/unit/pops/parser/parse_heredoc_spec.rb +26 -0
  90. data/spec/unit/pops/transformer/transform_calls_spec.rb +1 -1
  91. data/spec/unit/pops/types/type_calculator_spec.rb +204 -11
  92. data/spec/unit/pops/validation_spec.rb +66 -0
  93. data/spec/unit/provider/group/windows_adsi_spec.rb +65 -1
  94. data/spec/unit/provider/mount/parsed_spec.rb +31 -5
  95. data/spec/unit/provider/package/pip_spec.rb +19 -7
  96. data/spec/unit/provider/package/zypper_spec.rb +25 -14
  97. data/spec/unit/provider/scheduled_task/win32_taskscheduler_spec.rb +312 -70
  98. data/spec/unit/provider/service/base_spec.rb +42 -31
  99. data/spec/unit/provider/service/freebsd_spec.rb +1 -0
  100. data/spec/unit/provider/service/gentoo_spec.rb +1 -0
  101. data/spec/unit/provider/service/init_spec.rb +18 -0
  102. data/spec/unit/provider/service/openbsd_spec.rb +1 -0
  103. data/spec/unit/provider/service/redhat_spec.rb +1 -0
  104. data/spec/unit/provider/user/windows_adsi_spec.rb +21 -0
  105. data/spec/unit/provider/zpool/zpool_spec.rb +47 -10
  106. data/spec/unit/util/log_spec.rb +113 -0
  107. data/spec/unit/util/windows/adsi_spec.rb +106 -26
  108. metadata +10 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f98c35894808b86825e10207fb4e0d2949cfa7a5
4
- data.tar.gz: 83a870953aa97c1df32ad46f6ac02765acc379f2
3
+ metadata.gz: 3cbb9e827897a13e505bc5017ab1d2cc994784e3
4
+ data.tar.gz: 203f468002d77e44e83b9c81a6acece4cd078833
5
5
  SHA512:
6
- metadata.gz: 46c60c132ab121e4842a8b68cb1a737ed969cb200c5b0d7aa2b94184c8ba15f999ac8ad947770b378e822c0fc00597d8c5a5af8a2834ad75ec40f48100d8a695
7
- data.tar.gz: 986bf3141e644cbf7820821b4b2efd1e8b450db35196249a89f70bdcb1d20acbbeb7b56427ca68e823d85be5261d03c211c72356d20329824b2f212ccaa482b0
6
+ metadata.gz: b320bbc00292e2988f19fae0c143fc77a0611dec3af195551d2e31bfbbe8f73e710c230f253c4c3b95b6f657953101588cb68d0caaf2744581572d4e4209cb66
7
+ data.tar.gz: b54f4e65775c62b00f9d498129e79bb53e46fefafdf7a5ca34bac5a8fd666ed5e5005be887856b00c37770367a5107d4110ad0f6075de1278ab62aa493b46d58
@@ -2,21 +2,21 @@
2
2
  packaging_url: 'git://github.com/puppetlabs/packaging.git --branch=master'
3
3
  packaging_repo: 'packaging'
4
4
  default_cow: 'base-squeeze-i386.cow'
5
- cows: 'base-lucid-i386.cow base-precise-i386.cow base-squeeze-i386.cow base-stable-i386.cow base-testing-i386.cow base-trusty-i386.cow base-wheezy-i386.cow'
5
+ cows: 'base-precise-i386.cow base-squeeze-i386.cow base-stable-i386.cow base-testing-i386.cow base-trusty-i386.cow base-wheezy-i386.cow'
6
6
  pbuild_conf: '/etc/pbuilderrc'
7
7
  packager: 'puppetlabs'
8
8
  gpg_name: 'info@puppetlabs.com'
9
9
  gpg_key: '4BD6EC30'
10
10
  sign_tar: FALSE
11
11
  # a space separated list of mock configs
12
- final_mocks: 'pl-el-5-i386 pl-el-6-i386 pl-el-7-x86_64 pl-fedora-19-i386 pl-fedora-20-i386'
12
+ final_mocks: 'pl-el-5-i386 pl-el-6-i386 pl-el-7-x86_64 pl-fedora-20-i386'
13
13
  yum_host: 'yum.puppetlabs.com'
14
14
  yum_repo_path: '/opt/repository/yum/'
15
15
  build_gem: TRUE
16
16
  build_dmg: TRUE
17
17
  build_msi:
18
18
  puppet_for_the_win:
19
- ref: '4eb71b5b063f611eb447d561d51481831a66b5dd'
19
+ ref: '2476cd007b1b52fb1b9f22202b56218629626b5c'
20
20
  repo: 'git://github.com/puppetlabs/puppet_for_the_win.git'
21
21
  facter:
22
22
  ref: 'refs/tags/2.3.0'
@@ -26,8 +26,8 @@ build_msi:
26
26
  repo: 'git://github.com/puppetlabs/hiera.git'
27
27
  sys:
28
28
  ref:
29
- x86: '8db9d84da9950760144b5dfcd807213eecee4842'
30
- x64: '12030f11e9bb2f085c68108bff34be6956b25df9'
29
+ x86: '2f25839c5c11ec10b781debf4808095d6895a844'
30
+ x64: '017c63ca11e38f74b7e011ecd2006100452c620b'
31
31
  repo: 'git://github.com/puppetlabs/puppet-win32-ruby.git'
32
32
  apt_host: 'apt.puppetlabs.com'
33
33
  apt_repo_url: 'http://apt.puppetlabs.com'
@@ -12,10 +12,15 @@ class Hiera::PuppetFunction < Puppet::Functions::InternalFunction
12
12
  param 'Tuple[String, Any, Any, 1, 3]', :args
13
13
  end
14
14
 
15
- dispatch :hiera do
15
+ dispatch :hiera_no_default do
16
16
  scope_param
17
17
  param 'String',:key
18
- optional_param 'Any', :default
18
+ end
19
+
20
+ dispatch :hiera_with_default do
21
+ scope_param
22
+ param 'String',:key
23
+ param 'Any', :default
19
24
  optional_param 'Any', :override
20
25
  end
21
26
 
@@ -37,8 +42,14 @@ class Hiera::PuppetFunction < Puppet::Functions::InternalFunction
37
42
  hiera(scope, *args)
38
43
  end
39
44
 
40
- def hiera(scope, key, default = nil, override = nil)
41
- post_lookup(key, lookup(scope, key, default, override))
45
+ def hiera_no_default(scope, key)
46
+ post_lookup(key, lookup(scope, key, nil, nil))
47
+ end
48
+
49
+ def hiera_with_default(scope, key, default, override = nil)
50
+ undefined = (@@undefined_value ||= Object.new)
51
+ result = lookup(scope, key, undefined, override)
52
+ post_lookup(key, result.equal?(undefined) ? default : result)
42
53
  end
43
54
 
44
55
  def hiera_block1(scope, key, &default_block)
data/lib/puppet.rb CHANGED
@@ -259,8 +259,11 @@ module Puppet
259
259
  # The single instance used for normal operation
260
260
  @context = Puppet::Context.new(bootstrap_context)
261
261
 
262
- def self.future_parser?
263
- env = Puppet.lookup(:current_environment) { return Puppet[:parser] == 'future' }
262
+ # Is the future parser in effect for the given environment, or in :current_environment if no
263
+ # environment is given.
264
+ #
265
+ def self.future_parser?(in_environment = nil)
266
+ env = in_environment || Puppet.lookup(:current_environment) { return Puppet[:parser] == 'future' }
264
267
  env_conf = Puppet.lookup(:environments).get_conf(env.name)
265
268
 
266
269
  if env_conf.nil?
@@ -231,6 +231,11 @@ generated by running puppet agent with '--genconfig'.
231
231
  file. If debugging or verbosity is enabled, this defaults to 'console'.
232
232
  Otherwise, it defaults to 'syslog' on POSIX systems and 'eventlog' on Windows.
233
233
 
234
+ A path ending with '.json' will receive structured output in JSON format. The
235
+ log file will not have an ending ']' automatically written to it due to the
236
+ appending nature of logging. It must be appended manually to make the content
237
+ valid JSON.
238
+
234
239
  * --masterport:
235
240
  The port on which to contact the puppet master.
236
241
  (This is a Puppet setting, and can go in puppet.conf.)
@@ -99,6 +99,11 @@ configuration options can also be generated by running puppet with
99
99
  service), 'eventlog' (the Windows Event Log), 'console', or the path to a log
100
100
  file. Defaults to 'console'.
101
101
 
102
+ A path ending with '.json' will receive structured output in JSON format. The
103
+ log file will not have an ending ']' automatically written to it due to the
104
+ appending nature of logging. It must be appended manually to make the content
105
+ valid JSON.
106
+
102
107
  * --noop:
103
108
  Use 'noop' mode where Puppet runs in a no-op or dry-run mode. This
104
109
  is useful for seeing what changes Puppet will make without actually
@@ -124,9 +124,14 @@ parameter, so you can specify '--server <servername>' as an argument.
124
124
  Print this help message
125
125
 
126
126
  * --logdest:
127
- Where to send messages. Choose between syslog, the console, and a log file.
128
- Defaults to sending messages to syslog, or the console if debugging or
129
- verbosity is enabled.
127
+ Where to send log messages. Choose between 'syslog' (the POSIX syslog
128
+ service), 'console', or the path to a log file. If debugging or verbosity is
129
+ enabled, this defaults to 'console'. Otherwise, it defaults to 'syslog'.
130
+
131
+ A path ending with '.json' will receive structured output in JSON format. The
132
+ log file will not have an ending ']' automatically written to it due to the
133
+ appending nature of logging. It must be appended manually to make the content
134
+ valid JSON.
130
135
 
131
136
  * --verbose:
132
137
  Turn on verbose reporting.
@@ -86,6 +86,11 @@ generated by running puppet master with '--genconfig'.
86
86
  service), 'console', or the path to a log file. If debugging or verbosity is
87
87
  enabled, this defaults to 'console'. Otherwise, it defaults to 'syslog'.
88
88
 
89
+ A path ending with '.json' will receive structured output in JSON format. The
90
+ log file will not have an ending ']' automatically written to it due to the
91
+ appending nature of logging. It must be appended manually to make the content
92
+ valid JSON.
93
+
89
94
  * --masterport:
90
95
  The port on which to listen for traffic.
91
96
  (This is a Puppet setting, and can go in puppet.conf.)
@@ -576,6 +576,14 @@ module Puppet
576
576
  :default => '$trusted_node_data',
577
577
  :type => :boolean,
578
578
  :desc => "When true, also prevents $trusted and $facts from being overridden in any scope",
579
+ },
580
+ :preview_outputdir => {
581
+ :default => '$vardir/preview',
582
+ :type => :directory,
583
+ :mode => "0750",
584
+ :owner => "service",
585
+ :group => "service",
586
+ :desc => "The directory where catalog previews per node are generated."
579
587
  }
580
588
  )
581
589
  Puppet.define_settings(:module_tool,
data/lib/puppet/error.rb CHANGED
@@ -54,8 +54,34 @@ module Puppet
54
54
  include ExternalFileError
55
55
  end
56
56
 
57
+ # Contains an issue code and can be annotated with an environment and a node
58
+ class ParseErrorWithIssue < Puppet::ParseError
59
+ attr_reader :issue_code, :basic_message
60
+ attr_accessor :environment, :node
61
+
62
+ # @param message [String] The error message
63
+ # @param file [String] The path to the file where the error was found
64
+ # @param line [Integer] The line in the file
65
+ # @param pos [Integer] The position on the line
66
+ # @param original [Exception] Original exception
67
+ # @param issue_code [Symbol] The issue code
68
+ #
69
+ def initialize(message, file=nil, line=nil, pos=nil, original=nil, issue_code= nil)
70
+ super(message, file, line, pos, original)
71
+ @issue_code = issue_code
72
+ @basic_message = message
73
+ end
74
+
75
+ def to_s
76
+ msg = super
77
+ msg = "Could not parse for environment #{environment}: #{msg}" if environment
78
+ msg = "#{msg} on node #{node}" if node
79
+ msg
80
+ end
81
+ end
82
+
57
83
  # An error that already contains location information in the message text
58
- class PreformattedError < Puppet::ParseError
84
+ class PreformattedError < Puppet::ParseErrorWithIssue
59
85
  end
60
86
 
61
87
  # An error class for when I don't know what happened. Automatically
@@ -129,6 +129,19 @@ module Puppet::FileSystem
129
129
  @impl.read(assert_path(path))
130
130
  end
131
131
 
132
+ # Read a file keeping the original line endings intact. This
133
+ # attempts to open files using binary mode using some encoding
134
+ # overrides and falling back to IO.read when none of the
135
+ # encodings are valid.
136
+ #
137
+ # @return [String] The contents of the file
138
+ #
139
+ # @api public
140
+ #
141
+ def self.read_preserve_line_endings(path)
142
+ @impl.read_preserve_line_endings(assert_path(path))
143
+ end
144
+
132
145
  # @return [String] The binary contents of the file
133
146
  #
134
147
  # @api public
@@ -91,6 +91,14 @@ class Puppet::FileSystem::File19Windows < Puppet::FileSystem::File19
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
@@ -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?
@@ -328,7 +328,25 @@ module Puppet::Functions
328
328
  #
329
329
  # @api public
330
330
  def repeated_param(type, name)
331
- internal_param(type, name)
331
+ internal_param(type, name, true)
332
+ @max = :default
333
+ end
334
+ alias optional_repeated_param repeated_param
335
+
336
+ # Defines a repeated positional parameter with _type_ and _name_ that may occur 1 to "infinite" number of times.
337
+ # It may only appear last or just before a block parameter.
338
+ #
339
+ # @param type [String] The type specification for the parameter.
340
+ # @param name [Symbol] The name of the parameter. This is primarily used
341
+ # for error message output and does not have to match an implementation
342
+ # method parameter.
343
+ # @return [Void]
344
+ #
345
+ # @api public
346
+ def required_repeated_param(type, name)
347
+ internal_param(type, name, true)
348
+ raise ArgumentError, 'A required repeated parameter cannot be added after an optional parameter' if @min != @max
349
+ @min += 1
332
350
  @max = :default
333
351
  end
334
352
 
@@ -385,14 +403,18 @@ module Puppet::Functions
385
403
  private
386
404
 
387
405
  # @api private
388
- def internal_param(type, name)
406
+ def internal_param(type, name, repeat = false)
389
407
  raise ArgumentError, 'Parameters cannot be added after a block parameter' unless @block_type.nil?
390
408
  raise ArgumentError, 'Parameters cannot be added after a repeated parameter' if @max == :default
391
409
  if type.is_a?(String)
392
410
  @types << type
393
411
  @names << name
394
412
  # mark what should be picked for this position when dispatching
395
- @weaving << @names.size()-1
413
+ if repeat
414
+ @weaving << -@names.size()
415
+ else
416
+ @weaving << @names.size()-1
417
+ end
396
418
  else
397
419
  raise ArgumentError, "Parameter 'type' must be a String reference to a Puppet Data Type. Got #{type.class}"
398
420
  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