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 +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
|