Class: SecureDataBag::Item

Inherits:
Chef::DataBagItem
  • Object
show all
Defined in:
lib/secure_data_bag/item.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ Item

Initializer

Parameters:

  • opts (Hash) (defaults to: {})

    optional options to configure the SecureDataBag::Item opts the initial data to set opts the secret key to use when encrypting/decrypting opts the path to the secret key opts an array of keys to encrypt opts the SecureDataBag::Item format to enforce

Since:

  • 3.0.0



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/secure_data_bag/item.rb', line 77

def initialize(opts = {})
  opts = Mash.new(opts)

  # Initiate the APIClient in Chef 12.3+
  begin super(chef_server_rest: opts.delete(:chef_server_rest))
  rescue ArgumentError; super()
  end

  # Optionally define the Item vesion
  @version = opts[:version] || SecureDataBag::VERSION

  # Optionally define the Item formats
  @encryption_format = opts[:encryption_format]
  @decryption_format = opts[:decryption_format]

  # Optionally provide the shared secret
  @secret = opts[:secret] if opts[:secret]

  # Optionally provide a path to the shared secret. If not provided, the
  # secret loader will automatically attempt to select one.
  @secret_path = opts[:secret_path]

  # Optionally provide a list of keys that should be encrypted or attempt
  # to determine it based on configuration options.
  @encrypted_keys = (
    opts[:encrypted_keys] ||
    Chef::Config[:knife][:secure_data_bag][:encrypted_keys] ||
    []
  ).uniq

  self.raw_data = opts[:data] if opts[:data]
  self
end

Instance Attribute Details

#decryption_formatObject

Format to enforce when decrypting this Item. This item will automatically be updated when importing decrypted data.

Since:

  • 3.0.0



125
126
127
# File 'lib/secure_data_bag/item.rb', line 125

def decryption_format
  @decryption_format
end

#encrypted_keysObject

Array of hash keys which should be encrypted when encrypting this item. For previously decrypted items, this will contain the keys which has previously been encrypted.

Since:

  • 3.0.0



115
116
117
# File 'lib/secure_data_bag/item.rb', line 115

def encrypted_keys
  @encrypted_keys
end

#encryption_formatObject

Format to enforce when encrypting this Item. This item will automatically be updated when importing encrypted data.

Since:

  • 3.0.0



120
121
122
# File 'lib/secure_data_bag/item.rb', line 120

def encryption_format
  @encryption_format
end

Class Method Details

.from_hash(hash, opts = {}) ⇒ SecureDataBag::Item

Create a new SecureDataBag::Item from a hash and optional options.

Parameters:

  • hash (Hash)

    the data

  • opts (Hash) (defaults to: {})

    the optional options to pass to Item.new

Returns:

Since:

  • 3.0.0



44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/secure_data_bag/item.rb', line 44

def from_hash(hash, opts = {})
  data = hash.dup
  data.delete('chef_type')
  data.delete('json_class')

   = Mash.new(data.delete(SecureDataBag::METADATA_KEY) || {})
   = .merge(opts)

  item = new()
  item.data_bag(data.delete('data_bag')) if data.key?('data_bag')
  item.raw_data = data.key?('raw_data') ? data['raw_data'] : data
  item
end

.from_item(data_bag_item, opts = {}) ⇒ SecureDataBag::Item

Create a new SecureDataBag::Item from a DataBagItem.

Parameters:

  • data_bag_item (Chef::DataBagItem)

    the item to create from

  • opts (Hash) (defaults to: {})

    the optional options ot pass to Item.new

Returns:

Since:

  • 3.0.0



63
64
65
66
# File 'lib/secure_data_bag/item.rb', line 63

def from_item(data_bag_item, opts = {})
  data = data_bag_item.to_hash
  from_hash(data, opts)
end

.load(data_bag, name, opts = {}) ⇒ SecureDataBag::Item

Load a data_bag_item and convert into the a SecureDataBag::Item.

Parameters:

  • data_bag (String)

    the data_bag to load the item from

  • name (String)

    the data_bag_item id

  • opts (Hash) (defaults to: {})

    optional options to pass to SecureDataBag::Item.new

Returns:

Since:

  • 3.0.0



28
29
30
31
32
33
34
35
36
37
# File 'lib/secure_data_bag/item.rb', line 28

def load(data_bag, name, opts = {})
  data = {
    'data_bag' => data_bag,
    'id' => name
  }.merge(
    Chef::DataBagItem.load(data_bag, name).to_hash
  )
  item = from_hash(data, opts)
  item
end

.load_secret(path = nil) ⇒ String

Class method used to load the secret key from path

Parameters:

  • path (String) (defaults to: nil)

    the optional path to the file

Returns:

  • (String)

    the secret

Since:

  • 3.0.0



14
15
16
17
18
19
20
# File 'lib/secure_data_bag/item.rb', line 14

def load_secret(path = nil)
  path ||= (
    Chef::Config[:knife][:secure_data_bag][:secret_file] ||
    Chef::Config[:encrypted_data_bag_secret]
  )
  Chef::EncryptedDataBagItem.load_secret(path)
end

Instance Method Details

#metadataHash

Hash representing the metadata associated to this Item

Returns:

  • (Hash)

    the metadata

Since:

  • 3.0.0



139
140
141
142
143
144
145
146
# File 'lib/secure_data_bag/item.rb', line 139

def 
  Mash.new(
    encryption_format: @encryption_format,
    decryption_format: @decryption_format,
    encrypted_keys: @encrypted_keys,
    version: @version
  )
end

#raw_data=(new_data) ⇒ Object

Override the default setter to first ensure that the data is a Mash and then to automatically decrypt the data.

Parameters:

  • new_data (Hash)

    the potentially encrypted data

Since:

  • 3.0.0



152
153
154
155
156
# File 'lib/secure_data_bag/item.rb', line 152

def raw_data=(new_data)
  new_data = Mash.new(new_data)
  new_data.delete(SecureDataBag::METADATA_KEY)
  super(decrypt_data!(new_data))
end

#secret(arg = nil) ⇒ String

Fetch, Set or optionally Load the shared secret

Parameters:

  • arg (String) (defaults to: nil)

    optionally set the shared set

Returns:

  • (String)

    the shared secret

Since:

  • 3.0.0



131
132
133
134
# File 'lib/secure_data_bag/item.rb', line 131

def secret(arg = nil)
  @secret = arg unless arg.nil?
  @secret ||= load_secret
end

#to_data(opts = {}) ⇒ Hash

Export this SecureDataBag::Item to it’s raw_data

Parameters:

  • opts (Hash) (defaults to: {})

    the optional options

Returns:

  • (Hash)

Since:

  • 3.0.0



162
163
164
165
166
167
# File 'lib/secure_data_bag/item.rb', line 162

def to_data(opts = {})
  opts = Mash.new(opts)
  result = opts[:encrypt] ? encrypt_data(raw_data) : raw_data
  result[SecureDataBag::METADATA_KEY] =  if opts[:metadata]
  result
end

#to_hash(opts = {}) ⇒ Hash

Export this SecureDataBag::Item to a Chef::DataBagItem compatible hash

Parameters:

  • opts (Hash) (defaults to: {})

    the optional options

Returns:

  • (Hash)

Since:

  • 3.0.0



173
174
175
176
177
178
179
# File 'lib/secure_data_bag/item.rb', line 173

def to_hash(opts = {})
  opts = Mash.new(opts)
  result = to_data(opts)
  result['chef_type'] = 'data_bag_item'
  result['data_bag'] = data_bag.to_s
  result
end

#to_json(*a) ⇒ String

Export this SecureDataBag::Item to a Chef::DataBagItem compatible json

Returns:

  • (String)

Since:

  • 3.0.0



184
185
186
187
188
189
190
191
192
193
# File 'lib/secure_data_bag/item.rb', line 184

def to_json(*a)
  result = {
    'name' => object_name,
    'json_class' => 'Chef::DataBagItem',
    'chef_type' => 'data_bag_item',
    'data_bag' => data_bag.to_s,
    'raw_data' => encrypt_data(raw_data)
  }
  result.to_json(*a)
end