hiera-secrets-manager 0.1.0 → 0.1.1
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/lib/hiera/backend/secrets_manager_backend.rb +52 -6
- data/spec/secrets_manager_backend_spec.rb +96 -21
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c62c6220168593608f0c75ea45f2c6669cfeab3394d3a00ea8471e9df634b6df
|
4
|
+
data.tar.gz: 0ff04f5c3f5def5bb5251017d475c30217ac9e1f338ccfd3be76efa1c8e773b3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 296c97802ac92301ae42ae581edb461bc570e63564a5732bd14b1acd0453c68eec7ece9461be07573f6ac145c2ea51fcf50f4a29f687eb2cf28e8f0dedee6b6d
|
7
|
+
data.tar.gz: 317abde2b8f974939dd5282f5dd4e42d3c86cfbc947826b0a24c074dab95cb80002520cb0584e9104be84492a1454925b32ca8eef786ba37665c5d188f201c29
|
@@ -3,16 +3,23 @@ class Hiera
|
|
3
3
|
class Secrets_manager_backend
|
4
4
|
def initialize
|
5
5
|
require 'aws-sdk-secretsmanager'
|
6
|
-
@
|
7
|
-
|
8
|
-
)
|
9
|
-
|
10
|
-
Hiera.debug('AWS Secrets Manager backend starting')
|
6
|
+
@config = Config
|
7
|
+
@client = create_client
|
11
8
|
end
|
12
9
|
|
13
10
|
def lookup(key, scope, order_override, resolution_type)
|
14
11
|
answer = nil
|
15
12
|
|
13
|
+
if @client.nil?
|
14
|
+
Hiera.debug('Key lookup failed. AWS Secrets Manager backend is in a bad state.')
|
15
|
+
return answer
|
16
|
+
end
|
17
|
+
|
18
|
+
if contains_illegal_characters?(key)
|
19
|
+
Hiera.debug("#{key} contains illegal characters. Skipping lookup.")
|
20
|
+
return answer
|
21
|
+
end
|
22
|
+
|
16
23
|
key_to_query = format_key(key, scope, Config[:secrets_manager])
|
17
24
|
|
18
25
|
begin
|
@@ -26,6 +33,12 @@ class Hiera
|
|
26
33
|
|
27
34
|
private
|
28
35
|
|
36
|
+
# AWS Secrets Manager only allows alphanumeric characters or (/_+=.@-) in key names
|
37
|
+
# GetSecret requests will fail for keys which have illegal characters
|
38
|
+
def contains_illegal_characters?(key)
|
39
|
+
%r{^[a-zA-Z0-9\/_+=.@\-]+$}.match(key).nil?
|
40
|
+
end
|
41
|
+
|
29
42
|
def get_prefix(environments, scope)
|
30
43
|
if environments && environments.key?(scope['environment'])
|
31
44
|
environments[scope['environment']]
|
@@ -35,7 +48,7 @@ class Hiera
|
|
35
48
|
end
|
36
49
|
|
37
50
|
def format_key(key, scope, config)
|
38
|
-
if scope.
|
51
|
+
if scope.include?('environment') && scope['environment']
|
39
52
|
environments = config[:environments]
|
40
53
|
prefix = get_prefix(environments, scope)
|
41
54
|
"#{prefix}/#{key}"
|
@@ -43,6 +56,39 @@ class Hiera
|
|
43
56
|
key
|
44
57
|
end
|
45
58
|
end
|
59
|
+
|
60
|
+
def create_client
|
61
|
+
if missing_config?
|
62
|
+
Hiera.debug('Warning! Config is empty. Starting in a bad state.')
|
63
|
+
return nil
|
64
|
+
end
|
65
|
+
|
66
|
+
if missing_keys?
|
67
|
+
Hiera.debug("Warning! Missing key(s) #{missing_keys} in Config. Starting in a bad state.")
|
68
|
+
return nil
|
69
|
+
end
|
70
|
+
|
71
|
+
Hiera.debug('AWS Secrets Manager backend starting')
|
72
|
+
Aws::SecretsManager::Client.new(
|
73
|
+
region: @config[:secrets_manager][:region],
|
74
|
+
access_key_id: @config[:secrets_manager][:access_key_id],
|
75
|
+
secret_access_key: @config[:secrets_manager][:secret_access_key]
|
76
|
+
)
|
77
|
+
end
|
78
|
+
|
79
|
+
def missing_config?
|
80
|
+
@config[:secrets_manager].nil?
|
81
|
+
end
|
82
|
+
|
83
|
+
def missing_keys?
|
84
|
+
!missing_keys.empty?
|
85
|
+
end
|
86
|
+
|
87
|
+
def missing_keys
|
88
|
+
%i[region access_key_id secret_access_key].reject do |key|
|
89
|
+
@config[:secrets_manager].include?(key)
|
90
|
+
end
|
91
|
+
end
|
46
92
|
end
|
47
93
|
end
|
48
94
|
end
|
@@ -4,23 +4,38 @@ require 'hiera/backend/secrets_manager_backend'
|
|
4
4
|
class Hiera
|
5
5
|
module Backend
|
6
6
|
describe Secrets_manager_backend do
|
7
|
-
before do
|
7
|
+
before(:each) do
|
8
8
|
@region_object = { region: 'some_region' }
|
9
|
+
@credentials = { access_key_id: 'some_id',
|
10
|
+
secret_access_key: 'some_access_key' }
|
9
11
|
@config_object = { secrets_manager:
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
12
|
+
{
|
13
|
+
region: @region_object[:region],
|
14
|
+
access_key_id: @credentials[:access_key_id],
|
15
|
+
secret_access_key: @credentials[:secret_access_key],
|
16
|
+
environments:
|
17
|
+
{
|
18
|
+
'env1' => 'production',
|
19
|
+
'env2' => 'staging',
|
20
|
+
'env3' => 'development'
|
21
|
+
}
|
22
|
+
} }
|
23
|
+
|
19
24
|
Config.load(@config_object)
|
20
25
|
Hiera.stubs(:debug)
|
26
|
+
@mock_client = mock('client')
|
21
27
|
Aws::SecretsManager::Client
|
22
28
|
.stubs(:new)
|
23
|
-
.with(@region_object
|
29
|
+
.with(region: @region_object[:region],
|
30
|
+
access_key_id: @credentials[:access_key_id],
|
31
|
+
secret_access_key: @credentials[:secret_access_key])
|
32
|
+
.returns(@mock_client)
|
33
|
+
end
|
34
|
+
|
35
|
+
def mock_scope_with_environment(environment)
|
36
|
+
mock_scope = mock
|
37
|
+
mock_scope.stubs(:lookupvar).with('environment').returns(environment)
|
38
|
+
Hiera::Scope.new(mock_scope)
|
24
39
|
end
|
25
40
|
|
26
41
|
describe '#initialize' do
|
@@ -34,19 +49,59 @@ class Hiera
|
|
34
49
|
it 'should set up a connection to AWS Secrets Manager' do
|
35
50
|
Aws::SecretsManager::Client
|
36
51
|
.expects(:new)
|
37
|
-
.with(@region_object
|
52
|
+
.with(region: @region_object[:region],
|
53
|
+
access_key_id: @credentials[:access_key_id],
|
54
|
+
secret_access_key: @credentials[:secret_access_key])
|
38
55
|
Secrets_manager_backend.new
|
39
56
|
end
|
57
|
+
|
58
|
+
context 'with bad config' do
|
59
|
+
after do
|
60
|
+
Secrets_manager_backend.new
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'with empty config, should announce that it has no config' do
|
64
|
+
config_object = {}
|
65
|
+
Config.load(config_object)
|
66
|
+
Hiera
|
67
|
+
.expects(:debug)
|
68
|
+
.with('Warning! Config is empty. Starting in a bad state.')
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'with no params, should announce that it is in a bad state' do
|
72
|
+
config_object = { secrets_manager: {} }
|
73
|
+
Config.load(config_object)
|
74
|
+
Hiera
|
75
|
+
.expects(:debug)
|
76
|
+
.with('Warning! Missing key(s) [:region, :access_key_id, :secret_access_key] in Config. Starting in a bad state.')
|
77
|
+
end
|
78
|
+
|
79
|
+
[:region, :access_key_id, :secret_access_key].each do |key|
|
80
|
+
it "debug should announce when key [#{key}] is missing in config" do
|
81
|
+
@config_object[:secrets_manager].delete(key)
|
82
|
+
Config.load(@config_object)
|
83
|
+
Hiera
|
84
|
+
.expects(:debug)
|
85
|
+
.with("Warning! Missing key(s) [:#{key}] in Config. Starting in a bad state.")
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
40
89
|
end
|
41
90
|
|
42
91
|
describe '#lookup' do
|
43
92
|
before do
|
44
|
-
@mock_client = mock('client')
|
45
|
-
Aws::SecretsManager::Client
|
46
|
-
.stubs(:new)
|
47
|
-
.with(@region_object).returns(@mock_client)
|
48
93
|
@backend = Secrets_manager_backend.new
|
49
|
-
@scope =
|
94
|
+
@scope = mock_scope_with_environment('env1')
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'should announce if it is in a bad state' do
|
98
|
+
config_object = { secrets_manager: {} }
|
99
|
+
Config.load(config_object)
|
100
|
+
Hiera
|
101
|
+
.expects(:debug)
|
102
|
+
.with('Key lookup failed. AWS Secrets Manager backend is in a bad state.')
|
103
|
+
backend = Secrets_manager_backend.new
|
104
|
+
backend.lookup('some_secret', {}, nil, nil)
|
50
105
|
end
|
51
106
|
|
52
107
|
it 'should return a secret that exists' do
|
@@ -85,7 +140,8 @@ class Hiera
|
|
85
140
|
end
|
86
141
|
|
87
142
|
it 'falls back to provided scope environment when Hiera config does not include environment as a key / value pair' do
|
88
|
-
scope =
|
143
|
+
scope = mock_scope_with_environment('some_env_not_in_config')
|
144
|
+
|
89
145
|
prefixed_secret_name = 'some_env_not_in_config/secret_name'
|
90
146
|
|
91
147
|
@mock_client
|
@@ -99,7 +155,8 @@ class Hiera
|
|
99
155
|
incomplete_config = { secrets_manager: { region: @region_object[:region] } }
|
100
156
|
Config.load(incomplete_config)
|
101
157
|
|
102
|
-
scope =
|
158
|
+
scope = mock_scope_with_environment('some_env')
|
159
|
+
|
103
160
|
prefixed_secret_name = 'some_env/secret_name'
|
104
161
|
|
105
162
|
@mock_client
|
@@ -110,14 +167,32 @@ class Hiera
|
|
110
167
|
end
|
111
168
|
|
112
169
|
it 'does not use prefix if no environment is provided in scope' do
|
113
|
-
scope =
|
170
|
+
scope = mock_scope_with_environment(nil)
|
171
|
+
|
114
172
|
secret_name = 'secret_name'
|
115
173
|
|
116
174
|
@mock_client
|
117
175
|
.expects(:get_secret_value)
|
118
176
|
.with(secret_id: secret_name)
|
119
177
|
.returns('secret_string' => 'the_secret')
|
120
|
-
|
178
|
+
|
179
|
+
@backend.lookup(secret_name, scope, nil, nil)
|
180
|
+
end
|
181
|
+
|
182
|
+
%w[: ~ # \\].each do |character|
|
183
|
+
it "returns nil if key has illegal character [#{character}] (according to AWS)" do
|
184
|
+
@mock_client
|
185
|
+
.expects(:get_secret_value)
|
186
|
+
.never
|
187
|
+
|
188
|
+
secret_name = "secret#{character}name"
|
189
|
+
|
190
|
+
Hiera
|
191
|
+
.expects(:debug)
|
192
|
+
.with("#{secret_name} contains illegal characters. Skipping lookup.")
|
193
|
+
|
194
|
+
@backend.lookup(secret_name, @scope, nil, nil)
|
195
|
+
end
|
121
196
|
end
|
122
197
|
end
|
123
198
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hiera-secrets-manager
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Unruly
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-08-
|
11
|
+
date: 2018-08-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-secretsmanager
|