chef-encrypted-attributes 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -0,0 +1,521 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
#
|
3
|
+
# Author:: Xabier de Zuazo (<xabier@onddo.com>)
|
4
|
+
# Copyright:: Copyright (c) 2014 Onddo Labs, SL. (www.onddo.com)
|
5
|
+
# License:: Apache License, Version 2.0
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
19
|
+
|
20
|
+
require 'chef/encrypted_attribute/config'
|
21
|
+
require 'chef/encrypted_attribute/encrypted_mash'
|
22
|
+
require 'chef/config'
|
23
|
+
|
24
|
+
require 'chef/encrypted_attribute/local_node'
|
25
|
+
require 'chef/encrypted_attribute/remote_node'
|
26
|
+
require 'chef/encrypted_attribute/encrypted_mash/version0'
|
27
|
+
require 'chef/encrypted_attribute/encrypted_mash/version1'
|
28
|
+
require 'chef/encrypted_attribute/encrypted_mash/version2'
|
29
|
+
|
30
|
+
class Chef
|
31
|
+
class EncryptedAttribute
|
32
|
+
# Main EncryptedAttribute class methods API module.
|
33
|
+
#
|
34
|
+
# All these methods are available as static methods in the
|
35
|
+
# {Chef::EncryptedAttribute} class.
|
36
|
+
#
|
37
|
+
# These methods are intended to be used from Chef
|
38
|
+
# [Recipes](http://docs.getchef.com/recipes.html) or
|
39
|
+
# [Resources](https://docs.getchef.com/resource.html).
|
40
|
+
#
|
41
|
+
# The attributes created by these methods are encrypted **only for the local
|
42
|
+
# node** by default.
|
43
|
+
#
|
44
|
+
# The static `*_on_node` methods can be used, although they have not been
|
45
|
+
# designed for this purpose (have not been tested).
|
46
|
+
#
|
47
|
+
# This module uses the {Chef::EncryptedAttribute} instance methods
|
48
|
+
# internally.
|
49
|
+
#
|
50
|
+
# # Configuration
|
51
|
+
#
|
52
|
+
# All the methods read the default configuration from the
|
53
|
+
# `Chef::Config[:encrypted_attributes]` hash. Most of methods also support
|
54
|
+
# setting some configuration parameters as last argument. Both the global
|
55
|
+
# and the method argument configuration will be merged.
|
56
|
+
#
|
57
|
+
# If the configuration value to be merged is an array or a hash (for example
|
58
|
+
# `keys`), the method argument configuration value has preference over the
|
59
|
+
# global configuration. arrays and hashes are not merged.
|
60
|
+
#
|
61
|
+
# Both `Chef::Config[:encrypted_attributes]` and method's `config` parameter
|
62
|
+
# should be a hash which may have any of the following keys:
|
63
|
+
#
|
64
|
+
# * `:version` - `EncryptedMash` format version to use, by default `1` is
|
65
|
+
# used which is recommended. The version `2` uses [GCM]
|
66
|
+
# (http://en.wikipedia.org/wiki/Galois/Counter_Mode) and probably should
|
67
|
+
# be considered the most secure, but it is disabled by default because it
|
68
|
+
# has some more requirements: Ruby `>= 2` and OpenSSL `>= 1.0.1`.
|
69
|
+
# * `:partial_search` - Whether to use Chef Server partial search, enabled
|
70
|
+
# by default. It may not work in some old versions of Chef Server.
|
71
|
+
# * `:client_search` - Search query for clients allowed to read the
|
72
|
+
# encrypted attribute. Can be a simple string or an array of queries to be
|
73
|
+
# *OR*-ed.
|
74
|
+
# * `:node_search` - Search query for nodes allowed to read the encrypted
|
75
|
+
# attribute. Can be a simple string or an array of queries to be *OR*-ed.
|
76
|
+
# * `:users` - Array of user names to be allowed to read the encrypted
|
77
|
+
# attribute(s). `"*"` to allow access to all users. Keep in mind that only
|
78
|
+
# admin clients or admin users are allowed to read user public keys. It is
|
79
|
+
# **not recommended** to use this from cookbooks unless you know what you
|
80
|
+
# are doing.
|
81
|
+
# * `:keys` - raw RSA public keys to be allowed to read encrypted
|
82
|
+
# attributes(s), in PEM (string) format. Can be client public keys, user
|
83
|
+
# public keys or any other RSA public key.
|
84
|
+
#
|
85
|
+
# @see Config
|
86
|
+
#
|
87
|
+
# For example, to disable Partial Search globally:
|
88
|
+
#
|
89
|
+
# ```ruby
|
90
|
+
# Chef::Config[:encrypted_attributes][:partial_search] = false
|
91
|
+
#
|
92
|
+
# # ftp_pass = Chef::EncryptedAttribute.load(node['myapp']['ftp_password'])
|
93
|
+
# # ...
|
94
|
+
# ```
|
95
|
+
#
|
96
|
+
# To disable Partial Search locally:
|
97
|
+
#
|
98
|
+
# ```ruby
|
99
|
+
# ftp_pass = Chef::EncryptedAttribute.load(
|
100
|
+
# node['myapp']['ftp_password'], { :partial_search => false }
|
101
|
+
# )
|
102
|
+
# ```
|
103
|
+
#
|
104
|
+
# To use protocol version 2 globally, which uses [GCM]
|
105
|
+
# (http://en.wikipedia.org/wiki/Galois/Counter_Mode):
|
106
|
+
#
|
107
|
+
# ```ruby
|
108
|
+
# Chef::Config[:encrypted_attributes][:version] = 2
|
109
|
+
# # ...
|
110
|
+
# ```
|
111
|
+
#
|
112
|
+
# If you want to use knife to work with encrypted attributes, surely you
|
113
|
+
# will need to save your Chef User public keys in a Data Bag (there is no
|
114
|
+
# need to encrypt them because they are public) and add them to the `:keys`
|
115
|
+
# configuration option. See the [Example Using User Keys Data Bag]
|
116
|
+
# (README.md#example-using-user-keys-data-bag) in the README for more
|
117
|
+
# information on this.
|
118
|
+
#
|
119
|
+
# # Caches
|
120
|
+
#
|
121
|
+
# This API uses some LRU caches to avoid making many requests to the Chef
|
122
|
+
# Server. All the caches are global and has the following methods:
|
123
|
+
#
|
124
|
+
# * `max_size` - Gets or sets the cache maximum item size.
|
125
|
+
# * `clear` - To empty the cache.
|
126
|
+
# * `[]` - To read a cache value (used internally).
|
127
|
+
# * `[]=` - To set a cache value (used internally).
|
128
|
+
#
|
129
|
+
# @see CacheLru
|
130
|
+
#
|
131
|
+
# This are the currently available caches:
|
132
|
+
#
|
133
|
+
# * `Chef::EncryptedAttribute::RemoteClients.cache` - Caches the
|
134
|
+
# `:client_search` query results (max_size: `1024`).
|
135
|
+
# * `Chef::EncryptedAttribute::RemoteNodes.cache` - Caches the
|
136
|
+
# `:node_search` query results (max_size: `1024`).
|
137
|
+
# * `Chef::EncryptedAttribute::RemoteUsers.cache` - Caches the Chef Users
|
138
|
+
# public keys (max_size: `1024`).
|
139
|
+
# * `Chef::EncryptedAttribute::RemoteNode.cache` - Caches the node
|
140
|
+
# (encrypted) attributes. Disabled by default (max_size: `0`).
|
141
|
+
#
|
142
|
+
# ### Clear All the Caches
|
143
|
+
#
|
144
|
+
# You can clear all the caches with the following code:
|
145
|
+
#
|
146
|
+
# ```ruby
|
147
|
+
# Chef::EncryptedAttribute::RemoteClients.cache.clear
|
148
|
+
# Chef::EncryptedAttribute::RemoteNodes.cache.clear
|
149
|
+
# Chef::EncryptedAttribute::RemoteUsers.cache.clear
|
150
|
+
# Chef::EncryptedAttribute::RemoteNode.cache.clear
|
151
|
+
# ```
|
152
|
+
#
|
153
|
+
# ### Disable All the Caches
|
154
|
+
#
|
155
|
+
# You can disable all the caches with the following code:
|
156
|
+
#
|
157
|
+
# ```ruby
|
158
|
+
# Chef::EncryptedAttribute::RemoteClients.cache.max_size(0)
|
159
|
+
# Chef::EncryptedAttribute::RemoteNodes.cache.max_size(0)
|
160
|
+
# Chef::EncryptedAttribute::RemoteUsers.cache.max_size(0)
|
161
|
+
# Chef::EncryptedAttribute::RemoteNode.cache.max_size(0)
|
162
|
+
# ```
|
163
|
+
#
|
164
|
+
# @see RemoteClients.cache
|
165
|
+
# @see RemoteNodes.cache
|
166
|
+
# @see RemoteUsers.cache
|
167
|
+
# @see RemoteNode.cache
|
168
|
+
module API
|
169
|
+
# Prints a Chef debug message.
|
170
|
+
#
|
171
|
+
# @param msg [String] message to print.
|
172
|
+
# @return void
|
173
|
+
# @api private
|
174
|
+
def debug(msg)
|
175
|
+
Chef::Log.debug("Chef::EncryptedAttribute: #{msg}")
|
176
|
+
end
|
177
|
+
|
178
|
+
# Prints a Chef warning message.
|
179
|
+
#
|
180
|
+
# @param msg [String] message to print.
|
181
|
+
# @return void
|
182
|
+
# @api private
|
183
|
+
def warn(msg)
|
184
|
+
Chef::Log.warn(msg)
|
185
|
+
end
|
186
|
+
|
187
|
+
# Gets local node object.
|
188
|
+
#
|
189
|
+
# @return [LocalNode] local node object.
|
190
|
+
# @api private
|
191
|
+
def local_node
|
192
|
+
LocalNode.new
|
193
|
+
end
|
194
|
+
|
195
|
+
# Creates a new {Config} object.
|
196
|
+
#
|
197
|
+
# Reads the default configuration from
|
198
|
+
# `Chef::Config[:encrypted_attributes]`.
|
199
|
+
#
|
200
|
+
# When the parameter is a {Chef::EncryptedAttribute::Config} class, all
|
201
|
+
# the configuration options will be replaced.
|
202
|
+
#
|
203
|
+
# When the parameter is a _Hash_, only the provided keys will be replaced.
|
204
|
+
#
|
205
|
+
# The local node public key will always be added to the provided
|
206
|
+
# configuration keys.
|
207
|
+
#
|
208
|
+
# @param arg [Config, Hash] the configuration to set.
|
209
|
+
# @return [Config] the read or set configuration object.
|
210
|
+
# @api private
|
211
|
+
def config(arg)
|
212
|
+
config =
|
213
|
+
EncryptedAttribute::Config.new(Chef::Config[:encrypted_attributes])
|
214
|
+
config.update!(arg)
|
215
|
+
config.keys(config.keys + [local_node.public_key])
|
216
|
+
config
|
217
|
+
end
|
218
|
+
|
219
|
+
# Reads an encrypted attribute from a hash, usually a node attribute.
|
220
|
+
#
|
221
|
+
# Uses the local private key to decrypt the attribute.
|
222
|
+
#
|
223
|
+
# An exception is thrown if the attribute cannot be decrypted or no
|
224
|
+
# encrypted attribute is found.
|
225
|
+
#
|
226
|
+
# @param enc_hs [Mash] an encrypted hash, usually a node attribute. For
|
227
|
+
# example: `node['myapp']['ftp_password']`.
|
228
|
+
# @param c [Config, Hash] a configuration hash. For example:
|
229
|
+
# `{ :partial_search => false }`.
|
230
|
+
# @return [Hash, Array, String, ...] the attribute in clear text,
|
231
|
+
# decrypted.
|
232
|
+
# @raise [UnacceptableEncryptedAttributeFormat] if encrypted attribute
|
233
|
+
# format is wrong.
|
234
|
+
# @raise [UnsupportedEncryptedAttributeFormat] if encrypted attribute
|
235
|
+
# format is not supported or unknown.
|
236
|
+
def load(enc_hs, c = {})
|
237
|
+
debug("Loading Local Encrypted Attribute from: #{enc_hs.inspect}")
|
238
|
+
enc_attr = EncryptedAttribute.new(config(c))
|
239
|
+
result = enc_attr.load(enc_hs)
|
240
|
+
debug('Local Encrypted Attribute loaded.')
|
241
|
+
result
|
242
|
+
end
|
243
|
+
|
244
|
+
# Reads an encrypted attribute from a remote node.
|
245
|
+
#
|
246
|
+
# Uses the local private key to decrypt the attribute.
|
247
|
+
#
|
248
|
+
# An exception is thrown if the attribute cannot be decrypted or no
|
249
|
+
# encrypted attribute is found.
|
250
|
+
#
|
251
|
+
# @param name [String] the node name.
|
252
|
+
# @param attr_ary [Array<String>] the attribute path as *array of
|
253
|
+
# strings*. For example: `%w(myapp ftp_password)`.
|
254
|
+
# @param c [Config, Hash] a configuration hash. For example:
|
255
|
+
# `{ :partial_search => false }`.
|
256
|
+
# @return [Hash, Array, String, ...] decrypted attribute value.
|
257
|
+
# @raise [ArgumentError] if the attribute path format is wrong.
|
258
|
+
# @raise [UnacceptableEncryptedAttributeFormat] if encrypted attribute
|
259
|
+
# format is wrong.
|
260
|
+
# @raise [UnsupportedEncryptedAttributeFormat] if encrypted attribute
|
261
|
+
# format is not supported or unknown.
|
262
|
+
# @raise [SearchFailure] if there is a Chef search error.
|
263
|
+
# @raise [SearchFatalError] if the Chef search response is wrong.
|
264
|
+
# @raise [InvalidSearchKeys] if search keys structure is wrong.
|
265
|
+
def load_from_node(name, attr_ary, c = {})
|
266
|
+
debug(
|
267
|
+
"Loading Remote Encrypted Attribute from #{name}: #{attr_ary.inspect}"
|
268
|
+
)
|
269
|
+
enc_attr = EncryptedAttribute.new(config(c))
|
270
|
+
result = enc_attr.load_from_node(name, attr_ary)
|
271
|
+
debug('Remote Encrypted Attribute loaded.')
|
272
|
+
result
|
273
|
+
end
|
274
|
+
|
275
|
+
# Creates an encrypted attribute.
|
276
|
+
#
|
277
|
+
# The returned value should be saved in a node attribute, like
|
278
|
+
# `node.normal[...] = Chef::EncryptedAttribute.create(...)`.
|
279
|
+
#
|
280
|
+
# The local node will always be able to decrypt the attribute.
|
281
|
+
#
|
282
|
+
# An exception is thrown if any error arises in the encryption process.
|
283
|
+
#
|
284
|
+
# @param value [Hash, Array, String, ...] the value to be encrypted. Can
|
285
|
+
# be a boolean, a number, a string, an array or a hash (the value will
|
286
|
+
# be converted to JSON internally).
|
287
|
+
# @param c [Config, Hash] a configuration hash. For example:
|
288
|
+
# `{ :client_search => "admin:true" }`.
|
289
|
+
# @return [EncryptedMash] encrypted attribute value. This is usually what
|
290
|
+
# is saved in the node attributes.
|
291
|
+
# @raise [ArgumentError] if user list is wrong.
|
292
|
+
# @raise [UnacceptableEncryptedAttributeFormat] if encrypted attribute
|
293
|
+
# format is wrong or does not exist.
|
294
|
+
# @raise [UnsupportedEncryptedAttributeFormat] if encrypted attribute
|
295
|
+
# format is not supported or unknown.
|
296
|
+
# @raise [EncryptionFailure] if there are encryption errors.
|
297
|
+
# @raise [MessageAuthenticationFailure] if HMAC calculation error.
|
298
|
+
# @raise [InvalidPublicKey] if it is not a valid RSA public key.
|
299
|
+
# @raise [InvalidKey] if the RSA key format is wrong.
|
300
|
+
# @raise [InsufficientPrivileges] if you lack enough privileges to read
|
301
|
+
# the keys from the Chef Server.
|
302
|
+
# @raise [ClientNotFound] if client does not exist.
|
303
|
+
# @raise [Net::HTTPServerException] for Chef Server HTTP errors.
|
304
|
+
# @raise [RequirementsFailure] if the specified encrypted attribute
|
305
|
+
# version cannot be used.
|
306
|
+
# @raise [SearchFailure] if there is a Chef search error.
|
307
|
+
# @raise [SearchFatalError] if the Chef search response is wrong.
|
308
|
+
# @raise [InvalidSearchKeys] if search keys structure is wrong.
|
309
|
+
def create(value, c = {})
|
310
|
+
debug('Creating Encrypted Attribute.')
|
311
|
+
enc_attr = EncryptedAttribute.new(config(c))
|
312
|
+
result = enc_attr.create(value)
|
313
|
+
debug('Encrypted Attribute created.')
|
314
|
+
result
|
315
|
+
end
|
316
|
+
|
317
|
+
# Creates an encrypted attribute on a remote node.
|
318
|
+
#
|
319
|
+
# Both the local node and the remote node will be able to decrypt the
|
320
|
+
# attribute.
|
321
|
+
#
|
322
|
+
# This method **requires admin privileges**. So in most cases, cannot be
|
323
|
+
# used from cookbooks.
|
324
|
+
#
|
325
|
+
# An exception is thrown if any error arises in the encryption process.
|
326
|
+
#
|
327
|
+
# @param name [String] the node name.
|
328
|
+
# @param attr_ary [Array<String>] the attribute path as *array of
|
329
|
+
# strings*. For example: `%w(myapp ftp_password)`.
|
330
|
+
# @param value [Hash, Array, String, Fixnum, ...] the value to be
|
331
|
+
# encrypted. Can be a boolean, a number, a string, an array or a hash
|
332
|
+
# (the value will be converted to JSON internally).
|
333
|
+
# @param c [Config, Hash] a configuration hash. For example:
|
334
|
+
# `{ :client_search => 'admin:true' }`.
|
335
|
+
# @return [EncryptedMash] encrypted attribute value.
|
336
|
+
# @raise [ArgumentError] if the attribute path format or the user list is
|
337
|
+
# wrong.
|
338
|
+
# @raise [UnacceptableEncryptedAttributeFormat] if encrypted attribute
|
339
|
+
# format is wrong or does not exist.
|
340
|
+
# @raise [UnsupportedEncryptedAttributeFormat] if encrypted attribute
|
341
|
+
# format is not supported or unknown.
|
342
|
+
# @raise [EncryptionFailure] if there are encryption errors.
|
343
|
+
# @raise [MessageAuthenticationFailure] if HMAC calculation error.
|
344
|
+
# @raise [InvalidPublicKey] if it is not a valid RSA public key.
|
345
|
+
# @raise [InvalidKey] if the RSA key format is wrong.
|
346
|
+
# @raise [InsufficientPrivileges] if you lack enough privileges to read
|
347
|
+
# the keys from the Chef Server.
|
348
|
+
# @raise [ClientNotFound] if client does not exist.
|
349
|
+
# @raise [Net::HTTPServerException] for Chef Server HTTP errors.
|
350
|
+
# @raise [RequirementsFailure] if the specified encrypted attribute
|
351
|
+
# version cannot be used.
|
352
|
+
# @raise [SearchFailure] if there is a Chef search error.
|
353
|
+
# @raise [SearchFatalError] if the Chef search response is wrong.
|
354
|
+
# @raise [InvalidSearchKeys] if search keys structure is wrong.
|
355
|
+
def create_on_node(name, attr_ary, value, c = {})
|
356
|
+
debug(
|
357
|
+
"Creating Remote Encrypted Attribute on #{name}: #{attr_ary.inspect}"
|
358
|
+
)
|
359
|
+
enc_attr = EncryptedAttribute.new(config(c))
|
360
|
+
result = enc_attr.create_on_node(name, attr_ary, value)
|
361
|
+
debug('Encrypted Remote Attribute created.')
|
362
|
+
result
|
363
|
+
end
|
364
|
+
|
365
|
+
# Updates who can read the attribute. This is intended to be used to
|
366
|
+
# update to the new nodes returned by `:client_search` and `:node_search`
|
367
|
+
# or perhaps global configuration changes.
|
368
|
+
#
|
369
|
+
# For example, in case new nodes are added or some are removed, and the
|
370
|
+
# clients returned by `:client_search` or `:node_search` are different,
|
371
|
+
# this `#update` method will decrypt the attribute and encrypt it again
|
372
|
+
# for the new nodes (or remove the old ones).
|
373
|
+
#
|
374
|
+
# If an update is made, the shared secrets are regenerated.
|
375
|
+
#
|
376
|
+
# Both the local node and the remote node will be able to decrypt the
|
377
|
+
# attribute.
|
378
|
+
#
|
379
|
+
# An exception is thrown if there is any error in the updating process.
|
380
|
+
#
|
381
|
+
# @param enc_hs [Mash] This must be a node encrypted attribute, this
|
382
|
+
# attribute will be updated, so it is mandatory to specify the type
|
383
|
+
# (usually `normal`). For example:
|
384
|
+
# `node.normal['myapp']['ftp_password']`.
|
385
|
+
# @param c [Config, Hash] a configuration hash. Surely you want this
|
386
|
+
# `#update` method to use the same `config` that the `#create` call.
|
387
|
+
# @return [Boolean] `true` if the encrypted attribute has been updated,
|
388
|
+
# `false` if not.
|
389
|
+
# @raise [ArgumentError] if user list is wrong.
|
390
|
+
# @raise [UnacceptableEncryptedAttributeFormat] if encrypted attribute
|
391
|
+
# format is wrong or does not exist.
|
392
|
+
# @raise [UnsupportedEncryptedAttributeFormat] if encrypted attribute
|
393
|
+
# format is not supported or unknown.
|
394
|
+
# @raise [EncryptionFailure] if there are encryption errors.
|
395
|
+
# @raise [MessageAuthenticationFailure] if HMAC calculation error.
|
396
|
+
# @raise [InvalidPublicKey] if it is not a valid RSA public key.
|
397
|
+
# @raise [InvalidKey] if the RSA key format is wrong.
|
398
|
+
# @raise [InsufficientPrivileges] if you lack enough privileges to read
|
399
|
+
# the keys from the Chef Server.
|
400
|
+
# @raise [ClientNotFound] if client does not exist.
|
401
|
+
# @raise [Net::HTTPServerException] for Chef Server HTTP errors.
|
402
|
+
# @raise [RequirementsFailure] if the specified encrypted attribute
|
403
|
+
# version cannot be used.
|
404
|
+
# @raise [SearchFailure] if there is a Chef search error.
|
405
|
+
# @raise [SearchFatalError] if the Chef search response is wrong.
|
406
|
+
# @raise [InvalidSearchKeys] if search keys structure is wrong.
|
407
|
+
def update(enc_hs, c = {})
|
408
|
+
debug("Updating Encrypted Attribute: #{enc_hs.inspect}")
|
409
|
+
enc_attr = EncryptedAttribute.new(config(c))
|
410
|
+
result = enc_attr.update(enc_hs)
|
411
|
+
if result
|
412
|
+
debug('Encrypted Attribute updated.')
|
413
|
+
else
|
414
|
+
debug('Encrypted Attribute not updated.')
|
415
|
+
end
|
416
|
+
result
|
417
|
+
end
|
418
|
+
|
419
|
+
# Updates who can decrypt the remote attribute.
|
420
|
+
#
|
421
|
+
# This method **requires admin privileges**. So in most cases, cannot be
|
422
|
+
# used from cookbooks.
|
423
|
+
#
|
424
|
+
# An exception is thrown if there is any error in the updating process.
|
425
|
+
#
|
426
|
+
# @param name [String] the node name.
|
427
|
+
# @param attr_ary [Array<String>] the attribute path as *array of
|
428
|
+
# strings*. For example: `%w(myapp ftp_password)`.
|
429
|
+
# @param c [Config, Hash] a configuration hash. Surely you want this
|
430
|
+
# `#update_on_node` method to use the same `config` that the `#create`
|
431
|
+
# call.
|
432
|
+
# @return [Boolean] `true` if the encrypted attribute has been updated,
|
433
|
+
# `false` if not.
|
434
|
+
# @raise [ArgumentError] if the attribute path format or the user list is
|
435
|
+
# wrong.
|
436
|
+
# @raise [UnacceptableEncryptedAttributeFormat] if encrypted attribute
|
437
|
+
# format is wrong or does not exist.
|
438
|
+
# @raise [UnsupportedEncryptedAttributeFormat] if encrypted attribute
|
439
|
+
# format is not supported or unknown.
|
440
|
+
# @raise [EncryptionFailure] if there are encryption errors.
|
441
|
+
# @raise [MessageAuthenticationFailure] if HMAC calculation error.
|
442
|
+
# @raise [InvalidPublicKey] if it is not a valid RSA public key.
|
443
|
+
# @raise [InvalidKey] if the RSA key format is wrong.
|
444
|
+
# @raise [InsufficientPrivileges] if you lack enough privileges to read
|
445
|
+
# the keys from the Chef Server.
|
446
|
+
# @raise [ClientNotFound] if client does not exist.
|
447
|
+
# @raise [Net::HTTPServerException] for Chef Server HTTP errors.
|
448
|
+
# @raise [RequirementsFailure] if the specified encrypted attribute
|
449
|
+
# version cannot be used.
|
450
|
+
# @raise [SearchFailure] if there is a Chef search error.
|
451
|
+
# @raise [SearchFatalError] if the Chef search response is wrong.
|
452
|
+
# @raise [InvalidSearchKeys] if search keys structure is wrong.
|
453
|
+
def update_on_node(name, attr_ary, c = {})
|
454
|
+
debug(
|
455
|
+
"Updating Remote Encrypted Attribute on #{name}: #{attr_ary.inspect}"
|
456
|
+
)
|
457
|
+
enc_attr = EncryptedAttribute.new(config(c))
|
458
|
+
result = enc_attr.update_on_node(name, attr_ary)
|
459
|
+
debug("Encrypted Remote Attribute #{result ? '' : 'not '}updated.")
|
460
|
+
result
|
461
|
+
end
|
462
|
+
|
463
|
+
# Checks whether an encrypted attribute exists.
|
464
|
+
#
|
465
|
+
# @param hs [Mash] an encrypted hash, usually a node attribute. The
|
466
|
+
# attribute type can be specified but is not necessary. For example:
|
467
|
+
# `node['myapp']['ftp_password']`.
|
468
|
+
# @return [Boolean] `true` if an encrypted attribute is found, `false` if
|
469
|
+
# not.
|
470
|
+
def exist?(hs)
|
471
|
+
debug("Checking if Encrypted Attribute exists here: #{hs.inspect}")
|
472
|
+
result = EncryptedMash.exist?(hs)
|
473
|
+
debug("Encrypted Attribute #{result ? '' : 'not '}found.")
|
474
|
+
result
|
475
|
+
end
|
476
|
+
|
477
|
+
# Checks whether an encrypted attribute exists in a remote node.
|
478
|
+
#
|
479
|
+
# @param [Mixed] args {#exist?} arguments.
|
480
|
+
# @return [Boolean] `true` if an encrypted attribute is found, `false` if
|
481
|
+
# not.
|
482
|
+
# @deprecated Use {#exist?} instead.
|
483
|
+
def exists?(*args)
|
484
|
+
warn("#{name}.exists? is deprecated in favor of #{name}.exist?.")
|
485
|
+
exist?(*args)
|
486
|
+
end
|
487
|
+
|
488
|
+
# Checks whether an encrypted attribute exists in a remote node.
|
489
|
+
#
|
490
|
+
# @param name [String] the node name.
|
491
|
+
# @param attr_ary [Array<String>] the attribute path as *array of
|
492
|
+
# strings*. For example: `%w(myapp ftp_password)`.
|
493
|
+
# @param c [Config, Hash] a configuration hash. For example:
|
494
|
+
# `{ :partial_search => false }`.
|
495
|
+
# @return [Boolean] `true` if an encrypted attribute is found, `false` if
|
496
|
+
# not.
|
497
|
+
# @raise [ArgumentError] if the attribute path format is wrong.
|
498
|
+
def exist_on_node?(name, attr_ary, c = {})
|
499
|
+
debug("Checking if Remote Encrypted Attribute exists on #{name}")
|
500
|
+
remote_node = RemoteNode.new(name)
|
501
|
+
node_attr =
|
502
|
+
remote_node.load_attribute(attr_ary, config(c).partial_search)
|
503
|
+
Chef::EncryptedAttribute.exist?(node_attr)
|
504
|
+
end
|
505
|
+
|
506
|
+
# Checks whether an encrypted attribute exists in a remote node.
|
507
|
+
#
|
508
|
+
# @param [Mixed] args {#exist_on_node?} arguments.
|
509
|
+
# @return [Boolean] `true` if an encrypted attribute is found, `false` if
|
510
|
+
# not.
|
511
|
+
# @deprecated Use {#exist_on_node?} instead.
|
512
|
+
def exists_on_node?(*args)
|
513
|
+
warn(
|
514
|
+
"#{name}.exists_on_node? is deprecated in favor of "\
|
515
|
+
"#{name}.exist_on_node?."
|
516
|
+
)
|
517
|
+
exist_on_node?(*args)
|
518
|
+
end
|
519
|
+
end
|
520
|
+
end
|
521
|
+
end
|