bolt 1.34.0 → 1.35.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of bolt might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/bolt-modules/boltlib/lib/puppet/functions/apply_prep.rb +1 -1
- data/bolt-modules/ctrl/lib/puppet/functions/ctrl/do_until.rb +16 -3
- data/lib/bolt/config.rb +1 -1
- data/lib/bolt/inventory.rb +1 -1
- data/lib/bolt/inventory/group.rb +1 -1
- data/lib/bolt/inventory/group2.rb +232 -216
- data/lib/bolt/inventory/inventory2.rb +64 -219
- data/lib/bolt/inventory/target.rb +227 -0
- data/lib/bolt/module.rb +4 -4
- data/lib/bolt/plugin.rb +0 -3
- data/lib/bolt/plugin/module.rb +52 -5
- data/lib/bolt/plugin/task.rb +5 -1
- data/lib/bolt/target.rb +24 -46
- data/lib/bolt/util.rb +18 -0
- data/lib/bolt/version.rb +1 -1
- metadata +3 -5
- data/lib/bolt/plugin/aws_inventory.rb +0 -102
- data/lib/bolt/plugin/terraform.rb +0 -175
- data/lib/bolt/plugin/vault.rb +0 -206
data/lib/bolt/plugin/vault.rb
DELETED
@@ -1,206 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Bolt
|
4
|
-
class Plugin
|
5
|
-
class Vault
|
6
|
-
class VaultHTTPError < Bolt::Error
|
7
|
-
def initialize(response)
|
8
|
-
err = JSON.parse(response.body)['errors']
|
9
|
-
m = String.new("#{response.code} \"#{response.msg}\"")
|
10
|
-
m << ": #{err.join(';')}" unless err.nil?
|
11
|
-
super(m, 'bolt.plugin/vault-http-error')
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
attr_reader :config
|
16
|
-
|
17
|
-
# All requests for secrets must have a token in the request header
|
18
|
-
TOKEN_HEADER = "X-Vault-Token"
|
19
|
-
|
20
|
-
# Default header for all requests, including auth methods
|
21
|
-
DEFAULT_HEADER = {
|
22
|
-
"Content-Type" => "application/json",
|
23
|
-
"Accept" => "application/json"
|
24
|
-
}.freeze
|
25
|
-
|
26
|
-
# Make sure no unexpected keys are in the config
|
27
|
-
def validate_config(config)
|
28
|
-
known_keys = %w[server_url auth cacert]
|
29
|
-
|
30
|
-
config.each do |key, _v|
|
31
|
-
next if known_keys.include?(key)
|
32
|
-
raise Bolt::ValidationError, "Unexpected key in Vault plugin config: #{key}"
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
# Make sure no unexpected keys are in the inventory config and
|
37
|
-
# that required keys are present
|
38
|
-
def validate_options(opts)
|
39
|
-
known_keys = %w[_plugin server_url auth path field version cacert]
|
40
|
-
required_keys = %w[path]
|
41
|
-
|
42
|
-
opts.each do |key, _v|
|
43
|
-
next if known_keys.include?(key)
|
44
|
-
raise Bolt::ValidationError, "Unexpected key in inventory config: #{key}"
|
45
|
-
end
|
46
|
-
|
47
|
-
required_keys.each do |key|
|
48
|
-
next if opts[key]
|
49
|
-
raise Bolt::ValidationError, "Expected key in inventory config: #{key}"
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def name
|
54
|
-
'vault'
|
55
|
-
end
|
56
|
-
|
57
|
-
def hooks
|
58
|
-
[:resolve_reference]
|
59
|
-
end
|
60
|
-
|
61
|
-
def initialize(config:, **_opts)
|
62
|
-
validate_config(config)
|
63
|
-
@config = config
|
64
|
-
@logger = Logging.logger[self]
|
65
|
-
end
|
66
|
-
|
67
|
-
def resolve_reference(opts)
|
68
|
-
validate_options(opts)
|
69
|
-
|
70
|
-
header = {
|
71
|
-
TOKEN_HEADER => token(opts)
|
72
|
-
}
|
73
|
-
|
74
|
-
response = request(:Get, uri(opts), opts, nil, header)
|
75
|
-
|
76
|
-
parse_response(response, opts)
|
77
|
-
end
|
78
|
-
|
79
|
-
# Request uri - built up from Vault server url and secrets path
|
80
|
-
def uri(opts, path = nil)
|
81
|
-
url = opts['server_url'] || config['server_url'] || ENV['VAULT_ADDR']
|
82
|
-
|
83
|
-
# Handle the different versions of the API
|
84
|
-
if opts['version'] == 2
|
85
|
-
mount, store = opts['path'].split('/', 2)
|
86
|
-
opts['path'] = [mount, 'data', store].join('/')
|
87
|
-
end
|
88
|
-
|
89
|
-
path ||= opts['path']
|
90
|
-
|
91
|
-
URI.parse(File.join(url, "v1", path))
|
92
|
-
end
|
93
|
-
|
94
|
-
# Configure the http/s client
|
95
|
-
def client(uri, opts)
|
96
|
-
client = Net::HTTP.new(uri.host, uri.port)
|
97
|
-
|
98
|
-
if uri.scheme == 'https'
|
99
|
-
cacert = opts['cacert'] || config['cacert'] || ENV['VAULT_CACERT']
|
100
|
-
|
101
|
-
unless cacert
|
102
|
-
raise Bolt::ValidationError, "Expected cacert to be set when using https"
|
103
|
-
end
|
104
|
-
|
105
|
-
client.use_ssl = true
|
106
|
-
client.ssl_version = :TLSv1_2
|
107
|
-
client.ca_file = cacert
|
108
|
-
client.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
109
|
-
end
|
110
|
-
|
111
|
-
client
|
112
|
-
end
|
113
|
-
|
114
|
-
# Auth token to vault server
|
115
|
-
def token(opts)
|
116
|
-
if (auth = opts['auth'] || config['auth'])
|
117
|
-
request_token(auth, opts)
|
118
|
-
else
|
119
|
-
ENV['VAULT_TOKEN']
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
def request(verb, uri, opts, data, header = {})
|
124
|
-
# Add on any header options
|
125
|
-
header = DEFAULT_HEADER.merge(header)
|
126
|
-
|
127
|
-
# Create the HTTP request
|
128
|
-
client = client(uri, opts)
|
129
|
-
request = Net::HTTP.const_get(verb).new(uri.request_uri, header)
|
130
|
-
|
131
|
-
# Attach any data
|
132
|
-
request.body = data if data
|
133
|
-
|
134
|
-
# Send the request
|
135
|
-
begin
|
136
|
-
response = client.request(request)
|
137
|
-
rescue StandardError => e
|
138
|
-
raise Bolt::Error.new(
|
139
|
-
"Failed to connect to #{uri}: #{e.message}",
|
140
|
-
'CONNECT_ERROR'
|
141
|
-
)
|
142
|
-
end
|
143
|
-
|
144
|
-
case response
|
145
|
-
when Net::HTTPOK
|
146
|
-
JSON.parse(response.body)
|
147
|
-
else
|
148
|
-
raise VaultHTTPError, response
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
def parse_response(response, opts)
|
153
|
-
data = case opts['version']
|
154
|
-
when 2
|
155
|
-
response['data']['data']
|
156
|
-
else
|
157
|
-
response['data']
|
158
|
-
end
|
159
|
-
|
160
|
-
if opts['field']
|
161
|
-
unless data[opts['field']]
|
162
|
-
raise Bolt::ValidationError, "Unknown secrets field: #{opts['field']}"
|
163
|
-
end
|
164
|
-
data[opts['field']]
|
165
|
-
else
|
166
|
-
data
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
# Request a token from Vault using one of the auth methods
|
171
|
-
def request_token(auth, opts)
|
172
|
-
case auth['method']
|
173
|
-
when 'token'
|
174
|
-
auth_token(auth)
|
175
|
-
when 'userpass'
|
176
|
-
auth_userpass(auth, opts)
|
177
|
-
else
|
178
|
-
raise Bolt::ValidationError, "Unknown auth method: #{auth['method']}"
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
def validate_auth(auth, required_keys)
|
183
|
-
required_keys.each do |key|
|
184
|
-
next if auth[key]
|
185
|
-
raise Bolt::ValidationError, "Expected key in #{auth['method']} auth method: #{key}"
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|
189
|
-
# Authenticate with Vault using the 'Token' auth method
|
190
|
-
def auth_token(auth)
|
191
|
-
validate_auth(auth, %w[token])
|
192
|
-
auth['token']
|
193
|
-
end
|
194
|
-
|
195
|
-
# Authenticate with Vault using the 'Userpass' auth method
|
196
|
-
def auth_userpass(auth, opts)
|
197
|
-
validate_auth(auth, %w[user pass])
|
198
|
-
path = "auth/userpass/login/#{auth['user']}"
|
199
|
-
uri = uri(opts, path)
|
200
|
-
data = { "password" => auth['pass'] }.to_json
|
201
|
-
|
202
|
-
request(:Post, uri, opts, data)['auth']['client_token']
|
203
|
-
end
|
204
|
-
end
|
205
|
-
end
|
206
|
-
end
|