chef-encrypted-attributes 0.3.0 → 0.4.0
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
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.yardopts +8 -0
- data/CHANGELOG.md +40 -4
- data/CONTRIBUTING.md +7 -6
- data/KNIFE.md +151 -0
- data/README.md +70 -192
- data/Rakefile +27 -14
- data/TESTING.md +18 -7
- data/TODO.md +2 -5
- data/lib/chef-encrypted-attributes.rb +7 -1
- data/lib/chef/encrypted_attribute.rb +282 -121
- data/lib/chef/encrypted_attribute/api.rb +521 -0
- data/lib/chef/encrypted_attribute/assertions.rb +16 -6
- data/lib/chef/encrypted_attribute/cache_lru.rb +54 -13
- data/lib/chef/encrypted_attribute/config.rb +198 -89
- data/lib/chef/encrypted_attribute/encrypted_mash.rb +127 -33
- data/lib/chef/encrypted_attribute/encrypted_mash/version0.rb +236 -48
- data/lib/chef/encrypted_attribute/encrypted_mash/version1.rb +249 -36
- data/lib/chef/encrypted_attribute/encrypted_mash/version2.rb +133 -19
- data/lib/chef/encrypted_attribute/exceptions.rb +19 -3
- data/lib/chef/encrypted_attribute/local_node.rb +15 -4
- data/lib/chef/encrypted_attribute/remote_clients.rb +33 -17
- data/lib/chef/encrypted_attribute/remote_node.rb +84 -29
- data/lib/chef/encrypted_attribute/remote_nodes.rb +62 -11
- data/lib/chef/encrypted_attribute/remote_users.rb +58 -19
- data/lib/chef/encrypted_attribute/search_helper.rb +214 -74
- data/lib/chef/encrypted_attribute/version.rb +3 -1
- data/lib/chef/encrypted_attributes.rb +20 -0
- data/lib/chef/knife/core/config.rb +4 -1
- data/lib/chef/knife/core/encrypted_attribute_base.rb +179 -0
- data/lib/chef/knife/core/encrypted_attribute_depends.rb +43 -0
- data/lib/chef/knife/core/encrypted_attribute_editor_options.rb +125 -61
- data/lib/chef/knife/encrypted_attribute_create.rb +51 -31
- data/lib/chef/knife/encrypted_attribute_delete.rb +32 -40
- data/lib/chef/knife/encrypted_attribute_edit.rb +51 -32
- data/lib/chef/knife/encrypted_attribute_show.rb +30 -55
- data/lib/chef/knife/encrypted_attribute_update.rb +43 -28
- data/spec/benchmark_helper.rb +2 -1
- data/spec/integration_helper.rb +1 -0
- data/spec/spec_helper.rb +21 -7
- metadata +75 -36
- metadata.gz.sig +1 -1
- data/API.md +0 -174
- data/INTERNAL.md +0 -166
@@ -1,3 +1,4 @@
|
|
1
|
+
# encoding: UTF-8
|
1
2
|
#
|
2
3
|
# Author:: Xabier de Zuazo (<xabier@onddo.com>)
|
3
4
|
# Copyright:: Copyright (c) 2014 Onddo Labs, SL. (www.onddo.com)
|
@@ -20,17 +21,26 @@ require 'chef/encrypted_attribute/exceptions'
|
|
20
21
|
|
21
22
|
class Chef
|
22
23
|
class EncryptedAttribute
|
24
|
+
# Include some assertions that throw exceptions if not met.
|
23
25
|
module Assertions
|
24
|
-
|
26
|
+
# Checks some assertions related with OpenSSL AEAD support, required to
|
27
|
+
# to use [GCM](http://en.wikipedia.org/wiki/Galois/Counter_Mode).
|
28
|
+
#
|
29
|
+
# @param algorithm [String] the name of the algorithm to use.
|
30
|
+
# @return void
|
31
|
+
# @raise [RequirementsFailure] if any of the requirements to use AEAD is
|
32
|
+
# not met.
|
25
33
|
def assert_aead_requirements_met!(algorithm)
|
26
34
|
unless OpenSSL::Cipher.method_defined?(:auth_data=)
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
raise RequirementsFailure, "The used Encrypted Attributes protocol version requires an OpenSSL version with \"#{algorithm}\" algorithm support"
|
35
|
+
fail RequirementsFailure,
|
36
|
+
'The used Encrypted Attributes protocol version requires Ruby '\
|
37
|
+
'>= 1.9'
|
31
38
|
end
|
39
|
+
return if OpenSSL::Cipher.ciphers.include?(algorithm)
|
40
|
+
fail RequirementsFailure,
|
41
|
+
'The used Encrypted Attributes protocol version requires an '\
|
42
|
+
"OpenSSL version with \"#{algorithm}\" algorithm support"
|
32
43
|
end
|
33
|
-
|
34
44
|
end
|
35
45
|
end
|
36
46
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# encoding: UTF-8
|
1
2
|
#
|
2
3
|
# Author:: Xabier de Zuazo (<xabier@onddo.com>)
|
3
4
|
# Copyright:: Copyright (c) 2014 Onddo Labs, SL. (www.onddo.com)
|
@@ -18,33 +19,63 @@
|
|
18
19
|
|
19
20
|
require 'chef/mixin/params_validate'
|
20
21
|
|
21
|
-
# Based on https://github.com/SamSaffron/lru_redux
|
22
22
|
class Chef
|
23
23
|
class EncryptedAttribute
|
24
|
+
# Implements an LRU (Least Recently Used) cache object.
|
25
|
+
#
|
26
|
+
# The LRU cache algorithm discards the least recently used items first.
|
27
|
+
#
|
28
|
+
# This class extends from *Hash* class and adds methods to behave as a
|
29
|
+
# cache.
|
30
|
+
#
|
31
|
+
# You can use the `clear` class method to clean a cache:
|
32
|
+
#
|
33
|
+
# ```ruby
|
34
|
+
# Chef::EncryptedAttribute::RemoteClients.cache.clear
|
35
|
+
# Chef::EncryptedAttribute::RemoteNodes.cache.clear
|
36
|
+
# Chef::EncryptedAttribute::RemoteUsers.cache.clear
|
37
|
+
# Chef::EncryptedAttribute::RemoteNode.cache.clear
|
38
|
+
# ```
|
39
|
+
#
|
40
|
+
# @note Based on [SamSaffron](https://github.com/SamSaffron) work:
|
41
|
+
# https://github.com/SamSaffron/lru_redux
|
42
|
+
# @see API
|
24
43
|
class CacheLru < Hash
|
25
44
|
include ::Chef::Mixin::ParamsValidate
|
26
45
|
|
27
|
-
|
46
|
+
# Constructs a new Cache LRU object.
|
47
|
+
#
|
48
|
+
# @param size [Fixnum] Cache maximum size in object count.
|
49
|
+
def initialize(size = nil)
|
28
50
|
super
|
29
51
|
max_size(size)
|
30
52
|
end
|
31
53
|
|
32
|
-
|
54
|
+
# Reads or sets the cache maximum size.
|
55
|
+
#
|
56
|
+
# Removes some values if needed (when the size is reduced).
|
57
|
+
#
|
58
|
+
# The cache size is `1024` by default.
|
59
|
+
#
|
60
|
+
# @param arg [Fixnum] cache maximum size to set.
|
61
|
+
# @return [Fixnum] cache maximum size.
|
62
|
+
def max_size(arg = nil)
|
33
63
|
set_or_return(
|
34
64
|
:max_size,
|
35
65
|
arg,
|
36
|
-
:
|
37
|
-
:
|
38
|
-
:callbacks => begin
|
39
|
-
{ 'should not be lower that zero' => lambda { |x| x >= 0 } }
|
40
|
-
end
|
66
|
+
kind_of: [Fixnum], default: 1024,
|
67
|
+
callbacks: { 'should not be lower that zero' => ->(x) { x >= 0 } }
|
41
68
|
)
|
42
69
|
pop_tail unless arg.nil?
|
43
70
|
@max_size
|
44
71
|
end
|
45
72
|
|
73
|
+
# Reads a cache key.
|
74
|
+
#
|
75
|
+
# @param key [String, Symbol] cache key to read.
|
76
|
+
# @return [Mixed] cache key value.
|
46
77
|
def [](key)
|
47
|
-
if
|
78
|
+
if key?(key)
|
48
79
|
val = super(key)
|
49
80
|
self[key] = val
|
50
81
|
else
|
@@ -52,6 +83,14 @@ class Chef
|
|
52
83
|
end
|
53
84
|
end
|
54
85
|
|
86
|
+
# Sets a cache key.
|
87
|
+
#
|
88
|
+
# Some keys will be removed if the cache size grows too much. The keys to
|
89
|
+
# be removed will be chosen using the LRU algorithm.
|
90
|
+
#
|
91
|
+
# @param key [String, Symbol] cache key to set.
|
92
|
+
# @param val [Mixed] cache key value.
|
93
|
+
# @return [Mixed] cache key value.
|
55
94
|
def []=(key, val)
|
56
95
|
if max_size > 0 # unnecessary "if", small optimization?
|
57
96
|
delete(key)
|
@@ -63,12 +102,14 @@ class Chef
|
|
63
102
|
|
64
103
|
protected
|
65
104
|
|
105
|
+
# Removes the tail elements until the size is correct.
|
106
|
+
#
|
107
|
+
# This method is needed to implement the LRU algorithm.
|
108
|
+
#
|
109
|
+
# @return void
|
66
110
|
def pop_tail
|
67
|
-
while size > max_size
|
68
|
-
delete(first[0])
|
69
|
-
end
|
111
|
+
delete(first[0]) while size > max_size
|
70
112
|
end
|
71
|
-
|
72
113
|
end
|
73
114
|
end
|
74
115
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# encoding: UTF-8
|
1
2
|
#
|
2
3
|
# Author:: Xabier de Zuazo (<xabier@onddo.com>)
|
3
4
|
# Copyright:: Copyright (c) 2014 Onddo Labs, SL. (www.onddo.com)
|
@@ -20,137 +21,191 @@ require 'chef/mixin/params_validate'
|
|
20
21
|
|
21
22
|
class Chef
|
22
23
|
class EncryptedAttribute
|
24
|
+
# Encrypted attributes configuration options object.
|
23
25
|
class Config
|
24
26
|
include ::Chef::Mixin::ParamsValidate
|
25
27
|
|
28
|
+
# Returns configuration options list.
|
29
|
+
#
|
30
|
+
# @api private
|
26
31
|
OPTIONS = [
|
27
32
|
:version,
|
28
33
|
:partial_search,
|
29
34
|
:client_search,
|
30
35
|
:node_search,
|
31
36
|
:users,
|
32
|
-
:keys
|
37
|
+
:keys
|
33
38
|
].freeze
|
34
39
|
|
35
|
-
|
40
|
+
# Constructs a {Config} object.
|
41
|
+
#
|
42
|
+
# @param config [Config, Hash] configuration object to clone.
|
43
|
+
def initialize(config = nil)
|
36
44
|
update!(config) unless config.nil?
|
37
45
|
end
|
38
46
|
|
39
|
-
|
40
|
-
|
41
|
-
|
47
|
+
# Reads or sets Encrypted Mash protocol version.
|
48
|
+
#
|
49
|
+
# @param arg [String, Fixnum] protocol version to use. Must be a number.
|
50
|
+
# @return [Fixnum] protocol version.
|
51
|
+
def version(arg = nil)
|
52
|
+
unless arg.nil? || !arg.is_a?(String)
|
53
|
+
begin
|
54
|
+
arg = Integer(arg)
|
55
|
+
rescue ArgumentError
|
56
|
+
arg
|
57
|
+
end
|
42
58
|
end
|
43
|
-
set_or_return(
|
44
|
-
:version,
|
45
|
-
arg,
|
46
|
-
:kind_of => [ Fixnum, String ],
|
47
|
-
:default => 1
|
48
|
-
)
|
59
|
+
set_or_return(:version, arg, kind_of: [Fixnum, String], default: 1)
|
49
60
|
end
|
50
61
|
|
51
|
-
|
62
|
+
# Reads or sets partial search support.
|
63
|
+
#
|
64
|
+
# Set it to `false` to disable partial search. Defaults to `true`.
|
65
|
+
#
|
66
|
+
# @param arg [Boolean] whether to enable partial search.
|
67
|
+
# @return [Boolean] partial search usage.
|
68
|
+
# @see
|
69
|
+
# http://docs.getchef.com/chef_search.html Chef Search documentation
|
70
|
+
def partial_search(arg = nil)
|
52
71
|
set_or_return(
|
53
|
-
:partial_search,
|
54
|
-
arg,
|
55
|
-
:kind_of => [ TrueClass, FalseClass ],
|
56
|
-
:default => true
|
72
|
+
:partial_search, arg, kind_of: [TrueClass, FalseClass], default: true
|
57
73
|
)
|
58
74
|
end
|
59
75
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
)
|
76
|
+
# Reads or sets client search query.
|
77
|
+
#
|
78
|
+
# This query will return a list of clients that will be able to read the
|
79
|
+
# encrypted attribute.
|
80
|
+
#
|
81
|
+
# @param arg [String, Array<String>] list of client queries to perform.
|
82
|
+
# @return [Array<String>] list of client queries.
|
83
|
+
# @see
|
84
|
+
# http://docs.getchef.com/chef_search.html Chef Search documentation
|
85
|
+
def client_search(arg = nil)
|
86
|
+
set_or_return_search_array(:client_search, arg)
|
71
87
|
end
|
72
88
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
:callbacks => config_search_array_callbacks
|
83
|
-
)
|
89
|
+
# Reads or sets node search query.
|
90
|
+
#
|
91
|
+
# This query will return a list of nodes that will be able to read the
|
92
|
+
# encrypted attribute.
|
93
|
+
#
|
94
|
+
# @param arg [String, Array<String>] list of node queries to perform.
|
95
|
+
# @return [Array<String>] list of node queries.
|
96
|
+
def node_search(arg = nil)
|
97
|
+
set_or_return_search_array(:node_search, arg)
|
84
98
|
end
|
85
99
|
|
86
|
-
|
100
|
+
# Reads or sets user list.
|
101
|
+
#
|
102
|
+
# This contains the user list that will be able to read the encrypted
|
103
|
+
# attribute.
|
104
|
+
#
|
105
|
+
# @param arg [String, Array<String>] list of users to set.
|
106
|
+
# @return [Array<String>] list of users.
|
107
|
+
def users(arg = nil)
|
87
108
|
set_or_return(
|
88
|
-
:users,
|
89
|
-
|
90
|
-
:
|
91
|
-
:default => [],
|
92
|
-
:callbacks => config_users_arg_callbacks
|
109
|
+
:users, arg,
|
110
|
+
kind_of: [String, Array], default: [],
|
111
|
+
callbacks: config_users_arg_callbacks
|
93
112
|
)
|
94
113
|
end
|
95
114
|
|
96
|
-
|
115
|
+
# Reads or sets key list.
|
116
|
+
#
|
117
|
+
# This contains the raw key list that will be able to read the encrypted
|
118
|
+
# attribute.
|
119
|
+
#
|
120
|
+
# @param arg [Array<String, OpenSSL::PKey::RSA>] the keys in PEM format.
|
121
|
+
# @return [Array<String, OpenSSL::PKey::RSA>] the keys in PEM format
|
122
|
+
def keys(arg = nil)
|
97
123
|
set_or_return(
|
98
|
-
:keys,
|
99
|
-
|
100
|
-
:
|
101
|
-
:default => [],
|
102
|
-
:callbacks => config_valid_keys_array_callbacks
|
124
|
+
:keys, arg,
|
125
|
+
kind_of: Array, default: [],
|
126
|
+
callbacks: config_valid_keys_array_callbacks
|
103
127
|
)
|
104
128
|
end
|
105
129
|
|
130
|
+
# Replaces the current config.
|
131
|
+
#
|
132
|
+
# When setting using a {Chef::EncryptedAttribute::Config} class, all the
|
133
|
+
# configuration options will be replaced.
|
134
|
+
#
|
135
|
+
# When setting using a _Hash_, only the provided keys will be replaced.
|
136
|
+
#
|
137
|
+
# @param config [Config, Hash] the configuration to set.
|
138
|
+
# @return [Config] `self`.
|
106
139
|
def update!(config)
|
107
|
-
if config.
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
end
|
112
|
-
elsif config.kind_of?(Hash)
|
113
|
-
config.each do |attr, value|
|
114
|
-
attr = attr.to_sym if attr.kind_of?(String)
|
115
|
-
if OPTIONS.include?(attr)
|
116
|
-
value = dup_object(value)
|
117
|
-
self.send(attr, value)
|
118
|
-
else
|
119
|
-
Chef::Log.warn("#{self.class.to_s}: configuration method not found: \"#{attr.to_s}\".")
|
120
|
-
end
|
121
|
-
end
|
140
|
+
if config.is_a?(self.class)
|
141
|
+
update_from_config!(config)
|
142
|
+
elsif config.is_a?(Hash)
|
143
|
+
update_from_hash!(config)
|
122
144
|
end
|
123
145
|
end
|
124
146
|
|
147
|
+
# Reads a configuration option.
|
148
|
+
#
|
149
|
+
# @param key [String, Symbol] configuration option to read.
|
150
|
+
# @return [Mixed] configuration value.
|
125
151
|
def [](key)
|
126
|
-
key = key.to_sym if key.
|
127
|
-
if OPTIONS.include?(key)
|
128
|
-
self.send(key)
|
129
|
-
end
|
152
|
+
key = key.to_sym if key.is_a?(String)
|
153
|
+
send(key) if OPTIONS.include?(key)
|
130
154
|
end
|
131
155
|
|
156
|
+
# Sets a configuration option.
|
157
|
+
#
|
158
|
+
# @param key [String, Symbol] configuration option name to set.
|
159
|
+
# @param value [Mixed] configuration value to set.
|
160
|
+
# @return [Mixed] configuration value.
|
132
161
|
def []=(key, value)
|
133
|
-
key = key.to_sym if key.
|
134
|
-
if OPTIONS.include?(key)
|
135
|
-
self.send(key, value)
|
136
|
-
end
|
162
|
+
key = key.to_sym if key.is_a?(String)
|
163
|
+
send(key, value) if OPTIONS.include?(key)
|
137
164
|
end
|
138
165
|
|
139
166
|
protected
|
140
167
|
|
168
|
+
# Duplicates an object avoiding Ruby exceptions if not supported.
|
169
|
+
#
|
170
|
+
# @param o [Object] object to duplicate.
|
171
|
+
# @return [Object] duplicated object.
|
141
172
|
def dup_object(o)
|
142
173
|
o.dup
|
143
174
|
rescue TypeError
|
144
175
|
o
|
145
176
|
end
|
146
177
|
|
178
|
+
# Creates getter and setter method for **search array** configuration
|
179
|
+
# options.
|
180
|
+
#
|
181
|
+
# This configuration options contains an array of search queries.
|
182
|
+
#
|
183
|
+
# @param name [Symbol] configuration option name.
|
184
|
+
# @param arg [Array<String>, String] configuration option value to set.
|
185
|
+
# @return [Array<String>] configuration option value.
|
186
|
+
def set_or_return_search_array(name, arg = nil)
|
187
|
+
arg = [arg] unless arg.nil? || !arg.is_a?(String)
|
188
|
+
set_or_return(
|
189
|
+
name, arg,
|
190
|
+
kind_of: Array, default: [], callbacks: config_search_array_callbacks
|
191
|
+
)
|
192
|
+
end
|
193
|
+
|
194
|
+
# Checks a search query array list.
|
195
|
+
#
|
196
|
+
# @param s_ary [Array<String>] search query array.
|
197
|
+
# @return [Boolean] `true` if the search query list is in the correct
|
198
|
+
# format.
|
147
199
|
def config_valid_search_array?(s_ary)
|
148
200
|
s_ary.each do |s|
|
149
|
-
return false unless s.
|
201
|
+
return false unless s.is_a?(String)
|
150
202
|
end
|
151
203
|
true
|
152
204
|
end
|
153
205
|
|
206
|
+
# Returns configuration option callback function for search arrays.
|
207
|
+
#
|
208
|
+
# @return [Proc] search arrays checking callback function.
|
154
209
|
def config_search_array_callbacks
|
155
210
|
{
|
156
211
|
'should be a valid array of search patterns' => lambda do |cs|
|
@@ -159,14 +214,22 @@ class Chef
|
|
159
214
|
}
|
160
215
|
end
|
161
216
|
|
217
|
+
# Checks a user list option value.
|
218
|
+
#
|
219
|
+
# @param users [Array<String>, '*'] user list to check.
|
220
|
+
# @return [Boolean] `true` if the user list is in the correct
|
221
|
+
# format.
|
162
222
|
def config_valid_user_arg?(users)
|
163
|
-
return users == '*' if users.
|
223
|
+
return users == '*' if users.is_a?(String)
|
164
224
|
users.each do |u|
|
165
|
-
return false unless u.
|
225
|
+
return false unless u.is_a?(String) && u.match(/^[a-z0-9\-_]+$/)
|
166
226
|
end
|
167
227
|
true
|
168
228
|
end
|
169
229
|
|
230
|
+
# Returns configuration option callback function for user lists.
|
231
|
+
#
|
232
|
+
# @return [Proc] user lists checking callback function.
|
170
233
|
def config_users_arg_callbacks
|
171
234
|
{
|
172
235
|
'should be a valid array of search patterns' => lambda do |us|
|
@@ -175,32 +238,45 @@ class Chef
|
|
175
238
|
}
|
176
239
|
end
|
177
240
|
|
241
|
+
# Checks if an OpenSSL key is in the correct format.
|
242
|
+
#
|
243
|
+
# Only checks that has a public key. It may lack private key.
|
244
|
+
#
|
245
|
+
# @param k [String, OpenSSL::PKey::RSA] key to check.
|
246
|
+
# @return [Boolean] `true` if the public key is correct.
|
178
247
|
def config_valid_key?(k)
|
179
|
-
rsa_k =
|
180
|
-
|
181
|
-
k
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
248
|
+
rsa_k =
|
249
|
+
case k
|
250
|
+
when OpenSSL::PKey::RSA then k
|
251
|
+
when String
|
252
|
+
begin
|
253
|
+
OpenSSL::PKey::RSA.new(k)
|
254
|
+
rescue OpenSSL::PKey::RSAError, TypeError
|
255
|
+
nil
|
256
|
+
end
|
257
|
+
else
|
186
258
|
nil
|
187
259
|
end
|
188
|
-
else
|
189
|
-
nil
|
190
|
-
end
|
191
260
|
return false if rsa_k.nil?
|
192
261
|
rsa_k.public?
|
193
262
|
end
|
194
263
|
|
264
|
+
# Checks if an OpenSSL key array is in the correct format.
|
265
|
+
#
|
266
|
+
# Only checks that the keys have a public key. They may lack private key.
|
267
|
+
#
|
268
|
+
# @param k_ary [Array<String, OpenSSL::PKey::RSA>] array of keys to check.
|
269
|
+
# @return [Boolean] `true` if the public keys are all correct.
|
195
270
|
def config_valid_keys_array?(k_ary)
|
196
271
|
k_ary.each do |k|
|
197
|
-
unless config_valid_key?(k)
|
198
|
-
return false
|
199
|
-
end
|
272
|
+
return false unless config_valid_key?(k)
|
200
273
|
end
|
201
274
|
true
|
202
275
|
end
|
203
276
|
|
277
|
+
# Returns configuration option callback function for public keys.
|
278
|
+
#
|
279
|
+
# @return [Proc] public keys checking callback function.
|
204
280
|
def config_valid_keys_array_callbacks
|
205
281
|
{
|
206
282
|
'should be a valid array of keys' => lambda do |keys|
|
@@ -209,6 +285,39 @@ class Chef
|
|
209
285
|
}
|
210
286
|
end
|
211
287
|
|
288
|
+
# Copies a configuration. All the current configuration options will be
|
289
|
+
# replaced.
|
290
|
+
#
|
291
|
+
# Called by {#update_from!} for {Config} objects.
|
292
|
+
#
|
293
|
+
# @param config [Config] configuration options to copy.
|
294
|
+
def update_from_config!(config)
|
295
|
+
OPTIONS.each do |attr|
|
296
|
+
value = dup_object(config.send(attr))
|
297
|
+
instance_variable_set("@#{attr}", value)
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
# Copies a configuration option. Only the provided Hash keys will be
|
302
|
+
# replaced, the others will be preserved.
|
303
|
+
#
|
304
|
+
# Called by {#update_from!} for *Hash* objects.
|
305
|
+
#
|
306
|
+
# @param config [Hash] configuration options to copy.
|
307
|
+
def update_from_hash!(config)
|
308
|
+
config.each do |attr, value|
|
309
|
+
attr = attr.to_sym if attr.is_a?(String)
|
310
|
+
if OPTIONS.include?(attr)
|
311
|
+
value = dup_object(value)
|
312
|
+
send(attr, value)
|
313
|
+
else
|
314
|
+
Chef::Log.warn(
|
315
|
+
"#{self.class}: configuration method not found: "\
|
316
|
+
"#{attr.to_s.inspect}."
|
317
|
+
)
|
318
|
+
end
|
319
|
+
end
|
320
|
+
end
|
212
321
|
end
|
213
322
|
end
|
214
323
|
end
|