moonshot 1.1.0.beta1 → 1.1.0.beta2
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
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 47ebc9ac74a51f7c8b474a1947508d4f32d16e9d
|
4
|
+
data.tar.gz: 84c3812ddc48bb7308027d442306a85288be1c94
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2bd8244804aa2441c7f95434f68ae5f39c8e0c9fa305d986a66e5477e0285d244a6cb196a77036d22080fe62cf4897b8438f932fba53638fe71120c1b2bc065a
|
7
|
+
data.tar.gz: fb7bba6e3ae5e84e2a8f4f9c70953f1578425770fe37ea9ce2a2f2bc7f920757a31f311c7cacc3834488a3355b828871ca22a271fb385620fbb4e0a2c4935a54
|
@@ -0,0 +1,111 @@
|
|
1
|
+
# This plugin encrypts parameters of the stack using a KMS Key,
|
2
|
+
# storing and passing the key used to the stack as a parameter as
|
3
|
+
# well. The resources in the stack can then use that KMS Key to
|
4
|
+
# decrypt those values.
|
5
|
+
#
|
6
|
+
# Example:
|
7
|
+
#
|
8
|
+
# Moonshot.config do |s|
|
9
|
+
# # .. mechanism config, etc. ..
|
10
|
+
#
|
11
|
+
# # The user will be prompted for values for SecretParameter1 and
|
12
|
+
# # SecretParameter2, which will then be encrypted by this plugins
|
13
|
+
# # pre_create and pre_update hooks.
|
14
|
+
# c.plugins << Moonshot::Plugins::EncryptedParameters.new(
|
15
|
+
# 'KMSKey1', %w(SecretParameter1 SecretParameter2)
|
16
|
+
#
|
17
|
+
# # Don't prompt the user for a KMS Key, since the default of 'Auto'
|
18
|
+
# # will generate a new key. They can override it with an answer
|
19
|
+
# # file or command line parameter if needed.
|
20
|
+
# c.parameter_sources['KMSKey1'] = Moonshot::AlwaysUseDefaultSource.new
|
21
|
+
# end
|
22
|
+
module Moonshot
|
23
|
+
class EncryptedParameters
|
24
|
+
# @param [String] kms_key_parameter_name
|
25
|
+
# The parameter name to store the KMS Key ARN as.
|
26
|
+
# @param [Array<String>] parameters
|
27
|
+
# Names of parameters to encrypt, if they are not already set.
|
28
|
+
def initialize(kms_key_parameter_name, parameters)
|
29
|
+
@kms_key_parameter_name = kms_key_parameter_name
|
30
|
+
@parameters = parameters
|
31
|
+
@delete_key = true
|
32
|
+
end
|
33
|
+
|
34
|
+
def pre_create(res)
|
35
|
+
@ilog = res.ilog
|
36
|
+
|
37
|
+
key_arn = find_or_create_kms_key
|
38
|
+
pe = ParameterEncrypter.new(key_arn)
|
39
|
+
|
40
|
+
@parameters.each do |parameter_name|
|
41
|
+
sp = Moonshot.config.parameters[parameter_name]
|
42
|
+
raise "No such parameter #{parameter_name}" unless sp
|
43
|
+
|
44
|
+
@ilog.start_threaded "Handling encrypted parameter #{parameter_name.blue}..." do |s|
|
45
|
+
if sp.use_previous?
|
46
|
+
# TODO: Remove this and the one below when the upstream race is fixed.
|
47
|
+
# See https://github.com/askreet/interactive-logger/issues/7
|
48
|
+
sleep 0.05
|
49
|
+
s.success "Using previous encrypted value for #{parameter_name.blue}."
|
50
|
+
elsif !sp.set? && !sp.default?
|
51
|
+
# If the parameter isn't set, we can't encrypt it. Doing
|
52
|
+
# nothing means we will give the user a friendly error message
|
53
|
+
# about unset parameters when the controller resumes.
|
54
|
+
sleep 0.05
|
55
|
+
s.failure "No value to encrypt for #{parameter_name.blue}!"
|
56
|
+
else
|
57
|
+
s.continue "Encrypting new value for parameter #{parameter_name.blue}..."
|
58
|
+
Moonshot.config.parameters[sp.name].set(pe.encrypt(sp.value))
|
59
|
+
s.success "Encrypted new value for parameter #{parameter_name.blue}!"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
alias pre_update pre_create
|
65
|
+
|
66
|
+
def post_delete(res)
|
67
|
+
key_arn = Moonshot.config.parameters[@kms_key_parameter_name].value
|
68
|
+
|
69
|
+
res.ilog.start_threaded "Cleaning up KMS Key #{@kms_key_parameter_name.blue}..." do |s|
|
70
|
+
if @delete_key
|
71
|
+
KmsKey.new(key_arn).delete
|
72
|
+
s.success "Deleted KMS Key #{@kms_key_parameter_name.blue}!"
|
73
|
+
else
|
74
|
+
# TODO: See above.
|
75
|
+
sleep 0.05
|
76
|
+
s.success "Retained KMS Key #{@kms_key_parameter_name.blue}."
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def delete_cli_hook(parser)
|
82
|
+
parser.on('--retain-kms-key', TrueClass, 'Do not delete the KMS Key for this environment.') do
|
83
|
+
@delete_key = false
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def find_or_create_kms_key
|
90
|
+
key_arn = nil
|
91
|
+
|
92
|
+
@ilog.start_threaded "Checking for KMS Key #{@kms_key_parameter_name}" do |s|
|
93
|
+
if Moonshot.config.parameters.key?(@kms_key_parameter_name)
|
94
|
+
if 'Auto' == Moonshot.config.parameters[@kms_key_parameter_name].value
|
95
|
+
s.continue "Auto-generating KMS Key for #{@kms_key_parameter_name.blue}... "
|
96
|
+
key_arn = KmsKey.create.arn
|
97
|
+
Moonshot.config.parameters[@kms_key_parameter_name].set(key_arn)
|
98
|
+
s.success "Created a new KMS Key for #{@kms_key_parameter_name.blue}!"
|
99
|
+
else
|
100
|
+
key_arn = KmsKey.new(Moonshot.config.parameters[@kms_key_parameter_name].value).arn
|
101
|
+
s.success "Using existing KMS Key for #{@kms_key_parameter_name.blue}!"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
raise "No such Stack Parameter #{@kms_key_parameter_name}!" unless key_arn
|
107
|
+
|
108
|
+
key_arn
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class EncryptedParameters
|
2
|
+
# Class that manages KMS keys in AWS.
|
3
|
+
class KmsKey
|
4
|
+
attr_reader :arn
|
5
|
+
|
6
|
+
def initialize(arn)
|
7
|
+
@arn = arn
|
8
|
+
@kms_client = Aws::KMS::Client.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.create
|
12
|
+
resp = Aws::KMS::Client.new.create_key
|
13
|
+
arn = resp.key_metadata.arn
|
14
|
+
|
15
|
+
new(arn)
|
16
|
+
end
|
17
|
+
|
18
|
+
def delete
|
19
|
+
@kms_client.schedule_key_deletion(key_id: @arn, pending_window_in_days: 7)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'base64'
|
2
|
+
|
3
|
+
class EncryptedParameters
|
4
|
+
# Class that can encrypt and decrypt parameters using KMS.
|
5
|
+
class ParameterEncrypter
|
6
|
+
# @param [String] key_arn The ARN for the KMS key.
|
7
|
+
def initialize(key_arn)
|
8
|
+
@kms_client = Aws::KMS::Client.new
|
9
|
+
@key_arn = key_arn
|
10
|
+
end
|
11
|
+
|
12
|
+
# Encrypt and base64 encode the parameter value.
|
13
|
+
#
|
14
|
+
# @param [String] param_value The parameter to encrypt.
|
15
|
+
# @return [String] base64 encoded encrypted ciphertext.
|
16
|
+
def encrypt(param_value)
|
17
|
+
resp = @kms_client.encrypt(key_id: @key_arn, plaintext: param_value)
|
18
|
+
|
19
|
+
# Use strict here to avoid newlines which cause issues with parameters.
|
20
|
+
Base64.strict_encode64(resp.ciphertext_blob)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: moonshot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.0.
|
4
|
+
version: 1.1.0.beta2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cloud Engineering <engineering@acquia.com>
|
@@ -317,6 +317,9 @@ files:
|
|
317
317
|
- lib/moonshot/unicode_table.rb
|
318
318
|
- lib/moonshot/yaml_stack_template.rb
|
319
319
|
- lib/plugins/backup.rb
|
320
|
+
- lib/plugins/encrypted_parameters.rb
|
321
|
+
- lib/plugins/encrypted_parameters/kms_key.rb
|
322
|
+
- lib/plugins/encrypted_parameters/parameter_encrypter.rb
|
320
323
|
homepage: https://github.com/acquia/moonshot
|
321
324
|
licenses:
|
322
325
|
- Apache-2.0
|