Module: Chef::EncryptedAttribute::API
- Included in:
- Chef::EncryptedAttribute
- Defined in:
- lib/chef/encrypted_attribute/api.rb
Overview
Main EncryptedAttribute class methods API module.
All these methods are available as static methods in the Chef::EncryptedAttribute class.
These methods are intended to be used from Chef Recipes or Resources.
The attributes created by these methods are encrypted only for the local node by default.
The static *_on_node
methods can be used, although they have not been
designed for this purpose (have not been tested).
This module uses the Chef::EncryptedAttribute instance methods internally.
Configuration
All the methods read the default configuration from the
Chef::Config[:encrypted_attributes]
hash. Most of methods also support
setting some configuration parameters as last argument. Both the global
and the method argument configuration will be merged.
If the configuration value to be merged is an array or a hash (for example
keys
), the method argument configuration value has preference over the
global configuration. arrays and hashes are not merged.
Both Chef::Config[:encrypted_attributes]
and method's config
parameter
should be a hash which may have any of the following keys:
:version
-EncryptedMash
format version to use, by default1
is used which is recommended. The version2
uses GCM and probably should be considered the most secure, but it is disabled by default because it has some more requirements: Ruby>= 2
and OpenSSL>= 1.0.1
.:partial_search
- Whether to use Chef Server partial search, enabled by default. It may not work in some old versions of Chef Server.:client_search
- Search query for clients allowed to read the encrypted attribute. Can be a simple string or an array of queries to be OR-ed.:node_search
- Search query for nodes allowed to read the encrypted attribute. Can be a simple string or an array of queries to be OR-ed.:search_max_rows
- Maximum nodes returned by the internal chef searches. This number should be above the maximum expected nodes in the Chef Server. Defaults to1000
nodes.:users
- Array of user names to be allowed to read the encrypted attribute(s)."*"
to allow access to all users. Keep in mind that only admin clients or admin users are allowed to read user public keys. It is not recommended to use this from cookbooks unless you know what you are doing.:keys
- raw RSA public keys to be allowed to read encrypted attributes(s), in PEM (string) format. Can be client public keys, user public keys or any other RSA public key.
For example, to disable Partial Search globally:
Chef::Config[:encrypted_attributes][:partial_search] = false
# ftp_pass = Chef::EncryptedAttribute.load(node['myapp']['ftp_password'])
# ...
To disable Partial Search locally:
ftp_pass = Chef::EncryptedAttribute.load(
node['myapp']['ftp_password'], :partial_search => false
)
To use protocol version 2 globally, which uses GCM:
Chef::Config[:encrypted_attributes][:version] = 2
# ...
If you want to use knife to work with encrypted attributes, surely you
will need to save your Chef User public keys in a Data Bag (there is no
need to encrypt them because they are public) and add them to the :keys
configuration option. See the Example Using User Keys Data Bag in the README for more
information on this.
Caches
This API uses some LRU caches to avoid making many requests to the Chef Server. All the caches are global and has the following methods:
max_size
- Gets or sets the cache maximum item size.clear
- To empty the cache.[]
- To read a cache value (used internally).[]=
- To set a cache value (used internally).
This are the currently available caches:
Chef::EncryptedAttribute::RemoteClients.cache
- Caches the:client_search
query results (max_size:1024
).Chef::EncryptedAttribute::RemoteNodes.cache
- Caches the:node_search
query results (max_size:1024
).Chef::EncryptedAttribute::RemoteUsers.cache
- Caches the Chef Users public keys (max_size:1024
).Chef::EncryptedAttribute::RemoteNode.cache
- Caches the node (encrypted) attributes. Disabled by default (max_size:0
).
Clear All the Caches
You can clear all the caches with the following code:
Chef::EncryptedAttribute::RemoteClients.cache.clear
Chef::EncryptedAttribute::RemoteNodes.cache.clear
Chef::EncryptedAttribute::RemoteUsers.cache.clear
Chef::EncryptedAttribute::RemoteNode.cache.clear
Disable All the Caches
You can disable all the caches with the following code:
Chef::EncryptedAttribute::RemoteClients.cache.max_size(0)
Chef::EncryptedAttribute::RemoteNodes.cache.max_size(0)
Chef::EncryptedAttribute::RemoteUsers.cache.max_size(0)
Chef::EncryptedAttribute::RemoteNode.cache.max_size(0)
Instance Method Summary collapse
-
#config(arg) ⇒ Config
private
Creates a new Config object.
-
#create(value, c = {}) ⇒ EncryptedMash
Creates an encrypted attribute.
-
#create_on_node(name, attr_ary, value, c = {}) ⇒ EncryptedMash
Creates an encrypted attribute on a remote node.
-
#debug(msg) ⇒ Object
private
Prints a Chef debug message.
-
#exist?(hs) ⇒ Boolean
Checks whether an encrypted attribute exists.
-
#exist_on_node?(name, attr_ary, c = {}) ⇒ Boolean
Checks whether an encrypted attribute exists in a remote node.
-
#exists?(*args) ⇒ Boolean
deprecated
Deprecated.
Use #exist? instead.
-
#exists_on_node?(*args) ⇒ Boolean
deprecated
Deprecated.
Use #exist_on_node? instead.
-
#load(enc_hs, c = {}) ⇒ Hash, ...
Reads an encrypted attribute from a hash, usually a node attribute.
-
#load_from_node(name, attr_ary, c = {}) ⇒ Hash, ...
Reads an encrypted attribute from a remote node.
-
#local_node ⇒ LocalNode
private
Gets local node object.
-
#update(enc_hs, c = {}) ⇒ Boolean
Updates who can read the attribute.
-
#update_on_node(name, attr_ary, c = {}) ⇒ Boolean
Updates who can decrypt the remote attribute.
-
#warn(msg) ⇒ Object
private
Prints a Chef warning message.
Instance Method Details
#config(arg) ⇒ Config
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Creates a new Config object.
Reads the default configuration from
Chef::Config[:encrypted_attributes]
.
When the parameter is a Config class, all the configuration options will be replaced.
When the parameter is a Hash, only the provided keys will be replaced.
The local node public key will always be added to the provided configuration keys.
214 215 216 217 218 219 220 |
# File 'lib/chef/encrypted_attribute/api.rb', line 214 def config(arg) config = EncryptedAttribute::Config.new(Chef::Config[:encrypted_attributes]) config.update!(arg) config.keys(config.keys + [local_node.public_key]) config end |
#create(value, c = {}) ⇒ EncryptedMash
Creates an encrypted attribute.
The returned value should be saved in a node attribute, like
node.normal[...] = Chef::EncryptedAttribute.create(...)
.
The local node will always be able to decrypt the attribute.
An exception is thrown if any error arises in the encryption process.
312 313 314 315 316 317 318 |
# File 'lib/chef/encrypted_attribute/api.rb', line 312 def create(value, c = {}) debug('Creating Encrypted Attribute.') enc_attr = EncryptedAttribute.new(config(c)) result = enc_attr.create(value) debug('Encrypted Attribute created.') result end |
#create_on_node(name, attr_ary, value, c = {}) ⇒ EncryptedMash
Creates an encrypted attribute on a remote node.
Both the local node and the remote node will be able to decrypt the attribute.
This method requires admin privileges. So in most cases, cannot be used from cookbooks.
An exception is thrown if any error arises in the encryption process.
358 359 360 361 362 363 364 365 366 |
# File 'lib/chef/encrypted_attribute/api.rb', line 358 def create_on_node(name, attr_ary, value, c = {}) debug( "Creating Remote Encrypted Attribute on #{name}: #{attr_ary.inspect}" ) enc_attr = EncryptedAttribute.new(config(c)) result = enc_attr.create_on_node(name, attr_ary, value) debug('Encrypted Remote Attribute created.') result end |
#debug(msg) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Prints a Chef debug message.
177 178 179 |
# File 'lib/chef/encrypted_attribute/api.rb', line 177 def debug(msg) Chef::Log.debug("Chef::EncryptedAttribute: #{msg}") end |
#exist?(hs) ⇒ Boolean
Checks whether an encrypted attribute exists.
473 474 475 476 477 478 |
# File 'lib/chef/encrypted_attribute/api.rb', line 473 def exist?(hs) debug("Checking if Encrypted Attribute exists here: #{hs.inspect}") result = EncryptedMash.exist?(hs) debug("Encrypted Attribute #{result ? '' : 'not '}found.") result end |
#exist_on_node?(name, attr_ary, c = {}) ⇒ Boolean
Checks whether an encrypted attribute exists in a remote node.
501 502 503 504 505 506 507 508 509 510 511 |
# File 'lib/chef/encrypted_attribute/api.rb', line 501 def exist_on_node?(name, attr_ary, c = {}) debug("Checking if Remote Encrypted Attribute exists on #{name}") remote_node = RemoteNode.new(name) config_merged = config(c) node_attr = remote_node.load_attribute( attr_ary, config_merged.search_max_rows, config_merged.partial_search ) Chef::EncryptedAttribute.exist?(node_attr) end |
#exists?(*args) ⇒ Boolean
Use #exist? instead.
Checks whether an encrypted attribute exists in a remote node.
486 487 488 489 |
# File 'lib/chef/encrypted_attribute/api.rb', line 486 def exists?(*args) warn("#{name}.exists? is deprecated in favor of #{name}.exist?.") exist?(*args) end |
#exists_on_node?(*args) ⇒ Boolean
Use #exist_on_node? instead.
Checks whether an encrypted attribute exists in a remote node.
519 520 521 522 523 524 525 |
# File 'lib/chef/encrypted_attribute/api.rb', line 519 def exists_on_node?(*args) warn( "#{name}.exists_on_node? is deprecated in favor of "\ "#{name}.exist_on_node?." ) exist_on_node?(*args) end |
#load(enc_hs, c = {}) ⇒ Hash, ...
Reads an encrypted attribute from a hash, usually a node attribute.
Uses the local private key to decrypt the attribute.
An exception is thrown if the attribute cannot be decrypted or no encrypted attribute is found.
239 240 241 242 243 244 245 |
# File 'lib/chef/encrypted_attribute/api.rb', line 239 def load(enc_hs, c = {}) debug("Loading Local Encrypted Attribute from: #{enc_hs.inspect}") enc_attr = EncryptedAttribute.new(config(c)) result = enc_attr.load(enc_hs) debug('Local Encrypted Attribute loaded.') result end |
#load_from_node(name, attr_ary, c = {}) ⇒ Hash, ...
Reads an encrypted attribute from a remote node.
Uses the local private key to decrypt the attribute.
An exception is thrown if the attribute cannot be decrypted or no encrypted attribute is found.
268 269 270 271 272 273 274 275 276 |
# File 'lib/chef/encrypted_attribute/api.rb', line 268 def load_from_node(name, attr_ary, c = {}) debug( "Loading Remote Encrypted Attribute from #{name}: #{attr_ary.inspect}" ) enc_attr = EncryptedAttribute.new(config(c)) result = enc_attr.load_from_node(name, attr_ary) debug('Remote Encrypted Attribute loaded.') result end |
#local_node ⇒ LocalNode
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Gets local node object.
194 195 196 |
# File 'lib/chef/encrypted_attribute/api.rb', line 194 def local_node LocalNode.new end |
#update(enc_hs, c = {}) ⇒ Boolean
Updates who can read the attribute. This is intended to be used to
update to the new nodes returned by :client_search
and :node_search
or perhaps global configuration changes.
For example, in case new nodes are added or some are removed, and the
clients returned by :client_search
or :node_search
are different,
this #update
method will decrypt the attribute and encrypt it again
for the new nodes (or remove the old ones).
If an update is made, the shared secrets are regenerated.
Both the local node and the remote node will be able to decrypt the attribute.
An exception is thrown if there is any error in the updating process.
410 411 412 413 414 415 416 417 418 419 420 |
# File 'lib/chef/encrypted_attribute/api.rb', line 410 def update(enc_hs, c = {}) debug("Updating Encrypted Attribute: #{enc_hs.inspect}") enc_attr = EncryptedAttribute.new(config(c)) result = enc_attr.update(enc_hs) if result debug('Encrypted Attribute updated.') else debug('Encrypted Attribute not updated.') end result end |
#update_on_node(name, attr_ary, c = {}) ⇒ Boolean
Updates who can decrypt the remote attribute.
This method requires admin privileges. So in most cases, cannot be used from cookbooks.
An exception is thrown if there is any error in the updating process.
456 457 458 459 460 461 462 463 464 |
# File 'lib/chef/encrypted_attribute/api.rb', line 456 def update_on_node(name, attr_ary, c = {}) debug( "Updating Remote Encrypted Attribute on #{name}: #{attr_ary.inspect}" ) enc_attr = EncryptedAttribute.new(config(c)) result = enc_attr.update_on_node(name, attr_ary) debug("Encrypted Remote Attribute #{result ? '' : 'not '}updated.") result end |
#warn(msg) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Prints a Chef warning message.
186 187 188 |
# File 'lib/chef/encrypted_attribute/api.rb', line 186 def warn(msg) Chef::Log.warn(msg) end |