fingerpuppet 0.0.1 → 0.0.2
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.
- data/README.md +75 -16
- data/bin/fingerpuppet +5 -4
- data/lib/fingerpuppet/restapi.rb +87 -87
- metadata +12 -4
data/README.md
CHANGED
@@ -1,26 +1,53 @@
|
|
1
|
-
|
1
|
+
Introduction
|
2
|
+
============
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
`fingerpuppet` is a simple library and commandline tool to interact with Puppet's REST API
|
5
|
+
without needing to have Puppet itself installed. This may be integrated, for example,
|
6
|
+
into a provisioning tool to allow your provisioning process to remotely sign certificates
|
7
|
+
of newly built systems. Alternatively, you could use it to request known facts about
|
8
|
+
a node from your Puppet Master, or even to request a catalog for a node to, for example,
|
9
|
+
perform acceptance testing against a new version of Puppet before upgrading your
|
10
|
+
production master.
|
8
11
|
|
9
|
-
|
12
|
+
Limitations
|
13
|
+
============
|
10
14
|
|
11
|
-
|
12
|
-
|
15
|
+
This is still in early development. Features may not work completely as advertised, and will
|
16
|
+
certainly be less polished than an established product. Pull requests are welcome!
|
13
17
|
|
14
|
-
4:) ...
|
15
18
|
|
16
|
-
|
19
|
+
Usage
|
20
|
+
============
|
17
21
|
|
18
|
-
|
19
|
-
See http://docs.puppetlabs.com/guides/rest_auth_conf.html for more information.
|
22
|
+
`fingerpuppet [commandstring]`
|
20
23
|
|
21
|
-
|
24
|
+
Steps for using the API with fingerpuppet:
|
22
25
|
|
23
|
-
|
26
|
+
1. `fingerpuppet --init --certname my.cert.name --server my.server.name`
|
27
|
+
* Builds the config file
|
28
|
+
* Generates the certificate and CSR
|
29
|
+
* Submits the CSR to the Puppetmaster
|
30
|
+
2. On puppetmaster: `puppet cert sign my.cert.name`
|
31
|
+
3. `fingerpuppet --install`
|
32
|
+
* Downloads the signed certificate and installs it
|
33
|
+
4. ...
|
34
|
+
5. Profit!
|
35
|
+
|
36
|
+
Your Puppetmaster must be configured to allow requests other than certificate requests.
|
37
|
+
See [http://docs.puppetlabs.com/guides/rest_auth_conf.html](http://docs.puppetlabs.com/guides/rest_auth_conf.html) for more information.
|
38
|
+
|
39
|
+
For example, you could add the stanza below as one of the first rules in `auth.conf` to
|
40
|
+
allow a single authenticated provisioning system complete access to all endpoints.
|
41
|
+
|
42
|
+
# Allow the provisioner unfettered access to any endpoint
|
43
|
+
path /
|
44
|
+
auth yes
|
45
|
+
allow provision.mycompany.com
|
46
|
+
|
47
|
+
|
48
|
+
The certname can be specified with `--certname` or with optional `CERTNAME` argument to many options.
|
49
|
+
|
50
|
+
You may want to use the `-dcn` options to print the cURL equivalent command.
|
24
51
|
|
25
52
|
-d, --debug runs in debug mode
|
26
53
|
-h, --help Displays this help
|
@@ -46,7 +73,7 @@ Usage : fingerpuppet <commandstring>
|
|
46
73
|
--certificate [CERTNAME] Retrieve the certificate for a given certname or 'ca'.
|
47
74
|
--cert_status [CERTNAME] Retrieve the certificate status for a given certname. Set the status by using --state.
|
48
75
|
--cert_revocation_list Retrieve and display the certifiacte revocation list from the master.
|
49
|
-
--sign [CERTNAME] Instruct the Puppetmaster to sign a certificate. Requires
|
76
|
+
--sign [CERTNAME] Instruct the Puppetmaster to sign a certificate. Requires significant privileges in auth.conf.
|
50
77
|
|
51
78
|
--file_metadata PATH Retrieve the metadata for a file.
|
52
79
|
--getfile PATH Download a file from the Puppetmaster. Save to --file or output on stdout.
|
@@ -54,3 +81,35 @@ Usage : fingerpuppet <commandstring>
|
|
54
81
|
--resource RESOURCE Returns a list of resources (e.g. user) or information about a resource (e.g. 'user/elvis')
|
55
82
|
--report [CERTNAME] Sends a YAML report to the Puppetmaster. Requires --file or --state.
|
56
83
|
--status Check to make sure the Puppetmaster is alive and well.
|
84
|
+
|
85
|
+
Contact
|
86
|
+
=======
|
87
|
+
|
88
|
+
* Author: Ben Ford
|
89
|
+
* Email: ben.ford@puppetlabs.com
|
90
|
+
* Twitter: @binford2k
|
91
|
+
* IRC (Freenode): binford2k
|
92
|
+
|
93
|
+
License
|
94
|
+
=======
|
95
|
+
|
96
|
+
Copyright (c) 2012 Puppet Labs, info@puppetlabs.com
|
97
|
+
|
98
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
99
|
+
a copy of this software and associated documentation files (the
|
100
|
+
"Software"), to deal in the Software without restriction, including
|
101
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
102
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
103
|
+
permit persons to whom the Software is furnished to do so, subject to
|
104
|
+
the following conditions:
|
105
|
+
|
106
|
+
The above copyright notice and this permission notice shall be
|
107
|
+
included in all copies or substantial portions of the Software.
|
108
|
+
|
109
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
110
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
111
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
112
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
113
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
114
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
115
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/bin/fingerpuppet
CHANGED
@@ -15,7 +15,7 @@ optparse = OptionParser.new { |opts|
|
|
15
15
|
|
16
16
|
2:) On puppetmaster: puppet cert sign my.cert.name
|
17
17
|
|
18
|
-
3:)
|
18
|
+
3:) fingerpuppet --install
|
19
19
|
Downloads the signed certificate and installs it
|
20
20
|
|
21
21
|
4:) ...
|
@@ -30,7 +30,7 @@ optparse = OptionParser.new { |opts|
|
|
30
30
|
You may want to use the '-dcn' options to print the cURL equivalent command.
|
31
31
|
|
32
32
|
"
|
33
|
-
|
33
|
+
|
34
34
|
options[:show]=false
|
35
35
|
opts.on("-d", "--debug", "runs in debug mode") do
|
36
36
|
options[:debug] = true
|
@@ -193,7 +193,7 @@ begin
|
|
193
193
|
when 'delete'
|
194
194
|
restAPI.delete(options[:certname])
|
195
195
|
when 'file_metadata'
|
196
|
-
restAPI.file_metadata(options[:argument])
|
196
|
+
restAPI.file_metadata(options[:argument])
|
197
197
|
when 'getfile'
|
198
198
|
restAPI.getfile(options[:argument])
|
199
199
|
when 'certificate'
|
@@ -210,7 +210,8 @@ begin
|
|
210
210
|
restAPI.report(options[:certname], options[:filename], options[:state])
|
211
211
|
else
|
212
212
|
puts 'Use -h/--help for usage documentation.'
|
213
|
-
end
|
213
|
+
end
|
214
214
|
rescue Exception => e
|
215
215
|
puts e
|
216
216
|
end
|
217
|
+
|
data/lib/fingerpuppet/restapi.rb
CHANGED
@@ -4,14 +4,14 @@ require "net/https"
|
|
4
4
|
module Fingerpuppet
|
5
5
|
class RestAPI
|
6
6
|
attr_accessor :server, :certname
|
7
|
-
|
7
|
+
|
8
8
|
def initialize( options={} )
|
9
9
|
@debug = options[:debug]
|
10
10
|
@curl = options[:curl]
|
11
11
|
@nop = options[:nop]
|
12
12
|
@output = options[:output]
|
13
13
|
@configdir = File.expand_path('~/.fingerpuppet')
|
14
|
-
|
14
|
+
|
15
15
|
begin
|
16
16
|
config = YAML.load_file("#{@configdir}/config.yaml")
|
17
17
|
@server = config['server']
|
@@ -20,19 +20,19 @@ module Fingerpuppet
|
|
20
20
|
puts 'Initializing API...'
|
21
21
|
end
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
# a helper that allows one to use either commandline curl or Net::HTTP
|
25
25
|
# this is useful mostly with -dcn to just print out the curl commandline
|
26
26
|
# you would use to accomplish what you're trying to do
|
27
27
|
def command( opts={} )
|
28
28
|
# this allows a global @output var, but to also override that per call
|
29
29
|
opts[:output] ||= @output
|
30
|
-
|
30
|
+
|
31
31
|
if @curl
|
32
32
|
curl(opts)
|
33
33
|
else
|
34
34
|
data = rest(opts)
|
35
|
-
|
35
|
+
|
36
36
|
if opts[:output]
|
37
37
|
save(opts[:output], data)
|
38
38
|
else
|
@@ -42,36 +42,36 @@ module Fingerpuppet
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
def save(path, data)
|
47
47
|
file = File.new(path, 'w')
|
48
48
|
file.syswrite(data)
|
49
49
|
file.close
|
50
50
|
end
|
51
|
-
|
51
|
+
|
52
52
|
def rest( opts={} )
|
53
53
|
opts[:type] ||= 'yaml'
|
54
54
|
uri = "/production/#{opts[:action]}/#{opts[:argument]}"
|
55
|
-
|
55
|
+
|
56
56
|
http = Net::HTTP.new(@server, 8140)
|
57
57
|
http.use_ssl = true
|
58
|
-
|
58
|
+
|
59
59
|
unless opts[:noauth]
|
60
60
|
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
61
|
-
|
61
|
+
|
62
62
|
store = OpenSSL::X509::Store.new
|
63
63
|
store.add_cert(OpenSSL::X509::Certificate.new(File.read("#{@configdir}/ca_crt.pem")))
|
64
64
|
http.cert_store = store
|
65
|
-
|
65
|
+
|
66
66
|
http.key = OpenSSL::PKey::RSA.new(File.read("#{@configdir}/#{@certname}.key"))
|
67
67
|
http.cert = OpenSSL::X509::Certificate.new(File.read("#{@configdir}/#{@certname}.pem"))
|
68
68
|
end
|
69
|
-
|
69
|
+
|
70
70
|
case opts[:method]
|
71
71
|
when 'PUT'
|
72
72
|
request = Net::HTTP::Put.new(uri)
|
73
73
|
request["Content-Type"] = "text/#{opts[:type]}"
|
74
|
-
|
74
|
+
|
75
75
|
if opts[:file]
|
76
76
|
# set the body to the binary contents of :file
|
77
77
|
file = File.open(opts[:file], 'rb')
|
@@ -80,7 +80,7 @@ module Fingerpuppet
|
|
80
80
|
# set the body to the string value of :data
|
81
81
|
request.body = opts[:data]
|
82
82
|
end
|
83
|
-
|
83
|
+
|
84
84
|
when 'DELETE'
|
85
85
|
request = Net::HTTP::Delete.new(uri)
|
86
86
|
when 'HEAD'
|
@@ -89,44 +89,44 @@ module Fingerpuppet
|
|
89
89
|
# default to a GET request
|
90
90
|
request = Net::HTTP::Get.new(uri)
|
91
91
|
end
|
92
|
-
|
92
|
+
|
93
93
|
request["Accept"] = opts[:type]
|
94
|
-
|
94
|
+
|
95
95
|
if @debug
|
96
96
|
puts '------ HTTP Request ------'
|
97
97
|
puts request.to_yaml
|
98
98
|
puts '--------------------------'
|
99
99
|
end
|
100
|
-
|
100
|
+
|
101
101
|
return @nop ? '' : http.request(request).body
|
102
102
|
end
|
103
|
-
|
103
|
+
|
104
104
|
#def command(action, argument='', method='GET', type='yaml', output=false, file=false, data=false)
|
105
105
|
def curl( opts={} )
|
106
106
|
opts[:type] ||= 'yaml'
|
107
|
-
|
107
|
+
|
108
108
|
if opts[:noauth]
|
109
109
|
auth = '-k '
|
110
110
|
else
|
111
111
|
auth = "--cert #{@configdir}/#{@certname}.pem --key #{@configdir}/#{@certname}.key --cacert #{@configdir}/ca_crt.pem"
|
112
112
|
end
|
113
|
-
|
113
|
+
|
114
114
|
output = opts[:output] ? "-o #{opts[:output]}" : ''
|
115
115
|
header = "-H 'Accept: #{opts[:type]}'"
|
116
|
-
|
116
|
+
|
117
117
|
case opts[:method]
|
118
118
|
when 'PUT'
|
119
119
|
methodstr = '-X PUT'
|
120
120
|
header = "-H 'Content-Type: text/#{opts[:type]}'"
|
121
|
-
|
121
|
+
|
122
122
|
if opts[:file]
|
123
123
|
filestr = "--data-binary @#{opts[:file]}"
|
124
124
|
end
|
125
|
-
|
125
|
+
|
126
126
|
if opts[:data]
|
127
127
|
datastr = "--data '#{opts[:data]}'"
|
128
128
|
end
|
129
|
-
|
129
|
+
|
130
130
|
when 'DELETE'
|
131
131
|
methodstr = '-X DELETE'
|
132
132
|
when 'HEAD'
|
@@ -135,7 +135,7 @@ module Fingerpuppet
|
|
135
135
|
# default to a GET request
|
136
136
|
methodstr = ''
|
137
137
|
end
|
138
|
-
|
138
|
+
|
139
139
|
uri = "https://#{@server}:8140/production/#{opts[:action]}/#{opts[:argument]}"
|
140
140
|
cmd = "curl #{auth} #{methodstr} #{output} #{filestr} #{datastr} #{header} \"#{uri}\"" #quoted uri for fact ampersands
|
141
141
|
if @debug
|
@@ -147,50 +147,50 @@ module Fingerpuppet
|
|
147
147
|
puts # newline after curl output
|
148
148
|
end
|
149
149
|
end
|
150
|
-
|
150
|
+
|
151
151
|
def init(certname, server)
|
152
152
|
if certname == nil || server == nil
|
153
153
|
puts "Must set server and certname to initialize API"
|
154
154
|
exit
|
155
155
|
end
|
156
|
-
|
156
|
+
|
157
157
|
@certname = certname
|
158
158
|
@server = server
|
159
|
-
|
159
|
+
|
160
160
|
if File::directory?( @configdir )
|
161
161
|
require 'fileutils'
|
162
162
|
FileUtils.rm_rf( @configdir )
|
163
163
|
end
|
164
|
-
|
164
|
+
|
165
165
|
Dir.mkdir( @configdir )
|
166
166
|
configfile = File.new("#{@configdir}/config.yaml", 'w')
|
167
167
|
configfile.syswrite("version: 0.1\n")
|
168
168
|
configfile.syswrite("certname: #{@certname}\n")
|
169
169
|
configfile.syswrite("server: #{@server}\n")
|
170
170
|
configfile.close
|
171
|
-
|
171
|
+
|
172
172
|
begin
|
173
173
|
if not system("openssl genrsa -out #{@configdir}/#{@certname}.key 1024")
|
174
174
|
raise StandardError, 'Certificate generation failed.'
|
175
175
|
end
|
176
|
-
|
176
|
+
|
177
177
|
if not system("openssl req -new -key #{@configdir}/#{@certname}.key -subj '/CN=#{@certname}' -out #{@configdir}/#{@certname}.csr")
|
178
178
|
raise StandardError, 'CSR generation failed.'
|
179
179
|
end
|
180
|
-
|
180
|
+
|
181
181
|
self.command( { :action => 'certificate_request',
|
182
182
|
:argument => @certname,
|
183
183
|
:file => "#{@configdir}/#{@certname}.csr",
|
184
184
|
:type => 'plain',
|
185
185
|
:method => 'PUT',
|
186
186
|
:noauth => true } )
|
187
|
-
|
187
|
+
|
188
188
|
puts "CSR submitted. Now go sign it on the server and rerun this with --install."
|
189
189
|
rescue Exception => e
|
190
190
|
puts "Failure: #{e.message}"
|
191
191
|
end
|
192
192
|
end
|
193
|
-
|
193
|
+
|
194
194
|
def install
|
195
195
|
begin
|
196
196
|
self.command( { :action => 'certificate',
|
@@ -198,134 +198,134 @@ module Fingerpuppet
|
|
198
198
|
:output => "#{@configdir}/#{@certname}.pem",
|
199
199
|
:type => 's',
|
200
200
|
:noauth => true } )
|
201
|
-
|
201
|
+
|
202
202
|
self.command( { :action => 'certificate',
|
203
203
|
:argument => 'ca',
|
204
204
|
:output => "#{@configdir}/ca_crt.pem",
|
205
205
|
:type => 's',
|
206
206
|
:noauth => true } )
|
207
|
-
|
207
|
+
|
208
208
|
puts "Certificate installed. API ready for use."
|
209
209
|
rescue Exception => e
|
210
210
|
puts "Failure: #{e.message}"
|
211
211
|
end
|
212
212
|
end
|
213
|
-
|
213
|
+
|
214
214
|
def catalog
|
215
|
-
self.command( { :action => 'catalog',
|
215
|
+
self.command( { :action => 'catalog',
|
216
216
|
:argument => @certname } )
|
217
217
|
end
|
218
|
-
|
218
|
+
|
219
219
|
def status
|
220
|
-
self.command( { :action => 'status',
|
220
|
+
self.command( { :action => 'status',
|
221
221
|
:argument => 'no_key' } )
|
222
222
|
end
|
223
|
-
|
223
|
+
|
224
224
|
def facts(node)
|
225
|
-
self.command( { :action => 'facts',
|
225
|
+
self.command( { :action => 'facts',
|
226
226
|
:argument => node } )
|
227
227
|
end
|
228
|
-
|
228
|
+
|
229
229
|
def search(query)
|
230
230
|
query.map!{ |item| "facts.#{item}"}
|
231
|
-
self.command( { :action => 'facts_search',
|
231
|
+
self.command( { :action => 'facts_search',
|
232
232
|
:argument => "search?#{query.join('&')}" } )
|
233
233
|
end
|
234
|
-
|
234
|
+
|
235
235
|
def node(node)
|
236
|
-
self.command( { :action => 'node',
|
236
|
+
self.command( { :action => 'node',
|
237
237
|
:argument => node } )
|
238
238
|
end
|
239
|
-
|
239
|
+
|
240
240
|
def insert(node, path)
|
241
|
-
self.command( { :action => 'facts',
|
242
|
-
:argument => node,
|
243
|
-
:method => 'PUT',
|
241
|
+
self.command( { :action => 'facts',
|
242
|
+
:argument => node,
|
243
|
+
:method => 'PUT',
|
244
244
|
:file => path } )
|
245
245
|
end
|
246
|
-
|
246
|
+
|
247
247
|
def file_metadata(path)
|
248
248
|
self.command( { :action => 'file_content',
|
249
249
|
:argument => path,
|
250
250
|
:type => 'yaml' } )
|
251
251
|
end
|
252
|
-
|
252
|
+
|
253
253
|
def getfile(path)
|
254
254
|
self.command( { :action => 'file_content',
|
255
255
|
:argument => path,
|
256
256
|
:type => 'raw' } )
|
257
257
|
end
|
258
|
-
|
258
|
+
|
259
259
|
def delete(node)
|
260
260
|
self.certificate_status(node, 'revoked')
|
261
|
-
self.command( { :action => 'certificate_status',
|
262
|
-
:argument => node,
|
263
|
-
:method => 'DELETE',
|
261
|
+
self.command( { :action => 'certificate_status',
|
262
|
+
:argument => node,
|
263
|
+
:method => 'DELETE',
|
264
264
|
:type => 'pson' } )
|
265
265
|
end
|
266
|
-
|
266
|
+
|
267
267
|
def certificate(node)
|
268
|
-
self.command( { :action => 'certificate',
|
269
|
-
:argument => node,
|
268
|
+
self.command( { :action => 'certificate',
|
269
|
+
:argument => node,
|
270
270
|
:type => 's' } )
|
271
271
|
end
|
272
|
-
|
272
|
+
|
273
273
|
def sign(node)
|
274
|
-
self.command( { :action => 'certificate_status',
|
275
|
-
:argument => node,
|
276
|
-
:method => 'PUT',
|
274
|
+
self.command( { :action => 'certificate_status',
|
275
|
+
:argument => node,
|
276
|
+
:method => 'PUT',
|
277
277
|
:type => 'pson',
|
278
|
-
:noauth => true,
|
279
278
|
:data => "{\"desired_state\":\"signed\"}" } )
|
280
279
|
end
|
281
|
-
|
280
|
+
|
282
281
|
def certificate_revocation_list
|
283
|
-
self.command( { :action => 'certificate_revocation_list',
|
284
|
-
:argument => 'ca',
|
282
|
+
self.command( { :action => 'certificate_revocation_list',
|
283
|
+
:argument => 'ca',
|
285
284
|
:type => 's' } )
|
286
285
|
end
|
287
|
-
|
286
|
+
|
288
287
|
def certificate_status(node, state=nil)
|
289
288
|
if node == nil
|
290
|
-
self.command( { :action => 'certificate_statuses',
|
291
|
-
:action => 'no_key',
|
289
|
+
self.command( { :action => 'certificate_statuses',
|
290
|
+
:action => 'no_key',
|
292
291
|
:type => 'pson' } )
|
293
292
|
elsif state == nil
|
294
|
-
self.command( { :action => 'certificate_status',
|
295
|
-
:argument => node,
|
293
|
+
self.command( { :action => 'certificate_status',
|
294
|
+
:argument => node,
|
296
295
|
:type => 'pson' } )
|
297
296
|
else
|
298
|
-
self.command( { :action => 'certificate_status',
|
299
|
-
:argument => node,
|
300
|
-
:method => 'PUT',
|
301
|
-
:type => 'pson',
|
297
|
+
self.command( { :action => 'certificate_status',
|
298
|
+
:argument => node,
|
299
|
+
:method => 'PUT',
|
300
|
+
:type => 'pson',
|
302
301
|
:data => "{\"desired_state\":\"#{state}\"}" } )
|
303
302
|
end
|
304
303
|
end
|
305
|
-
|
304
|
+
|
306
305
|
def resource(resource)
|
307
|
-
self.command( { :action => 'resource',
|
306
|
+
self.command( { :action => 'resource',
|
308
307
|
:argument => resource } )
|
309
308
|
end
|
310
|
-
|
309
|
+
|
311
310
|
def report(node, file, data=nil)
|
312
311
|
if data
|
313
|
-
self.command( { :action => 'report',
|
314
|
-
:argument => node,
|
315
|
-
:method => 'PUT',
|
312
|
+
self.command( { :action => 'report',
|
313
|
+
:argument => node,
|
314
|
+
:method => 'PUT',
|
316
315
|
:data => data } )
|
317
316
|
else
|
318
|
-
self.command( { :action => 'report',
|
319
|
-
:argument => node,
|
320
|
-
:method => 'PUT',
|
317
|
+
self.command( { :action => 'report',
|
318
|
+
:argument => node,
|
319
|
+
:method => 'PUT',
|
321
320
|
:file => file } )
|
322
321
|
end
|
323
322
|
end
|
324
|
-
|
323
|
+
|
325
324
|
def debug
|
326
325
|
puts "@configdir: #{@configdir}"
|
327
326
|
puts " @server: #{@server}"
|
328
327
|
puts " @certname: #{@certname}"
|
329
328
|
end
|
330
329
|
end
|
331
|
-
end
|
330
|
+
end
|
331
|
+
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 2
|
9
|
+
version: 0.0.2
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Ben Ford
|
@@ -14,11 +14,19 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2013-03-28 00:00:00 -
|
17
|
+
date: 2013-03-28 00:00:00 -04:00
|
18
18
|
default_executable:
|
19
19
|
dependencies: []
|
20
20
|
|
21
|
-
description:
|
21
|
+
description: |
|
22
|
+
`fingerpuppet` is a simple library and commandline tool to interact with Puppet's REST API
|
23
|
+
without needing to have Puppet itself installed. This may be integrated, for example,
|
24
|
+
into a provisioning tool to allow your provisioning process to remotely sign certificates
|
25
|
+
of newly built systems. Alternatively, you could use it to request known facts about
|
26
|
+
a node from your Puppet Master, or even to request a catalog for a node to, for example,
|
27
|
+
perform acceptance testing against a new version of Puppet before upgrading your
|
28
|
+
production master.
|
29
|
+
|
22
30
|
email: binford2k@gmail.com
|
23
31
|
executables:
|
24
32
|
- fingerpuppet
|