puppetserver-ca 0.2.0 → 0.3.0
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/puppetserver/ca/clean_action.rb +159 -0
- data/lib/puppetserver/ca/cli.rb +25 -18
- data/lib/puppetserver/ca/create_action.rb +267 -0
- data/lib/puppetserver/ca/generate_action.rb +227 -0
- data/lib/puppetserver/ca/host.rb +26 -0
- data/lib/puppetserver/ca/import_action.rb +11 -69
- data/lib/puppetserver/ca/list_action.rb +155 -0
- data/lib/puppetserver/ca/puppet_config.rb +71 -9
- data/lib/puppetserver/ca/revoke_action.rb +138 -0
- data/lib/puppetserver/ca/sign_action.rb +192 -0
- data/lib/puppetserver/ca/utils.rb +80 -0
- data/lib/puppetserver/ca/version.rb +1 -1
- data/lib/puppetserver/settings/ttl_setting.rb +48 -0
- data/lib/puppetserver/utils/file_utilities.rb +78 -0
- data/lib/puppetserver/utils/http_client.rb +116 -0
- data/lib/puppetserver/utils/signing_digest.rb +25 -0
- data/puppetserver-ca.gemspec +2 -0
- metadata +34 -2
@@ -0,0 +1,227 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'openssl'
|
3
|
+
require 'puppetserver/utils/file_utilities'
|
4
|
+
require 'puppetserver/ca/host'
|
5
|
+
require 'puppetserver/utils/signing_digest'
|
6
|
+
|
7
|
+
module Puppetserver
|
8
|
+
module Ca
|
9
|
+
class GenerateAction
|
10
|
+
include Puppetserver::Utils
|
11
|
+
|
12
|
+
CA_EXTENSIONS = [
|
13
|
+
["basicConstraints", "CA:TRUE", true],
|
14
|
+
["keyUsage", "keyCertSign, cRLSign", true],
|
15
|
+
["subjectKeyIdentifier", "hash", false],
|
16
|
+
["authorityKeyIdentifier", "keyid:always", false]
|
17
|
+
].freeze
|
18
|
+
|
19
|
+
# Make the certificate valid as of yesterday, because so many people's
|
20
|
+
# clocks are out of sync. This gives one more day of validity than people
|
21
|
+
# might expect, but is better than making every person who has a messed up
|
22
|
+
# clock fail, and better than having every cert we generate expire a day
|
23
|
+
# before the user expected it to when they asked for "one year".
|
24
|
+
CERT_VALID_FROM = (Time.now - (60*60*24)).freeze
|
25
|
+
|
26
|
+
SUMMARY = "Generate a root and intermediate signing CA for Puppet Server"
|
27
|
+
BANNER = <<-BANNER
|
28
|
+
Usage:
|
29
|
+
puppetserver ca generate [--help]
|
30
|
+
puppetserver ca generate [--config PATH]
|
31
|
+
|
32
|
+
Description:
|
33
|
+
Generate a root and intermediate signing CA for Puppet Server
|
34
|
+
and store generated CA keys, certs, and crls on disk.
|
35
|
+
|
36
|
+
To determine the target location, the default puppet.conf
|
37
|
+
is consulted for custom values. If using a custom puppet.conf
|
38
|
+
provide it with the --config flag
|
39
|
+
|
40
|
+
Options:
|
41
|
+
BANNER
|
42
|
+
|
43
|
+
def initialize(logger)
|
44
|
+
@logger = logger
|
45
|
+
end
|
46
|
+
|
47
|
+
def run(input)
|
48
|
+
# Validate config_path provided
|
49
|
+
config_path = input['config']
|
50
|
+
if config_path
|
51
|
+
errors = FileUtilities.validate_file_paths(config_path)
|
52
|
+
return 1 if Utils.handle_errors(@logger, errors)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Load, resolve, and validate puppet config settings
|
56
|
+
puppet = PuppetConfig.parse(config_path)
|
57
|
+
return 1 if Utils.handle_errors(@logger, puppet.errors)
|
58
|
+
|
59
|
+
# Load most secure signing digest we can for cers/crl/csr signing.
|
60
|
+
signer = SigningDigest.new
|
61
|
+
return 1 if Utils.handle_errors(@logger, signer.errors)
|
62
|
+
|
63
|
+
# Generate root and intermediate ca and put all the certificates, crls,
|
64
|
+
# and keys where they should go.
|
65
|
+
generate_root_and_intermediate_ca(puppet.settings, signer.digest)
|
66
|
+
|
67
|
+
# Puppet's internal CA expects these file to exist.
|
68
|
+
FileUtilities.ensure_file(puppet.settings[:serial], "001", 0640)
|
69
|
+
FileUtilities.ensure_file(puppet.settings[:cert_inventory], "", 0640)
|
70
|
+
|
71
|
+
@logger.inform "Generation succeeded. Find your files in #{puppet.settings[:cadir]}"
|
72
|
+
return 0
|
73
|
+
end
|
74
|
+
|
75
|
+
def generate_root_and_intermediate_ca(settings, signing_digest)
|
76
|
+
valid_until = Time.now + settings[:ca_ttl]
|
77
|
+
host = Puppetserver::Ca::Host.new(signing_digest)
|
78
|
+
|
79
|
+
root_key = host.create_private_key(settings[:keylength])
|
80
|
+
root_cert = self_signed_ca(root_key, settings[:root_ca_name], valid_until, signing_digest)
|
81
|
+
root_crl = create_crl_for(root_cert, root_key, valid_until, signing_digest)
|
82
|
+
|
83
|
+
int_key = host.create_private_key(settings[:keylength])
|
84
|
+
int_csr = host.create_csr(settings[:ca_name], int_key)
|
85
|
+
int_cert = sign_intermediate(root_key, root_cert, int_csr, valid_until, signing_digest)
|
86
|
+
int_crl = create_crl_for(int_cert, int_key, valid_until, signing_digest)
|
87
|
+
|
88
|
+
FileUtilities.ensure_dir(settings[:cadir])
|
89
|
+
|
90
|
+
file_properties = [
|
91
|
+
[settings[:cacert], [int_cert, root_cert]],
|
92
|
+
[settings[:cakey], int_key],
|
93
|
+
[settings[:rootkey], root_key],
|
94
|
+
[settings[:cacrl], [int_crl, root_crl]]
|
95
|
+
]
|
96
|
+
|
97
|
+
file_properties.each do |location, content|
|
98
|
+
@logger.warn "#{location} exists, overwriting" if File.exist?(location)
|
99
|
+
FileUtilities.write_file(location, content, 0640)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def self_signed_ca(key, name, valid_until, signing_digest)
|
104
|
+
cert = OpenSSL::X509::Certificate.new
|
105
|
+
|
106
|
+
cert.public_key = key.public_key
|
107
|
+
cert.subject = OpenSSL::X509::Name.new([["CN", name]])
|
108
|
+
cert.issuer = cert.subject
|
109
|
+
cert.version = 2
|
110
|
+
cert.serial = 1
|
111
|
+
|
112
|
+
cert.not_before = CERT_VALID_FROM
|
113
|
+
cert.not_after = valid_until
|
114
|
+
|
115
|
+
ef = extension_factory_for(cert, cert)
|
116
|
+
CA_EXTENSIONS.each do |ext|
|
117
|
+
extension = ef.create_extension(*ext)
|
118
|
+
cert.add_extension(extension)
|
119
|
+
end
|
120
|
+
|
121
|
+
cert.sign(key, signing_digest)
|
122
|
+
|
123
|
+
cert
|
124
|
+
end
|
125
|
+
|
126
|
+
def extension_factory_for(ca, cert = nil)
|
127
|
+
ef = OpenSSL::X509::ExtensionFactory.new
|
128
|
+
ef.issuer_certificate = ca
|
129
|
+
ef.subject_certificate = cert if cert
|
130
|
+
|
131
|
+
ef
|
132
|
+
end
|
133
|
+
|
134
|
+
def create_crl_for(ca_cert, ca_key, valid_until, signing_digest)
|
135
|
+
crl = OpenSSL::X509::CRL.new
|
136
|
+
crl.version = 1
|
137
|
+
crl.issuer = ca_cert.subject
|
138
|
+
|
139
|
+
ef = extension_factory_for(ca_cert)
|
140
|
+
crl.add_extension(
|
141
|
+
ef.create_extension(["authorityKeyIdentifier", "keyid:always", false]))
|
142
|
+
crl.add_extension(
|
143
|
+
OpenSSL::X509::Extension.new("crlNumber", OpenSSL::ASN1::Integer(0)))
|
144
|
+
|
145
|
+
crl.last_update = CERT_VALID_FROM
|
146
|
+
crl.next_update = valid_until
|
147
|
+
crl.sign(ca_key, signing_digest)
|
148
|
+
|
149
|
+
crl
|
150
|
+
end
|
151
|
+
|
152
|
+
def sign_intermediate(ca_key, ca_cert, csr, valid_until, signing_digest)
|
153
|
+
cert = OpenSSL::X509::Certificate.new
|
154
|
+
|
155
|
+
cert.public_key = csr.public_key
|
156
|
+
cert.subject = csr.subject
|
157
|
+
cert.issuer = ca_cert.subject
|
158
|
+
cert.version = 2
|
159
|
+
cert.serial = 2
|
160
|
+
|
161
|
+
cert.not_before = CERT_VALID_FROM
|
162
|
+
cert.not_after = valid_until
|
163
|
+
|
164
|
+
ef = extension_factory_for(ca_cert, cert)
|
165
|
+
CA_EXTENSIONS.each do |ext|
|
166
|
+
extension = ef.create_extension(*ext)
|
167
|
+
cert.add_extension(extension)
|
168
|
+
end
|
169
|
+
cert.sign(ca_key, signing_digest)
|
170
|
+
|
171
|
+
cert
|
172
|
+
end
|
173
|
+
|
174
|
+
def parse(cli_args)
|
175
|
+
parser, inputs, unparsed = parse_inputs(cli_args)
|
176
|
+
|
177
|
+
if !unparsed.empty?
|
178
|
+
@logger.err 'Error:'
|
179
|
+
@logger.err 'Unknown arguments or flags:'
|
180
|
+
unparsed.each do |arg|
|
181
|
+
@logger.err " #{arg}"
|
182
|
+
end
|
183
|
+
|
184
|
+
@logger.err ''
|
185
|
+
@logger.err parser.help
|
186
|
+
|
187
|
+
exit_code = 1
|
188
|
+
else
|
189
|
+
exit_code = nil
|
190
|
+
end
|
191
|
+
|
192
|
+
return inputs, exit_code
|
193
|
+
end
|
194
|
+
|
195
|
+
def parse_inputs(inputs)
|
196
|
+
parsed = {}
|
197
|
+
unparsed = []
|
198
|
+
|
199
|
+
parser = self.class.parser(parsed)
|
200
|
+
|
201
|
+
begin
|
202
|
+
parser.order!(inputs) do |nonopt|
|
203
|
+
unparsed << nonopt
|
204
|
+
end
|
205
|
+
rescue OptionParser::ParseError => e
|
206
|
+
unparsed += e.args
|
207
|
+
unparsed << inputs.shift unless inputs.first =~ /^-{1,2}/
|
208
|
+
retry
|
209
|
+
end
|
210
|
+
|
211
|
+
return parser, parsed, unparsed
|
212
|
+
end
|
213
|
+
|
214
|
+
def self.parser(parsed = {})
|
215
|
+
OptionParser.new do |opts|
|
216
|
+
opts.banner = BANNER
|
217
|
+
opts.on('--help', 'Display this generate specific help output') do |help|
|
218
|
+
parsed['help'] = true
|
219
|
+
end
|
220
|
+
opts.on('--config CONF', 'Path to puppet.conf') do |conf|
|
221
|
+
parsed['config'] = conf
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
|
3
|
+
module Puppetserver
|
4
|
+
module Ca
|
5
|
+
class Host
|
6
|
+
|
7
|
+
def initialize(digest)
|
8
|
+
@digest = digest
|
9
|
+
end
|
10
|
+
|
11
|
+
def create_private_key(keylength)
|
12
|
+
OpenSSL::PKey::RSA.new(keylength)
|
13
|
+
end
|
14
|
+
|
15
|
+
def create_csr(name, key)
|
16
|
+
csr = OpenSSL::X509::Request.new
|
17
|
+
csr.public_key = key.public_key
|
18
|
+
csr.subject = OpenSSL::X509::Name.new([["CN", name]])
|
19
|
+
csr.version = 2
|
20
|
+
csr.sign(key, @digest)
|
21
|
+
|
22
|
+
csr
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -1,6 +1,5 @@
|
|
1
|
-
require 'etc'
|
2
|
-
require 'fileutils'
|
3
1
|
require 'optparse'
|
2
|
+
require 'puppetserver/utils/file_utilities'
|
4
3
|
require 'puppetserver/ca/x509_loader'
|
5
4
|
require 'puppetserver/ca/puppet_config'
|
6
5
|
|
@@ -11,7 +10,7 @@ module Puppetserver
|
|
11
10
|
SUMMARY = "Import the CA's key, certs, and crls"
|
12
11
|
BANNER = <<-BANNER
|
13
12
|
Usage:
|
14
|
-
puppetserver ca import [--help
|
13
|
+
puppetserver ca import [--help]
|
15
14
|
puppetserver ca import [--config PATH]
|
16
15
|
--private-key PATH --cert-bundle PATH --crl-chain PATH
|
17
16
|
|
@@ -38,7 +37,7 @@ BANNER
|
|
38
37
|
|
39
38
|
files = [bundle_path, key_path, chain_path, config_path].compact
|
40
39
|
|
41
|
-
errors = validate_file_paths(files)
|
40
|
+
errors = Puppetserver::Utils::FileUtilities.validate_file_paths(files)
|
42
41
|
return 1 if log_possible_errors(errors)
|
43
42
|
|
44
43
|
loader = X509Loader.new(bundle_path, key_path, chain_path)
|
@@ -47,65 +46,22 @@ BANNER
|
|
47
46
|
puppet = PuppetConfig.parse(config_path)
|
48
47
|
return 1 if log_possible_errors(puppet.errors)
|
49
48
|
|
50
|
-
|
49
|
+
Puppetserver::Utils::FileUtilities.ensure_dir(puppet.settings[:cadir])
|
51
50
|
|
52
|
-
|
53
|
-
FileUtils.mkdir_p(puppet.settings[:cadir], mode: 0750)
|
54
|
-
FileUtils.chown(user, group, puppet.settings[:cadir])
|
55
|
-
end
|
56
|
-
|
57
|
-
write_file(puppet.settings[:cacert], loader.certs, user, group, 0640)
|
51
|
+
Puppetserver::Utils::FileUtilities.write_file(puppet.settings[:cacert], loader.certs, 0640)
|
58
52
|
|
59
|
-
write_file(puppet.settings[:cakey], loader.key,
|
53
|
+
Puppetserver::Utils::FileUtilities.write_file(puppet.settings[:cakey], loader.key, 0640)
|
60
54
|
|
61
|
-
write_file(puppet.settings[:cacrl], loader.crls,
|
55
|
+
Puppetserver::Utils::FileUtilities.write_file(puppet.settings[:cacrl], loader.crls, 0640)
|
62
56
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
if !File.exist?(puppet.settings[:cert_inventory])
|
68
|
-
write_file(puppet.settings[:cert_inventory],
|
69
|
-
"", user, group, 0640)
|
70
|
-
end
|
57
|
+
# Puppet's internal CA expects these file to exist.
|
58
|
+
Puppetserver::Utils::FileUtilities.ensure_file(puppet.settings[:serial], "001", 0640)
|
59
|
+
Puppetserver::Utils::FileUtilities.ensure_file(puppet.settings[:cert_inventory], "", 0640)
|
71
60
|
|
61
|
+
@logger.inform "Import succeeded. Find your files in #{puppet.settings[:cadir]}"
|
72
62
|
return 0
|
73
63
|
end
|
74
64
|
|
75
|
-
def find_user_and_group
|
76
|
-
if !running_as_root?
|
77
|
-
return Process.euid, Process.egid
|
78
|
-
else
|
79
|
-
if pe_puppet_exists?
|
80
|
-
return 'pe-puppet', 'pe-puppet'
|
81
|
-
else
|
82
|
-
return 'puppet', 'puppet'
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
def running_as_root?
|
88
|
-
!Gem.win_platform? && Process.euid == 0
|
89
|
-
end
|
90
|
-
|
91
|
-
def pe_puppet_exists?
|
92
|
-
!!(Etc.getpwnam('pe-puppet') rescue nil)
|
93
|
-
end
|
94
|
-
|
95
|
-
def write_file(path, one_or_more_objects, user, group, mode)
|
96
|
-
if File.exist?(path)
|
97
|
-
@logger.warn("#{path} exists, overwriting")
|
98
|
-
end
|
99
|
-
|
100
|
-
File.open(path, 'w', mode) do |f|
|
101
|
-
Array(one_or_more_objects).each do |object|
|
102
|
-
f.puts object.to_s
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
FileUtils.chown(user, group, path)
|
107
|
-
end
|
108
|
-
|
109
65
|
def log_possible_errors(maybe_errors)
|
110
66
|
errors = Array(maybe_errors).compact
|
111
67
|
unless errors.empty?
|
@@ -178,9 +134,6 @@ BANNER
|
|
178
134
|
opts.on('--help', 'Display this import specific help output') do |help|
|
179
135
|
parsed['help'] = true
|
180
136
|
end
|
181
|
-
opts.on('--version', 'Output the version') do |v|
|
182
|
-
parsed['version'] = true
|
183
|
-
end
|
184
137
|
opts.on('--config CONF', 'Path to puppet.conf') do |conf|
|
185
138
|
parsed['config'] = conf
|
186
139
|
end
|
@@ -195,17 +148,6 @@ BANNER
|
|
195
148
|
end
|
196
149
|
end
|
197
150
|
end
|
198
|
-
|
199
|
-
def validate_file_paths(one_or_more_paths)
|
200
|
-
errors = []
|
201
|
-
Array(one_or_more_paths).each do |path|
|
202
|
-
if !File.exist?(path) || !File.readable?(path)
|
203
|
-
errors << "Could not read file '#{path}'"
|
204
|
-
end
|
205
|
-
end
|
206
|
-
|
207
|
-
errors
|
208
|
-
end
|
209
151
|
end
|
210
152
|
end
|
211
153
|
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
require 'puppetserver/ca/utils'
|
2
|
+
require 'puppetserver/utils/http_client'
|
3
|
+
require 'puppetserver/utils/file_utilities'
|
4
|
+
require 'puppetserver/ca/puppet_config'
|
5
|
+
require 'optparse'
|
6
|
+
require 'json'
|
7
|
+
|
8
|
+
module Puppetserver
|
9
|
+
module Ca
|
10
|
+
class ListAction
|
11
|
+
|
12
|
+
include Puppetserver::Utils
|
13
|
+
|
14
|
+
SUMMARY = 'List all certificate requests'
|
15
|
+
BANNER = <<-BANNER
|
16
|
+
Usage:
|
17
|
+
puppetserver ca list [--help]
|
18
|
+
puppetserver ca list [--config]
|
19
|
+
puppetserver ca list [--all]
|
20
|
+
|
21
|
+
Description:
|
22
|
+
List outstanding certificate requests. If --all is specified, signed and revoked certificates will be listed as well.
|
23
|
+
|
24
|
+
Options:
|
25
|
+
BANNER
|
26
|
+
|
27
|
+
BODY = JSON.dump({desired_state: 'signed'})
|
28
|
+
|
29
|
+
def initialize(logger)
|
30
|
+
@logger = logger
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.parser(parsed = {})
|
34
|
+
OptionParser.new do |opts|
|
35
|
+
opts.banner = BANNER
|
36
|
+
opts.on('--config CONF', 'Custom path to Puppet\'s config file') do |conf|
|
37
|
+
parsed['config'] = conf
|
38
|
+
end
|
39
|
+
opts.on('--help', 'Display this command specific help output') do |help|
|
40
|
+
parsed['help'] = true
|
41
|
+
end
|
42
|
+
opts.on('--all', 'List all certificates') do |a|
|
43
|
+
parsed['all'] = true
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def run(input)
|
49
|
+
config = input['config']
|
50
|
+
|
51
|
+
if config
|
52
|
+
errors = FileUtilities.validate_file_paths(config)
|
53
|
+
return 1 if Utils.handle_errors(@logger, errors)
|
54
|
+
end
|
55
|
+
|
56
|
+
puppet = PuppetConfig.parse(config)
|
57
|
+
return 1 if Utils.handle_errors(@logger, puppet.errors)
|
58
|
+
|
59
|
+
all_certs = get_all_certs(puppet.settings)
|
60
|
+
return 1 if all_certs.nil?
|
61
|
+
|
62
|
+
requested, signed, revoked = separate_certs(all_certs)
|
63
|
+
input['all'] ? output_certs_by_state(requested, signed, revoked) : output_certs_by_state(requested)
|
64
|
+
|
65
|
+
return 0
|
66
|
+
end
|
67
|
+
|
68
|
+
def output_certs_by_state(requested, signed = [], revoked = [])
|
69
|
+
if revoked.empty? && signed.empty? && requested.empty?
|
70
|
+
@logger.inform "No certificates to list"
|
71
|
+
return
|
72
|
+
end
|
73
|
+
|
74
|
+
unless requested.empty?
|
75
|
+
@logger.inform "Requested Certificates:"
|
76
|
+
output_certs(requested)
|
77
|
+
end
|
78
|
+
|
79
|
+
unless signed.empty?
|
80
|
+
@logger.inform "Signed Certificates:"
|
81
|
+
output_certs(signed)
|
82
|
+
end
|
83
|
+
|
84
|
+
unless revoked.empty?
|
85
|
+
@logger.inform "Revoked Certificates:"
|
86
|
+
output_certs(revoked)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def output_certs(certs)
|
91
|
+
padded = 0
|
92
|
+
certs.each do |cert|
|
93
|
+
cert_size = cert["name"].size
|
94
|
+
padded = cert_size if cert_size > padded
|
95
|
+
end
|
96
|
+
|
97
|
+
certs.each do |cert|
|
98
|
+
@logger.inform " #{cert["name"]}".ljust(padded + 6) + " (SHA256) " + " #{cert["fingerprints"]["SHA256"]}" +
|
99
|
+
(cert["dns_alt_names"].empty? ? "" : "\talt names: #{cert["dns_alt_names"]}")
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def http_client(settings)
|
104
|
+
@client ||= HttpClient.new(settings[:localcacert],
|
105
|
+
settings[:certificate_revocation],
|
106
|
+
settings[:hostcrl])
|
107
|
+
end
|
108
|
+
|
109
|
+
def get_certificate_statuses(settings)
|
110
|
+
client = http_client(settings)
|
111
|
+
url = client.make_ca_url(settings[:ca_server],
|
112
|
+
settings[:ca_port],
|
113
|
+
'certificate_statuses',
|
114
|
+
'any_key')
|
115
|
+
client.with_connection(url) do |connection|
|
116
|
+
connection.get(url)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def separate_certs(all_certs)
|
121
|
+
certs = all_certs.group_by { |v| v["state"]}
|
122
|
+
requested = certs.fetch("requested", [])
|
123
|
+
signed = certs.fetch("signed", [])
|
124
|
+
revoked = certs.fetch("revoked", [])
|
125
|
+
return requested, signed, revoked
|
126
|
+
end
|
127
|
+
|
128
|
+
def get_all_certs(settings)
|
129
|
+
result = get_certificate_statuses(settings)
|
130
|
+
|
131
|
+
unless result.code == '200'
|
132
|
+
@logger.err 'Error:'
|
133
|
+
@logger.err " code: #{result.code}"
|
134
|
+
@logger.err " body: #{result.body}" if result.body
|
135
|
+
return nil
|
136
|
+
end
|
137
|
+
|
138
|
+
JSON.parse(result.body)
|
139
|
+
end
|
140
|
+
|
141
|
+
def parse(args)
|
142
|
+
results = {}
|
143
|
+
parser = self.class.parser(results)
|
144
|
+
|
145
|
+
errors = Utils.parse_with_errors(parser, args)
|
146
|
+
|
147
|
+
errors_were_handled = Utils.handle_errors(@logger, errors, parser.help)
|
148
|
+
|
149
|
+
exit_code = errors_were_handled ? 1 : nil
|
150
|
+
|
151
|
+
return results, exit_code
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|