secrets_parser 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +2 -0
- data/lib/secrets_parser/parser.rb +55 -62
- data/lib/secrets_parser/s3.rb +38 -0
- data/lib/secrets_parser/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bebee18f1aec76f28803a0e6d930d45db6100a76c67b1310681b30b93b8594cb
|
4
|
+
data.tar.gz: d6fa1b8673811b3eaf2174241774e7a9525d3f679968f5fabd6b3be3185921b3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d75d57d335287068bd8f57bd15e4d1c95f60e6302062eda46e187c4cf4e70c7b05f49c9e62f1b030a3d3bc5b5320960422cb44e78c195e62f184e971feca748f
|
7
|
+
data.tar.gz: 947134c3cf57df1e0e902c87c304c902fe58d575f219d36b91699ebd1cb3bc299be75377f31cbf122da2675421867d2b19dac05d9c8c84169d922a67afc42222
|
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# Secrets Parser
|
2
2
|
|
3
|
+
[](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
|
-
|
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
|
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
|
-
|
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}"
|
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
|
-
|
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
|
47
|
-
|
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
|
-
|
52
|
-
|
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
|
56
|
-
|
57
|
-
|
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
|
-
|
68
|
+
secret_file = secret_file_from(value)
|
69
|
+
secret_key = secret_key_from(value)
|
61
70
|
|
62
|
-
|
63
|
-
|
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
|
-
|
77
|
+
variables
|
67
78
|
end
|
68
79
|
|
69
|
-
def
|
70
|
-
|
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
|
78
|
-
|
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
|
85
|
-
|
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
|
-
|
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
|
-
|
97
|
+
@secret_variables[secret_file][secret_key]
|
105
98
|
end
|
106
99
|
|
107
|
-
def
|
108
|
-
|
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
|
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
|
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.
|
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:
|
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
|
-
|
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.
|