secrets_parser 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 482b595adb191ed6b889340e239cdcc376e84a3ee3e0e0e15a4df745ee28009f
4
- data.tar.gz: 3e077fcda36d288afaebac53430bc567aae58b50e936e66cad5464e3dd4c1e9e
3
+ metadata.gz: bebee18f1aec76f28803a0e6d930d45db6100a76c67b1310681b30b93b8594cb
4
+ data.tar.gz: d6fa1b8673811b3eaf2174241774e7a9525d3f679968f5fabd6b3be3185921b3
5
5
  SHA512:
6
- metadata.gz: 48775396ba15fa9ff16ec517d13ee4e53a8349072ed9704c455c24cb42c53f5c627b1f00cbfc7e6b070ce5db96ed6044aa1822299fc46656c9b6e092bb8bb851
7
- data.tar.gz: eb1f9e854bb59043f2f9bc50f190b03e4177fbe76d7f110302bdd470cf769a9f449e25b64c5b1cae909a897f737aa89ade8e8420365f24e67bc7af0f65410949
6
+ metadata.gz: d75d57d335287068bd8f57bd15e4d1c95f60e6302062eda46e187c4cf4e70c7b05f49c9e62f1b030a3d3bc5b5320960422cb44e78c195e62f184e971feca748f
7
+ data.tar.gz: 947134c3cf57df1e0e902c87c304c902fe58d575f219d36b91699ebd1cb3bc299be75377f31cbf122da2675421867d2b19dac05d9c8c84169d922a67afc42222
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Secrets Parser
2
2
 
3
+ [![Build Status](https://travis-ci.org/peertransfer/secrets_parser.svg?branch=master)](https://travis-ci.org/peertransfer/secrets_parser)
4
+
3
5
  This gem parse the secrets reading a field in a JSON file, download the encrypted secrets file from S3 and change the values for the encrypted ones.
4
6
 
5
7
  ## Usage
@@ -1,32 +1,45 @@
1
- require 'json'
2
1
  require 'aws-sdk-s3'
2
+ require 'json'
3
+ require 'logger'
3
4
  require_relative 'helpers'
5
+ require_relative 's3'
4
6
 
5
7
  module Secrets
8
+ module Errors
9
+ class NoSuchKey < StandardError; end
10
+ end
11
+
6
12
  class Parser
7
13
  SECRETS_FILE_SUFFIX = '.json.encrypted'.freeze
8
14
 
15
+ class Configuration
16
+ SETTINGS = %i[s3_client kms_client logger s3].freeze
17
+
18
+ attr_accessor(*SETTINGS)
19
+
20
+ def []=(key, value)
21
+ public_send("#{key}=", value)
22
+ end
23
+ end
24
+
9
25
  def initialize
10
- @config = {
11
- s3_client: nil,
12
- kms_client: nil,
13
- logger: nil
14
- }
26
+ @config = Configuration.new
27
+ @secret_variables = {}
15
28
  end
16
29
 
17
30
  def set_config
18
- yield @config
31
+ yield(@config)
32
+ @config.logger ||= Logger.new(File::NULL)
33
+ self
19
34
  end
20
35
 
21
36
  def parse(file_to_parse, field_to_parse)
22
- Aws.config.update(
23
- region: ENV['AWS_DEFAULT_REGION']
24
- )
37
+ @config.s3 = S3.new(@config.s3_client, @config.kms_client, @config.logger)
25
38
 
26
39
  app_json = JSON.parse(IO.read(file_to_parse))
27
40
  app_variables = app_json[field_to_parse]
28
41
 
29
- logger.info "Parsing #{field_to_parse} section of #{file_to_parse}" if logger?
42
+ logger.info "Parsing #{field_to_parse} section of #{file_to_parse}"
30
43
 
31
44
  app_json[field_to_parse] = parse_secrets_from app_variables
32
45
 
@@ -36,80 +49,60 @@ module Secrets
36
49
  private
37
50
 
38
51
  def secret?(string)
39
- if string.is_a? String
40
- string.start_with? 'secret:'
41
- else
42
- false
43
- end
52
+ string.is_a?(String) && string.start_with?('secret:')
44
53
  end
45
54
 
46
- def secret_file_path_from(secret)
47
- secret_file_path = secret[secret.index(':') + 1..secret.rindex(':') - 1]
48
- Helpers.expand_param_from_env secret_file_path
49
- end
55
+ def secrets_from(secret_file)
56
+ return @secret_variables[secret_file] if already_decrypted?(secret_file)
50
57
 
51
- def secret_key_from(secret)
52
- secret[secret.rindex(':') + 1..secret.length]
58
+ encrypted_secrets_io = @config.s3.download(secret_file + SECRETS_FILE_SUFFIX)
59
+ decrypted_secrets = @config.s3.decrypt(encrypted_secrets_io)
60
+
61
+ JSON.parse(decrypted_secrets)
53
62
  end
54
63
 
55
- def download(file)
56
- bucket_name = file[0, file.index('/')]
57
- file = file[file.index('/') + 1..file.length] + SECRETS_FILE_SUFFIX
58
- tmp_file = "/tmp/secrets#{SECRETS_FILE_SUFFIX}"
64
+ def parse_secrets_from(variables)
65
+ variables.each_pair do |key, value|
66
+ next unless secret?(value)
59
67
 
60
- logger.info "Downloading #{file} from #{bucket_name}" if logger?
68
+ secret_file = secret_file_from(value)
69
+ secret_key = secret_key_from(value)
61
70
 
62
- File.open(tmp_file, 'wb') do |secret_file|
63
- @config[:s3_client].get_object({ bucket: bucket_name, key: file }, target: secret_file)
71
+ @secret_variables[secret_file] = secrets_from(secret_file)
72
+
73
+ logger.info "Updating #{key} value"
74
+ variables[key] = secret_value_from(secret_file, secret_key)
64
75
  end
65
76
 
66
- tmp_file
77
+ variables
67
78
  end
68
79
 
69
- def decrypt(file)
70
- kms = @config[:kms_client]
71
-
72
- kms.decrypt(
73
- ciphertext_blob: IO.read(file)
74
- )
80
+ def already_decrypted?(secret_file)
81
+ @secret_variables.key?(secret_file)
75
82
  end
76
83
 
77
- def extract_secrets_from(secret_file)
78
- encrypted_secrets_file = download secret_file
79
- decrypted_secrets_file = decrypt encrypted_secrets_file
80
-
81
- JSON.parse(decrypted_secrets_file.plaintext)
84
+ def secret_file_from(secret)
85
+ Helpers.expand_param_from_env(secret).split(':')[1]
82
86
  end
83
87
 
84
- def parse_secrets_from(variables)
85
- secret_variables = {}
86
-
87
- variables.each_pair do |key, value|
88
- next unless secret?(value)
89
-
90
- secret = value
91
-
92
- secret_file = secret_file_path_from(secret)
93
- secret_key = secret_key_from(secret)
94
-
95
- unless secret_variables.key?(secret_file)
96
- secret_variables[secret_file] = extract_secrets_from secret_file
97
- end
98
-
99
- logger.info "Updating #{key} value" if logger?
88
+ def secret_key_from(secret)
89
+ Helpers.expand_param_from_env(secret).split(':')[2]
90
+ end
100
91
 
101
- variables[key] = secret_variables[secret_file][secret_key]
92
+ def secret_value_from(secret_file, secret_key)
93
+ unless secret_key_exists?(secret_file, secret_key)
94
+ raise Secrets::Errors::NoSuchKey, "Secret key #{secret_key} does not exist in #{secret_file}"
102
95
  end
103
96
 
104
- variables
97
+ @secret_variables[secret_file][secret_key]
105
98
  end
106
99
 
107
- def logger?
108
- !logger.nil?
100
+ def secret_key_exists?(secret_file, secret_key)
101
+ !@secret_variables[secret_file][secret_key].nil?
109
102
  end
110
103
 
111
104
  def logger
112
- @config[:logger]
105
+ @config.logger
113
106
  end
114
107
  end
115
108
  end
@@ -0,0 +1,38 @@
1
+ require 'aws-sdk-s3'
2
+ require 'json'
3
+ require 'logger'
4
+ require_relative 'helpers'
5
+
6
+ module Secrets
7
+ module Errors
8
+ class NoSuchFile < StandardError; end
9
+ end
10
+
11
+ class S3
12
+ def initialize(s3_client, kms_client, logger)
13
+ @s3_client = s3_client
14
+ @kms_client = kms_client
15
+ @logger = logger
16
+ end
17
+
18
+ def download(filename)
19
+ bucket_name, file = filename.split('/', 2)
20
+
21
+ @logger.info "Downloading #{file} from #{bucket_name}"
22
+ begin
23
+ resp = @s3_client.get_object(bucket: bucket_name, key: file)
24
+ resp.body
25
+ rescue Aws::S3::Errors::NoSuchKey
26
+ raise Secrets::Errors::NoSuchFile, "Secret file #{file} does not exist in #{bucket_name}"
27
+ end
28
+ end
29
+
30
+ def decrypt(io)
31
+ @kms_client.decrypt(ciphertext_blob: io.read).plaintext
32
+ end
33
+
34
+ def logger
35
+ @config.logger
36
+ end
37
+ end
38
+ end
@@ -1,3 +1,3 @@
1
1
  module SecretsParser
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: secrets_parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paco Sanchez
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-10-10 00:00:00.000000000 Z
11
+ date: 2019-05-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -66,6 +66,7 @@ files:
66
66
  - lib/secrets_parser.rb
67
67
  - lib/secrets_parser/helpers.rb
68
68
  - lib/secrets_parser/parser.rb
69
+ - lib/secrets_parser/s3.rb
69
70
  - lib/secrets_parser/version.rb
70
71
  - secrets_parser.gemspec
71
72
  homepage: https://github.com/peertransfer/secrets_parser
@@ -88,8 +89,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
88
89
  - !ruby/object:Gem::Version
89
90
  version: '0'
90
91
  requirements: []
91
- rubyforge_project:
92
- rubygems_version: 2.7.7
92
+ rubygems_version: 3.0.3
93
93
  signing_key:
94
94
  specification_version: 4
95
95
  summary: Write a short summary, because RubyGems requires one.