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 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
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+
4
+ gem 'pry'
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 [![Gem Version](https://badge.fury.io/rb/capistrano-lets-encrypt.png)](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,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -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: