Class: Veil::CredentialCollection::ChefSecretsFile

Inherits:
Base
  • Object
show all
Defined in:
lib/veil/credential_collection/chef_secrets_file.rb

Constant Summary collapse

CURRENT_VERSION =
2.freeze

Instance Attribute Summary collapse

Attributes inherited from Base

#credentials, #decryptor, #encryptor, #hasher, #version

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#add, #add_from_file, create, #exist?, #get, #remove, #rotate, #rotate_credentials, #rotate_hasher, #to_hash

Constructor Details

#initialize(opts = {}) ⇒ ChefSecretsFile

Create a new ChefSecretsFile

Parameters:

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

    a hash of options to pass to the constructor



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/veil/credential_collection/chef_secrets_file.rb', line 27

def initialize(opts = {})
  @path = (opts[:path] && File.expand_path(opts[:path])) || "/etc/opscode/private-chef-secrets.json"

  import_existing = File.exists?(path) && (File.size(path) != 0)
  legacy = true

  if import_existing
    begin
      hash = JSON.parse(IO.read(path), symbolize_names: true)
    rescue JSON::ParserError, Errno::ENOENT => e
      raise InvalidCredentialCollectionFile.new("#{path} is not a valid credentials file:\n #{e.message}")
    end

    if hash.key?(:veil) && hash[:veil][:type] == "Veil::CredentialCollection::ChefSecretsFile"
      opts = Veil::Utils.symbolize_keys(hash[:veil]).merge(opts)
      legacy = false
    end
  end

  @user    = opts[:user]
  @group   = opts[:group] || @user
  opts[:version] = CURRENT_VERSION
  super(opts)

  import_legacy_credentials(hash) if import_existing && legacy
end

Instance Attribute Details

#groupObject (readonly)

Returns the value of attribute group.



21
22
23
# File 'lib/veil/credential_collection/chef_secrets_file.rb', line 21

def group
  @group
end

#keyObject (readonly)

Returns the value of attribute key.



21
22
23
# File 'lib/veil/credential_collection/chef_secrets_file.rb', line 21

def key
  @key
end

#pathObject

Returns the value of attribute path.



21
22
23
# File 'lib/veil/credential_collection/chef_secrets_file.rb', line 21

def path
  @path
end

#userObject (readonly)

Returns the value of attribute user.



21
22
23
# File 'lib/veil/credential_collection/chef_secrets_file.rb', line 21

def user
  @user
end

Class Method Details

.from_file(path, opts = {}) ⇒ Object



10
11
12
13
14
15
16
# File 'lib/veil/credential_collection/chef_secrets_file.rb', line 10

def from_file(path, opts = {})
  unless File.exists?(path)
    raise InvalidCredentialCollectionFile.new("#{path} does not exist")
  end

  new(opts.merge(path: path))
end

Instance Method Details

#credentials_for_exportObject Also known as: legacy_credentials_hash



81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/veil/credential_collection/chef_secrets_file.rb', line 81

def credentials_for_export
  hash = Hash.new

  credentials.each do |namespace, cred_or_creds|
    if cred_or_creds.is_a?(Veil::Credential)
      hash[namespace] = cred_or_creds.value
    else
      hash[namespace] = {}
      cred_or_creds.each { |name, cred| hash[namespace][name] = cred.value }
    end
  end

  hash
end

#import_legacy_credentials(hash) ⇒ Object



97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/veil/credential_collection/chef_secrets_file.rb', line 97

def import_legacy_credentials(hash)
  hash.each do |namespace, creds_hash|
    credentials[namespace.to_s] ||= Hash.new
    creds_hash.each do |cred, value|
      credentials[namespace.to_s][cred.to_s] = Veil::Credential.new(
        name: cred.to_s,
        value: value,
        length: value.length
      )
    end
  end
end

#saveObject

Save the CredentialCollection to file, encrypt it



63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/veil/credential_collection/chef_secrets_file.rb', line 63

def save
  FileUtils.mkdir_p(File.dirname(path))

  f = Tempfile.new("veil") # defaults to mode 0600
  FileUtils.chown(user, group, f.path) if user
  f.puts(JSON.pretty_generate(secrets_hash))
  f.flush
  f.close

  FileUtils.mv(f.path, path)
  true
end

#secrets_hashObject

Return the instance as a secrets style hash



77
78
79
# File 'lib/veil/credential_collection/chef_secrets_file.rb', line 77

def secrets_hash
  { "veil" => to_h }
end