chef 13.8.5-universal-mingw32 → 13.9.1-universal-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/chef.gemspec +1 -1
- data/lib/chef/cookbook/remote_file_vendor.rb +1 -1
- data/lib/chef/deprecated.rb +7 -0
- data/lib/chef/mixin/params_validate.rb +19 -9
- data/lib/chef/mixin/properties.rb +17 -0
- data/lib/chef/property.rb +48 -1
- data/lib/chef/provider.rb +14 -0
- data/lib/chef/provider/mount.rb +9 -1
- data/lib/chef/provider/mount/aix.rb +1 -1
- data/lib/chef/provider/mount/mount.rb +8 -7
- data/lib/chef/provider/mount/solaris.rb +18 -17
- data/lib/chef/resource.rb +32 -2
- data/lib/chef/version.rb +1 -1
- data/lib/chef/win32/security.rb +14 -16
- data/spec/functional/win32/security_spec.rb +35 -0
- data/spec/unit/mixin/params_validate_spec.rb +12 -1
- data/spec/unit/mixin/properties_spec.rb +12 -2
- data/spec/unit/property/validation_spec.rb +9 -0
- data/spec/unit/property_spec.rb +24 -0
- data/spec/unit/provider/mount/mount_spec.rb +31 -2
- data/spec/unit/provider/mount/solaris_spec.rb +2 -2
- data/spec/unit/resource/mount_spec.rb +4 -41
- data/spec/unit/resource_spec.rb +31 -0
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 129ea66d9537785a3cc9ede009017b0ae4857e15
|
4
|
+
data.tar.gz: 72cb987366e8e5b7b9299d9e761da3b50ff4ea65
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dfe7fd479ee6bed400163e06b4c3ca5e34b081111b8fb262081311529cf8e7792c1cd1e838021691885aade50fc433e8a14c275ad82e31e4c4a4be5554ffed9c
|
7
|
+
data.tar.gz: 2cbc29e666e7c612592dbdceb324ed3bc2e0abc9b4ca738fdbd32a7cedf8ab74831be034af3a7cf3b3c59d185bd97cad2504f44f3fc6031ea56c42165a580c9b
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
13.
|
1
|
+
13.9.1
|
data/chef.gemspec
CHANGED
@@ -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", "
|
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
|
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.")
|
data/lib/chef/deprecated.rb
CHANGED
@@ -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-
|
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
|
data/lib/chef/property.rb
CHANGED
@@ -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
|
data/lib/chef/provider.rb
CHANGED
@@ -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
|
data/lib/chef/provider/mount.rb
CHANGED
@@ -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
|
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
|
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.
|
63
|
-
@current_resource.
|
64
|
-
@current_resource.
|
65
|
-
@current_resource.
|
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("
|
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("
|
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 =
|
125
|
-
current_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
|
-
|
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 =
|
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
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
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
|
data/lib/chef/resource.rb
CHANGED
@@ -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
|
#
|
data/lib/chef/version.rb
CHANGED
data/lib/chef/win32/security.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
607
|
-
|
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-
|
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
|
data/spec/unit/property_spec.rb
CHANGED
@@ -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
|
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}
|
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\
|
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
|
data/spec/unit/resource_spec.rb
CHANGED
@@ -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.
|
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
|
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.
|
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.
|
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
|