acmesmith 0.4.2 → 0.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 881527f31c9c553cd24f871fdf3096f69d9ae7ae
4
- data.tar.gz: 5baeb24754042ddbfbe1cd64f15e7c617d293770
3
+ metadata.gz: acb392ec6aa3ec962ef269435f61e0eee59191bb
4
+ data.tar.gz: 54e3498de72de66e12af34fd7cdeafeb0aad6530
5
5
  SHA512:
6
- metadata.gz: 2334b213b01c42a9a751bf7264b66b2c154363c3fd01ec6977b4c519609177cb6dfeb0aa971942553a4bc449b2a5fae39694db557853750884dce2620b6ed225
7
- data.tar.gz: eef530c96908705825f82fed413f36fd86e59eb5449471ab1e088ca8854b4fa5b2c9bc8aa4383e39120cd6df5bd367d84c38758c3fbf3a2e64f2dcaaa8832f10
6
+ metadata.gz: 7c9d77926eb2cca01db936ac89cacdf6b71779f743c0af3dbeeeb43af781bb62f065e20e65b0e44fdfc93a2c0f4c84f9a597d112c1d482cf645d45495170d6b7
7
+ data.tar.gz: 2ca4345dc71166a781b58e869c4fb3dd086f29fb118c3d54d1329be2c28810ea1901d6ca1389ff0ca2476769a18f3abfb2b0040f032836a713505dbb2ae85822
data/README.md CHANGED
@@ -10,12 +10,10 @@ This tool is written in Ruby, but Acmesmith saves certificates in simple scheme,
10
10
  - ACME registration, domain authorization, certificate requests
11
11
  - Tested against [Let's encrypt](https://letsencrypt.org)
12
12
  - Storing keys in several ways
13
- - Currently AWS S3 is supported
14
13
  - Challenge response
15
- - Currently `dns-01` with AWS Route 53 is supported
16
- - Pluggable modules, you can use 3rd party one or write:
17
- - Storages for other than AWS S3
18
- - Challenge reponses for other than AWS Route53 or dns-01 challenges, like for Openstack DNSaaS.
14
+ - Many cloud services support
15
+ - AWS S3 storage and Route53 `dns-01` responder support out-of-the-box
16
+ - 3rd party plugins available for OpenStack designate, Google Cloud DNS, simple http-01, and Google Cloud Storage. See [Plugins](#3rd-party-plugins) below
19
17
 
20
18
  ### Planned
21
19
 
@@ -141,12 +139,34 @@ challenge_responders:
141
139
  # "example.org.": "/hostedzone/DEADBEEF"
142
140
  ```
143
141
 
142
+ ### Post Issueing Hooks
143
+
144
+ Post issueing hooks are configurable actions that are executed
145
+ when a new certificate has been succesfully issued. The hooks are
146
+ sequentially executed in the same order as they are configured, and they
147
+ are configurable per certificate's common-name.
148
+
149
+ Currently `shell` action is available out of the box. It sets `COMMON_NAME` environment variable for use in a script.
150
+
151
+ ```
152
+ post_issueing_hooks:
153
+ "test.example.com":
154
+ - shell:
155
+ command: mail -s "New cert for ${COMMON_NAME} has been issued" user@example.com < /dev/null
156
+ - shell:
157
+ command: touch /tmp/certs-has-been-issued-${COMMON_NAME}
158
+ "admin.example.com":
159
+ - shell:
160
+ command: /usr/bin/dosomethingelse ${COMMON_NAME}
161
+ ```
162
+
144
163
  ## 3rd party Plugins
145
164
 
146
165
  ### Challenge responders
147
166
 
148
167
  - [hanazuki/acmesmith-designate](https://github.com/hanazuki/acmesmith-designate) `dns-01` challenge responder with OpenStack-based DNSaaS (Designate v1 API), e.g. for ConoHa.
149
168
  - [nagachika/acmesmith-google-cloud-dns](https://github.com/nagachika/acmesmith-google-cloud-dns) `dns-01` challenge responder with [Google Cloud DNS](https://cloud.google.com/dns/).
169
+ - [mipmip/acmesmith-http-path](https://github.com/mipmip/acmesmith-http-path) - `http-01` challenge reponder if you have write access to the vhost server root.
150
170
 
151
171
  ### Storage
152
172
 
@@ -64,7 +64,15 @@ module Acmesmith
64
64
 
65
65
  puts cert.certificate.to_text
66
66
  puts cert.certificate.to_pem
67
+
68
+ execute_post_issue_hooks(common_name)
69
+ end
70
+
71
+ desc "post-issue-hooks COMMON_NAME", "Run all post-issueing hooks for common name. (for testing purpose)"
72
+ def post_issue_hooks(common_name)
73
+ execute_post_issue_hooks(common_name)
67
74
  end
75
+ map 'post-issue-hooks' => :post_issue_hooks
68
76
 
69
77
  desc "list [COMMON_NAME]", "list certificates or its versions"
70
78
  def list(common_name = nil)
@@ -156,7 +164,7 @@ module Acmesmith
156
164
  end
157
165
 
158
166
  desc "autorenew", "request renewal of certificates which expires soon"
159
- method_option :days, aliases: %w(-d), default: 7, desc: 'specify threshold in days to select certificates to renew'
167
+ method_option :days, type: :numeric, aliases: %w(-d), default: 7, desc: 'specify threshold in days to select certificates to renew'
160
168
  def autorenew
161
169
  storage.list_certificates.each do |cn|
162
170
  puts "=> #{cn}"
@@ -214,5 +222,15 @@ module Acmesmith
214
222
  config['account_key_passphrase']
215
223
  end
216
224
  end
225
+
226
+ def execute_post_issue_hooks(common_name)
227
+ post_issues_hooks_for_common_name = config.post_issueing_hooks(common_name)
228
+ if post_issues_hooks_for_common_name
229
+ post_issues_hooks_for_common_name.each do |hook|
230
+ hook.execute
231
+ end
232
+ end
233
+ end
234
+
217
235
  end
218
236
  end
@@ -1,6 +1,7 @@
1
1
  require 'yaml'
2
2
  require 'acmesmith/storages'
3
3
  require 'acmesmith/challenge_responders'
4
+ require 'acmesmith/post_issueing_hooks'
4
5
 
5
6
  module Acmesmith
6
7
  class Config
@@ -42,8 +43,22 @@ module Acmesmith
42
43
  end
43
44
  end
44
45
 
46
+ def post_issueing_hooks(common_name)
47
+ @post_issueing_hooks ||= begin
48
+ if @config.key?('post_issueing_hooks') && @config['post_issueing_hooks'].key?(common_name)
49
+ specs = @config['post_issueing_hooks'][common_name]
50
+ specs.flat_map do |specs_sub|
51
+ specs_sub[specs_sub.flatten[0]]['common_name'] = common_name
52
+ specs_sub.map do |k, v|
53
+ PostIssueingHooks.find(k).new(**v.map{ |k_,v_| [k_.to_sym, v_]}.to_h)
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+
45
60
  def challenge_responders
46
- @challange_responders ||= begin
61
+ @challenge_responders ||= begin
47
62
  specs = @config['challenge_responders'].kind_of?(Hash) ? @config['challenge_responders'].map { |k,v| [k => v] } : @config['challenge_responders']
48
63
  specs.flat_map do |specs_sub|
49
64
  specs_sub.map do |k, v|
@@ -0,0 +1,14 @@
1
+ module Acmesmith
2
+ module PostIssueingHooks
3
+ class Base
4
+ def initialize
5
+ end
6
+
7
+ def execute(domain)
8
+ raise NotImplementedError
9
+ end
10
+
11
+ end
12
+ end
13
+ end
14
+
@@ -0,0 +1,33 @@
1
+ require 'open3'
2
+ require 'acmesmith/post_issueing_hooks/base'
3
+
4
+ module Acmesmith
5
+ module PostIssueingHooks
6
+ class Shell < Base
7
+ class HostedZoneNotFound < StandardError; end
8
+ class AmbiguousHostedZones < StandardError; end
9
+
10
+ def initialize(common_name:, command:, ignore_failure:false)
11
+ @common_name = common_name
12
+ @command = command
13
+ @ignore_failure = ignore_failure
14
+ end
15
+
16
+ def execute
17
+ puts "=> Executing Post Issueing Hook for #{@common_name} in #{self.class.name}"
18
+ puts "=> ENV: COMMON_NAME=#{@common_name}"
19
+ puts "=> Running: #{@command}"
20
+
21
+ status = system({"COMMON_NAME" => @common_name}, "#{@command};")
22
+
23
+ unless status
24
+ if @ignore_failure
25
+ $stderr.puts "WARNING, command failed"
26
+ else
27
+ raise "FATAL, command failed"
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,9 @@
1
+ require 'acmesmith/utils/finder'
2
+
3
+ module Acmesmith
4
+ module PostIssueingHooks
5
+ def self.find(name)
6
+ Utils::Finder.find(self, 'acmesmith/post_issueing_hooks', name)
7
+ end
8
+ end
9
+ end
@@ -1,3 +1,3 @@
1
1
  module Acmesmith
2
- VERSION = "0.4.2"
2
+ VERSION = "0.5.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acmesmith
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - sorah (Shota Fukumori)
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-27 00:00:00.000000000 Z
11
+ date: 2017-01-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: acme-client
@@ -126,6 +126,9 @@ files:
126
126
  - lib/acmesmith/challenge_responders/route53.rb
127
127
  - lib/acmesmith/command.rb
128
128
  - lib/acmesmith/config.rb
129
+ - lib/acmesmith/post_issueing_hooks.rb
130
+ - lib/acmesmith/post_issueing_hooks/base.rb
131
+ - lib/acmesmith/post_issueing_hooks/shell.rb
129
132
  - lib/acmesmith/storages.rb
130
133
  - lib/acmesmith/storages/base.rb
131
134
  - lib/acmesmith/storages/filesystem.rb
@@ -154,7 +157,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
154
157
  version: '0'
155
158
  requirements: []
156
159
  rubyforge_project:
157
- rubygems_version: 2.6.4
160
+ rubygems_version: 2.6.8
158
161
  signing_key:
159
162
  specification_version: 4
160
163
  summary: ACME client (Let's encrypt client) to manage certificate in multi server