hiera-eyaml-vault 0.0.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
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 2500c39c866bab8c7403755030356b0fcecaa9cd433157e961e6a4e7f87d7d8a
|
4
|
+
data.tar.gz: 44966b8d2fba03c146d9f8835893f4c5245bd0655bc4db6667f708e25f78ce63
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d8e4f2a4655ec04907d4ca9f1687123eea7b106b669a6fdd90c341acb23f6e693071a1026172b25c964928cc956e9d2a476781185f7569010984349938d99f6d
|
7
|
+
data.tar.gz: caddceb7edacdaf8a3f00a2b63bf5de647df5b54613aef49d54b74f5c62e7f510e4f3b205849740715bb605347e377a7d0c1f85c5b5fb17214cb5c78dbbc5445
|
@@ -0,0 +1,202 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require 'hiera/backend/eyaml/encryptor'
|
3
|
+
require 'hiera/backend/eyaml/encryptors/vault/httphandler'
|
4
|
+
require 'hiera/backend/eyaml/utils'
|
5
|
+
require 'hiera/backend/eyaml/plugins'
|
6
|
+
require 'hiera/backend/eyaml/options'
|
7
|
+
|
8
|
+
class Hiera
|
9
|
+
module Backend
|
10
|
+
module Eyaml
|
11
|
+
module Encryptors
|
12
|
+
class Vault < Encryptor
|
13
|
+
class AuthenticationError < Exception
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
VERSION = "0.0.1"
|
18
|
+
HTTP_HANDLER = Hiera::Backend::Eyaml::Encryptors::Vault::Httphandler
|
19
|
+
|
20
|
+
self.tag = 'VAULT'
|
21
|
+
|
22
|
+
self.options = {
|
23
|
+
:addr => {
|
24
|
+
desc: "Address of the vault server",
|
25
|
+
type: :string,
|
26
|
+
default: "https://127.0.0.1:8200"
|
27
|
+
},
|
28
|
+
|
29
|
+
:role_id => {
|
30
|
+
desc: "role_id for the Approle",
|
31
|
+
type: :string,
|
32
|
+
},
|
33
|
+
|
34
|
+
:secret_id => {
|
35
|
+
desc: "secret_id for the Approle",
|
36
|
+
type: :string,
|
37
|
+
},
|
38
|
+
|
39
|
+
:use_ssl => {
|
40
|
+
desc: "Use SSL to connect to vault",
|
41
|
+
type: :boolean,
|
42
|
+
default: true
|
43
|
+
},
|
44
|
+
|
45
|
+
:ssl_verify => {
|
46
|
+
desc: "Verify SSL certs",
|
47
|
+
type: :boolean,
|
48
|
+
default: true
|
49
|
+
},
|
50
|
+
|
51
|
+
:keyname => {
|
52
|
+
desc: "Vault transit key name (default 'hiera')",
|
53
|
+
type: :string,
|
54
|
+
default: 'hiera'
|
55
|
+
},
|
56
|
+
|
57
|
+
:api_version => {
|
58
|
+
desc: "API version to use",
|
59
|
+
type: :integer,
|
60
|
+
default: 1
|
61
|
+
}
|
62
|
+
}
|
63
|
+
class << self
|
64
|
+
|
65
|
+
def create_keys
|
66
|
+
diagnostic_message = self.option :diagnostic_message
|
67
|
+
puts "Create_keys: #{diagnostic_message}"
|
68
|
+
end
|
69
|
+
|
70
|
+
#### BEGIN IMPORT
|
71
|
+
|
72
|
+
def vault_url(endpoint)
|
73
|
+
uri = []
|
74
|
+
uri << option(:addr)
|
75
|
+
uri << "v#{option :api_version}"
|
76
|
+
uri << endpoint
|
77
|
+
uri.flatten.join("/")
|
78
|
+
end
|
79
|
+
|
80
|
+
def login
|
81
|
+
role_id = option :role_id
|
82
|
+
secret_id = option :secret_id
|
83
|
+
|
84
|
+
login_data = { "role_id" => role_id }
|
85
|
+
login_data['secret_id'] = secret_id unless secret_id.nil?
|
86
|
+
|
87
|
+
response = vault_post(login_data, :login, false)
|
88
|
+
@approle_token = response['auth']['client_token']
|
89
|
+
end
|
90
|
+
|
91
|
+
def ssl?
|
92
|
+
option :use_ssl
|
93
|
+
end
|
94
|
+
|
95
|
+
def read_file(file)
|
96
|
+
raise Exception, "Cannot read #{file}" unless File.exists?(file)
|
97
|
+
File.read(file)
|
98
|
+
end
|
99
|
+
|
100
|
+
def ssl_key
|
101
|
+
return nil if option(:ssl_key).nil?
|
102
|
+
@vault_ssl_key ||= read_file(option :ssl_key)
|
103
|
+
@vault_ssl_key
|
104
|
+
end
|
105
|
+
|
106
|
+
def ssl_cert
|
107
|
+
return nil if option(:ssl_cert).nil?
|
108
|
+
@vault_ssl_cert ||= read_file(option :ssl_cert)
|
109
|
+
@vault_ssl_cert
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
def token_configured?
|
114
|
+
not option(:token).nil?
|
115
|
+
end
|
116
|
+
|
117
|
+
def token
|
118
|
+
authenticate
|
119
|
+
option(:token) || @approle_token
|
120
|
+
end
|
121
|
+
|
122
|
+
def authenticate
|
123
|
+
unless token_configured?
|
124
|
+
login if @approle_token.nil?
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def endpoint(action)
|
129
|
+
{
|
130
|
+
:decrypt => "transit/decrypt/#{option :keyname}",
|
131
|
+
:encrypt => "transit/encrypt/#{option :keyname}",
|
132
|
+
:login => "auth/approle/login"
|
133
|
+
}[action]
|
134
|
+
end
|
135
|
+
|
136
|
+
def url_path(action)
|
137
|
+
vault_url(endpoint(action))
|
138
|
+
end
|
139
|
+
|
140
|
+
|
141
|
+
|
142
|
+
def parse_response(response)
|
143
|
+
body = JSON.load(response.body)
|
144
|
+
if response.code_type == Net::HTTPOK
|
145
|
+
return body
|
146
|
+
else
|
147
|
+
if response.code == "403"
|
148
|
+
raise AuthenticationError, body
|
149
|
+
end
|
150
|
+
if body['errors'].is_a?(Array)
|
151
|
+
message = body['errors'].join("\n")
|
152
|
+
else
|
153
|
+
message = "Failed to decrypt entry #{body}"
|
154
|
+
end
|
155
|
+
raise Exception, "Error decrypting data from Vault: #{message}"
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def vault_post(data, action, use_token=true, headers={})
|
160
|
+
url = url_path(action)
|
161
|
+
http_options = {}
|
162
|
+
|
163
|
+
if ssl?
|
164
|
+
http_options = {
|
165
|
+
:ssl => true,
|
166
|
+
:ssl_verify => option(:ssl_verify),
|
167
|
+
:ssl_cert => ssl_cert,
|
168
|
+
:ssl_key => ssl_key,
|
169
|
+
}
|
170
|
+
end
|
171
|
+
|
172
|
+
begin
|
173
|
+
tries ||= 0
|
174
|
+
headers['X-Vault-Token'] = token if use_token
|
175
|
+
parse_response HTTP_HANDLER.post(url, data, headers, http_options)
|
176
|
+
rescue AuthenticationError => e
|
177
|
+
login
|
178
|
+
retry if (tries += 1) < 2
|
179
|
+
raise
|
180
|
+
rescue HTTPError => e
|
181
|
+
raise Exception, "HTTP Error: #{e}"
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
def decrypt(string)
|
186
|
+
response = vault_post({ 'ciphertext' => string}, :decrypt)
|
187
|
+
response_data=response['data']
|
188
|
+
Base64.decode64(response_data['plaintext'])
|
189
|
+
end
|
190
|
+
|
191
|
+
def encrypt(plain)
|
192
|
+
encoded = Base64.encode64(plain)
|
193
|
+
response = vault_post({ 'plaintext' => encoded}, :encrypt)
|
194
|
+
response_data=response['data']
|
195
|
+
response_data['ciphertext']
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'json'
|
3
|
+
require 'openssl'
|
4
|
+
|
5
|
+
class Hiera
|
6
|
+
module Backend
|
7
|
+
module Eyaml
|
8
|
+
module Encryptors
|
9
|
+
class Vault < Encryptor
|
10
|
+
class HTTPError < Exception
|
11
|
+
end
|
12
|
+
class Httphandler
|
13
|
+
class << self
|
14
|
+
|
15
|
+
def post(uri_str, data={}, headers={}, options={})
|
16
|
+
uri = URI.parse(uri_str)
|
17
|
+
request = Net::HTTP::Post.new(uri.path)
|
18
|
+
request.body = data.to_json
|
19
|
+
http_send(uri, request, headers, options)
|
20
|
+
end
|
21
|
+
|
22
|
+
def put(uri_str, data={}, headers={}, options={})
|
23
|
+
uri = URI.parse(uri_str)
|
24
|
+
request = Net::HTTP::Put.new(uri.path)
|
25
|
+
request.body = data.to_json
|
26
|
+
http_send(uri, request, headers, options)
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
def http_send(uri, request, headers={}, options={})
|
31
|
+
request.add_field('Content-Type', options[:content_type]) if options[:content_type]
|
32
|
+
|
33
|
+
headers.each do |header, value|
|
34
|
+
request.add_field(header, value)
|
35
|
+
end
|
36
|
+
|
37
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
38
|
+
if options[:ssl]
|
39
|
+
http.use_ssl = true
|
40
|
+
http.verify_mode = options[:ssl_verify] ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
|
41
|
+
http.cert = OpenSSL::X509::Certificate.new(options[:ssl_cert]) if options[:ssl_cert]
|
42
|
+
http.key = OpenSSL::PKey::RSA.new(options[:ssl_key]) if options[:ssl_key]
|
43
|
+
end
|
44
|
+
|
45
|
+
begin
|
46
|
+
response = http.request(request)
|
47
|
+
return response
|
48
|
+
rescue => e
|
49
|
+
raise HTTPError, e.message
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
metadata
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hiera-eyaml-vault
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Craig Dunn
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-11-05 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: hiera-http
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "<"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 4.0.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "<"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 4.0.0
|
27
|
+
description: Eyaml plugin for Vault transit secrets engine
|
28
|
+
email:
|
29
|
+
executables: []
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files: []
|
32
|
+
files:
|
33
|
+
- lib/hiera/backend/eyaml/encryptors/vault.rb
|
34
|
+
- lib/hiera/backend/eyaml/encryptors/vault/eyaml_init.rb
|
35
|
+
- lib/hiera/backend/eyaml/encryptors/vault/httphandler.rb
|
36
|
+
homepage: http://github.com/crayfishx/hiera-eyaml-vault
|
37
|
+
licenses:
|
38
|
+
- Apache-2.0
|
39
|
+
metadata: {}
|
40
|
+
post_install_message:
|
41
|
+
rdoc_options: []
|
42
|
+
require_paths:
|
43
|
+
- lib
|
44
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
requirements: []
|
55
|
+
rubyforge_project:
|
56
|
+
rubygems_version: 2.7.6.2
|
57
|
+
signing_key:
|
58
|
+
specification_version: 4
|
59
|
+
summary: Encryption plugin for hiera-eyaml to use Vault's transit secrets engine
|
60
|
+
test_files: []
|