bolt 0.23.0 → 0.24.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of bolt might be problematic. Click here for more details.

Files changed (192) hide show
  1. checksums.yaml +4 -4
  2. data/bolt-modules/boltlib/lib/puppet/functions/apply_prep.rb +5 -2
  3. data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_query.rb +5 -1
  4. data/bolt-modules/boltlib/lib/puppet/functions/run_task.rb +5 -8
  5. data/lib/bolt/applicator.rb +11 -8
  6. data/lib/bolt/boltdir.rb +13 -5
  7. data/lib/bolt/catalog.rb +22 -47
  8. data/lib/bolt/config.rb +1 -26
  9. data/lib/bolt/executor.rb +1 -1
  10. data/lib/bolt/outputter.rb +0 -9
  11. data/lib/bolt/outputter/human.rb +29 -14
  12. data/lib/bolt/outputter/json.rb +12 -1
  13. data/lib/bolt/pal.rb +12 -10
  14. data/lib/bolt/target.rb +0 -6
  15. data/lib/bolt/task.rb +53 -10
  16. data/lib/bolt/transport/base.rb +1 -6
  17. data/lib/bolt/transport/local.rb +11 -13
  18. data/lib/bolt/transport/local/shell.rb +2 -2
  19. data/lib/bolt/transport/ssh.rb +16 -11
  20. data/lib/bolt/transport/winrm.rb +8 -11
  21. data/lib/bolt/version.rb +1 -1
  22. data/lib/bolt_ext/schemas/task.json +12 -5
  23. data/libexec/apply_catalog.rb +3 -1
  24. data/libexec/bolt_catalog +4 -0
  25. data/vendored/puppet/lib/puppet.rb +2 -1
  26. data/vendored/puppet/lib/puppet/application/agent.rb +2 -6
  27. data/vendored/puppet/lib/puppet/application/apply.rb +100 -60
  28. data/vendored/puppet/lib/puppet/application/cert.rb +26 -291
  29. data/vendored/puppet/lib/puppet/application/device.rb +0 -5
  30. data/vendored/puppet/lib/puppet/application/lookup.rb +1 -1
  31. data/vendored/puppet/lib/puppet/application/ssl.rb +133 -0
  32. data/vendored/puppet/lib/puppet/application_support.rb +1 -2
  33. data/vendored/puppet/lib/puppet/configurer.rb +34 -50
  34. data/vendored/puppet/lib/puppet/configurer/downloader.rb +1 -1
  35. data/vendored/puppet/lib/puppet/configurer/plugin_handler.rb +1 -1
  36. data/vendored/puppet/lib/puppet/daemon.rb +1 -1
  37. data/vendored/puppet/lib/puppet/defaults.rb +40 -117
  38. data/vendored/puppet/lib/puppet/face/epp.rb +2 -2
  39. data/vendored/puppet/lib/puppet/face/help.rb +21 -7
  40. data/vendored/puppet/lib/puppet/face/node/clean.rb +14 -10
  41. data/vendored/puppet/lib/puppet/feature/base.rb +7 -23
  42. data/vendored/puppet/lib/puppet/feature/eventlog.rb +1 -1
  43. data/vendored/puppet/lib/puppet/file_serving/base.rb +2 -2
  44. data/vendored/puppet/lib/puppet/file_serving/fileset.rb +1 -1
  45. data/vendored/puppet/lib/puppet/file_serving/metadata.rb +2 -2
  46. data/vendored/puppet/lib/puppet/functions.rb +133 -0
  47. data/vendored/puppet/lib/puppet/functions/eyaml_lookup_key.rb +4 -5
  48. data/vendored/puppet/lib/puppet/functions/filter.rb +7 -6
  49. data/vendored/puppet/lib/puppet/functions/new.rb +37 -53
  50. data/vendored/puppet/lib/puppet/functions/warning.rb +1 -1
  51. data/vendored/puppet/lib/puppet/functions/yaml_data.rb +4 -5
  52. data/vendored/puppet/lib/puppet/gettext/config.rb +1 -1
  53. data/vendored/puppet/lib/puppet/graph.rb +0 -2
  54. data/vendored/puppet/lib/puppet/indirector/catalog/json.rb +14 -3
  55. data/vendored/puppet/lib/puppet/indirector/catalog/yaml.rb +0 -16
  56. data/vendored/puppet/lib/puppet/indirector/certificate/file.rb +0 -1
  57. data/vendored/puppet/lib/puppet/indirector/facts/yaml.rb +4 -2
  58. data/vendored/puppet/lib/puppet/indirector/key/file.rb +1 -6
  59. data/vendored/puppet/lib/puppet/indirector/node/exec.rb +1 -3
  60. data/vendored/puppet/lib/puppet/indirector/node/yaml.rb +0 -6
  61. data/vendored/puppet/lib/puppet/indirector/request.rb +1 -1
  62. data/vendored/puppet/lib/puppet/indirector/ssl_file.rb +3 -44
  63. data/vendored/puppet/lib/puppet/indirector/yaml.rb +4 -4
  64. data/vendored/puppet/lib/puppet/info_service/task_information_service.rb +7 -3
  65. data/vendored/puppet/lib/puppet/loaders.rb +1 -0
  66. data/vendored/puppet/lib/puppet/module/task.rb +198 -29
  67. data/vendored/puppet/lib/puppet/module_tool/applications/unpacker.rb +1 -1
  68. data/vendored/puppet/lib/puppet/network/format_support.rb +13 -8
  69. data/vendored/puppet/lib/puppet/network/formats.rb +93 -2
  70. data/vendored/puppet/lib/puppet/network/http/api/indirected_routes.rb +10 -3
  71. data/vendored/puppet/lib/puppet/node/facts.rb +11 -1
  72. data/vendored/puppet/lib/puppet/parser/catalog_compiler.rb +56 -0
  73. data/vendored/puppet/lib/puppet/parser/compiler.rb +3 -1
  74. data/vendored/puppet/lib/puppet/parser/functions.rb +3 -1
  75. data/vendored/puppet/lib/puppet/parser/functions/filter.rb +1 -1
  76. data/vendored/puppet/lib/puppet/parser/functions/generate.rb +1 -1
  77. data/vendored/puppet/lib/puppet/parser/functions/sprintf.rb +12 -1
  78. data/vendored/puppet/lib/puppet/parser/functions/tagged.rb +1 -4
  79. data/vendored/puppet/lib/puppet/parser/scope.rb +1 -1
  80. data/vendored/puppet/lib/puppet/parser/script_compiler.rb +7 -2
  81. data/vendored/puppet/lib/puppet/pops/evaluator/deferred_resolver.rb +5 -3
  82. data/vendored/puppet/lib/puppet/pops/evaluator/runtime3_converter.rb +23 -4
  83. data/vendored/puppet/lib/puppet/pops/evaluator/runtime3_support.rb +3 -4
  84. data/vendored/puppet/lib/puppet/pops/functions/dispatch.rb +4 -0
  85. data/vendored/puppet/lib/puppet/pops/issues.rb +8 -0
  86. data/vendored/puppet/lib/puppet/pops/loader/loader.rb +2 -2
  87. data/vendored/puppet/lib/puppet/pops/loader/loader_paths.rb +3 -1
  88. data/vendored/puppet/lib/puppet/pops/loader/module_loaders.rb +30 -9
  89. data/vendored/puppet/lib/puppet/pops/loader/ruby_legacy_function_instantiator.rb +62 -0
  90. data/vendored/puppet/lib/puppet/pops/loader/static_loader.rb +0 -1
  91. data/vendored/puppet/lib/puppet/pops/loader/task_instantiator.rb +13 -70
  92. data/vendored/puppet/lib/puppet/pops/loaders.rb +19 -29
  93. data/vendored/puppet/lib/puppet/pops/lookup/hiera_config.rb +1 -1
  94. data/vendored/puppet/lib/puppet/pops/model/model_label_provider.rb +4 -1
  95. data/vendored/puppet/lib/puppet/pops/pcore.rb +10 -33
  96. data/vendored/puppet/lib/puppet/pops/serialization.rb +2 -0
  97. data/vendored/puppet/lib/puppet/pops/serialization/from_data_converter.rb +2 -1
  98. data/vendored/puppet/lib/puppet/pops/serialization/to_data_converter.rb +11 -3
  99. data/vendored/puppet/lib/puppet/pops/serialization/to_stringified_converter.rb +226 -0
  100. data/vendored/puppet/lib/puppet/pops/types/p_object_type.rb +3 -0
  101. data/vendored/puppet/lib/puppet/pops/validation/checker4_0.rb +97 -47
  102. data/vendored/puppet/lib/puppet/pops/validation/validator_factory_4_0.rb +7 -8
  103. data/vendored/puppet/lib/puppet/property/keyvalue.rb +70 -8
  104. data/vendored/puppet/lib/puppet/provider/aix_object.rb +483 -0
  105. data/vendored/puppet/lib/puppet/provider/file/windows.rb +1 -1
  106. data/vendored/puppet/lib/puppet/provider/group/aix.rb +51 -112
  107. data/vendored/puppet/lib/puppet/provider/package/gem.rb +1 -1
  108. data/vendored/puppet/lib/puppet/provider/package/pip.rb +1 -1
  109. data/vendored/puppet/lib/puppet/provider/package/puppet_gem.rb +1 -1
  110. data/vendored/puppet/lib/puppet/provider/package/rpm.rb +1 -1
  111. data/vendored/puppet/lib/puppet/provider/package/windows/package.rb +1 -1
  112. data/vendored/puppet/lib/puppet/provider/package/zypper.rb +1 -1
  113. data/vendored/puppet/lib/puppet/provider/service/systemd.rb +1 -1
  114. data/vendored/puppet/lib/puppet/provider/service/windows.rb +37 -40
  115. data/vendored/puppet/lib/puppet/provider/user/aix.rb +142 -254
  116. data/vendored/puppet/lib/puppet/resource.rb +20 -3
  117. data/vendored/puppet/lib/puppet/resource/catalog.rb +2 -12
  118. data/vendored/puppet/lib/puppet/rest/routes.rb +97 -34
  119. data/vendored/puppet/lib/puppet/settings.rb +1 -1
  120. data/vendored/puppet/lib/puppet/settings/file_setting.rb +1 -1
  121. data/vendored/puppet/lib/puppet/ssl/base.rb +1 -9
  122. data/vendored/puppet/lib/puppet/ssl/certificate_request.rb +1 -13
  123. data/vendored/puppet/lib/puppet/ssl/certificate_request_attributes.rb +1 -1
  124. data/vendored/puppet/lib/puppet/ssl/host.rb +114 -232
  125. data/vendored/puppet/lib/puppet/ssl/key.rb +1 -5
  126. data/vendored/puppet/lib/puppet/ssl/oids.rb +1 -1
  127. data/vendored/puppet/lib/puppet/test/test_helper.rb +0 -4
  128. data/vendored/puppet/lib/puppet/transaction/event.rb +3 -7
  129. data/vendored/puppet/lib/puppet/transaction/persistence.rb +1 -1
  130. data/vendored/puppet/lib/puppet/type/exec.rb +18 -16
  131. data/vendored/puppet/lib/puppet/type/file.rb +3 -3
  132. data/vendored/puppet/lib/puppet/type/file/source.rb +20 -7
  133. data/vendored/puppet/lib/puppet/type/group.rb +3 -5
  134. data/vendored/puppet/lib/puppet/type/notify.rb +1 -1
  135. data/vendored/puppet/lib/puppet/type/package.rb +2 -5
  136. data/vendored/puppet/lib/puppet/type/schedule.rb +1 -1
  137. data/vendored/puppet/lib/puppet/type/service.rb +3 -6
  138. data/vendored/puppet/lib/puppet/type/tidy.rb +1 -1
  139. data/vendored/puppet/lib/puppet/type/user.rb +13 -20
  140. data/vendored/puppet/lib/puppet/util.rb +8 -9
  141. data/vendored/puppet/lib/puppet/util/execution.rb +3 -3
  142. data/vendored/puppet/lib/puppet/util/feature.rb +61 -39
  143. data/vendored/puppet/lib/puppet/util/log/destinations.rb +1 -1
  144. data/vendored/puppet/lib/puppet/util/rdoc.rb +1 -1
  145. data/vendored/puppet/lib/puppet/util/run_mode.rb +1 -1
  146. data/vendored/puppet/lib/puppet/util/storage.rb +1 -1
  147. data/vendored/puppet/lib/puppet/util/suidmanager.rb +7 -5
  148. data/vendored/puppet/lib/puppet/util/tag_set.rb +1 -1
  149. data/vendored/puppet/lib/puppet/util/tagging.rb +1 -1
  150. data/vendored/puppet/lib/puppet/util/windows.rb +18 -2
  151. data/vendored/puppet/lib/puppet/util/windows/adsi.rb +154 -205
  152. data/vendored/puppet/lib/puppet/util/windows/service.rb +770 -0
  153. data/vendored/puppet/lib/puppet/util/yaml.rb +41 -5
  154. data/vendored/puppet/lib/puppet/version.rb +1 -1
  155. data/vendored/puppet/lib/puppet_pal.rb +280 -24
  156. metadata +8 -38
  157. data/lib/bolt/catalog/compiler.rb +0 -48
  158. data/lib/bolt/catalog/loaders.rb +0 -19
  159. data/vendored/puppet/lib/puppet/application/ca.rb +0 -11
  160. data/vendored/puppet/lib/puppet/application/certificate.rb +0 -17
  161. data/vendored/puppet/lib/puppet/application/certificate_request.rb +0 -7
  162. data/vendored/puppet/lib/puppet/application/certificate_revocation_list.rb +0 -7
  163. data/vendored/puppet/lib/puppet/face/ca.rb +0 -266
  164. data/vendored/puppet/lib/puppet/face/certificate.rb +0 -167
  165. data/vendored/puppet/lib/puppet/face/certificate_request.rb +0 -56
  166. data/vendored/puppet/lib/puppet/face/certificate_revocation_list.rb +0 -56
  167. data/vendored/puppet/lib/puppet/graph/random_prioritizer.rb +0 -16
  168. data/vendored/puppet/lib/puppet/graph/title_hash_prioritizer.rb +0 -16
  169. data/vendored/puppet/lib/puppet/indirector/certificate/ca.rb +0 -9
  170. data/vendored/puppet/lib/puppet/indirector/certificate/disabled_ca.rb +0 -22
  171. data/vendored/puppet/lib/puppet/indirector/certificate_request/ca.rb +0 -22
  172. data/vendored/puppet/lib/puppet/indirector/certificate_request/disabled_ca.rb +0 -22
  173. data/vendored/puppet/lib/puppet/indirector/certificate_revocation_list/ca.rb +0 -8
  174. data/vendored/puppet/lib/puppet/indirector/certificate_revocation_list/disabled_ca.rb +0 -22
  175. data/vendored/puppet/lib/puppet/indirector/certificate_revocation_list/file.rb +0 -8
  176. data/vendored/puppet/lib/puppet/indirector/certificate_revocation_list/rest.rb +0 -11
  177. data/vendored/puppet/lib/puppet/indirector/certificate_status.rb +0 -4
  178. data/vendored/puppet/lib/puppet/indirector/certificate_status/file.rb +0 -91
  179. data/vendored/puppet/lib/puppet/indirector/certificate_status/rest.rb +0 -11
  180. data/vendored/puppet/lib/puppet/indirector/key/ca.rb +0 -16
  181. data/vendored/puppet/lib/puppet/indirector/key/disabled_ca.rb +0 -22
  182. data/vendored/puppet/lib/puppet/indirector/ldap.rb +0 -86
  183. data/vendored/puppet/lib/puppet/indirector/node/ldap.rb +0 -275
  184. data/vendored/puppet/lib/puppet/provider/aixobject.rb +0 -392
  185. data/vendored/puppet/lib/puppet/provider/cron/crontab.rb +0 -297
  186. data/vendored/puppet/lib/puppet/ssl/certificate_authority.rb +0 -475
  187. data/vendored/puppet/lib/puppet/ssl/certificate_authority/autosign_command.rb +0 -45
  188. data/vendored/puppet/lib/puppet/ssl/certificate_authority/interface.rb +0 -324
  189. data/vendored/puppet/lib/puppet/ssl/certificate_factory.rb +0 -219
  190. data/vendored/puppet/lib/puppet/ssl/certificate_revocation_list.rb +0 -111
  191. data/vendored/puppet/lib/puppet/ssl/inventory.rb +0 -55
  192. data/vendored/puppet/lib/puppet/type/cron.rb +0 -480
@@ -22,13 +22,12 @@ module Util
22
22
  require 'puppet/util/posix'
23
23
  extend Puppet::Util::POSIX
24
24
 
25
- # Can't use Puppet.features.microsoft_windows? as it may be mocked out in a test. This can cause test recurring test failures
26
25
  require 'puppet/util/windows/process' if Puppet::Util::Platform.windows?
27
26
 
28
27
  extend Puppet::Util::SymbolicFileMode
29
28
 
30
29
  def default_env
31
- Puppet.features.microsoft_windows? ?
30
+ Puppet::Util::Platform.windows? ?
32
31
  :windows :
33
32
  :posix
34
33
  end
@@ -272,7 +271,7 @@ module Util
272
271
  raise
273
272
  end
274
273
  else
275
- if Puppet.features.microsoft_windows? && File.extname(dest).empty?
274
+ if Puppet::Util::Platform.windows? && File.extname(dest).empty?
276
275
  exts.each do |ext|
277
276
  destext = File.expand_path(dest + ext)
278
277
  return destext if FileTest.file? destext and FileTest.executable? destext
@@ -322,7 +321,7 @@ module Util
322
321
 
323
322
  params = { :scheme => 'file' }
324
323
 
325
- if Puppet.features.microsoft_windows?
324
+ if Puppet::Util::Platform.windows?
326
325
  path = path.gsub(/\\/, '/')
327
326
 
328
327
  if unc = /^\/\/([^\/]+)(\/.+)/.match(path)
@@ -356,7 +355,7 @@ module Util
356
355
  # URI.unescape does, but returns strings in their original encoding
357
356
  path = URI.unescape(uri.path.encode(Encoding::UTF_8))
358
357
 
359
- if Puppet.features.microsoft_windows? and uri.scheme == 'file'
358
+ if Puppet::Util::Platform.windows? && uri.scheme == 'file'
360
359
  if uri.host
361
360
  path = "//#{uri.host}" + path # UNC
362
361
  else
@@ -570,7 +569,7 @@ module Util
570
569
 
571
570
  mode = symbolic_mode_to_int(normalize_symbolic_mode(default_mode))
572
571
  else
573
- if Puppet.features.microsoft_windows?
572
+ if Puppet::Util::Platform.windows?
574
573
  mode = DEFAULT_WINDOWS_MODE
575
574
  else
576
575
  mode = DEFAULT_POSIX_MODE
@@ -583,9 +582,9 @@ module Util
583
582
  tempfile = Puppet::FileSystem::Uniquefile.new(Puppet::FileSystem.basename_string(file), Puppet::FileSystem.dir_string(file))
584
583
 
585
584
  effective_mode =
586
- if !Puppet.features.microsoft_windows?
585
+ if !Puppet::Util::Platform.windows?
587
586
  # Grab the current file mode, and fall back to the defaults.
588
-
587
+
589
588
  if Puppet::FileSystem.exist?(file)
590
589
  stat = Puppet::FileSystem.lstat(file)
591
590
  tempfile.chown(stat.uid, stat.gid)
@@ -620,7 +619,7 @@ module Util
620
619
 
621
620
  tempfile.close
622
621
 
623
- if Puppet.features.microsoft_windows?
622
+ if Puppet::Util::Platform.windows?
624
623
  # Windows ReplaceFile needs a file to exist, so touch handles this
625
624
  if !Puppet::FileSystem.exist?(file)
626
625
  Puppet::FileSystem.touch(file)
@@ -184,7 +184,7 @@ module Puppet::Util::Execution
184
184
  Puppet.debug "Executing#{user_log_s}: '#{command_str}'"
185
185
  end
186
186
 
187
- null_file = Puppet.features.microsoft_windows? ? 'NUL' : '/dev/null'
187
+ null_file = Puppet::Util::Platform.windows? ? 'NUL' : '/dev/null'
188
188
 
189
189
  begin
190
190
  stdin = Puppet::FileSystem.open(options[:stdinfile] || null_file, nil, 'r')
@@ -264,7 +264,7 @@ module Puppet::Util::Execution
264
264
 
265
265
  raise e
266
266
  end
267
- elsif Puppet.features.microsoft_windows?
267
+ elsif Puppet::Util::Platform.windows?
268
268
  process_info = execute_windows(*exec_args)
269
269
  begin
270
270
  [stdin, stderr].each {|io| io.close rescue nil}
@@ -290,7 +290,7 @@ module Puppet::Util::Execution
290
290
  if !options[:squelch]
291
291
  # if we opened a pipe, we need to clean it up.
292
292
  reader.close if reader
293
- stdout.close! if Puppet.features.microsoft_windows?
293
+ stdout.close! if Puppet::Util::Platform.windows?
294
294
  end
295
295
  end
296
296
 
@@ -3,40 +3,56 @@ require 'puppet'
3
3
  class Puppet::Util::Feature
4
4
  attr_reader :path
5
5
 
6
- # Create a new feature test. You have to pass the feature name,
7
- # and it must be unique. You can either provide a block that
8
- # will get executed immediately to determine if the feature
9
- # is present, or you can pass an option to determine it.
10
- # Currently, the only supported option is 'libs' (must be
11
- # passed as a symbol), which will make sure that each lib loads
12
- # successfully.
13
- def add(name, options = {})
6
+ # Create a new feature test. You have to pass the feature name, and it must be
7
+ # unique. You can pass a block to determine if the feature is present:
8
+ #
9
+ # Puppet.features.add(:myfeature) do
10
+ # # return true or false if feature is available
11
+ # # return nil if feature may become available later
12
+ # end
13
+ #
14
+ # The block should return true if the feature is available, false if it is
15
+ # not, or nil if the state is unknown. True and false values will be cached. A
16
+ # nil value will not be cached, and should be used if the feature may become
17
+ # true in the future.
18
+ #
19
+ # Features are often used to detect if a ruby library is installed. To support
20
+ # that common case, you can pass one or more ruby libraries, and the feature
21
+ # will be true if all of the libraries load successfully:
22
+ #
23
+ # Puppet.features.add(:myfeature, libs: 'mylib')
24
+ # Puppet.features.add(:myfeature, libs: ['mylib', 'myotherlib'])
25
+ #
26
+ # If the ruby library is not installed, then the failure is not cached, as
27
+ # it's assumed puppet may install the gem during catalog application.
28
+ #
29
+ # If a feature is defined using `:libs` and a block, then the block is
30
+ # used and the `:libs` are ignored.
31
+ #
32
+ # Puppet evaluates the feature test when the `Puppet.features.myfeature?`
33
+ # method is called. If the feature test was defined using a block and the
34
+ # block returns nil, then the feature test will be re-evaluated the next time
35
+ # `Puppet.features.myfeature?` is called.
36
+ #
37
+ # @param [Symbol] name The unique feature name
38
+ # @param [Hash<Symbol,Array<String>>] options The libraries to load
39
+ def add(name, options = {}, &block)
14
40
  method = name.to_s + "?"
15
41
  @results.delete(name)
16
42
 
17
- if block_given?
18
- begin
19
- result = yield
20
- rescue StandardError,ScriptError => detail
21
- warn _("Failed to load feature test for %{name}: %{detail}") % { name: name, detail: detail }
22
- result = false
23
- end
24
- @results[name] = result
25
- end
26
-
27
43
  meta_def(method) do
28
44
  # we return a cached result if:
29
- # * if a block is given (and we just evaluated it above)
30
- # * if we already have a positive result
31
- # * if we've tested this feature before and it failed, but we're
32
- # configured to always cache
33
- if block_given? ||
34
- @results[name] ||
35
- (@results.has_key?(name) && (!Puppet[:always_retry_plugins]))
36
- @results[name]
45
+ # * if we've tested this feature before
46
+ # AND
47
+ # * the result was true/false
48
+ # OR
49
+ # * we're configured to never retry
50
+ if @results.has_key?(name) &&
51
+ (!@results[name].nil? || !Puppet[:always_retry_plugins])
52
+ !!@results[name]
37
53
  else
38
- @results[name] = test(name, options)
39
- @results[name]
54
+ @results[name] = test(name, options, &block)
55
+ !!@results[name]
40
56
  end
41
57
  end
42
58
  end
@@ -64,16 +80,22 @@ class Puppet::Util::Feature
64
80
  # Actually test whether the feature is present. We only want to test when
65
81
  # someone asks for the feature, so we don't unnecessarily load
66
82
  # files.
67
- def test(name, options)
68
- return true unless ary = options[:libs]
69
- ary = [ary] unless ary.is_a?(Array)
70
-
71
- ary.each do |lib|
72
- return false unless load_library(lib, name)
83
+ def test(name, options, &block)
84
+ if block_given?
85
+ begin
86
+ result = yield
87
+ rescue StandardError,ScriptError => detail
88
+ warn _("Failed to load feature test for %{name}: %{detail}") % { name: name, detail: detail }
89
+ result = nil
90
+ end
91
+ @results[name] = result
92
+ result
93
+ elsif libs = options[:libs]
94
+ libs = [libs] unless libs.is_a?(Array)
95
+ libs.all? { |lib| load_library(lib, name) } ? true : nil
96
+ else
97
+ true
73
98
  end
74
-
75
- # We loaded all of the required libraries
76
- true
77
99
  end
78
100
 
79
101
  private
@@ -86,10 +108,10 @@ class Puppet::Util::Feature
86
108
 
87
109
  begin
88
110
  require lib
111
+ true
89
112
  rescue ScriptError => detail
90
113
  Puppet.debug _("Failed to load library '%{lib}' for feature '%{name}': %{detail}") % { lib: lib, name: name, detail: detail }
91
- return false
114
+ false
92
115
  end
93
- true
94
116
  end
95
117
  end
@@ -219,7 +219,7 @@ Puppet::Util::Log.newdesttype :eventlog do
219
219
  Puppet::Util::Log::DestEventlog::EVENTLOG_CHARACTER_LIMIT = 31838
220
220
 
221
221
  def self.suitable?(obj)
222
- Puppet.features.microsoft_windows?
222
+ Puppet::Util::Platform.windows?
223
223
  end
224
224
 
225
225
  def initialize
@@ -30,7 +30,7 @@ module Puppet::Util::RDoc
30
30
  # replacing Ruby's normal / with \. When RDoc generates relative paths it
31
31
  # uses relative_path_from that will generate errors when the slashes don't
32
32
  # properly match. This is a workaround for that issue.
33
- if Puppet.features.microsoft_windows? && RDoc::VERSION !~ /^[0-3]\./
33
+ if Puppet::Util::Platform.windows? && RDoc::VERSION !~ /^[0-3]\./
34
34
  options += [ "--root", Dir.pwd.gsub(/\\/, '/')]
35
35
  end
36
36
  options += files
@@ -11,7 +11,7 @@ module Puppet
11
11
 
12
12
  def self.[](name)
13
13
  @run_modes ||= {}
14
- if Puppet.features.microsoft_windows?
14
+ if Puppet::Util::Platform.windows?
15
15
  @run_modes[name] ||= WindowsRunMode.new(name)
16
16
  else
17
17
  @run_modes[name] ||= UnixRunMode.new(name)
@@ -55,7 +55,7 @@ class Puppet::Util::Storage
55
55
  end
56
56
  Puppet::Util.benchmark(:debug, "Loaded state in %{seconds} seconds") do
57
57
  begin
58
- @@state = Puppet::Util::Yaml.load_file(filename)
58
+ @@state = Puppet::Util::Yaml.safe_load_file(filename, [Symbol, Time])
59
59
  rescue Puppet::Util::Yaml::YamlLoadError => detail
60
60
  Puppet.err _("Checksumfile %{filename} is corrupt (%{detail}); replacing") % { filename: filename, detail: detail }
61
61
 
@@ -47,10 +47,12 @@ module Puppet::Util::SUIDManager
47
47
  module_function :groups=
48
48
 
49
49
  def self.root?
50
- return Process.uid == 0 unless Puppet.features.microsoft_windows?
51
-
52
- require 'puppet/util/windows/user'
53
- Puppet::Util::Windows::User.admin?
50
+ if Puppet::Util::Platform.windows?
51
+ require 'puppet/util/windows/user'
52
+ Puppet::Util::Windows::User.admin?
53
+ else
54
+ Process.uid == 0
55
+ end
54
56
  end
55
57
 
56
58
  # Methods to handle changing uid/gid of the running process. In general,
@@ -61,7 +63,7 @@ module Puppet::Util::SUIDManager
61
63
  # If running on Windows or without root, the block will be run with the
62
64
  # current euid/egid.
63
65
  def asuser(new_uid=nil, new_gid=nil)
64
- return yield if Puppet.features.microsoft_windows?
66
+ return yield if Puppet::Util::Platform.windows?
65
67
  return yield unless root?
66
68
  return yield unless new_uid or new_gid
67
69
 
@@ -5,7 +5,7 @@ class Puppet::Util::TagSet < Set
5
5
  include Puppet::Network::FormatSupport
6
6
 
7
7
  def self.from_yaml(yaml)
8
- self.new(YAML.load(yaml))
8
+ self.new(Puppet::Util::Yaml.safe_load(yaml, [Symbol]))
9
9
  end
10
10
 
11
11
  def to_yaml
@@ -10,7 +10,7 @@ module Puppet::Util::Tagging
10
10
  def tag(*ary)
11
11
  @tags ||= new_tags
12
12
 
13
- ary.flatten.each do |tag|
13
+ ary.flatten.compact.each do |tag|
14
14
  name = tag.to_s.downcase
15
15
  # Add the tag before testing if it's valid since this means that
16
16
  # we never need to test the same valid tag twice. This speeds things
@@ -1,9 +1,10 @@
1
1
  require 'puppet/util/platform'
2
2
  module Puppet::Util::Windows
3
3
  module ADSI
4
- class User; end
4
+ class ADSIObject; end
5
+ class User < ADSIObject; end
5
6
  class UserProfile; end
6
- class Group; end
7
+ class Group < ADSIObject; end
7
8
  end
8
9
  module File; end
9
10
  module Registry
@@ -14,6 +15,20 @@ module Puppet::Util::Windows
14
15
  class EventLog; end
15
16
 
16
17
  if Puppet::Util::Platform.windows?
18
+ require 'Win32API' # case matters in this require!
19
+
20
+ # Note: Setting codepage here globally ensures all strings returned via
21
+ # WIN32OLE (Ruby's late-bound COM support) are encoded in Encoding::UTF_8
22
+ #
23
+ # Also, this does not modify the value of WIN32OLE.locale - which defaults
24
+ # to 2048 (at least on US English Windows) and is not listed in the MS
25
+ # locales table, here: https://msdn.microsoft.com/en-us/library/ms912047(v=winembedded.10).aspx
26
+ require 'win32ole' ; WIN32OLE.codepage = WIN32OLE::CP_UTF8
27
+ # gems
28
+ require 'win32/process'
29
+ require 'win32/dir'
30
+ require 'win32/service'
31
+
17
32
  # these reference platform specific gems
18
33
  require 'puppet/util/windows/api_types'
19
34
  require 'puppet/util/windows/string'
@@ -32,5 +47,6 @@ module Puppet::Util::Windows
32
47
  require 'puppet/util/windows/adsi'
33
48
  require 'puppet/util/windows/registry'
34
49
  require 'puppet/util/windows/eventlog'
50
+ require 'puppet/util/windows/service'
35
51
  end
36
52
  end
@@ -106,138 +106,200 @@ module Puppet::Util::Windows::ADSI
106
106
  [:lpwstr, :lpdword], :win32_bool
107
107
  end
108
108
 
109
- module Shared
110
- def localized_domains
111
- @localized_domains ||= [
112
- # localized version of BUILTIN
113
- # for instance VORDEFINIERT on German Windows
114
- Puppet::Util::Windows::SID.sid_to_name('S-1-5-32').upcase,
115
- # localized version of NT AUTHORITY (can't use S-1-5)
116
- # for instance AUTORITE NT on French Windows
117
- Puppet::Util::Windows::SID.name_to_principal('SYSTEM').domain.upcase
118
- ]
119
- end
109
+ # Common base class shared by the User and Group
110
+ # classes below.
111
+ class ADSIObject
112
+ extend Enumerable
120
113
 
121
- def uri(name, host = '.')
122
- host = '.' if (localized_domains << Socket.gethostname.upcase).include?(host.upcase)
114
+ # Define some useful class-level methods
115
+ class << self
116
+ # Is either 'user' or 'group'
117
+ attr_reader :object_class
118
+
119
+ def localized_domains
120
+ @localized_domains ||= [
121
+ # localized version of BUILTIN
122
+ # for instance VORDEFINIERT on German Windows
123
+ Puppet::Util::Windows::SID.sid_to_name('S-1-5-32').upcase,
124
+ # localized version of NT AUTHORITY (can't use S-1-5)
125
+ # for instance AUTORITE NT on French Windows
126
+ Puppet::Util::Windows::SID.name_to_principal('SYSTEM').domain.upcase
127
+ ]
128
+ end
123
129
 
124
- # group or user
125
- account_type = self.name.split('::').last.downcase
130
+ def uri(name, host = '.')
131
+ host = '.' if (localized_domains << Socket.gethostname.upcase).include?(host.upcase)
132
+ Puppet::Util::Windows::ADSI.uri(name, @object_class, host)
133
+ end
126
134
 
127
- Puppet::Util::Windows::ADSI.uri(name, account_type, host)
128
- end
135
+ def parse_name(name)
136
+ if name =~ /\//
137
+ raise Puppet::Error.new( _("Value must be in DOMAIN\\user style syntax") )
138
+ end
129
139
 
130
- def parse_name(name)
131
- if name =~ /\//
132
- raise Puppet::Error.new( _("Value must be in DOMAIN\\user style syntax") )
133
- end
140
+ matches = name.scan(/((.*)\\)?(.*)/)
141
+ domain = matches[0][1] || '.'
142
+ account = matches[0][2]
134
143
 
135
- matches = name.scan(/((.*)\\)?(.*)/)
136
- domain = matches[0][1] || '.'
137
- account = matches[0][2]
144
+ return account, domain
145
+ end
138
146
 
139
- return account, domain
140
- end
147
+ # returns Puppet::Util::Windows::SID::Principal[]
148
+ # may contain objects that represent unresolvable SIDs
149
+ def get_sids(adsi_child_collection)
150
+ sids = []
151
+ adsi_child_collection.each do |m|
152
+ sids << Puppet::Util::Windows::SID.ads_to_principal(m)
153
+ end
141
154
 
142
- # returns Puppet::Util::Windows::SID::Principal[]
143
- # may contain objects that represent unresolvable SIDs
144
- def get_sids(adsi_child_collection)
145
- sids = []
146
- adsi_child_collection.each do |m|
147
- sids << Puppet::Util::Windows::SID.ads_to_principal(m)
155
+ sids
148
156
  end
149
157
 
150
- sids
151
- end
158
+ def name_sid_hash(names)
159
+ return {} if names.nil? || names.empty?
152
160
 
153
- def name_sid_hash(names)
154
- return {} if names.nil? || names.empty?
161
+ sids = names.map do |name|
162
+ sid = Puppet::Util::Windows::SID.name_to_principal(name)
163
+ raise Puppet::Error.new( _("Could not resolve name: %{name}") % { name: name } ) if !sid
164
+ [sid.sid, sid]
165
+ end
155
166
 
156
- sids = names.map do |name|
157
- sid = Puppet::Util::Windows::SID.name_to_principal(name)
158
- raise Puppet::Error.new( _("Could not resolve name: %{name}") % { name: name } ) if !sid
159
- [sid.sid, sid]
167
+ Hash[ sids ]
160
168
  end
161
169
 
162
- Hash[ sids ]
163
- end
164
- end
165
170
 
166
- class User
167
- extend Enumerable
168
- extend Puppet::Util::Windows::ADSI::Shared
169
- extend FFI::Library
171
+ def delete(name)
172
+ Puppet::Util::Windows::ADSI.delete(name, @object_class)
173
+ end
170
174
 
171
- # https://msdn.microsoft.com/en-us/library/aa746340.aspx
172
- # IADsUser interface
175
+ def exists?(name_or_sid)
176
+ well_known = false
177
+ if (sid = Puppet::Util::Windows::SID.name_to_principal(name_or_sid))
178
+ # Examples of SidType include SidTypeUser, SidTypeGroup
179
+ return true if sid.account_type == "SidType#{@object_class.capitalize}".to_sym
180
+
181
+ # 'well known group' is special as it can be a group like Everyone OR a user like SYSTEM
182
+ # so try to resolve it
183
+ # https://msdn.microsoft.com/en-us/library/cc234477.aspx
184
+ well_known = sid.account_type == :SidTypeWellKnownGroup
185
+ return false if sid.account_type != :SidTypeAlias && !well_known
186
+ name_or_sid = "#{sid.domain}\\#{sid.account}"
187
+ end
173
188
 
174
- require 'puppet/util/windows/sid'
189
+ object = Puppet::Util::Windows::ADSI.connect(uri(*parse_name(name_or_sid)))
190
+ object.Class.downcase == @object_class
191
+ rescue
192
+ # special accounts like SYSTEM or special groups like Authenticated Users cannot
193
+ # resolve via monikers like WinNT://./SYSTEM,user or WinNT://./Authenticated Users,group
194
+ # -- they'll fail to connect. thus, given a validly resolved SID, this failure is
195
+ # ambiguous as it may indicate either a group like Service or an account like SYSTEM
196
+ well_known
197
+ end
175
198
 
176
- attr_accessor :native_user
177
- attr_reader :name, :sid
178
- def initialize(name, native_user = nil)
179
- @name = name
180
- @native_user = native_user
199
+ def list_all
200
+ raise NotImplementedError, _("Subclass must implement class-level method 'list_all'!")
201
+ end
202
+
203
+ def each(&block)
204
+ objects = []
205
+ list_all.each do |o|
206
+ # Setting WIN32OLE.codepage in the microsoft_windows feature ensures
207
+ # values are returned as UTF-8
208
+ objects << new(o.name)
209
+ end
210
+
211
+ objects.each(&block)
212
+ end
181
213
  end
182
214
 
183
- def native_user
184
- @native_user ||= Puppet::Util::Windows::ADSI.connect(self.class.uri(*self.class.parse_name(@name)))
215
+ attr_reader :name
216
+ def initialize(name, native_object = nil)
217
+ @name = name
218
+ @native_object = native_object
185
219
  end
186
220
 
187
- def sid
188
- @sid ||= Puppet::Util::Windows::SID.octet_string_to_principal(native_user.objectSID)
221
+ def object_class
222
+ self.class.object_class
189
223
  end
190
224
 
191
225
  def uri
192
226
  self.class.uri(sid.account, sid.domain)
193
227
  end
194
228
 
195
- def self.logon(name, password)
196
- Puppet::Util::Windows::User.password_is?(name, password)
229
+ def native_object
230
+ @native_object ||= Puppet::Util::Windows::ADSI.connect(self.class.uri(*self.class.parse_name(name)))
231
+ end
232
+
233
+ def sid
234
+ @sid ||= Puppet::Util::Windows::SID.octet_string_to_principal(native_object.objectSID)
197
235
  end
198
236
 
199
237
  def [](attribute)
200
- # Setting WIN32OLE.codepage in the microsoft_windows feature ensures
201
- # values are returned as UTF-8
202
- native_user.Get(attribute)
238
+ # Setting WIN32OLE.codepage ensures values are returned as UTF-8
239
+ native_object.Get(attribute)
203
240
  end
204
241
 
205
242
  def []=(attribute, value)
206
- native_user.Put(attribute, value)
243
+ native_object.Put(attribute, value)
207
244
  end
208
245
 
209
246
  def commit
210
247
  begin
211
- native_user.SetInfo unless native_user.nil?
248
+ native_object.SetInfo
212
249
  rescue WIN32OLERuntimeError => e
213
250
  # ERROR_BAD_USERNAME 2202L from winerror.h
214
251
  if e.message =~ /8007089A/m
215
252
  raise Puppet::Error.new(
216
- _("Puppet is not able to create/delete domain users with the user resource."),
217
- e
253
+ _("Puppet is not able to create/delete domain %{object_class}s with the %{object_class} resource.") % { object_class: object_class },
218
254
  )
219
255
  end
220
256
 
221
- raise Puppet::Error.new( _("User update failed: %{e}") % { e: e }, e )
257
+ raise Puppet::Error.new( _("%{object_class} update failed: %{error}") % { object_class: object_class.capitalize, error: e }, e )
222
258
  end
223
259
  self
224
260
  end
261
+ end
262
+
263
+ class User < ADSIObject
264
+ extend FFI::Library
265
+
266
+ require 'puppet/util/windows/sid'
267
+
268
+ # https://msdn.microsoft.com/en-us/library/aa746340.aspx
269
+ # IADsUser interface
270
+ @object_class = 'user'
271
+
272
+ class << self
273
+ def list_all
274
+ Puppet::Util::Windows::ADSI.execquery('select name from win32_useraccount where localaccount = "TRUE"')
275
+ end
276
+
277
+ def logon(name, password)
278
+ Puppet::Util::Windows::User.password_is?(name, password)
279
+ end
280
+
281
+ def create(name)
282
+ # Windows error 1379: The specified local group already exists.
283
+ raise Puppet::Error.new(_("Cannot create user if group '%{name}' exists.") % { name: name }) if Puppet::Util::Windows::ADSI::Group.exists? name
284
+ new(name, Puppet::Util::Windows::ADSI.create(name, @object_class))
285
+ end
286
+ end
225
287
 
226
288
  def password_is?(password)
227
289
  self.class.logon(name, password)
228
290
  end
229
291
 
230
292
  def add_flag(flag_name, value)
231
- flag = native_user.Get(flag_name) rescue 0
293
+ flag = native_object.Get(flag_name) rescue 0
232
294
 
233
- native_user.Put(flag_name, flag | value)
295
+ native_object.Put(flag_name, flag | value)
234
296
 
235
297
  commit
236
298
  end
237
299
 
238
300
  def password=(password)
239
301
  if !password.nil?
240
- native_user.SetPassword(password)
302
+ native_object.SetPassword(password)
241
303
  commit
242
304
  end
243
305
 
@@ -249,9 +311,8 @@ module Puppet::Util::Windows::ADSI
249
311
  # https://msdn.microsoft.com/en-us/library/aa746342.aspx
250
312
  # WIN32OLE objects aren't enumerable, so no map
251
313
  groups = []
252
- # Setting WIN32OLE.codepage in the microsoft_windows feature ensures
253
- # values are returned as UTF-8
254
- native_user.Groups.each {|g| groups << g.Name} rescue nil
314
+ # Setting WIN32OLE.codepage ensures values are returned as UTF-8
315
+ native_object.Groups.each {|g| groups << g.Name} rescue nil
255
316
  groups
256
317
  end
257
318
 
@@ -281,9 +342,13 @@ module Puppet::Util::Windows::ADSI
281
342
  end
282
343
 
283
344
  def group_sids
284
- self.class.get_sids(native_user.Groups)
345
+ self.class.get_sids(native_object.Groups)
285
346
  end
286
347
 
348
+ # TODO: This code's pretty similar to set_members in the Group class. Would be nice
349
+ # to refactor them into the ADSIObject class at some point. This was not done originally
350
+ # because these use different methods to do stuff that are also aliased to other methods,
351
+ # so the shared code isn't exactly a 1:1 mapping.
287
352
  def set_groups(desired_groups, minimum = true)
288
353
  return if desired_groups.nil?
289
354
 
@@ -311,11 +376,6 @@ module Puppet::Util::Windows::ADSI
311
376
  end
312
377
  end
313
378
 
314
- def self.create(name)
315
- # Windows error 1379: The specified local group already exists.
316
- raise Puppet::Error.new(_("Cannot create user if group '%{name}' exists.") % { name: name }) if Puppet::Util::Windows::ADSI::Group.exists? name
317
- new(name, Puppet::Util::Windows::ADSI.create(name, 'user'))
318
- end
319
379
 
320
380
  # UNLEN from lmcons.h - https://stackoverflow.com/a/2155176
321
381
  MAX_USERNAME_LENGTH = 256
@@ -341,47 +401,6 @@ module Puppet::Util::Windows::ADSI
341
401
  Puppet::Util::Windows::SID.name_to_principal(current_user_name)
342
402
  end
343
403
 
344
- def self.exists?(name_or_sid)
345
- well_known = false
346
- if (sid = Puppet::Util::Windows::SID.name_to_principal(name_or_sid))
347
- return true if sid.account_type == :SidTypeUser
348
-
349
- # 'well known group' is special as it can be a group like Everyone OR a user like SYSTEM
350
- # so try to resolve it
351
- # https://msdn.microsoft.com/en-us/library/cc234477.aspx
352
- well_known = sid.account_type == :SidTypeWellKnownGroup
353
- return false if sid.account_type != :SidTypeAlias && !well_known
354
- name_or_sid = "#{sid.domain}\\#{sid.account}"
355
- end
356
-
357
- user = Puppet::Util::Windows::ADSI.connect(User.uri(*User.parse_name(name_or_sid)))
358
- # otherwise, verify that the account is actually a User account
359
- user.Class == 'User'
360
- rescue
361
- # special accounts like SYSTEM cannot resolve via moniker like WinNT://./SYSTEM,user
362
- # and thus fail to connect - so given a validly resolved SID, this failure is ambiguous as it
363
- # may indicate either a group like Service or an account like SYSTEM
364
- well_known
365
- end
366
-
367
-
368
- def self.delete(name)
369
- Puppet::Util::Windows::ADSI.delete(name, 'user')
370
- end
371
-
372
- def self.each(&block)
373
- wql = Puppet::Util::Windows::ADSI.execquery('select name from win32_useraccount where localaccount = "TRUE"')
374
-
375
- users = []
376
- wql.each do |u|
377
- # Setting WIN32OLE.codepage in the microsoft_windows feature ensures
378
- # values are returned as UTF-8
379
- users << new(u.name)
380
- end
381
-
382
- users.each(&block)
383
- end
384
-
385
404
  ffi_convention :stdcall
386
405
 
387
406
  # https://msdn.microsoft.com/en-us/library/windows/desktop/ms724432(v=vs.85).aspx
@@ -410,58 +429,33 @@ module Puppet::Util::Windows::ADSI
410
429
  end
411
430
  end
412
431
 
413
- class Group
414
- extend Enumerable
415
- extend Puppet::Util::Windows::ADSI::Shared
432
+ class Group < ADSIObject
416
433
 
417
434
  # https://msdn.microsoft.com/en-us/library/aa706021.aspx
418
435
  # IADsGroup interface
436
+ @object_class = 'group'
419
437
 
420
- attr_accessor :native_group
421
- attr_reader :name, :sid
422
- def initialize(name, native_group = nil)
423
- @name = name
424
- @native_group = native_group
425
- end
426
-
427
- def uri
428
- self.class.uri(sid.account, sid.domain)
429
- end
430
-
431
- def native_group
432
- @native_group ||= Puppet::Util::Windows::ADSI.connect(self.class.uri(*self.class.parse_name(name)))
433
- end
434
-
435
- def sid
436
- @sid ||= Puppet::Util::Windows::SID.octet_string_to_principal(native_group.objectSID)
437
- end
438
-
439
- def commit
440
- begin
441
- native_group.SetInfo unless native_group.nil?
442
- rescue WIN32OLERuntimeError => e
443
- # ERROR_BAD_USERNAME 2202L from winerror.h
444
- if e.message =~ /8007089A/m
445
- raise Puppet::Error.new(
446
- _("Puppet is not able to create/delete domain groups with the group resource."),
447
- e
448
- )
449
- end
438
+ class << self
439
+ def list_all
440
+ Puppet::Util::Windows::ADSI.execquery('select name from win32_group where localaccount = "TRUE"')
441
+ end
450
442
 
451
- raise Puppet::Error.new( _("Group update failed: %{error}") % { error: e }, e )
443
+ def create(name)
444
+ # Windows error 2224: The account already exists.
445
+ raise Puppet::Error.new( _("Cannot create group if user '%{name}' exists.") % { name: name } ) if Puppet::Util::Windows::ADSI::User.exists?(name)
446
+ new(name, Puppet::Util::Windows::ADSI.create(name, @object_class))
452
447
  end
453
- self
454
448
  end
455
449
 
456
450
  def add_member_sids(*sids)
457
451
  sids.each do |sid|
458
- native_group.Add(Puppet::Util::Windows::ADSI.sid_uri(sid))
452
+ native_object.Add(Puppet::Util::Windows::ADSI.sid_uri(sid))
459
453
  end
460
454
  end
461
455
 
462
456
  def remove_member_sids(*sids)
463
457
  sids.each do |sid|
464
- native_group.Remove(Puppet::Util::Windows::ADSI.sid_uri(sid))
458
+ native_object.Remove(Puppet::Util::Windows::ADSI.sid_uri(sid))
465
459
  end
466
460
  end
467
461
 
@@ -469,7 +463,7 @@ module Puppet::Util::Windows::ADSI
469
463
  # may contain objects that represent unresolvable SIDs
470
464
  # qualified account names are returned by calling #domain_account
471
465
  def members
472
- self.class.get_sids(native_group.Members)
466
+ self.class.get_sids(native_object.Members)
473
467
  end
474
468
  alias member_sids members
475
469
 
@@ -496,50 +490,5 @@ module Puppet::Util::Windows::ADSI
496
490
  remove_member_sids(*members_to_remove)
497
491
  end
498
492
  end
499
-
500
- def self.create(name)
501
- # Windows error 2224: The account already exists.
502
- raise Puppet::Error.new( _("Cannot create group if user '%{name}' exists.") % { name: name } ) if Puppet::Util::Windows::ADSI::User.exists? name
503
- new(name, Puppet::Util::Windows::ADSI.create(name, 'group'))
504
- end
505
-
506
- def self.exists?(name_or_sid)
507
- well_known = false
508
- if (sid = Puppet::Util::Windows::SID.name_to_principal(name_or_sid))
509
- return true if sid.account_type == :SidTypeGroup
510
-
511
- # 'well known group' is special as it can be a group like Everyone OR a user like SYSTEM
512
- # so try to resolve it
513
- # https://msdn.microsoft.com/en-us/library/cc234477.aspx
514
- well_known = sid.account_type == :SidTypeWellKnownGroup
515
- return false if sid.account_type != :SidTypeAlias && !well_known
516
- name_or_sid = "#{sid.domain}\\#{sid.account}"
517
- end
518
-
519
- user = Puppet::Util::Windows::ADSI.connect(Group.uri(*Group.parse_name(name_or_sid)))
520
- user.Class == 'Group'
521
- rescue
522
- # special groups like Authenticated Users cannot resolve via moniker like WinNT://./Authenticated Users,group
523
- # and thus fail to connect - so given a validly resolved SID, this failure is ambiguous as it
524
- # may indicate either a group like Service or an account like SYSTEM
525
- well_known
526
- end
527
-
528
- def self.delete(name)
529
- Puppet::Util::Windows::ADSI.delete(name, 'group')
530
- end
531
-
532
- def self.each(&block)
533
- wql = Puppet::Util::Windows::ADSI.execquery('select name from win32_group where localaccount = "TRUE"')
534
-
535
- groups = []
536
- wql.each do |g|
537
- # Setting WIN32OLE.codepage in the microsoft_windows feature ensures
538
- # values are returned as UTF-8
539
- groups << new(g.name)
540
- end
541
-
542
- groups.each(&block)
543
- end
544
493
  end
545
494
  end