lester 1.0.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +63 -0
- data/bin/lester +8 -0
- data/lib/lester.rb +22 -0
- data/lib/lester/authenticator.rb +42 -0
- data/lib/lester/cli.rb +101 -0
- data/lib/lester/command.rb +7 -0
- data/lib/lester/command/init.rb +18 -0
- data/lib/lester/command/renew.rb +63 -0
- data/lib/lester/factory.rb +70 -0
- data/lib/lester/private_key.rb +18 -0
- data/lib/lester/s3_store.rb +42 -0
- data/lib/lester/uploader.rb +28 -0
- data/lib/lester/version.rb +3 -0
- data/spec/acceptance/cli_init_spec.rb +47 -0
- data/spec/acceptance/cli_renew_spec.rb +149 -0
- data/spec/lester/authenticator_spec.rb +80 -0
- data/spec/lester/cli_spec.rb +102 -0
- data/spec/lester/command/init_spec.rb +31 -0
- data/spec/lester/command/renew_spec.rb +123 -0
- data/spec/lester/private_key_spec.rb +41 -0
- data/spec/lester/s3_store_spec.rb +73 -0
- data/spec/lester/uploader_spec.rb +116 -0
- data/spec/spec_helper.rb +33 -0
- data/spec/support/acceptance_setup.rb +38 -0
- data/spec/support/cassettes/new-certificate-fail.yml +64 -0
- data/spec/support/cassettes/new-certificate.yml +432 -0
- data/spec/support/cassettes/verification-fail.yml +139 -0
- data/spec/support/fake_bucket.rb +54 -0
- data/spec/support/fake_cloudfront.rb +26 -0
- data/spec/support/fake_iam.rb +16 -0
- data/spec/support/parameter_validation.rb +60 -0
- data/spec/support/resources/privkey.json +1 -0
- data/spec/support/resources/privkey.pem +27 -0
- metadata +182 -0
@@ -0,0 +1,54 @@
|
|
1
|
+
class FakeBucket
|
2
|
+
attr_reader :name
|
3
|
+
|
4
|
+
def initialize(name)
|
5
|
+
@name = name
|
6
|
+
@store = Hash.new { |h, k| h[k] = [] }
|
7
|
+
end
|
8
|
+
|
9
|
+
def keys
|
10
|
+
@store.keys
|
11
|
+
end
|
12
|
+
|
13
|
+
def object(key)
|
14
|
+
@store[key]
|
15
|
+
end
|
16
|
+
|
17
|
+
def put_object(args)
|
18
|
+
if (key = args.delete(:key))
|
19
|
+
@store[key] = ObjectProxy.new(key, args.delete(:body), args)
|
20
|
+
else
|
21
|
+
raise ArgumentError, sprintf('mmissing :key in %p', args)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class ObjectProxy
|
26
|
+
attr_reader :key, :options
|
27
|
+
|
28
|
+
def initialize(key, body, options)
|
29
|
+
@key = key
|
30
|
+
@body = body
|
31
|
+
@options = options
|
32
|
+
end
|
33
|
+
|
34
|
+
def exists?
|
35
|
+
true
|
36
|
+
end
|
37
|
+
|
38
|
+
def get
|
39
|
+
self
|
40
|
+
end
|
41
|
+
|
42
|
+
def body
|
43
|
+
self
|
44
|
+
end
|
45
|
+
|
46
|
+
def read
|
47
|
+
if @body.respond_to?(:read)
|
48
|
+
@body.read
|
49
|
+
else
|
50
|
+
@body
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class FakeCloudFront
|
2
|
+
attr_reader :updates
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@config = {}
|
6
|
+
@updates = []
|
7
|
+
end
|
8
|
+
|
9
|
+
def add_config(id, config)
|
10
|
+
@config[id] = config
|
11
|
+
end
|
12
|
+
|
13
|
+
def get_distribution_config(args)
|
14
|
+
if (id = args[:id])
|
15
|
+
config = @config[id]
|
16
|
+
response = OpenStruct.new
|
17
|
+
response.distribution_config = config
|
18
|
+
response.etag = 'ETAG-' + id
|
19
|
+
response
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def update_distribution(args)
|
24
|
+
@updates << args
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class FakeIAM
|
2
|
+
attr_reader :certificates
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@certificates = []
|
6
|
+
end
|
7
|
+
|
8
|
+
def upload_server_certificate(args)
|
9
|
+
@certificates << args
|
10
|
+
metadata = OpenStruct.new
|
11
|
+
metadata.server_certificate_id = Digest::MD5.hexdigest(args[:server_certificate_name])
|
12
|
+
response = OpenStruct.new
|
13
|
+
response.server_certificate_metadata = metadata
|
14
|
+
response
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module ParameterValidation
|
2
|
+
def parameter_validation(name, error_prefix=nil)
|
3
|
+
let :arguments do
|
4
|
+
{
|
5
|
+
'domain' => 'example.org',
|
6
|
+
'endpoint' => 'http://127.0.0.1:4000',
|
7
|
+
'site-bucket' => 'example-org-site',
|
8
|
+
'storage-bucket' => 'example-org-backup',
|
9
|
+
'email' => 'contact@example.org',
|
10
|
+
'private-key' => 'path/to/private_key.pem',
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
let :argv do
|
15
|
+
arguments.flat_map { |k, v| [sprintf('--%s', k), v] }.unshift(command_name)
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'when it is missing' do
|
19
|
+
before do
|
20
|
+
arguments.delete(name.to_s)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'prints an error message' do
|
24
|
+
cli.run
|
25
|
+
expect(output).to match(/#{error_prefix || name} is required/)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'prints usage' do
|
29
|
+
cli.run
|
30
|
+
expect(output).to match(/Usage/)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'returns a non-ok exit code' do
|
34
|
+
code = cli.run
|
35
|
+
expect(code).to eq(1)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'when it is empty' do
|
40
|
+
before do
|
41
|
+
arguments[name] = ''
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'prints an error message' do
|
45
|
+
cli.run
|
46
|
+
expect(output).to match(/#{error_prefix || name} is required/)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'prints usage' do
|
50
|
+
cli.run
|
51
|
+
expect(output).to match(/Usage/)
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'returns a non-ok exit code' do
|
55
|
+
code = cli.run
|
56
|
+
expect(code).to eq(1)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
{"kty":"RSA","e":"AQAB","n":"xLM5Y9y8XpW678stJW8UMyGTXjH2m8h94qrmz3fb8GV1Ol73jhuNIl9B6t_RrS_hNDqWN8E0wxzDr8cKJodrBUll91VeKjfzXh7oXUn0T65lyL5O1LCJDY3vqBdIcTYf_ajV0vDQDNGoyad-SMv_zNu2UhR3X9Jr7p1TJI9hXjlYRLjQpjER9lO6xXB9LcuOO4WKhTkJMlEsVC9MtwDtHUiGhW322uU6Io7K4MpGwTaZDPVzHOuveYtvaAPhpkn8SDBeVWtWHpVWVmmABF714MrDb-bIDl6ZiX2vXVoaBo8-o36PcHkTZ15fgqv4lkUYM66nIMb-iPsZ5tE375XU8Q","d":"d3UFAJHY0HSMf_7bXyWTle3pKsabJ0betN7np836A4gKZrWwEFzJHLvPM45UL6KpWWfPPPMYUPpSGZl-n6GULDTEOS5eLrOmGF4a7jTwq8eVRxHUnDTONy4hAuuI8kBVs15q5V2cbHyTzkvrVNiXdFlm43hMeyQ2qkZfbQ-qqWaHgzkIXTBQvy6Q-X3j2XZgCyhDLgPy04SLSFW97vWBFeKFEQHkD7IrL7wcpnQZPjrMQpzU9TZi155vT3sDOL0Q2k2VqCZSrj0pWohLjgllIAoAqZ8wfJF9FvoFipxsr-dTqCAQ0dAmxxE8E8TrvVbkLc8hPkgyDs3Zq8W_V164QQ","p":"5aIUCPVEe-TxGsWqdVvP40Uj6NxCElxvsUPdPylonJTfCIWcipWMKowjlT1CZFfDbqAEc3QGxxMcRm_gIaxBrh4fT1NZGzXqh6hfMgiIii5BYy1lZ1oMI6GFcOBPdwg9Gs50s6DlK2bExClHVQ5t05dZX5soTQodvaiixOLFRLk","q":"20kZrYfe6yqfVevhWFVwV03uiP3T4pWkW9SrhTP87HLNl_zT0_usnqe4DNZEnTU6a2LXsqzDlvbtY3MXd3oPPdz-4Ci77Tg00kVXqWZM5AFSRMCmlGmsKDEU3p2MkU2nLiVta379zinhaal3EC2kEoh2cujZlsbsR423g7vhZfk"}
|
@@ -0,0 +1,27 @@
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
2
|
+
MIIEpQIBAAKCAQEA5BFsC1qQlQGTC+DbcY/cmMhQIHmrwuBbfNymA1OGazsZIbYZ
|
3
|
+
ozEhVj+Jc+qrBc638MndsQqKpP/z4ZOCCLCTrwNk3bc/jT/1iirxcX5EO6bekqN+
|
4
|
+
tKsdSdNvEQ6pcaEyhnA6gNRfk/UI35KHN7feii1IM9wdCEnjF0hp7FuzBaMZONia
|
5
|
+
9JapvHQ6imrtvp0Ri5CRI0slUMdtgfv4QEH9+wty53XlZtKOY3A/dGnyFlMpAIu8
|
6
|
+
EUD+11LQloGVs2+N5V/3+aSck346/ZE4A43fUbBctIrf4SRyT57tfnjsIuDM1Rdv
|
7
|
+
iQdT0xse1plUSeToF0kAN5NbWy7nSJ06GMh9rQIDAQABAoIBAQCDC8OyTmqPQ+VT
|
8
|
+
SPOusAQIQelQj7jy8+l9uGcnuCGfkciiBzl5/Kv0G/QGCAwW/S3SDJv2s2Dw6CUh
|
9
|
+
M5nfFl71jBS0FSxOJDcZGg27sdrRD9QKHCmc9EmS9wt1mKAiK4aVmvzys5TrtjtQ
|
10
|
+
A6jwihUz/krjiZGhBpuW8EP0zMfz7yqmpdwiwGpxtJYgUJHMgDJ8L1bLYZh2HtvX
|
11
|
+
qAF2vC8oiqkFe6TLGgOdHamLQeeMMewd15tuRK8SGK/G8HP6UlxOn/dX71QYG6Xy
|
12
|
+
9lQksv7Ka+wEtzUmc0jKFWYMXSiNDypC2jCYdFfs+JCF7MuYhO1rA9FpE7JhlXmx
|
13
|
+
TcSdjZ69AoGBAPmEFj2X5nPcLT7OBnAzv5cWkBSa7Ag0S1q6j34nil+6kzFCPqDl
|
14
|
+
QWQb4k7WwqUf3bwVf2kbSMEeb2iNCRJth6UDjBclyDQB4pNDj1yB60VjH4v0IxCc
|
15
|
+
8vsIFlVrPIOdhaLBEaq1NY2OflRUYVLl1hSiQmJU3m+fyN9OkedGq7nPAoGBAOn+
|
16
|
+
pvnoLwlTnYvIo19+cCSWGMUQjO9Hmn7d8L+xCI7uODFv/rmdHVwTUmyG+nwbi+eu
|
17
|
+
ho3OksTPk1hEiDCkdbdKEchsNgI0itfD7kVm3qPEHOOzXXF7DUHPHZ3ZMsMgPBgq
|
18
|
+
Mfl7YA0xCX9uyY7p6vWHtmbeUHlnmtgzUOPddPvDAoGBALcA1NsaBPEnJJwyuXAj
|
19
|
+
1Dp5VvV15vXhfP8vY70QPSIXEowHXS3e14YYGXTfeOVpKNUhI1CwrTzPGMEi5+t3
|
20
|
+
IAy8PExh7qOOWmLOI2Ci/S7oE6QvTGSL6H6LoO3HeBvENdZ4Kn/85ilLwIYTWUpW
|
21
|
+
vhxmIbBDNN3D4K0/0C1DnQHrAoGBALGZlIatkbXUfwlvmYCLaPZ77gT0kOO0RzDv
|
22
|
+
pyD3b3V8na34QTAEbhpKmA7DTC8SgVexgXL0TTWQD1e5fFzfFnGtiF3EtCFsW810
|
23
|
+
as7GS0mlOgAhTVUqfl9qoiICjqLHPpVgwVmIKNkaVQkhv133cVw2S108c3wSBNb/
|
24
|
+
6+9nULkdAoGAbCm8knHSqZHRYcBlFucIObYQYOezwC63iGeA0E/cvDDBNtNrazBl
|
25
|
+
U5G6YtzeFmKBF9RHB/bTmt61rMpwfcQ4YuP1lWR19P1isqtNp6tpQ6/TTMCWgbms
|
26
|
+
C0NiKZKcIvyjcf7ggZ3ELIg5VsrLjmt9MCfghHVobheHmzEu7IGRDgI=
|
27
|
+
-----END RSA PRIVATE KEY-----
|
metadata
ADDED
@@ -0,0 +1,182 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: lester
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0.pre1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mathias Söderberg
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-12-13 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: acme-client
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "<"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "<"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: aws-sdk
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: simplecov
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.11'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.11'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: webmock
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: vcr
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3'
|
97
|
+
description: Let's Encrypt certificate renewer for sites hosted on S3
|
98
|
+
email:
|
99
|
+
- mths@sdrbrg.se
|
100
|
+
executables:
|
101
|
+
- lester
|
102
|
+
extensions: []
|
103
|
+
extra_rdoc_files: []
|
104
|
+
files:
|
105
|
+
- README.md
|
106
|
+
- bin/lester
|
107
|
+
- lib/lester.rb
|
108
|
+
- lib/lester/authenticator.rb
|
109
|
+
- lib/lester/cli.rb
|
110
|
+
- lib/lester/command.rb
|
111
|
+
- lib/lester/command/init.rb
|
112
|
+
- lib/lester/command/renew.rb
|
113
|
+
- lib/lester/factory.rb
|
114
|
+
- lib/lester/private_key.rb
|
115
|
+
- lib/lester/s3_store.rb
|
116
|
+
- lib/lester/uploader.rb
|
117
|
+
- lib/lester/version.rb
|
118
|
+
- spec/acceptance/cli_init_spec.rb
|
119
|
+
- spec/acceptance/cli_renew_spec.rb
|
120
|
+
- spec/lester/authenticator_spec.rb
|
121
|
+
- spec/lester/cli_spec.rb
|
122
|
+
- spec/lester/command/init_spec.rb
|
123
|
+
- spec/lester/command/renew_spec.rb
|
124
|
+
- spec/lester/private_key_spec.rb
|
125
|
+
- spec/lester/s3_store_spec.rb
|
126
|
+
- spec/lester/uploader_spec.rb
|
127
|
+
- spec/spec_helper.rb
|
128
|
+
- spec/support/acceptance_setup.rb
|
129
|
+
- spec/support/cassettes/new-certificate-fail.yml
|
130
|
+
- spec/support/cassettes/new-certificate.yml
|
131
|
+
- spec/support/cassettes/verification-fail.yml
|
132
|
+
- spec/support/fake_bucket.rb
|
133
|
+
- spec/support/fake_cloudfront.rb
|
134
|
+
- spec/support/fake_iam.rb
|
135
|
+
- spec/support/parameter_validation.rb
|
136
|
+
- spec/support/resources/privkey.json
|
137
|
+
- spec/support/resources/privkey.pem
|
138
|
+
homepage: https://github.com/mthssdrbrg/lester
|
139
|
+
licenses:
|
140
|
+
- MIT
|
141
|
+
metadata: {}
|
142
|
+
post_install_message:
|
143
|
+
rdoc_options: []
|
144
|
+
require_paths:
|
145
|
+
- lib
|
146
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
147
|
+
requirements:
|
148
|
+
- - ">="
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: '2.1'
|
151
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
152
|
+
requirements:
|
153
|
+
- - ">"
|
154
|
+
- !ruby/object:Gem::Version
|
155
|
+
version: 1.3.1
|
156
|
+
requirements: []
|
157
|
+
rubyforge_project:
|
158
|
+
rubygems_version: 2.4.5.1
|
159
|
+
signing_key:
|
160
|
+
specification_version: 4
|
161
|
+
summary: Renew Let's Encrypt certificates using S3
|
162
|
+
test_files:
|
163
|
+
- spec/acceptance/cli_init_spec.rb
|
164
|
+
- spec/acceptance/cli_renew_spec.rb
|
165
|
+
- spec/lester/authenticator_spec.rb
|
166
|
+
- spec/lester/cli_spec.rb
|
167
|
+
- spec/lester/command/init_spec.rb
|
168
|
+
- spec/lester/command/renew_spec.rb
|
169
|
+
- spec/lester/private_key_spec.rb
|
170
|
+
- spec/lester/s3_store_spec.rb
|
171
|
+
- spec/lester/uploader_spec.rb
|
172
|
+
- spec/spec_helper.rb
|
173
|
+
- spec/support/acceptance_setup.rb
|
174
|
+
- spec/support/cassettes/new-certificate-fail.yml
|
175
|
+
- spec/support/cassettes/new-certificate.yml
|
176
|
+
- spec/support/cassettes/verification-fail.yml
|
177
|
+
- spec/support/fake_bucket.rb
|
178
|
+
- spec/support/fake_cloudfront.rb
|
179
|
+
- spec/support/fake_iam.rb
|
180
|
+
- spec/support/parameter_validation.rb
|
181
|
+
- spec/support/resources/privkey.json
|
182
|
+
- spec/support/resources/privkey.pem
|