amarillo 0.1.1 → 0.2.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/bin/amarillo +49 -41
- data/lib/amarillo.rb +124 -51
- data/lib/amarillo/environment.rb +226 -0
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b53b0e0803cc4bd89185cbfc67aeb3d468ab7f34988073d7c405f6e88f38e6fe
|
4
|
+
data.tar.gz: ef2b8ec288bae0acd3924aa61ded5ccde2f9915bb15ec664316693641d4391e8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 16eb56677f677b3b752de0af6e1b67dc6495b01a494e84e8c935ea19db84f3b16a2bf71cbc67893025388b4289b39d9ebf84f86b2e81b0abf0742c7707bd2e33
|
7
|
+
data.tar.gz: 94af28ad358c6313fa4a43c00b0b31fc9f01d577556c90e8bf49c9396c06946c7d689abdd6fcd826b558fbcf74b3767b93c183055c2db7514510369033a8c1f6
|
data/bin/amarillo
CHANGED
@@ -23,9 +23,18 @@
|
|
23
23
|
require 'optparse'
|
24
24
|
require 'fileutils'
|
25
25
|
require 'amarillo'
|
26
|
+
require 'amarillo/environment'
|
26
27
|
|
27
28
|
options = {}
|
28
29
|
OptionParser.new do |opts|
|
30
|
+
opts.on("-i", "--initialize", "Initialize amarillo defaults") do |i|
|
31
|
+
options[:initialize] = i
|
32
|
+
end
|
33
|
+
|
34
|
+
opts.on("-r", "--renew", "Renew certificates") do |r|
|
35
|
+
options[:renew] = r
|
36
|
+
end
|
37
|
+
|
29
38
|
opts.on("-z", "--zone ZONE", "Hosted zone") do |z|
|
30
39
|
options[:zone] = z
|
31
40
|
end
|
@@ -38,8 +47,8 @@ OptionParser.new do |opts|
|
|
38
47
|
options[:name] = n
|
39
48
|
end
|
40
49
|
|
41
|
-
opts.on("-
|
42
|
-
options[:
|
50
|
+
opts.on("-a", "--amarillo-home AMARILLO_HOME", "Home directory for configuration, keys, and certificates") do |o|
|
51
|
+
options[:amarillo_home] = a
|
43
52
|
end
|
44
53
|
|
45
54
|
opts.on("-h", "--help") do |h|
|
@@ -55,57 +64,56 @@ Usage: amarillo --zone ZONE --name COMMONNAME --email EMAIL [--output-path OUTP
|
|
55
64
|
exit 0
|
56
65
|
end
|
57
66
|
|
58
|
-
if options[:
|
59
|
-
|
60
|
-
options[:name].nil? then
|
67
|
+
if options[:initialize] then
|
68
|
+
e = Amarillo::Environment.new
|
61
69
|
|
62
|
-
|
70
|
+
e.init options[:zone], options[:email]
|
63
71
|
|
64
|
-
|
72
|
+
exit 0
|
65
73
|
end
|
66
74
|
|
67
|
-
|
68
|
-
|
69
|
-
|
75
|
+
e = Amarillo::Environment.new
|
76
|
+
e.load_config
|
77
|
+
|
78
|
+
if options[:zone].nil?
|
79
|
+
zone = e.config["defaults"]["zone"]
|
80
|
+
if zone.nil? or zone == '' then
|
81
|
+
puts "Error: Specify a default zone in config.yml or use --zone"
|
82
|
+
exit -1
|
83
|
+
end
|
70
84
|
else
|
71
|
-
|
72
|
-
key_path = "#{certificate_path}/private"
|
85
|
+
zone = options[:zone]
|
73
86
|
end
|
74
87
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
HEREDOC
|
84
|
-
print writableMessage
|
85
|
-
exit -1
|
86
|
-
end
|
88
|
+
if options[:email].nil?
|
89
|
+
email = e.config["defaults"]["email"]
|
90
|
+
if email.nil? or email == '' then
|
91
|
+
puts "Error: Specify a default e-mail address in config.yml or use --email"
|
92
|
+
exit -1
|
93
|
+
end
|
94
|
+
else
|
95
|
+
email = options[:email]
|
87
96
|
end
|
88
97
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
/etc/amarillo/aws.env must exist and set both aws_access_key_id and aws_secret_access_key for an IAM user with AmazonRoute53FullAccess permissions.
|
96
|
-
|
97
|
-
Example:
|
98
|
+
if options[:name].nil? and options[:renew].nil? then
|
99
|
+
puts "Usage: amarillo --name COMMONNAME [--zone ZONE] [--email EMAIL] [--amarillo-home AMARILLO_HOME]"
|
100
|
+
exit -1
|
101
|
+
else
|
102
|
+
name = options[:name]
|
103
|
+
end
|
98
104
|
|
99
|
-
[
|
100
|
-
|
101
|
-
|
102
|
-
|
105
|
+
if options[:amarillo_home].nil?
|
106
|
+
amarillo_home = "/usr/local/etc/amarillo"
|
107
|
+
else
|
108
|
+
amarillo_home = options[:amarillo_home]
|
109
|
+
end
|
103
110
|
|
104
|
-
|
111
|
+
y = Amarillo.new amarillo_home
|
105
112
|
|
106
|
-
|
113
|
+
if options[:renew] then
|
114
|
+
y.renewCertificates
|
115
|
+
else
|
116
|
+
y.requestCertificate zone, name, email, nil
|
107
117
|
end
|
108
118
|
|
109
119
|
|
110
|
-
y = Amarillo.new(certificate_path, key_path, awsEnvPath)
|
111
|
-
y.requestCertificate(options[:zone], options[:name], options[:email])
|
data/lib/amarillo.rb
CHANGED
@@ -29,14 +29,23 @@ require 'openssl' # Key Generation
|
|
29
29
|
require 'aws-sdk-core' # Credentials
|
30
30
|
require 'aws-sdk-route53' # Route 53
|
31
31
|
require 'resolv' # DNS Resolvers
|
32
|
+
require 'yaml' # YAML
|
32
33
|
|
33
34
|
class Amarillo
|
34
35
|
|
35
|
-
def initialize(
|
36
|
+
def initialize(amarilloHome)
|
36
37
|
|
37
|
-
@
|
38
|
-
|
39
|
-
@
|
38
|
+
@environment = Amarillo::Environment.new(amarilloHome: amarilloHome)
|
39
|
+
|
40
|
+
if not @environment.verify then raise "Cannot initialize amarillo" end
|
41
|
+
|
42
|
+
@environment.load_config
|
43
|
+
|
44
|
+
@certificatePath = @environment.certificatePath
|
45
|
+
@keyPath = @environment.keyPath
|
46
|
+
@config = @environment.config
|
47
|
+
@awsEnvFile = @environment.awsEnvFile
|
48
|
+
@configsPath = @environment.configsPath
|
40
49
|
|
41
50
|
@logger = Logger.new(STDOUT)
|
42
51
|
@logger.level = Logger::INFO
|
@@ -65,19 +74,35 @@ class Amarillo
|
|
65
74
|
valid
|
66
75
|
end
|
67
76
|
|
68
|
-
def
|
77
|
+
def get_route53
|
78
|
+
shared_creds = Aws::SharedCredentials.new(path: "#{@awsEnvFile}")
|
79
|
+
|
80
|
+
Aws.config.update(credentials: shared_creds)
|
81
|
+
|
82
|
+
region = @config["defaults"]["region"] ? @config["defaults"]["region"] : 'us-east-2'
|
83
|
+
@route53 = Aws::Route53::Client.new(region: region)
|
84
|
+
@hzone = @route53.list_hosted_zones(max_items: 100).hosted_zones.detect { |z| z.name == "#{@zone}." }
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
def requestCertificate(zone, commonName, email, key_type)
|
89
|
+
|
90
|
+
@zone = zone
|
91
|
+
|
92
|
+
acmeUrl = @config["defaults"]["acme_url"] ? @config["defaults"]["acme_url"] : 'https://acme-v02.api.letsencrypt.org/directory'
|
93
|
+
|
94
|
+
# Load private key
|
69
95
|
|
70
|
-
@logger.info "
|
71
|
-
|
72
|
-
client = Acme::Client.new(
|
73
|
-
private_key: key,
|
74
|
-
directory: 'https://acme-v02.api.letsencrypt.org/directory'
|
75
|
-
)
|
96
|
+
@logger.info "Loading 4096-bit RSA private key for Let's Encrypt account"
|
97
|
+
@logger.info "Let's Encrypt directory set to #{acmeUrl}"
|
76
98
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
99
|
+
key = OpenSSL::PKey::RSA.new File.read "#{@keyPath}/letsencrypt.key"
|
100
|
+
|
101
|
+
client = Acme::Client.new private_key: key,
|
102
|
+
directory: acmeUrl
|
103
|
+
|
104
|
+
account = client.new_account contact: "mailto:#{email}",
|
105
|
+
terms_of_service_agreed: true
|
81
106
|
|
82
107
|
# Generate a certificate order
|
83
108
|
@logger.info "Creating certificate order request for #{commonName}"
|
@@ -90,16 +115,7 @@ class Amarillo
|
|
90
115
|
|
91
116
|
@logger.info "Challenge value for #{commonName} in #{zone} zone is #{challengeValue}"
|
92
117
|
|
93
|
-
|
94
|
-
|
95
|
-
shared_creds = Aws::SharedCredentials.new(path: "#{@awsEnvPath}")
|
96
|
-
Aws.config.update(credentials: shared_creds)
|
97
|
-
|
98
|
-
# TODO: Allow the user to set the region
|
99
|
-
route53 = Aws::Route53::Client.new(region: 'us-east-2')
|
100
|
-
hzone = route53.list_hosted_zones(max_items: 100)
|
101
|
-
.hosted_zones
|
102
|
-
.detect { |z| z.name == "#{zone}." }
|
118
|
+
self.get_route53
|
103
119
|
|
104
120
|
change = {
|
105
121
|
action: 'UPSERT',
|
@@ -114,30 +130,20 @@ class Amarillo
|
|
114
130
|
}
|
115
131
|
|
116
132
|
options = {
|
117
|
-
hosted_zone_id: hzone.id,
|
133
|
+
hosted_zone_id: @hzone.id,
|
118
134
|
change_batch: {
|
119
135
|
changes: [change]
|
120
136
|
}
|
121
137
|
}
|
122
138
|
|
123
|
-
route53.change_resource_record_sets(options)
|
124
|
-
|
125
|
-
nameservers = []
|
139
|
+
@route53.change_resource_record_sets(options)
|
126
140
|
|
127
|
-
|
141
|
+
nameservers = @environment.get_zone_nameservers
|
128
142
|
|
129
|
-
|
130
|
-
while nameservers.length == 0
|
131
|
-
nameservers = dns.getresources(
|
132
|
-
zone,
|
133
|
-
Resolv::DNS::Resource::IN::NS
|
134
|
-
).map(&:name).map(&:to_s)
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
@logger.info "Waiting for DNS record to propogate"
|
143
|
+
@logger.info "Waiting for DNS record to propagate"
|
139
144
|
while !check_dns(commonName, nameservers, challengeValue)
|
140
|
-
sleep
|
145
|
+
sleep 2
|
146
|
+
@logger.info "Still waiting..."
|
141
147
|
end
|
142
148
|
|
143
149
|
authorization.dns.request_validation
|
@@ -150,15 +156,40 @@ class Amarillo
|
|
150
156
|
authorization.dns.reload
|
151
157
|
end
|
152
158
|
|
153
|
-
@logger.info "
|
159
|
+
@logger.info "Generating key"
|
160
|
+
|
161
|
+
# Create certificate yml
|
162
|
+
certConfig = {
|
163
|
+
"commonName" => commonName,
|
164
|
+
"email" => email,
|
165
|
+
"zone" => zone
|
166
|
+
}
|
154
167
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
168
|
+
if key_type
|
169
|
+
certConfig["key_type"] = key_type
|
170
|
+
else
|
171
|
+
key_type = @config["defaults"]["key_type"]
|
172
|
+
certConfig["key_type"] = key_type
|
173
|
+
end
|
160
174
|
|
161
|
-
|
175
|
+
type, args = key_type.split(',')
|
176
|
+
|
177
|
+
if type == 'ec' then
|
178
|
+
certPrivateKey = OpenSSL::PKey::EC.new(args).generate_key
|
179
|
+
elsif type == 'rsa' then
|
180
|
+
certPrivateKey = OpenSSL::PKey::RSA.new(args)
|
181
|
+
end
|
182
|
+
|
183
|
+
@logger.info "Requesting certificate..."
|
184
|
+
csr = Acme::Client::CertificateRequest.new private_key: certPrivateKey,
|
185
|
+
names: [commonName]
|
186
|
+
|
187
|
+
begin
|
188
|
+
order.finalize(csr: csr)
|
189
|
+
rescue
|
190
|
+
@logger.error("ERROR")
|
191
|
+
self.cleanup label, record_type, challengeValue
|
192
|
+
end
|
162
193
|
|
163
194
|
sleep(1) while order.status == 'processing'
|
164
195
|
|
@@ -168,8 +199,9 @@ class Amarillo
|
|
168
199
|
@logger.info "Saving private key to #{keyOutputPath}"
|
169
200
|
|
170
201
|
File.open(keyOutputPath, "w") do |f|
|
171
|
-
f.puts
|
202
|
+
f.puts certPrivateKey.to_pem.to_s
|
172
203
|
end
|
204
|
+
File.chmod(0600, keyOutputPath)
|
173
205
|
|
174
206
|
@logger.info "Saving certificate to #{certOutputPath}"
|
175
207
|
|
@@ -177,6 +209,14 @@ class Amarillo
|
|
177
209
|
f.puts order.certificate
|
178
210
|
end
|
179
211
|
|
212
|
+
certConfigFile = "#{@configsPath}/#{commonName}.yml"
|
213
|
+
File.write(certConfigFile, certConfig.to_yaml)
|
214
|
+
|
215
|
+
self.cleanup label, record_type, challengeValue
|
216
|
+
|
217
|
+
end
|
218
|
+
|
219
|
+
def cleanup(label, record_type, challengeValue)
|
180
220
|
@logger.info "Cleaning up..."
|
181
221
|
|
182
222
|
change = {
|
@@ -192,12 +232,45 @@ class Amarillo
|
|
192
232
|
}
|
193
233
|
|
194
234
|
options = {
|
195
|
-
hosted_zone_id: hzone.id,
|
235
|
+
hosted_zone_id: @hzone.id,
|
196
236
|
change_batch: {
|
197
237
|
changes: [change]
|
198
238
|
}
|
199
239
|
}
|
200
240
|
|
201
|
-
route53.change_resource_record_sets(options)
|
241
|
+
@route53.change_resource_record_sets(options)
|
242
|
+
end
|
243
|
+
|
244
|
+
def renewCertificate(zone, commonName, email)
|
245
|
+
|
246
|
+
end
|
247
|
+
|
248
|
+
def renewCertificates
|
249
|
+
t = Time.now
|
250
|
+
@logger.info "Renewing certificates"
|
251
|
+
|
252
|
+
Dir["#{@configsPath}/*.yml"].each do |c|
|
253
|
+
config = YAML.load(File.read(c))
|
254
|
+
|
255
|
+
cn = config["commonName"]
|
256
|
+
email = config["email"]
|
257
|
+
zone = config["zone"]
|
258
|
+
key_type = config["key_type"]
|
259
|
+
|
260
|
+
certificatePath = "#{@certificatePath}/#{cn}.crt"
|
261
|
+
raw = File.read certificatePath
|
262
|
+
certificate = OpenSSL::X509::Certificate.new raw
|
263
|
+
daysToExpiration = (certificate.not_after - t).to_i / (24 * 60 * 60)
|
264
|
+
|
265
|
+
if daysToExpiration < 30 then
|
266
|
+
@logger.info "#{cn} certificate needs to be renewed"
|
267
|
+
self.requestCertificate zone, cn, email, key_type
|
268
|
+
else
|
269
|
+
@logger.info "#{cn} certificate does not need to be renewed"
|
270
|
+
end
|
271
|
+
end
|
202
272
|
end
|
203
273
|
end
|
274
|
+
|
275
|
+
|
276
|
+
require 'amarillo/environment'
|
@@ -0,0 +1,226 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Inspired by Pete Keen's (pete@petekeen.net) post
|
4
|
+
# https://www.petekeen.net/lets-encrypt-without-certbot
|
5
|
+
#
|
6
|
+
# Copyright 2021 iAchieved.it LLC
|
7
|
+
#
|
8
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
9
|
+
# of this software and associated documentation files (the "Software"), to deal
|
10
|
+
# in the Software without restriction, including without limitation the rights
|
11
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
12
|
+
# copies of the Software, and to permit persons to whom the Software is
|
13
|
+
# furnished to do so, subject to the following conditions:
|
14
|
+
#
|
15
|
+
# The above copyright notice and this permission notice shall be included in
|
16
|
+
# all copies or substantial portions of the Software.
|
17
|
+
#
|
18
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
19
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
20
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
21
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
22
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
23
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
24
|
+
# SOFTWARE.
|
25
|
+
|
26
|
+
require 'logger'
|
27
|
+
require 'yaml'
|
28
|
+
require 'aws-sdk-core'
|
29
|
+
|
30
|
+
DefaultAmarilloHome = "/usr/local/etc/amarillo/"
|
31
|
+
|
32
|
+
class Amarillo::Environment
|
33
|
+
|
34
|
+
attr_reader :certificatePath, :keyPath, :configPath, :configsPath, :config, :awsEnvFile
|
35
|
+
|
36
|
+
def initialize(amarilloHome: DefaultAmarilloHome)
|
37
|
+
|
38
|
+
@logger = Logger.new(STDOUT)
|
39
|
+
@logger.level = Logger::INFO
|
40
|
+
|
41
|
+
@amarilloHome = amarilloHome
|
42
|
+
@certificatePath = amarilloHome + "/certificates"
|
43
|
+
@keyPath = amarilloHome + "/keys"
|
44
|
+
@configPath = amarilloHome
|
45
|
+
@configsPath = amarilloHome + "/configs"
|
46
|
+
@configFile = amarilloHome + "/config.yml"
|
47
|
+
@awsEnvFile = amarilloHome + "/aws.env"
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
# Public method to create default configuration files
|
52
|
+
def init(zone = nil, email = nil)
|
53
|
+
|
54
|
+
unless File.exist?(@configsPath) and File.directory?(@configsPath)
|
55
|
+
begin
|
56
|
+
@logger.info "Creating #{@configsPath} directory"
|
57
|
+
FileUtils.mkpath(@configsPath)
|
58
|
+
rescue
|
59
|
+
@logger.error("Cannot create #{@configsPath} directory")
|
60
|
+
return false
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
unless File.exist?(@certificatePath) and File.directory?(@certificatePath)
|
65
|
+
begin
|
66
|
+
@logger.info "Creating #{@certificatePath} directory"
|
67
|
+
FileUtils.mkpath(@certificatePath)
|
68
|
+
rescue
|
69
|
+
@logger.error("Cannot create #{@certificatePath} directory")
|
70
|
+
return false
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
unless File.exist?(@keyPath) and File.directory?(@keyPath)
|
75
|
+
begin
|
76
|
+
@logger.info "Creating #{@keyPath} directory"
|
77
|
+
FileUtils.mkpath(@keyPath)
|
78
|
+
rescue
|
79
|
+
@logger.error("Cannot create #{@keyPath} directory")
|
80
|
+
return false
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Create aws.env
|
85
|
+
unless File.exist?(@awsEnvFile) then
|
86
|
+
awsEnv = <<-HEREDOC
|
87
|
+
[default]
|
88
|
+
aws_access_key_id =
|
89
|
+
aws_secret_access_key =
|
90
|
+
HEREDOC
|
91
|
+
@logger.info("Creating blank #{@awsEnvFile}")
|
92
|
+
@logger.warn("NOTE: aws_access_key_id and aws_secret_access_key must be specified in this file.")
|
93
|
+
File.write(@awsEnvFile, awsEnv)
|
94
|
+
else
|
95
|
+
@logger.info("Refusing to overwrite #{@awsEnvFile}")
|
96
|
+
end
|
97
|
+
|
98
|
+
# Create config.yml
|
99
|
+
unless File.exist?(@configFile) then
|
100
|
+
@logger.info("Creating default configuration #{@configFile}")
|
101
|
+
config = {
|
102
|
+
"defaults" => {
|
103
|
+
"region" => 'us-east-2',
|
104
|
+
"profile" => 'default',
|
105
|
+
"email" => email,
|
106
|
+
"zone" => zone,
|
107
|
+
"nameservers" => ['208.67.222.222', '9.9.9.9'],
|
108
|
+
"key_type" => 'ec,secp384r1'
|
109
|
+
}}
|
110
|
+
File.write(@configFile, config.to_yaml)
|
111
|
+
else
|
112
|
+
@logger.info("Refusing to overwrite #{@configFile}")
|
113
|
+
end
|
114
|
+
|
115
|
+
# Create RSA private key for Let's Encrypt account
|
116
|
+
privateKeyPath = "#{@keyPath}/letsencrypt.key"
|
117
|
+
|
118
|
+
unless File.exist? privateKeyPath then
|
119
|
+
@logger.info "Generating 4096-bit RSA private key for Let's Encrypt account"
|
120
|
+
|
121
|
+
privateKey = OpenSSL::PKey::RSA.new(4096)
|
122
|
+
|
123
|
+
|
124
|
+
File.open(privateKeyPath, "w") do |f|
|
125
|
+
f.puts privateKey.to_pem.to_s
|
126
|
+
end
|
127
|
+
File.chmod(0400, privateKeyPath)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
#
|
132
|
+
# Verify paths exist and are writable
|
133
|
+
# Verify aws.env exists and is formatted correctly
|
134
|
+
# Verify config.yml exists and is formatted correctly
|
135
|
+
#
|
136
|
+
def verify
|
137
|
+
@logger.info "Verifying amarillo environment"
|
138
|
+
if not verify_env() then return false end
|
139
|
+
if not verify_awsenv() then return false end
|
140
|
+
if not verify_config() then return false end
|
141
|
+
return true
|
142
|
+
end
|
143
|
+
|
144
|
+
def verify_env
|
145
|
+
unless File.stat(@certificatePath).writable? then
|
146
|
+
@logger.error(@certificatePath + " is not writable")
|
147
|
+
return false
|
148
|
+
end
|
149
|
+
|
150
|
+
unless File.stat(@keyPath).writable? then
|
151
|
+
@logger.error(@keyPath + " is not writable")
|
152
|
+
return false
|
153
|
+
end
|
154
|
+
|
155
|
+
return true
|
156
|
+
end
|
157
|
+
|
158
|
+
def verify_awsenv()
|
159
|
+
awsEnvFile = Pathname.new(@awsEnvFile)
|
160
|
+
if not awsEnvFile.exist? then
|
161
|
+
@logger.error("#{awsEnvFile} does not exist")
|
162
|
+
return false
|
163
|
+
end
|
164
|
+
|
165
|
+
awsCredentials = Aws::SharedCredentials.new(path: "#{@awsEnvFile}")
|
166
|
+
|
167
|
+
if awsCredentials.credentials.access_key_id.length != 20 then
|
168
|
+
@logger.error("#{@awsEnvFile} aws_access_key_id does not appear to be valid")
|
169
|
+
return false
|
170
|
+
end
|
171
|
+
|
172
|
+
if awsCredentials.credentials.secret_access_key.length != 40 then
|
173
|
+
@logger.error("#{@awsEnvFile} aws_secret_access_key does not appear to be valid")
|
174
|
+
return false
|
175
|
+
end
|
176
|
+
|
177
|
+
return true
|
178
|
+
end
|
179
|
+
|
180
|
+
def verify_config()
|
181
|
+
if not File.exist?(@configFile) then
|
182
|
+
@logger.error("#{@configFile} does not exist")
|
183
|
+
return false
|
184
|
+
end
|
185
|
+
|
186
|
+
begin
|
187
|
+
YAML.load(File.read(@configFile))
|
188
|
+
rescue
|
189
|
+
@logger.error("Unable to load configuration file")
|
190
|
+
return false
|
191
|
+
end
|
192
|
+
|
193
|
+
return true
|
194
|
+
end
|
195
|
+
|
196
|
+
def load_config()
|
197
|
+
if verify_config() then
|
198
|
+
@config = YAML.load(File.read(@configFile))
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def get_zone_nameservers
|
203
|
+
|
204
|
+
self.load_config
|
205
|
+
|
206
|
+
nameservers = @config["defaults"]["nameservers"]
|
207
|
+
zone = @config["defaults"]["zone"]
|
208
|
+
|
209
|
+
@logger.info "Looking up nameservers for #{zone}"
|
210
|
+
|
211
|
+
zone_nameservers = []
|
212
|
+
Resolv::DNS.open(nameserver: nameservers) do |dns|
|
213
|
+
while zone_nameservers.length == 0
|
214
|
+
zone_nameservers = dns.getresources(
|
215
|
+
zone,
|
216
|
+
Resolv::DNS::Resource::IN::NS
|
217
|
+
).map(&:name).map(&:to_s)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
@logger.info "Found #{zone_nameservers.length} nameservers for zone #{zone}: #{zone_nameservers}"
|
222
|
+
|
223
|
+
return zone_nameservers
|
224
|
+
end
|
225
|
+
|
226
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: amarillo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- iAchieved.it LLC
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-05-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: acme-client
|
@@ -75,11 +75,12 @@ extra_rdoc_files: []
|
|
75
75
|
files:
|
76
76
|
- bin/amarillo
|
77
77
|
- lib/amarillo.rb
|
78
|
+
- lib/amarillo/environment.rb
|
78
79
|
homepage: https://github.com/iachievedit/amarillo
|
79
80
|
licenses:
|
80
81
|
- MIT
|
81
82
|
metadata: {}
|
82
|
-
post_install_message:
|
83
|
+
post_install_message:
|
83
84
|
rdoc_options: []
|
84
85
|
require_paths:
|
85
86
|
- lib
|
@@ -94,8 +95,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
94
95
|
- !ruby/object:Gem::Version
|
95
96
|
version: '0'
|
96
97
|
requirements: []
|
97
|
-
rubygems_version: 3.
|
98
|
-
signing_key:
|
98
|
+
rubygems_version: 3.2.3
|
99
|
+
signing_key:
|
99
100
|
specification_version: 4
|
100
101
|
summary: Amarillo
|
101
102
|
test_files: []
|