chef 13.8.5-universal-mingw32 → 13.9.1-universal-mingw32

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a696affe6cf16d554be6de2e78e982f55275dd88
4
- data.tar.gz: e3658761a4c3ac552071d840654674dbf09ef891
3
+ metadata.gz: 129ea66d9537785a3cc9ede009017b0ae4857e15
4
+ data.tar.gz: 72cb987366e8e5b7b9299d9e761da3b50ff4ea65
5
5
  SHA512:
6
- metadata.gz: 632a5ae329bb49fdb22d0f30f78b741276ab77fd9bde047bc19a0e15377144ff47ebfeec368e5228022801ed8e0bffa1f6befaa29a6c74dda1457fdc3fc2e477
7
- data.tar.gz: 50b74fbaa2ef9569c9455caee2f4ad501517df7bc5afeb967c339a44ac129b60eb8be9f91addd9939316a87c85328447cddebae02305be8dbd69a5fc67ff2402
6
+ metadata.gz: dfe7fd479ee6bed400163e06b4c3ca5e34b081111b8fb262081311529cf8e7792c1cd1e838021691885aade50fc433e8a14c275ad82e31e4c4a4be5554ffed9c
7
+ data.tar.gz: 2cbc29e666e7c612592dbdceb324ed3bc2e0abc9b4ca738fdbd32a7cedf8ab74831be034af3a7cf3b3c59d185bd97cad2504f44f3fc6031ea56c42165a580c9b
data/VERSION CHANGED
@@ -1 +1 @@
1
- 13.8.5
1
+ 13.9.1
@@ -32,7 +32,7 @@ Gem::Specification.new do |s|
32
32
  s.add_dependency "erubis", "~> 2.7"
33
33
  s.add_dependency "diff-lcs", "~> 1.2", ">= 1.2.4"
34
34
 
35
- s.add_dependency "chef-zero", ">= 13.0"
35
+ s.add_dependency "chef-zero", "~> 13.0"
36
36
 
37
37
  s.add_dependency "plist", "~> 3.2"
38
38
  s.add_dependency "iniparse", "~> 1.4"
@@ -62,7 +62,7 @@ class Chef
62
62
  # If the checksums are different between on-disk (current) and on-server
63
63
  # (remote, per manifest), do the update. This will also execute if there
64
64
  # is no current checksum.
65
- if found_manifest_record[:lazy] || current_checksum != found_manifest_record["checksum"]
65
+ if current_checksum != found_manifest_record["checksum"]
66
66
  raw_file = @rest.streaming_request(found_manifest_record[:url])
67
67
 
68
68
  Chef::Log.debug("Storing updated #{cache_filename} in the cache.")
@@ -280,6 +280,13 @@ class Chef
280
280
 
281
281
  # id 3694 was deleted
282
282
 
283
+ # Returned when using the deprecated option on a property
284
+ class Property < Base
285
+ def inspect
286
+ "#{message}\n#{location}"
287
+ end
288
+ end
289
+
283
290
  class Generic < Base
284
291
  def url
285
292
  "https://docs.chef.io/chef_deprecations_client.html"
@@ -1,6 +1,6 @@
1
1
  #
2
2
  # Author:: Adam Jacob (<adam@chef.io>)
3
- # Copyright:: Copyright 2008-2017, Chef Software Inc.
3
+ # Copyright:: Copyright 2008-2018, Chef Software Inc.
4
4
  # License:: Apache License, Version 2.0
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -35,6 +35,8 @@ class Chef
35
35
  # map options are:
36
36
  #
37
37
  # @param opts [Hash<Symbol,Object>] Validation opts.
38
+ # @option opts [String] :validation_message A custom message to return
39
+ # should validation fail.
38
40
  # @option opts [Object,Array] :is An object, or list of
39
41
  # objects, that must match the value using Ruby's `===` operator
40
42
  # (`opts[:is].any? { |v| v === value }`). (See #_pv_is.)
@@ -91,16 +93,20 @@ class Chef
91
93
  raise ArgumentError, "Options must be a hash" unless opts.kind_of?(Hash)
92
94
  raise ArgumentError, "Validation Map must be a hash" unless map.kind_of?(Hash)
93
95
 
96
+ @validation_message ||= {}
97
+
94
98
  map.each do |key, validation|
95
99
  unless key.kind_of?(Symbol) || key.kind_of?(String)
96
100
  raise ArgumentError, "Validation map keys must be symbols or strings!"
97
101
  end
102
+
98
103
  case validation
99
104
  when true
100
105
  _pv_required(opts, key)
101
106
  when false
102
107
  true
103
108
  when Hash
109
+ @validation_message[key] = validation.delete(:validation_message) if validation.has_key?(:validation_message)
104
110
  validation.each do |check, carg|
105
111
  check_method = "_pv_#{check}"
106
112
  if respond_to?(check_method, true)
@@ -129,6 +135,10 @@ class Chef
129
135
  validation.has_key?(:is) && _pv_is({ key => nil }, key, validation[:is], raise_error: false)
130
136
  end
131
137
 
138
+ def _validation_message(key, default)
139
+ @validation_message.has_key?(key) ? @validation_message[key] : default
140
+ end
141
+
132
142
  # Return the value of a parameter, or nil if it doesn't exist.
133
143
  def _pv_opts_lookup(opts, key)
134
144
  if opts.has_key?(key.to_s)
@@ -145,7 +155,7 @@ class Chef
145
155
  if is_required
146
156
  return true if opts.has_key?(key.to_s) && (explicitly_allows_nil || !opts[key.to_s].nil?)
147
157
  return true if opts.has_key?(key.to_sym) && (explicitly_allows_nil || !opts[key.to_sym].nil?)
148
- raise Exceptions::ValidationFailed, "Required argument #{key.inspect} is missing!"
158
+ raise Exceptions::ValidationFailed, _validation_message(key, "Required argument #{key.inspect} is missing!")
149
159
  end
150
160
  true
151
161
  end
@@ -168,7 +178,7 @@ class Chef
168
178
  to_be.each do |tb|
169
179
  return true if value == tb
170
180
  end
171
- raise Exceptions::ValidationFailed, "Option #{key} must be equal to one of: #{to_be.join(", ")}! You passed #{value.inspect}."
181
+ raise Exceptions::ValidationFailed, _validation_message(key, "Option #{key} must be equal to one of: #{to_be.join(", ")}! You passed #{value.inspect}.")
172
182
  end
173
183
  end
174
184
 
@@ -187,7 +197,7 @@ class Chef
187
197
  to_be.each do |tb|
188
198
  return true if value.kind_of?(tb)
189
199
  end
190
- raise Exceptions::ValidationFailed, "Option #{key} must be a kind of #{to_be}! You passed #{value.inspect}."
200
+ raise Exceptions::ValidationFailed, _validation_message(key, "Option #{key} must be a kind of #{to_be}! You passed #{value.inspect}.")
191
201
  end
192
202
  end
193
203
 
@@ -202,7 +212,7 @@ class Chef
202
212
  unless value.nil?
203
213
  Array(method_name_list).each do |method_name|
204
214
  unless value.respond_to?(method_name)
205
- raise Exceptions::ValidationFailed, "Option #{key} must have a #{method_name} method!"
215
+ raise Exceptions::ValidationFailed, _validation_message(key, "Option #{key} must have a #{method_name} method!")
206
216
  end
207
217
  end
208
218
  end
@@ -234,7 +244,7 @@ class Chef
234
244
 
235
245
  if value.respond_to?(predicate_method)
236
246
  if value.send(predicate_method)
237
- raise Exceptions::ValidationFailed, "Option #{key} cannot be #{predicate_method_base_name}"
247
+ raise Exceptions::ValidationFailed, _validation_message(key, "Option #{key} cannot be #{predicate_method_base_name}")
238
248
  end
239
249
  end
240
250
  end
@@ -294,7 +304,7 @@ class Chef
294
304
  Array(regex).flatten.each do |r|
295
305
  return true if r.match(value.to_s)
296
306
  end
297
- raise Exceptions::ValidationFailed, "Option #{key}'s value #{value} does not match regular expression #{regex.inspect}"
307
+ raise Exceptions::ValidationFailed, _validation_message(key, "Option #{key}'s value #{value} does not match regular expression #{regex.inspect}")
298
308
  end
299
309
  end
300
310
 
@@ -316,7 +326,7 @@ class Chef
316
326
  if !value.nil?
317
327
  callbacks.each do |message, zeproc|
318
328
  unless zeproc.call(value)
319
- raise Exceptions::ValidationFailed, "Option #{key}'s value #{value} #{message}!"
329
+ raise Exceptions::ValidationFailed, _validation_message(key, "Option #{key}'s value #{value} #{message}!")
320
330
  end
321
331
  end
322
332
  end
@@ -428,7 +438,7 @@ class Chef
428
438
  unless errors.empty?
429
439
  message << " Errors:\n#{errors.map { |m| "- #{m}" }.join("\n")}"
430
440
  end
431
- raise Exceptions::ValidationFailed, message
441
+ raise Exceptions::ValidationFailed, _validation_message(key, message)
432
442
  end
433
443
  end
434
444
 
@@ -75,6 +75,8 @@ class Chef
75
75
  # will return if the user does not set one. If this is `lazy`, it will
76
76
  # be run in the context of the instance (and able to access other
77
77
  # properties).
78
+ # @option options [String] :description A description of the property.
79
+ # @option options [String] :introduced The release that introduced this property
78
80
  # @option options [Boolean] :desired_state `true` if this property is
79
81
  # part of desired state. Defaults to `true`.
80
82
  # @option options [Boolean] :identity `true` if this property
@@ -147,6 +149,10 @@ class Chef
147
149
  Property.derive(**options)
148
150
  end
149
151
 
152
+ def deprecated_property_alias(from, to, message)
153
+ Property.emit_deprecated_alias(from, to, message, self)
154
+ end
155
+
150
156
  #
151
157
  # Create a lazy value for assignment to a default value.
152
158
  #
@@ -301,6 +307,17 @@ class Chef
301
307
  raise ArgumentError, "Property #{name} is not defined in class #{self}" if !property
302
308
  property.reset(self)
303
309
  end
310
+
311
+ #
312
+ # The description of the property
313
+ #
314
+ # @param name [Symbol] The name of the property.
315
+ # @return [String] The description of the property.
316
+ def property_description(name)
317
+ property = self.class.properties[name.to_sym]
318
+ raise ArgumentError, "Property #{name} is not defined in class #{self}" if !property
319
+ property.description
320
+ end
304
321
  end
305
322
  end
306
323
  end
@@ -51,6 +51,27 @@ class Chef
51
51
  new(**options)
52
52
  end
53
53
 
54
+ # This is to support #deprecated_property_alias, by emitting an alias and a
55
+ # deprecatation warning when called.
56
+ #
57
+ # @param from [String] Name of the deprecated property
58
+ # @param to [String] Name of the correct property
59
+ # @param message [String] Deprecation message to show to the cookbook author
60
+ # @param declared_in [Class] Class this property comes from
61
+ #
62
+ def self.emit_deprecated_alias(from, to, message, declared_in)
63
+ declared_in.class_eval <<-EOM, __FILE__, __LINE__ + 1
64
+ def #{from}(value=NOT_PASSED)
65
+ Chef.deprecated(:property, "#{message}")
66
+ #{to}(value)
67
+ end
68
+ def #{from}=(value)
69
+ Chef.deprecated(:property, "#{message}")
70
+ #{to} = value
71
+ end
72
+ EOM
73
+ end
74
+
54
75
  #
55
76
  # Create a new property.
56
77
  #
@@ -60,10 +81,12 @@ class Chef
60
81
  # options).
61
82
  # @option options [Symbol] :name The name of this property.
62
83
  # @option options [Class] :declared_in The class this property comes from.
84
+ # @option options [String] :description A description of the property.
63
85
  # @option options [Symbol] :instance_variable_name The instance variable
64
86
  # tied to this property. Must include a leading `@`. Defaults to `@<name>`.
65
87
  # `nil` means the property is opaque and not tied to a specific instance
66
88
  # variable.
89
+ # @option options [String] :introduced The release that introduced this property
67
90
  # @option options [Boolean] :desired_state `true` if this property is part of desired
68
91
  # state. Defaults to `true`.
69
92
  # @option options [Boolean] :identity `true` if this property is part of object
@@ -88,6 +111,8 @@ class Chef
88
111
  # @option options [Boolean] :required `true` if this property
89
112
  # must be present; `false` otherwise. This is checked after the resource
90
113
  # is fully initialized.
114
+ # @option options [String] :deprecated If set, this property is deprecated and
115
+ # will create a deprecation warning.
91
116
  #
92
117
  def initialize(**options)
93
118
  options = options.inject({}) { |memo, (key, value)| memo[key.to_sym] = value; memo }
@@ -157,6 +182,24 @@ class Chef
157
182
  options[:declared_in]
158
183
  end
159
184
 
185
+ #
186
+ # A description of this property.
187
+ #
188
+ # @return [String]
189
+ #
190
+ def description
191
+ options[:description]
192
+ end
193
+
194
+ #
195
+ # When this property was introduced
196
+ #
197
+ # @return [String]
198
+ #
199
+ def introduced
200
+ options[:introduced]
201
+ end
202
+
160
203
  #
161
204
  # The instance variable associated with this property.
162
205
  #
@@ -252,7 +295,7 @@ class Chef
252
295
  #
253
296
  def validation_options
254
297
  @validation_options ||= options.reject do |k, v|
255
- [:declared_in, :name, :instance_variable_name, :desired_state, :identity, :default, :name_property, :coerce, :required, :nillable, :sensitive].include?(k)
298
+ [:declared_in, :name, :instance_variable_name, :desired_state, :identity, :default, :name_property, :coerce, :required, :nillable, :sensitive, :description, :introduced, :deprecated].include?(k)
256
299
  end
257
300
  end
258
301
 
@@ -385,6 +428,10 @@ class Chef
385
428
  def set(resource, value)
386
429
  value = set_value(resource, input_to_stored_value(resource, value))
387
430
 
431
+ if options.has_key?(:deprecated)
432
+ Chef.deprecated(:property, options[:deprecated])
433
+ end
434
+
388
435
  if value.nil? && required?
389
436
  raise Chef::Exceptions::ValidationFailed, "#{name} is a required property"
390
437
  else
@@ -198,6 +198,20 @@ class Chef
198
198
  @requirements ||= ResourceRequirements.new(@new_resource, run_context)
199
199
  end
200
200
 
201
+ def description(description = "NOT_PASSED")
202
+ if description != "NOT_PASSED"
203
+ @description = description
204
+ end
205
+ @description
206
+ end
207
+
208
+ def introduced(introduced = "NOT_PASSED")
209
+ if introduced != "NOT_PASSED"
210
+ @introduced = introduced
211
+ end
212
+ @introduced
213
+ end
214
+
201
215
  def converge_by(descriptions, &block)
202
216
  converge_actions.add_action(descriptions, &block)
203
217
  end
@@ -83,7 +83,7 @@ class Chef
83
83
  end
84
84
 
85
85
  def action_enable
86
- unless current_resource.enabled && mount_options_unchanged?
86
+ unless current_resource.enabled && mount_options_unchanged? && device_unchanged?
87
87
  converge_by("enable #{current_resource.device}") do
88
88
  enable_fs
89
89
  Chef::Log.info("#{new_resource} enabled")
@@ -120,6 +120,14 @@ class Chef
120
120
  raise Chef::Exceptions::UnsupportedAction, "#{self} does not implement #mount_options_unchanged?"
121
121
  end
122
122
 
123
+ # It's entirely plausible that a site might prefer UUIDs or labels, so
124
+ # we need to be able to update fstab to conform with their wishes
125
+ # without necessarily needing to remount the device.
126
+ # See #6851 for more.
127
+ def device_unchanged?
128
+ @current_resource.device == @new_resource.device
129
+ end
130
+
123
131
  #
124
132
  # NOTE: for the following methods, this superclass will already have checked if the filesystem is
125
133
  # enabled and/or mounted and they will be called in converge_by blocks, so most defensive checking
@@ -29,7 +29,7 @@ class Chef
29
29
  super
30
30
  # options and fstype are set to "defaults" and "auto" respectively in the Mount Resource class. These options are not valid for AIX, override them.
31
31
  if @new_resource.options[0] == "defaults"
32
- @new_resource.options.clear
32
+ @new_resource.options([])
33
33
  end
34
34
  if @new_resource.fstype == "auto"
35
35
  @new_resource.send(:clear_fstype)
@@ -57,12 +57,13 @@ class Chef
57
57
  case line
58
58
  when /^[#\s]/
59
59
  next
60
- when /^#{device_fstab_regex}\s+#{Regexp.escape(@new_resource.mount_point)}\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/
60
+ when /^(#{device_fstab_regex})\s+#{Regexp.escape(@new_resource.mount_point)}\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/
61
61
  enabled = true
62
- @current_resource.fstype($1)
63
- @current_resource.options($2)
64
- @current_resource.dump($3.to_i)
65
- @current_resource.pass($4.to_i)
62
+ @current_resource.device($1)
63
+ @current_resource.fstype($2)
64
+ @current_resource.options($3)
65
+ @current_resource.dump($4.to_i)
66
+ @current_resource.pass($5.to_i)
66
67
  Chef::Log.debug("Found mount #{device_fstab} to #{@new_resource.mount_point} in /etc/fstab")
67
68
  next
68
69
  when /^[\/\w]+\s+#{Regexp.escape(@new_resource.mount_point)}\s+/
@@ -147,7 +148,7 @@ class Chef
147
148
  end
148
149
 
149
150
  def enable_fs
150
- if @current_resource.enabled && mount_options_unchanged?
151
+ if @current_resource.enabled && mount_options_unchanged? && device_unchanged?
151
152
  Chef::Log.debug("#{@new_resource} is already enabled - nothing to do")
152
153
  return nil
153
154
  end
@@ -253,7 +254,7 @@ class Chef
253
254
  if @new_resource.device_type == :device
254
255
  device_mount_regex
255
256
  else
256
- device_fstab
257
+ Regexp.union(device_fstab, device_mount_regex)
257
258
  end
258
259
  end
259
260
 
@@ -74,8 +74,8 @@ class Chef
74
74
  end
75
75
 
76
76
  def mount_fs
77
- actual_options = options || []
78
- actual_options.delete("noauto")
77
+ actual_options = native_options(options)
78
+ actual_options.delete("-")
79
79
  command = "mount -F #{fstype}"
80
80
  command << " -o #{actual_options.join(',')}" unless actual_options.empty?
81
81
  command << " #{device} #{mount_point}"
@@ -88,8 +88,8 @@ class Chef
88
88
 
89
89
  def remount_fs
90
90
  # FIXME: Should remount always do the remount or only if the options change?
91
- actual_options = options || []
92
- actual_options.delete("noauto")
91
+ actual_options = native_options(options)
92
+ actual_options.delete("-")
93
93
  mount_options = actual_options.empty? ? "" : ",#{actual_options.join(',')}"
94
94
  shell_out!("mount -o remount#{mount_options} #{mount_point}")
95
95
  end
@@ -121,8 +121,8 @@ class Chef
121
121
  end
122
122
 
123
123
  def mount_options_unchanged?
124
- new_options = options_remove_noauto(options)
125
- current_options = options_remove_noauto(current_resource.nil? ? nil : current_resource.options)
124
+ new_options = native_options(options)
125
+ current_options = native_options(current_resource.nil? ? nil : current_resource.options)
126
126
 
127
127
  current_resource.fsck_device == fsck_device &&
128
128
  current_resource.fstype == fstype &&
@@ -168,7 +168,8 @@ class Chef
168
168
  def read_vfstab_status
169
169
  # Check to see if there is an entry in /etc/vfstab. Last entry for a volume wins.
170
170
  enabled = false
171
- fstype = options = pass = nil
171
+ pass = false
172
+ fstype = options = nil
172
173
  ::File.foreach(VFSTAB) do |line|
173
174
  case line
174
175
  when /^[#\s]/
@@ -220,11 +221,7 @@ class Chef
220
221
  end
221
222
 
222
223
  def vfstab_entry
223
- actual_options = unless options.nil?
224
- tempops = options.dup
225
- tempops.delete("noauto")
226
- tempops
227
- end
224
+ actual_options = native_options(options)
228
225
  autostr = mount_at_boot? ? "yes" : "no"
229
226
  passstr = pass == 0 ? "-" : pass
230
227
  optstr = (actual_options.nil? || actual_options.empty?) ? "-" : actual_options.join(",")
@@ -251,11 +248,15 @@ class Chef
251
248
  contents << vfstab_entry
252
249
  end
253
250
 
254
- def options_remove_noauto(temp_options)
255
- new_options = []
256
- new_options += temp_options.nil? ? [] : temp_options
257
- new_options.delete("noauto")
258
- new_options
251
+ def native_options(temp_options)
252
+ if temp_options == %w{defaults}
253
+ ["-"]
254
+ else
255
+ new_options = []
256
+ new_options += temp_options.nil? ? [] : temp_options.dup
257
+ new_options.delete("noauto")
258
+ new_options
259
+ end
259
260
  end
260
261
 
261
262
  def device_regex
@@ -141,6 +141,7 @@ class Chef
141
141
  @not_if = []
142
142
  @only_if = []
143
143
  @source_line = nil
144
+ @deprecated = false
144
145
  # We would like to raise an error when the user gives us a guard
145
146
  # interpreter and a ruby_block to the guard. In order to achieve this
146
147
  # we need to understand when the user overrides the default guard
@@ -1179,8 +1180,8 @@ class Chef
1179
1180
  # Internal Resource Interface (for Chef)
1180
1181
  #
1181
1182
 
1182
- FORBIDDEN_IVARS = [:@run_context, :@not_if, :@only_if, :@enclosing_provider]
1183
- HIDDEN_IVARS = [:@allowed_actions, :@resource_name, :@source_line, :@run_context, :@name, :@not_if, :@only_if, :@elapsed_time, :@enclosing_provider]
1183
+ FORBIDDEN_IVARS = [:@run_context, :@not_if, :@only_if, :@enclosing_provider, :@description, :@introduced, :@examples, :@validation_message, :@deprecated]
1184
+ HIDDEN_IVARS = [:@allowed_actions, :@resource_name, :@source_line, :@run_context, :@name, :@not_if, :@only_if, :@elapsed_time, :@enclosing_provider, :@description, :@introduced, :@examples, :@validation_message, :@deprecated]
1184
1185
 
1185
1186
  include Chef::Mixin::ConvertToClassName
1186
1187
  extend Chef::Mixin::ConvertToClassName
@@ -1379,6 +1380,35 @@ class Chef
1379
1380
  end
1380
1381
  end
1381
1382
 
1383
+ def self.description(description = "NOT_PASSED")
1384
+ if description != "NOT_PASSED"
1385
+ @description = description
1386
+ end
1387
+ @description
1388
+ end
1389
+
1390
+ def self.introduced(introduced = "NOT_PASSED")
1391
+ if introduced != "NOT_PASSED"
1392
+ @introduced = introduced
1393
+ end
1394
+ @introduced
1395
+ end
1396
+
1397
+ def self.examples(examples = "NOT_PASSED")
1398
+ if examples != "NOT_PASSED"
1399
+ @examples = examples
1400
+ end
1401
+ @examples
1402
+ end
1403
+
1404
+ def self.deprecated(deprecated = "NOT_PASSED")
1405
+ if deprecated != "NOT_PASSED"
1406
+ @deprecated = true
1407
+ @deprecated_message = deprecated
1408
+ end
1409
+ @deprecated
1410
+ end
1411
+
1382
1412
  #
1383
1413
  # The cookbook in which this Resource was defined (if any).
1384
1414
  #
@@ -23,7 +23,7 @@ require "chef/version_string"
23
23
 
24
24
  class Chef
25
25
  CHEF_ROOT = File.expand_path("../..", __FILE__)
26
- VERSION = Chef::VersionString.new("13.8.5")
26
+ VERSION = Chef::VersionString.new("13.9.1")
27
27
  end
28
28
 
29
29
  #
@@ -113,10 +113,7 @@ class Chef
113
113
 
114
114
  with_lsa_policy(name) do |policy_handle, sid|
115
115
  result = LsaAddAccountRights(policy_handle.read_pointer, sid, privilege_pointer, 1)
116
- win32_error = LsaNtStatusToWinError(result)
117
- if win32_error != 0
118
- Chef::ReservedNames::Win32::Error.raise!(nil, win32_error)
119
- end
116
+ test_and_raise_lsa_nt_status(result)
120
117
  end
121
118
  end
122
119
 
@@ -190,15 +187,14 @@ class Chef
190
187
  result = LsaEnumerateAccountRights(policy_handle.read_pointer, sid, privilege_pointer, privilege_length)
191
188
  win32_error = LsaNtStatusToWinError(result)
192
189
  return [] if win32_error == 2 # FILE_NOT_FOUND - No rights assigned
193
- if win32_error != 0
194
- Chef::ReservedNames::Win32::Error.raise!(nil, win32_error)
195
- end
190
+ test_and_raise_lsa_nt_status(result)
196
191
 
197
192
  privilege_length.read_ulong.times do |i|
198
193
  privilege = LSA_UNICODE_STRING.new(privilege_pointer.read_pointer + i * LSA_UNICODE_STRING.size)
199
194
  privileges << privilege[:Buffer].read_wstring
200
195
  end
201
- LsaFreeMemory(privilege_pointer)
196
+ result = LsaFreeMemory(privilege_pointer.read_pointer)
197
+ test_and_raise_lsa_nt_status(result)
202
198
  end
203
199
 
204
200
  privileges
@@ -595,18 +591,13 @@ class Chef
595
591
 
596
592
  policy_handle = FFI::MemoryPointer.new(:pointer)
597
593
  result = LsaOpenPolicy(nil, LSA_OBJECT_ATTRIBUTES.new, access, policy_handle)
598
- win32_error = LsaNtStatusToWinError(result)
599
- if win32_error != 0
600
- Chef::ReservedNames::Win32::Error.raise!(nil, win32_error)
601
- end
594
+ test_and_raise_lsa_nt_status(result)
602
595
 
603
596
  begin
604
597
  yield policy_handle, sid.pointer
605
598
  ensure
606
- win32_error = LsaNtStatusToWinError(LsaClose(policy_handle.read_pointer))
607
- if win32_error != 0
608
- Chef::ReservedNames::Win32::Error.raise!(nil, win32_error)
609
- end
599
+ result = LsaClose(policy_handle.read_pointer)
600
+ test_and_raise_lsa_nt_status(result)
610
601
  end
611
602
  end
612
603
 
@@ -654,6 +645,13 @@ class Chef
654
645
  end
655
646
  Token.new(Handle.new(token.read_pointer))
656
647
  end
648
+
649
+ def self.test_and_raise_lsa_nt_status(result)
650
+ win32_error = LsaNtStatusToWinError(result)
651
+ if win32_error != 0
652
+ Chef::ReservedNames::Win32::Error.raise!(nil, win32_error)
653
+ end
654
+ end
657
655
  end
658
656
  end
659
657
  end
@@ -97,4 +97,39 @@ describe "Chef::Win32::Security", :windows_only do
97
97
  end
98
98
  end
99
99
  end
100
+
101
+ describe ".get_account_right" do
102
+ let(:username) { ENV["USERNAME"] }
103
+
104
+ context "when given a valid username" do
105
+ it "returns an array of account right constants" do
106
+ Chef::ReservedNames::Win32::Security.add_account_right(username, "SeBatchLogonRight")
107
+ expect(Chef::ReservedNames::Win32::Security.get_account_right(username)).to include("SeBatchLogonRight")
108
+ end
109
+
110
+ it "passes an FFI::Pointer to LsaFreeMemory" do
111
+ Chef::ReservedNames::Win32::Security.add_account_right(username, "SeBatchLogonRight") # otherwise we return an empty array before LsaFreeMemory
112
+ expect(Chef::ReservedNames::Win32::Security).to receive(:LsaFreeMemory).with(instance_of(FFI::Pointer)).and_return(0) # not FFI::MemoryPointer
113
+ Chef::ReservedNames::Win32::Security.get_account_right(username)
114
+ end
115
+ end
116
+
117
+ context "when given an invalid username" do
118
+ let(:username) { "noooooooooope" }
119
+
120
+ it "raises an exception" do
121
+ expect { Chef::ReservedNames::Win32::Security.get_account_right(username) }.to raise_error(Chef::Exceptions::Win32APIError)
122
+ end
123
+ end
124
+ end
125
+
126
+ describe ".test_and_raise_lsa_nt_status" do
127
+ # NTSTATUS code: 0xC0000001 / STATUS_UNSUCCESSFUL
128
+ # Windows Error: ERROR_GEN_FAILURE / 31 / 0x1F / A device attached to the system is not functioning.
129
+ let(:status_unsuccessful) { 0xC0000001 }
130
+
131
+ it "raises an exception with the Win Error if the win32 result is not 0" do
132
+ expect { Chef::ReservedNames::Win32::Security.test_and_raise_lsa_nt_status(status_unsuccessful) }.to raise_error(Chef::Exceptions::Win32APIError)
133
+ end
134
+ end
100
135
  end
@@ -1,6 +1,6 @@
1
1
  #
2
2
  # Author:: Adam Jacob (<adam@chef.io>)
3
- # Copyright:: Copyright 2008-2016, Chef Software Inc.
3
+ # Copyright:: Copyright 2008-2018, Chef Software Inc.
4
4
  # License:: Apache License, Version 2.0
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -342,6 +342,17 @@ describe Chef::Mixin::ParamsValidate do
342
342
  end.to raise_error(Chef::Exceptions::ValidationFailed)
343
343
  end
344
344
 
345
+ it "allows a custom validation message" do
346
+ expect do
347
+ @vo.validate({ :not_blank => "should pass" },
348
+ { :not_blank => { :cannot_be => [ :nil, :empty ], validation_message: "my validation message" } })
349
+ end.not_to raise_error
350
+ expect do
351
+ @vo.validate({ :not_blank => "" },
352
+ { :not_blank => { :cannot_be => [ :nil, :empty ], validation_message: "my validation message" } })
353
+ end.to raise_error(Chef::Exceptions::ValidationFailed, "my validation message")
354
+ end
355
+
345
356
  it "should set and return a value, then return the same value" do
346
357
  value = "meow"
347
358
  expect(@vo.set_or_return(:test, value, {}).object_id).to eq(value.object_id)
@@ -11,6 +11,7 @@ module ChefMixinPropertiesSpec
11
11
  property :a, "a", default: "a"
12
12
  property :ab, %w{a b}, default: "a"
13
13
  property :ac, %w{a c}, default: "a"
14
+ property :d, "d", description: "The d property", introduced: "14.0"
14
15
  end
15
16
 
16
17
  context "and a module B with properties b, ab and bc" do
@@ -30,11 +31,20 @@ module ChefMixinPropertiesSpec
30
31
  end
31
32
 
32
33
  it "A.properties has a, ab, and ac with types 'a', ['a', 'b'], and ['b', 'c']" do
33
- expect(A.properties.keys).to eq [ :a, :ab, :ac ]
34
+ expect(A.properties.keys).to eq [ :a, :ab, :ac, :d ]
34
35
  expect(A.properties[:a].validation_options[:is]).to eq "a"
35
36
  expect(A.properties[:ab].validation_options[:is]).to eq %w{a b}
36
37
  expect(A.properties[:ac].validation_options[:is]).to eq %w{a c}
37
38
  end
39
+
40
+ it "A.properties can get the description of `d`" do
41
+ expect(A.properties[:d].description).to eq "The d property"
42
+ end
43
+
44
+ it "A.properties can get the release that introduced `d`" do
45
+ expect(A.properties[:d].introduced).to eq "14.0"
46
+ end
47
+
38
48
  it "B.properties has b, ab, and bc with types 'b', nil and ['b', 'c']" do
39
49
  expect(B.properties.keys).to eq [ :b, :ab, :bc ]
40
50
  expect(B.properties[:b].validation_options[:is]).to eq "b"
@@ -42,7 +52,7 @@ module ChefMixinPropertiesSpec
42
52
  expect(B.properties[:bc].validation_options[:is]).to eq %w{b c}
43
53
  end
44
54
  it "C.properties has a, b, c, ac and bc with merged types" do
45
- expect(C.properties.keys).to eq [ :a, :ab, :ac, :b, :bc, :c ]
55
+ expect(C.properties.keys).to eq [ :a, :ab, :ac, :d, :b, :bc, :c ]
46
56
  expect(C.properties[:a].validation_options[:is]).to eq "a"
47
57
  expect(C.properties[:b].validation_options[:is]).to eq "b"
48
58
  expect(C.properties[:c].validation_options[:is]).to eq "c"
@@ -699,4 +699,13 @@ describe "Chef::Resource.property validation" do
699
699
  end
700
700
  end
701
701
  end
702
+
703
+ context "custom validation messages" do
704
+ with_property ":x, String, validation_message: 'Must be a string, fool'" do
705
+ it "raise with the correct error message" do
706
+ expect { resource.x 1 }.to raise_error Chef::Exceptions::ValidationFailed,
707
+ "Must be a string, fool"
708
+ end
709
+ end
710
+ end
702
711
  end
@@ -118,6 +118,19 @@ describe "Chef::Resource.property" do
118
118
  end
119
119
  end
120
120
 
121
+ context "deprecated properties" do
122
+ it "does not create a deprecation warning on definition" do
123
+ expect { resource_class.class_eval { property :x, String, deprecated: 10 } }.not_to raise_error Chef::Exceptions::DeprecatedFeatureError
124
+ end
125
+
126
+ with_property ":x, deprecated: 'a deprecated property'" do
127
+ it "deprecated properties emit a deprecation warning" do
128
+ expect(Chef).to receive(:deprecated).with(:property, "a deprecated property")
129
+ expect(resource.x 10).to eq 10
130
+ end
131
+ end
132
+ end
133
+
121
134
  with_property ":x, name_property: true" do
122
135
  context "and subclass" do
123
136
  let(:subresource_class) do
@@ -1143,6 +1156,17 @@ describe "Chef::Resource.property" do
1143
1156
 
1144
1157
  end
1145
1158
 
1159
+ context "with aliased properties" do
1160
+ with_property ":real, Integer" do
1161
+ it "should set the real property and emit a deprecation message" do
1162
+ expect(Chef).to receive(:deprecated).with(:property, "we don't like the deprecated property no more")
1163
+ resource_class.class_eval { deprecated_property_alias :deprecated, :real, "we don't like the deprecated property no more" }
1164
+ resource.deprecated 10
1165
+ expect(resource.real).to eq 10
1166
+ end
1167
+ end
1168
+ end
1169
+
1146
1170
  context "redefining Object methods" do
1147
1171
  it "disallows redefining Object methods" do
1148
1172
  expect { resource_class.class_eval { property :hash } }.to raise_error(ArgumentError)
@@ -53,13 +53,13 @@ describe Chef::Provider::Mount::Mount do
53
53
  expect(@provider.current_resource.device).to eq("/dev/sdz1")
54
54
  end
55
55
 
56
- it "should accecpt device_type :uuid", :not_supported_on_solaris do
56
+ it "should accept device_type :uuid", :not_supported_on_solaris do
57
57
  @status = double(:stdout => "/dev/sdz1\n", :exitstatus => 1)
58
58
  @new_resource.device_type :uuid
59
59
  @new_resource.device "d21afe51-a0fe-4dc6-9152-ac733763ae0a"
60
60
  @stdout_findfs = double("STDOUT", :first => "/dev/sdz1")
61
61
  expect(@provider).to receive(:shell_out).with("/sbin/findfs UUID=d21afe51-a0fe-4dc6-9152-ac733763ae0a").and_return(@status)
62
- @provider.load_current_resource()
62
+ @provider.load_current_resource
63
63
  @provider.mountable?
64
64
  end
65
65
 
@@ -470,5 +470,34 @@ describe Chef::Provider::Mount::Mount do
470
470
  @provider.disable_fs
471
471
  end
472
472
  end
473
+
474
+ # the fstab might contain the mount with the device as a device but the resource has a label.
475
+ # we should not create two mount lines, but update the existing one
476
+ context "when the device is described differently" do
477
+ it "should update the existing line" do
478
+ @current_resource.enabled(true)
479
+ status = double(:stdout => "/dev/sdz1\n", :exitstatus => 1)
480
+ expect(@provider).to receive(:shell_out).with("/sbin/findfs UUID=d21afe51-a0fe-4dc6-9152-ac733763ae0a").and_return(status)
481
+
482
+ filesystems = [%q{/dev/sdy1 /tmp/foo ext3 defaults 1 2},
483
+ %q{/dev/sdz1 /tmp/foo ext3 defaults 1 2}].join("\n")
484
+ fstab = StringIO.new filesystems
485
+
486
+ fstab_write = StringIO.new
487
+
488
+ allow(::File).to receive(:readlines).with("/etc/fstab").and_return(fstab.readlines)
489
+ allow(::File).to receive(:open).with("/etc/fstab", "w").and_yield(fstab_write)
490
+ allow(::File).to receive(:open).with("/etc/fstab", "a").and_yield(fstab_write)
491
+
492
+ @new_resource.device_type :uuid
493
+ @new_resource.device "d21afe51-a0fe-4dc6-9152-ac733763ae0a"
494
+ @new_resource.dump 1
495
+
496
+ @provider.enable_fs
497
+ expect(fstab_write.string).to match(%r{/dev/sdy1\s+/tmp/foo\s+ext3\s+defaults\s+1\s+2})
498
+ expect(fstab_write.string).to match(%r{UUID=d21afe51-a0fe-4dc6-9152-ac733763ae0a\s+/tmp/foo\s+ext3\s+defaults\s+1\s+2})
499
+ expect(fstab_write.string).not_to match(%r{/dev/sdz1\s+/tmp/foo\s+ext3\s+defaults\s+1\s+2})
500
+ end
501
+ end
473
502
  end
474
503
  end
@@ -538,7 +538,7 @@ describe Chef::Provider::Mount::Solaris, :unix_only do
538
538
  context "after the mount's state has been discovered" do
539
539
  describe "mount_fs" do
540
540
  it "should mount the filesystem" do
541
- expect(provider).to receive(:shell_out!).with("mount -F #{fstype} -o defaults #{device} #{mountpoint}")
541
+ expect(provider).to receive(:shell_out!).with("mount -F #{fstype} #{device} #{mountpoint}")
542
542
  provider.mount_fs()
543
543
  end
544
544
 
@@ -600,7 +600,7 @@ describe Chef::Provider::Mount::Solaris, :unix_only do
600
600
  context "in the typical case" do
601
601
  let(:other_mount) { "/dev/dsk/c0t2d0s0 /dev/rdsk/c0t2d0s0 / ufs 2 yes -" }
602
602
 
603
- let(:this_mount) { "/dev/dsk/c0t2d0s7\t/dev/rdsk/c0t2d0s7\t/mnt/foo\tufs\t2\tyes\tdefaults\n" }
603
+ let(:this_mount) { "/dev/dsk/c0t2d0s7\t/dev/rdsk/c0t2d0s7\t/mnt/foo\tufs\t2\tyes\t-\n" }
604
604
 
605
605
  let(:vfstab_file_contents) { [other_mount].join("\n") }
606
606
 
@@ -66,6 +66,10 @@ describe Chef::Resource::Mount do
66
66
  expect(resource.fstype).to eql("nfs")
67
67
  end
68
68
 
69
+ it "sets fstype to 'auto' by default" do
70
+ expect(resource.fstype).to eql("auto")
71
+ end
72
+
69
73
  it "allows you to set the dump attribute" do
70
74
  resource.dump 1
71
75
  expect(resource.dump).to eql(1)
@@ -169,45 +173,4 @@ describe Chef::Resource::Mount do
169
173
  resource.domain("TEST_DOMAIN")
170
174
  expect(resource.domain).to eq("TEST_DOMAIN")
171
175
  end
172
-
173
- describe "when it has mount point, device type, and fstype" do
174
- before do
175
- resource.device("charmander")
176
- resource.mount_point("123.456")
177
- resource.device_type(:device)
178
- resource.fstype("ranked")
179
- end
180
-
181
- it "describes its state" do
182
- state = resource.state_for_resource_reporter
183
- expect(state[:mount_point]).to eq("123.456")
184
- expect(state[:device_type]).to eql(:device)
185
- expect(state[:fstype]).to eq("ranked")
186
- end
187
-
188
- it "returns the device as its identity" do
189
- expect(resource.identity).to eq("charmander")
190
- end
191
- end
192
-
193
- describe "when it has username, password and domain" do
194
- before do
195
- resource.mount_point("T:")
196
- resource.device("charmander")
197
- resource.username("Administrator")
198
- resource.password("Jetstream123!")
199
- resource.domain("TEST_DOMAIN")
200
- end
201
-
202
- it "describes its state" do
203
- state = resource.state_for_resource_reporter
204
- expect(state[:mount_point]).to eq("T:")
205
- expect(state[:username]).to eq("Administrator")
206
- expect(state[:password]).to eq("*sensitive value suppressed*")
207
- expect(state[:domain]).to eq("TEST_DOMAIN")
208
- expect(state[:device_type]).to eql(:device)
209
- expect(state[:fstype]).to eq("auto")
210
- end
211
-
212
- end
213
176
  end
@@ -387,6 +387,37 @@ describe Chef::Resource do
387
387
  end
388
388
  end
389
389
 
390
+ context "Documentation of resources" do
391
+ it "can have a description" do
392
+ c = Class.new(Chef::Resource) do
393
+ description "my description"
394
+ end
395
+ expect(c.description).to eq "my description"
396
+ end
397
+
398
+ it "can say when it was introduced" do
399
+ c = Class.new(Chef::Resource) do
400
+ introduced "14.0"
401
+ end
402
+ expect(c.introduced).to eq "14.0"
403
+ end
404
+
405
+ it "can have some examples" do
406
+ c = Class.new(Chef::Resource) do
407
+ examples <<-EOH
408
+ resource "foo" do
409
+ foo foo
410
+ end
411
+ EOH
412
+ end
413
+ expect(c.examples).to eq <<-EOH
414
+ resource "foo" do
415
+ foo foo
416
+ end
417
+ EOH
418
+ end
419
+ end
420
+
390
421
  describe "self.resource_name" do
391
422
  context "When resource_name is not set" do
392
423
  it "and there are no provides lines, resource_name is nil" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chef
3
3
  version: !ruby/object:Gem::Version
4
- version: 13.8.5
4
+ version: 13.9.1
5
5
  platform: universal-mingw32
6
6
  authors:
7
7
  - Adam Jacob
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-03-07 00:00:00.000000000 Z
11
+ date: 2018-05-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chef-config
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 13.8.5
19
+ version: 13.9.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 13.8.5
26
+ version: 13.9.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: mixlib-cli
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -240,14 +240,14 @@ dependencies:
240
240
  name: chef-zero
241
241
  requirement: !ruby/object:Gem::Requirement
242
242
  requirements:
243
- - - ">="
243
+ - - "~>"
244
244
  - !ruby/object:Gem::Version
245
245
  version: '13.0'
246
246
  type: :runtime
247
247
  prerelease: false
248
248
  version_requirements: !ruby/object:Gem::Requirement
249
249
  requirements:
250
- - - ">="
250
+ - - "~>"
251
251
  - !ruby/object:Gem::Version
252
252
  version: '13.0'
253
253
  - !ruby/object:Gem::Dependency