Module: Pct
- Defined in:
- lib/pct.rb,
lib/pct/version.rb
Defined Under Namespace
Classes: Decryptable, Error
Constant Summary collapse
- DEFAULT =
<<~EOS configuration: example_key: "some value that should be encrypted" some: nested: "values" key_mapping: example_key: 'SomeKmsKeyAlias' some: nested: 'SomeKmsKeyAlias' EOS
- VERSION =
"0.7.2"
Class Method Summary collapse
- .client ⇒ Object
- .create(path) ⇒ Object
- .edit(path, decrypt) ⇒ Object
- .encrypt(value, key) ⇒ Object
- .load_config(path) ⇒ Object
- .set_placeholders(config) ⇒ Object
- .to_decrypted(configuration) ⇒ Object
- .to_encrypted(configuration, key_mapping, original_config = {}, potentially_decrypted = {}) ⇒ Object
- .to_usable(configuration) ⇒ Object
Class Method Details
.client ⇒ Object
34 35 36 |
# File 'lib/pct.rb', line 34 def self.client @client ||= Aws::KMS::Client.new end |
.create(path) ⇒ Object
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/pct.rb', line 87 def self.create(path) file = Tempfile.new(['new-config', '.yml']) File.open(file.path, 'w') do |f| f.puts(DEFAULT) end system("#{ENV['EDITOR']} #{file.path}") new_config = YAML.load(File.read(file.path)) encrypted_config = to_encrypted(new_config['configuration'], new_config['key_mapping']) File.open(path, 'w') do |f| f.write(encrypted_config.to_yaml) end ensure file.close file.unlink end |
.edit(path, decrypt) ⇒ Object
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/pct.rb', line 127 def self.edit(path, decrypt) file = Tempfile.new([path, '.yml']) processed_file = YAML.load(File.read(path)) original_file = YAML.load(File.read(path)) if decrypt processed_file['configuration'] = to_decrypted(processed_file['configuration']) else processed_file['configuration'] = set_placeholders(processed_file['configuration']) end File.open(file.path, 'w') do |f| f.puts(processed_file.to_yaml) end system("#{ENV['EDITOR']} #{file.path}") new_config = YAML.load(File.read(file.path)) encrypted_config = to_encrypted(new_config['configuration'], new_config['key_mapping'], original_file['configuration'], processed_file['configuration']) File.open(path, 'w') do |f| f.write(encrypted_config.to_yaml) end ensure file.close file.unlink end |
.encrypt(value, key) ⇒ Object
53 54 55 56 57 58 59 60 |
# File 'lib/pct.rb', line 53 def self.encrypt(value, key) raise ArgumentError, "all values for encryption must be a string" if !value.is_a?(String) Base64.strict_encode64(client.encrypt({ key_id: "alias/#{key}", plaintext: value }).ciphertext_blob) end |
.load_config(path) ⇒ Object
38 39 40 41 |
# File 'lib/pct.rb', line 38 def self.load_config(path) config = YAML.load(File.read(path)) to_usable(config['configuration']) end |
.set_placeholders(config) ⇒ Object
107 108 109 110 111 112 113 114 115 |
# File 'lib/pct.rb', line 107 def self.set_placeholders(config) config.each do |k, v| if v.is_a?(Hash) set_placeholders(v) else config[k] = '<encrypted>' end end end |
.to_decrypted(configuration) ⇒ Object
117 118 119 120 121 122 123 124 125 |
# File 'lib/pct.rb', line 117 def self.to_decrypted(configuration) Hash[configuration.map do |k, v| if v.is_a?(Hash) [k, to_decrypted(v)] else [k, client.decrypt({ciphertext_blob: Base64.decode64(v)}).plaintext] end end] end |
.to_encrypted(configuration, key_mapping, original_config = {}, potentially_decrypted = {}) ⇒ Object
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/pct.rb', line 62 def self.to_encrypted(configuration, key_mapping, original_config = {}, potentially_decrypted = {}) encrypted_config = Hash[configuration.map do |key, value| if value.is_a?(Hash) [key, to_encrypted(value, key_mapping[key], original_config[key] || {}, potentially_decrypted || {})['configuration']] else if value == '<encrypted>' if !original_config[key] raise "moving encrypted values is not supported" end [key, original_config[key]] elsif value == potentially_decrypted[key] [key, original_config[key]] else [key, encrypt(value, key_mapping[key])] end end end] { 'configuration' => encrypted_config, 'key_mapping' => key_mapping, } end |
.to_usable(configuration) ⇒ Object
43 44 45 46 47 48 49 50 51 |
# File 'lib/pct.rb', line 43 def self.to_usable(configuration) Hash[configuration.map do |k, v| if v.is_a?(Hash) [k, to_usable(v)] else [k, Decryptable.new(v)] end end] end |