capistrano-lets-encrypt 0.1.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 +7 -0
- data/.gitignore +1 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +101 -0
- data/Rakefile +2 -0
- data/capistrano-lets-encrypt.gemspec +24 -0
- data/lib/capistrano/lets-encrypt.rb +1 -0
- data/lib/capistrano/tasks/lets-encrypt.rake +190 -0
- data/lib/capistrano-lets-encrypt.rb +0 -0
- metadata +96 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f473171fd16aa1dce17e6fe5b6278a59b5170cba
|
4
|
+
data.tar.gz: af32bc3f5619c618c6ce81592aca906281d7cf82
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e303e3709d463323c185860a08c3507c14aeb99411674e3c860fa80706b945b1314cab424348278bcf8447ff619da8505fa1f743339459aa7534146f48e3b0f9
|
7
|
+
data.tar.gz: 61e95f90349114548fb6d73a9bb3ba35fc5a912809ec4f7fcd8cd5cbaafbebfb0cce2c2a44eb7f6268e1579a48be2d536c7cd3106c1523fac44e778ae92285a6
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
pkg/
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Copyright (c) 2015 Platanus
|
2
|
+
MIT License
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
a copy of this software and associated documentation files (the
|
6
|
+
"Software"), to deal in the Software without restriction, including
|
7
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
# Capistrano::LetsEncrypt [](http://badge.fury.io/rb/capistrano-lets-encrypt)
|
2
|
+
|
3
|
+
Let's encrypt support for Capistrano 3.x
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'capistrano-lets-encrypt', '~> 1.0'
|
10
|
+
gem 'capistrano'
|
11
|
+
|
12
|
+
And then execute:
|
13
|
+
|
14
|
+
$ bundle
|
15
|
+
|
16
|
+
Or install it yourself as:
|
17
|
+
|
18
|
+
$ gem install capistrano-lets-encrypt
|
19
|
+
|
20
|
+
## Usage
|
21
|
+
|
22
|
+
Require in `Capfile` to use the default task:
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
require 'capistrano/lets-encrypt'
|
26
|
+
```
|
27
|
+
|
28
|
+
You will get the following tasks
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
cap delayed_job:start # Start delayed_job service
|
32
|
+
cap delayed_job:stop # Stop delayed_job service
|
33
|
+
cap delayed_job:restart # Restart delayed_job service
|
34
|
+
```
|
35
|
+
|
36
|
+
Configurable options (copy into deploy.rb), shown here with examples:
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
# Number of delayed_job workers
|
40
|
+
# default value: 1
|
41
|
+
set :delayed_job_workers, 2
|
42
|
+
|
43
|
+
# String to be prefixed to worker process names
|
44
|
+
# This feature allows a prefix name to be placed in front of the process.
|
45
|
+
# For example: reports/delayed_job.0 instead of just delayed_job.0
|
46
|
+
set :delayed_job_prefix, :reports
|
47
|
+
|
48
|
+
# Delayed_job queue or queues
|
49
|
+
# Set the --queue or --queues option to work from a particular queue.
|
50
|
+
# default value: nil
|
51
|
+
set :delayed_job_queues, ['mailer','tracking']
|
52
|
+
|
53
|
+
# Specify different pools
|
54
|
+
# You can use this option multiple times to start different numbers of workers for different queues.
|
55
|
+
# default value: nil
|
56
|
+
set :delayed_job_pools, {
|
57
|
+
:mailer => 2,
|
58
|
+
:tracking => 1,
|
59
|
+
:* => 2
|
60
|
+
}
|
61
|
+
|
62
|
+
# Set the roles where the delayed_job process should be started
|
63
|
+
# default value: :app
|
64
|
+
set :delayed_job_roles, [:app, :background]
|
65
|
+
|
66
|
+
# Set the location of the delayed_job executable
|
67
|
+
# Can be relative to the release_path or absolute
|
68
|
+
# default value 'bin'
|
69
|
+
set :delayed_job_bin_path, 'script' # for rails 3.x
|
70
|
+
|
71
|
+
### Set the location of the delayed_job logfile
|
72
|
+
set :delayed_log_dir, 'path_to_logfile'
|
73
|
+
```
|
74
|
+
|
75
|
+
It also adds the following hook
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
after 'deploy:published', 'restart' do
|
79
|
+
invoke 'delayed_job:restart'
|
80
|
+
end
|
81
|
+
```
|
82
|
+
|
83
|
+
## Contributing
|
84
|
+
|
85
|
+
1. Fork it
|
86
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
87
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
88
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
89
|
+
5. Create new Pull Request
|
90
|
+
|
91
|
+
## Credits
|
92
|
+
|
93
|
+
Thank you [contributors](https://github.com/platanus/guides/graphs/contributors)!
|
94
|
+
|
95
|
+
<img src="http://platan.us/gravatar_with_text.png" alt="Platanus" width="250"/>
|
96
|
+
|
97
|
+
capistrano-lets-encrypt is maintained by [platanus](http://platan.us).
|
98
|
+
|
99
|
+
## License
|
100
|
+
|
101
|
+
Guides is © 2014 platanus, spa. It is free software and may be redistributed under the terms specified in the LICENSE file.
|
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "capistrano-lets-encrypt"
|
7
|
+
spec.version = "0.1.0"
|
8
|
+
spec.authors = ["Juan Ignacio Donoso"]
|
9
|
+
spec.email = ["juan.ignacio@platan.us"]
|
10
|
+
spec.summary = %q{Adds support for let's encrypt to Capistrano 3.x}
|
11
|
+
spec.description = %q{Adds support for let's encrypt to Capistrano 3.x}
|
12
|
+
spec.homepage = ""
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0")
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_dependency 'capistrano', '>= 3.0.0'
|
21
|
+
spec.add_dependency 'letsencrypt-cli', '>= 0.1.4'
|
22
|
+
|
23
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
24
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
load File.expand_path('../tasks/lets-encrypt.rake', __FILE__)
|
@@ -0,0 +1,190 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'letsencrypt/cli/acme_wrapper'
|
3
|
+
|
4
|
+
namespace :lets_encrypt do
|
5
|
+
|
6
|
+
desc 'Register Let\' Encrypt account with email'
|
7
|
+
task :register do
|
8
|
+
email = fetch(:lets_encrypt_email)
|
9
|
+
if email.nil? || email == ""
|
10
|
+
wrapper.log "no E-Mail specified!", :fatal
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
if !email[/.*@.*/]
|
14
|
+
wrapper.log "not an email", :fatal
|
15
|
+
exit 1
|
16
|
+
end
|
17
|
+
registration = client.register(contact: "mailto:" + email)
|
18
|
+
registration.agree_terms
|
19
|
+
wrapper.log "Account created, Terms accepted"
|
20
|
+
end
|
21
|
+
|
22
|
+
desc 'Check if the certificate are valid'
|
23
|
+
task :check_certificate do
|
24
|
+
on roles(fetch(:lets_encrypt_roles)) do
|
25
|
+
check_certificate
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
desc 'Authorize the domain using the ACME challenge'
|
30
|
+
task :authorize do
|
31
|
+
on roles(fetch(:lets_encrypt_roles), select: :primary) do
|
32
|
+
unless check_certificate
|
33
|
+
domains.each do |domain|
|
34
|
+
authorize(domain)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
desc "create certificate and private key pair for domains. The first domain is the main CN domain"
|
41
|
+
task :cert do
|
42
|
+
cert(domains)
|
43
|
+
on roles(fetch(:lets_encrypt_roles)) do
|
44
|
+
domains.each do |domain|
|
45
|
+
upload_certs domain
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# On server methods
|
51
|
+
|
52
|
+
def check_certificate
|
53
|
+
if test("[ -f #{certificate_path} ]")
|
54
|
+
temp_path = "/tmp/#{primary_domain}.cert.pem"
|
55
|
+
download! certificate_path, temp_path
|
56
|
+
wrapper.check_certificate(temp_path)
|
57
|
+
else
|
58
|
+
wrapper.log "No certificate found"
|
59
|
+
false
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def authorize(domain)
|
64
|
+
wrapper.log "Authorizing #{domain.blue}."
|
65
|
+
authorization = client.authorize(domain: domain)
|
66
|
+
|
67
|
+
challenge = authorization.http01
|
68
|
+
challenge_public_path = fetch(:lets_encrypt_challenge_public_path)
|
69
|
+
challenge_path = File.join(challenge_public_path, File.dirname(challenge.filename))
|
70
|
+
challenge_file_path = File.join(challenge_public_path, challenge.filename)
|
71
|
+
execute :mkdir, '-pv', challenge_path
|
72
|
+
|
73
|
+
wrapper.log "Writing challenge to #{challenge_file_path}", :debug
|
74
|
+
|
75
|
+
execute :echo, "\"#{challenge.file_content}\" > #{challenge_file_path}"
|
76
|
+
|
77
|
+
challenge.request_verification
|
78
|
+
|
79
|
+
5.times do
|
80
|
+
wrapper.log "Checking verification...", :debug
|
81
|
+
sleep 1
|
82
|
+
break if challenge.verify_status != 'pending'
|
83
|
+
end
|
84
|
+
if challenge.verify_status == 'valid'
|
85
|
+
wrapper.log "Authorization successful for #{domain.green}"
|
86
|
+
execute :rm, '-f', challenge_file_path
|
87
|
+
true
|
88
|
+
else
|
89
|
+
wrapper.log "Authorization error for #{domain.red}", :error
|
90
|
+
wrapper.log challenge.error['detail']
|
91
|
+
false
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def cert(domains)
|
96
|
+
domains.each do |domain|
|
97
|
+
FileUtils.mkdir_p(local_out_path(domain))
|
98
|
+
end
|
99
|
+
wrapper.cert(domains)
|
100
|
+
end
|
101
|
+
|
102
|
+
def upload_certs(domain)
|
103
|
+
execute :mkdir, '-pv', "#{fetch(:lets_encrypt_output_path)}/#{domain}"
|
104
|
+
upload! local_private_key_path, private_key_path
|
105
|
+
upload! local_fullchain_path, fullchain_path
|
106
|
+
upload! local_certificate_path, certificate_path
|
107
|
+
upload! local_chain_path, chain_path
|
108
|
+
end
|
109
|
+
|
110
|
+
# Helpers
|
111
|
+
def certificate_path(domain = primary_domain)
|
112
|
+
File.join(fetch(:lets_encrypt_output_path), domain, "cert.pem")
|
113
|
+
end
|
114
|
+
|
115
|
+
def chain_path(domain = primary_domain)
|
116
|
+
File.join(fetch(:lets_encrypt_output_path), domain, "chain.pem")
|
117
|
+
end
|
118
|
+
|
119
|
+
def fullchain_path(domain = primary_domain)
|
120
|
+
File.join(fetch(:lets_encrypt_output_path), domain, "fullchain.pem")
|
121
|
+
end
|
122
|
+
|
123
|
+
def private_key_path(domain = primary_domain)
|
124
|
+
File.join(fetch(:lets_encrypt_output_path), domain, "key.pem")
|
125
|
+
end
|
126
|
+
|
127
|
+
def local_certificate_path(domain = primary_domain)
|
128
|
+
File.join(local_out_path(domain), "cert.pem")
|
129
|
+
end
|
130
|
+
|
131
|
+
def local_chain_path(domain = primary_domain)
|
132
|
+
File.join(local_out_path(domain), "chain.pem")
|
133
|
+
end
|
134
|
+
|
135
|
+
def local_fullchain_path(domain = primary_domain)
|
136
|
+
File.join(local_out_path(domain), "fullchain.pem")
|
137
|
+
end
|
138
|
+
|
139
|
+
def local_private_key_path(domain = primary_domain)
|
140
|
+
File.join(local_out_path(domain), "key.pem")
|
141
|
+
end
|
142
|
+
|
143
|
+
def local_out_path(domain = primary_domain)
|
144
|
+
File.join(File.expand_path(fetch(:lets_encrypt_local_output_path)), domain)
|
145
|
+
end
|
146
|
+
|
147
|
+
def domains
|
148
|
+
fetch(:lets_encrypt_domains).split(" ")
|
149
|
+
end
|
150
|
+
|
151
|
+
def primary_domain
|
152
|
+
domains.first
|
153
|
+
end
|
154
|
+
|
155
|
+
def wrapper
|
156
|
+
@wrapper ||= AcmeWrapper.new(options)
|
157
|
+
end
|
158
|
+
|
159
|
+
def options
|
160
|
+
@options ||= {
|
161
|
+
account_key: fetch(:lets_encrypt_account_key),
|
162
|
+
test: fetch(:lets_encrypt_test),
|
163
|
+
log_level: "info",
|
164
|
+
color: true,
|
165
|
+
days_valid: fetch(:lets_encrypt_days_valid),
|
166
|
+
private_key_path: local_private_key_path,
|
167
|
+
fullchain_path: local_fullchain_path,
|
168
|
+
certificate_path: local_certificate_path,
|
169
|
+
chain_path: local_chain_path,
|
170
|
+
}
|
171
|
+
end
|
172
|
+
|
173
|
+
def client
|
174
|
+
@client ||= wrapper.client
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
namespace :load do
|
179
|
+
task :defaults do
|
180
|
+
set :lets_encrypt_roles, -> { :web }
|
181
|
+
set :lets_encrypt_test, -> { false }
|
182
|
+
set :lets_encrypt_email, -> { nil }
|
183
|
+
set :lets_encrypt_domains, -> { nil }
|
184
|
+
set :lets_encrypt_challenge_public_path, -> { "#{release_path}/public" }
|
185
|
+
set :lets_encrypt_output_path, -> { "#{shared_path}/ssl/certs" }
|
186
|
+
set :lets_encrypt_account_key, -> { "#{fetch(:lets_encrypt_email)}.account_key.pem" }
|
187
|
+
set :lets_encrypt_days_valid, -> { 30 }
|
188
|
+
set :lets_encrypt_local_output_path, -> { "~/certs" }
|
189
|
+
end
|
190
|
+
end
|
File without changes
|
metadata
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: capistrano-lets-encrypt
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Juan Ignacio Donoso
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-12-24 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: capistrano
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 3.0.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 3.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: letsencrypt-cli
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.1.4
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.1.4
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
description: Adds support for let's encrypt to Capistrano 3.x
|
56
|
+
email:
|
57
|
+
- juan.ignacio@platan.us
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- .gitignore
|
63
|
+
- Gemfile
|
64
|
+
- LICENSE.txt
|
65
|
+
- README.md
|
66
|
+
- Rakefile
|
67
|
+
- capistrano-lets-encrypt.gemspec
|
68
|
+
- lib/capistrano-lets-encrypt.rb
|
69
|
+
- lib/capistrano/lets-encrypt.rb
|
70
|
+
- lib/capistrano/tasks/lets-encrypt.rake
|
71
|
+
homepage: ''
|
72
|
+
licenses:
|
73
|
+
- MIT
|
74
|
+
metadata: {}
|
75
|
+
post_install_message:
|
76
|
+
rdoc_options: []
|
77
|
+
require_paths:
|
78
|
+
- lib
|
79
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - '>='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - '>='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
requirements: []
|
90
|
+
rubyforge_project:
|
91
|
+
rubygems_version: 2.4.8
|
92
|
+
signing_key:
|
93
|
+
specification_version: 4
|
94
|
+
summary: Adds support for let's encrypt to Capistrano 3.x
|
95
|
+
test_files: []
|
96
|
+
has_rdoc:
|