acmesmith 0.7.0.beta1 → 0.8.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: c4a9da6141839cd8a3b4850091f05ab7e024a252
4
- data.tar.gz: 64807174e4ee28afd2a4be93d7ae8cbcdcf8cde1
3
+ metadata.gz: 51baf45477f91b7ca8981c3e8da445348f44528f
4
+ data.tar.gz: 7ec32294fede6b7dd89e6f651e25dcb967d6a878
5
5
  SHA512:
6
- metadata.gz: 1be84d5808225cf30cd6dc324a4a7924f1dacfdb310cc5872e7bdfa74d12ef93e7de5c234ba9ad4fe0679ce03ded44e832a66065544cb9dd808360fb7da4e5a3
7
- data.tar.gz: 549065d60f3774ab1ef4be20da4b90d4f02f0e7b13af912b62128c65026ae5c1fb76880754251a3b69a929fe2d3a1581c8d09f5a8184829c57c33e317d875d4c
6
+ metadata.gz: 2deb54d234db5b03fa4b989e84b31a199973896daae57d8da3353e829f0dec3c094332837bebaba2dc9f1597a36d6516aa7da009352d66170c4b045d50e26d86
7
+ data.tar.gz: 4764a56467552cf763878b1857ef5989a2162cbb3013a1e28aa7ed3f343e849bb02cb6470414dbfc6af0073b7dfb86172d98847237b6bcd9b4a9fb58cbc9e967
data/README.md CHANGED
@@ -146,7 +146,9 @@ when a new certificate has been succesfully issued. The hooks are
146
146
  sequentially executed in the same order as they are configured, and they
147
147
  are configurable per certificate's common-name.
148
148
 
149
- Currently `shell` action is available out of the box. It sets `COMMON_NAME` environment variable for use in a script.
149
+ #### `shell`
150
+
151
+ Execute specified command on a shell. Environment variable `${COMMON_NAME}` is available.
150
152
 
151
153
  ```
152
154
  post_issueing_hooks:
@@ -160,6 +162,21 @@ post_issueing_hooks:
160
162
  command: /usr/bin/dosomethingelse ${COMMON_NAME}
161
163
  ```
162
164
 
165
+ ### `acm`
166
+
167
+ Import certificate into AWS ACM.
168
+
169
+ ```
170
+ post_issueing_hooks:
171
+ "test.example.com":
172
+ - acm:
173
+ region: us-east-1 # required
174
+ certificate_arn: arn:aws:acm:... # (optional)
175
+ ```
176
+
177
+ When `certificate_arn` is not present, `acm` hook attempts to find the certificate ARN from existing certificate list. Certificate with same common name ("domain name" on ACM), and `Acmesmith` tag
178
+ will be used. Otherwise, `acm` hook imports as a new certificate with `Acmesmith` tag.
179
+
163
180
  ## 3rd party Plugins
164
181
 
165
182
  ### Challenge responders
@@ -98,17 +98,15 @@ module Acmesmith
98
98
  cert = Certificate.from_acme_client_certificate(acme_cert)
99
99
  storage.put_certificate(cert, certificate_key_passphrase)
100
100
 
101
- execute_post_issue_hooks(common_name)
102
-
101
+ execute_post_issue_hooks(cert)
102
+
103
103
  cert
104
104
  end
105
105
 
106
- def execute_post_issue_hooks(common_name)
107
- post_issues_hooks_for_common_name = config.post_issueing_hooks(common_name)
108
- if post_issues_hooks_for_common_name
109
- post_issues_hooks_for_common_name.each do |hook|
110
- hook.execute
111
- end
106
+ def execute_post_issue_hooks(certificate)
107
+ hooks = config.post_issueing_hooks(certificate.common_name)
108
+ hooks.each do |hook|
109
+ hook.run(certificate: certificate)
112
110
  end
113
111
  end
114
112
 
@@ -52,16 +52,15 @@ module Acmesmith
52
52
  end
53
53
 
54
54
  def post_issueing_hooks(common_name)
55
- @post_issueing_hooks ||= begin
56
- if @config.key?('post_issueing_hooks') && @config['post_issueing_hooks'].key?(common_name)
57
- specs = @config['post_issueing_hooks'][common_name]
58
- specs.flat_map do |specs_sub|
59
- specs_sub[specs_sub.flatten[0]]['common_name'] = common_name
60
- specs_sub.map do |k, v|
61
- PostIssueingHooks.find(k).new(**v.map{ |k_,v_| [k_.to_sym, v_]}.to_h)
62
- end
55
+ if @config.key?('post_issueing_hooks') && @config['post_issueing_hooks'].key?(common_name)
56
+ specs = @config['post_issueing_hooks'][common_name]
57
+ specs.flat_map do |specs_sub|
58
+ specs_sub.map do |k, v|
59
+ PostIssueingHooks.find(k).new(**v.map{ |k_,v_| [k_.to_sym, v_]}.to_h)
63
60
  end
64
61
  end
62
+ else
63
+ []
65
64
  end
66
65
  end
67
66
 
@@ -0,0 +1,65 @@
1
+ require 'aws-sdk'
2
+ require 'acmesmith/post_issueing_hooks/base'
3
+
4
+ module Acmesmith
5
+ module PostIssueingHooks
6
+ class Acm < Base
7
+ def initialize(certificate_arn: nil, region:)
8
+ @certificate_arn = certificate_arn
9
+ @certificate_arn_set = true if @certificate_arn
10
+ @region = region
11
+ end
12
+
13
+ attr_reader :region
14
+
15
+ def certificate_arn
16
+ return @certificate_arn if @certificate_arn_set
17
+ @certificate_arn ||= find_certificate_arn
18
+ @certificate_arn_set = true
19
+ @certificate_arn
20
+ end
21
+
22
+ def find_certificate_arn
23
+ acm.list_certificates().each do |page|
24
+ page.certificate_summary_list.each do |summary|
25
+ if summary.domain_name == common_name
26
+ tags = acm.list_tags_for_certificate(certificate_arn: summary.certificate_arn).tags
27
+ if tags.find{ |_| _.key == 'Acmesmith' }
28
+ return summary.certificate_arn
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ def acm
36
+ @acm ||= Aws::ACM::Client.new(region: region)
37
+ end
38
+
39
+ def execute
40
+ puts "=> Importing certificate CN=#{common_name} into AWS ACM (region=#{region})"
41
+ if certificate_arn
42
+ puts " * updating ARN: #{certificate_arn}"
43
+ else
44
+ puts " * Importing as as new certificate"
45
+ end
46
+
47
+ resp = acm.import_certificate(
48
+ {
49
+ certificate: certificate.certificate.to_pem,
50
+ private_key: certificate.private_key.to_pem,
51
+ certificate_chain: certificate.chain,
52
+ }.merge(certificate_arn ? {certificate_arn: certificate_arn} : {})
53
+ )
54
+ unless certificate_arn
55
+ puts " * ARN: #{resp.certificate_arn}"
56
+ end
57
+
58
+ acm.add_tags_to_certificate(
59
+ certificate_arn: resp.certificate_arn,
60
+ tags: [key: 'Acmesmith', value: '1'],
61
+ )
62
+ end
63
+ end
64
+ end
65
+ end
@@ -1,13 +1,20 @@
1
1
  module Acmesmith
2
2
  module PostIssueingHooks
3
3
  class Base
4
- def initialize
4
+ attr_reader :certificate
5
+
6
+ def common_name
7
+ certificate.common_name
5
8
  end
6
9
 
7
- def execute(domain)
8
- raise NotImplementedError
10
+ def run(certificate:)
11
+ @certificate = certificate
12
+ execute
9
13
  end
10
14
 
15
+ def execute
16
+ raise NotImplementedError
17
+ end
11
18
  end
12
19
  end
13
20
  end
@@ -4,27 +4,22 @@ require 'acmesmith/post_issueing_hooks/base'
4
4
  module Acmesmith
5
5
  module PostIssueingHooks
6
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
7
+ def initialize(command:, ignore_failure: false)
12
8
  @command = command
13
9
  @ignore_failure = ignore_failure
14
10
  end
15
11
 
16
12
  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}"
13
+ puts "=> Executing Post Issueing Hook for #{common_name} in #{self.class.name}"
14
+ puts " $ #{@command}"
20
15
 
21
- status = system({"COMMON_NAME" => @common_name}, "#{@command};")
16
+ status = system({"COMMON_NAME" => common_name}, @command)
22
17
 
23
18
  unless status
24
19
  if @ignore_failure
25
- $stderr.puts "WARNING, command failed"
20
+ $stderr.puts " ! execution failed"
26
21
  else
27
- raise "FATAL, command failed"
22
+ raise "Execution failed"
28
23
  end
29
24
  end
30
25
  end
@@ -1,3 +1,3 @@
1
1
  module Acmesmith
2
- VERSION = "0.7.0.beta1"
2
+ VERSION = "0.8.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.7.0.beta1
4
+ version: 0.8.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: 2017-07-03 00:00:00.000000000 Z
11
+ date: 2017-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: acme-client
@@ -128,6 +128,7 @@ files:
128
128
  - lib/acmesmith/command.rb
129
129
  - lib/acmesmith/config.rb
130
130
  - lib/acmesmith/post_issueing_hooks.rb
131
+ - lib/acmesmith/post_issueing_hooks/acm.rb
131
132
  - lib/acmesmith/post_issueing_hooks/base.rb
132
133
  - lib/acmesmith/post_issueing_hooks/shell.rb
133
134
  - lib/acmesmith/storages.rb
@@ -153,9 +154,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
153
154
  version: '0'
154
155
  required_rubygems_version: !ruby/object:Gem::Requirement
155
156
  requirements:
156
- - - ">"
157
+ - - ">="
157
158
  - !ruby/object:Gem::Version
158
- version: 1.3.1
159
+ version: '0'
159
160
  requirements: []
160
161
  rubyforge_project:
161
162
  rubygems_version: 2.6.11