acmesmith 2.2.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 428d6ec71e91259de56ffd77471e823c9673eb9002e8c1bb419875f57f9086e3
4
- data.tar.gz: c85d4efa0fd6a36b04ea1fbfbd346a055426a1fdb818c5c7f25d28d4073f8b56
3
+ metadata.gz: 0dd12b4a45a6d9a46c3c3b6c55cd2918e534da57e25293b2b40f06b5e5faeea3
4
+ data.tar.gz: 6edaf583cdb673a28b4d549a7c7d2636a867365afe59482d34f79c28e0a60900
5
5
  SHA512:
6
- metadata.gz: f748341d751c06fe73c17e25c381979e6c77700a5df8bed4978fbfb5563e767d94a73cbfb5bc403cd60516e94fdf34af79b43c0ec3dcd82340e96c776a3cef70
7
- data.tar.gz: f25125c00a446baa23f7025594096081a2ddd10c920d8602b8df8eb8bac0def9bb6ea63ae00d984124dc5a306d79e86faf386135e9f4281ddf28cb77b8094918
6
+ metadata.gz: c00d5e1e8ad23acca150df071027c64e030429167b29bd25bd3347a19c558836ec9cf25405bc2e0493541e027f568a1e63f688894b40753774de76fefcd01e72
7
+ data.tar.gz: f0c02fbec4d3572499321be2279384ea9424b20a43166ea536c208d3cb3332de4841537c944bfd9664ba596e5da154645fc3d6cb4dc207c346740e5a5d4a086d
data/.dockerignore ADDED
@@ -0,0 +1,6 @@
1
+ .git/
2
+ pkg/
3
+ .bundle/
4
+ vendor/
5
+ acmesmith.yml
6
+ config*yml
@@ -0,0 +1,123 @@
1
+ name: ci
2
+ on:
3
+ schedule:
4
+ - cron: '36 7 2,12,22 * *'
5
+ release:
6
+ types: [published]
7
+ pull_request:
8
+ branches: [master]
9
+ push:
10
+ branches: [master, ci-test]
11
+
12
+ env:
13
+ DOCKER_REPO: 'sorah/ruby'
14
+
15
+ jobs:
16
+ test:
17
+ name: rspec
18
+ runs-on: ubuntu-latest
19
+ strategy:
20
+ fail-fast: false
21
+ matrix:
22
+ ruby-version: ['2.6', '2.7']
23
+ container:
24
+ image: sorah/ruby:${{ matrix.ruby-version }}-dev
25
+ steps:
26
+
27
+ - name: Cache bundled gems
28
+ uses: actions/cache@v1
29
+ id: rspec-bundle
30
+ with:
31
+ path: ~/bundle
32
+ key: ${{ runner.os }}-${{ matrix.ruby-version }}
33
+
34
+ - uses: actions/checkout@master
35
+ - run: 'bundle install --path ~/bundle'
36
+ - run: 'bundle exec rspec -fd'
37
+
38
+ integration-pebble:
39
+ name: integration-pebble
40
+ runs-on: ubuntu-latest
41
+ strategy:
42
+ fail-fast: false
43
+ matrix:
44
+ ruby-version: ['2.6', '2.7']
45
+
46
+ # FIXME: once GitHub Actions gains support of adding command line arguments to container
47
+ # services:
48
+ # # https://github.com/letsencrypt/pebble
49
+ # pebble:
50
+ # image: letsencrypt/pebble
51
+ # ports:
52
+ # - 14000:14000 # ACME port
53
+ # - 15000:15000 # Management port
54
+ # options: "pebble -config /test/config/pebble-config.json -strict -dnsserver 127.0.0.1:8053"
55
+ #
56
+ # challtestsrv:
57
+ # image: letsencrypt/pebble-challtestsrv:latest
58
+ # ports:
59
+ # - 8055:8055 # HTTP Management API
60
+ # - 8053:8053/udp # DNS
61
+ # - 8053:8053 # DNS
62
+ # options: 'pebble-challtestsrv -management :8055 -defaultIPv4 127.0.0.1'
63
+
64
+ steps:
65
+ - uses: actions/checkout@master
66
+
67
+ - name: Cache bundled gems
68
+ uses: actions/cache@v1
69
+ id: instegration-pebble-bundle
70
+ with:
71
+ path: ~/bundle
72
+ key: ${{ runner.os }}-${{ matrix.ruby-version }}
73
+
74
+ - run: 'docker run -d --net=host --rm letsencrypt/pebble pebble -config /test/config/pebble-config.json -strict -dnsserver 127.0.0.1:8053'
75
+ - run: 'docker run -d --net=host --rm letsencrypt/pebble-challtestsrv pebble-challtestsrv -management :8055 -defaultIPv4 127.0.0.1'
76
+ - run: 'docker run --net=host -e CI --rm -v $(pwd):/work -v $(realpath ~/bundle):/bundle sorah/ruby:${{ matrix.ruby-version }}-dev sh -c "cd /work && bundle install --path /bundle && bundle exec rspec -fd -t integration_pebble"'
77
+
78
+ docker-build:
79
+ name: docker-build
80
+ runs-on: ubuntu-latest
81
+ steps:
82
+ - uses: actions/checkout@master
83
+ - run: 'echo $GITHUB_SHA > REVISION'
84
+
85
+ - run: "docker pull ${DOCKER_REPO}:latest || :"
86
+ - name: "docker tag ${DOCKER_REPO}:${TAG} ${DOCKER_REPO}:latest"
87
+ run: |
88
+ TAG=$(basename "${{ github.ref }}")
89
+ docker pull ${DOCKER_REPO}:${TAG}
90
+ docker tag ${DOCKER_REPO}:${TAG} ${DOCKER_REPO}:latest
91
+ if: "${{ startsWith(github.ref, 'refs/tags/v') }}"
92
+
93
+ - run: "docker pull ${DOCKER_REPO}:builder || :"
94
+
95
+ - run: "docker build --pull --cache-from ${DOCKER_REPO}:builder --target builder -t ${DOCKER_REPO}:builder -f Dockerfile ."
96
+ - run: "docker build --pull --cache-from ${DOCKER_REPO}:builder --cache-from ${DOCKER_REPO}:latest -t ${DOCKER_REPO}:${GITHUB_SHA} -f Dockerfile ."
97
+
98
+ - run: "echo ${{ secrets.DOCKERHUB_TOKEN }} | docker login -u sorah --password-stdin"
99
+ if: "${{ github.event_name != 'pull_request' }}"
100
+
101
+ - run: "docker push ${DOCKER_REPO}:builder"
102
+ if: "${{ github.ref == 'refs/heads/master' }}"
103
+ - run: "docker push ${DOCKER_REPO}:${GITHUB_SHA}"
104
+ if: "${{ github.event_name != 'pull_request' }}"
105
+
106
+ docker-push:
107
+ name: docker-push
108
+ needs: [test, integration-pebble, docker-build]
109
+ if: "${{ github.event_name == 'push' || github.event_name == 'release' }}"
110
+ runs-on: ubuntu-latest
111
+ steps:
112
+ - run: "echo ${{ secrets.DOCKERHUB_TOKEN }} | docker login -u sorah --password-stdin"
113
+ - run: "docker pull ${DOCKER_REPO}:${GITHUB_SHA}"
114
+
115
+ - run: |
116
+ docker tag ${DOCKER_REPO}:${GITHUB_SHA} ${DOCKER_REPO}:latest
117
+ docker push ${DOCKER_REPO}:latest
118
+ if: "${{ github.ref == 'refs/heads/master' }}"
119
+ - run: |
120
+ TAG=$(basename "${{ github.ref }}")
121
+ docker tag ${DOCKER_REPO}:${GITHUB_SHA} ${DOCKER_REPO}:${TAG}
122
+ docker push ${DOCKER_REPO}:${TAG}
123
+ if: "${{ startsWith(github.ref, 'refs/tags/v') }}"
data/.gitignore CHANGED
@@ -1,6 +1,5 @@
1
1
  /.bundle/
2
2
  /.yardoc
3
- /Gemfile.lock
4
3
  /_yardoc/
5
4
  /coverage/
6
5
  /doc/
data/CHANGELOG.md CHANGED
@@ -1,3 +1,38 @@
1
+ ## v2.3.0 (2020-05-12)
2
+
3
+ ### Enhancement
4
+
5
+ - route53: Added support of assuming IAM Role to access Route 53. (requested at [#36](https://github.com/sorah/acmesmith/issues/36) [#37](https://github.com/sorah/acmesmith/pull/37) [#38](https://github.com/sorah/acmesmith/issues/36))
6
+
7
+ - Added filter for challenge responders. This allows selecting a challenge responder for specific domain names. (indirectly requested at [#36](https://github.com/sorah/acmesmith/issues/36) [#37](https://github.com/sorah/acmesmith/pull/37) [#38](https://github.com/sorah/acmesmith/issues/36))
8
+
9
+ ```yaml
10
+ challenge_responders:
11
+ # Use specific IAM role for the domain "example.dev" ...
12
+ - route53:
13
+ assume_role:
14
+ role_arn: 'arn:aws:iam:...'
15
+ filter:
16
+ subject_name_exact:
17
+ - example.dev
18
+
19
+ - manual_dns: {}
20
+ filter:
21
+ subject_name_suffix:
22
+ - example.net
23
+
24
+ # Default
25
+ - route53: {}
26
+ ```
27
+
28
+ - config: now accepts `connection_options` and `bad_nonce_retry` for [`Acme::Client`](https://github.com/unixcharles/acme-client).
29
+
30
+ ### Fixes
31
+
32
+ - Exported PKCS#12 were not included a certificate chain [#35](https://github.com/sorah/acmesmith/pulls/35)
33
+ - s3: `use_kms` option was not respected for certificate keys & PKCS#12. It was always `true`.
34
+ - A large refactoring of internal components.
35
+
1
36
  ## v2.2.0 (2018-08-08)
2
37
 
3
38
  ### Enhancement
data/Dockerfile ADDED
@@ -0,0 +1,29 @@
1
+ FROM sorah/ruby:2.7-dev as builder
2
+
3
+ #RUN apt-get update \
4
+ # && apt-get install -y libmysqlclient-dev git-core \
5
+ # && rm -rf /var/lib/apt/lists/*
6
+
7
+ WORKDIR /app
8
+ COPY Gemfile /app/
9
+ COPY Gemfile.lock /app/
10
+ COPY acmesmith.gemspec /app/
11
+ RUN sed -i -e 's|Acmesmith::VERSION|"0.0.0"|g' -e '/^require.*acmesmith.version/d' -e '/`git/d' acmesmith.gemspec
12
+
13
+ RUN bundle install --path /gems --jobs 100 --without development
14
+
15
+ FROM sorah/ruby:2.7
16
+
17
+ #RUN apt-get update \
18
+ # && apt-get install -y libmysqlclient20 \
19
+ # && rm -rf /var/lib/apt/lists/*
20
+
21
+ WORKDIR /app
22
+ COPY . /app/
23
+ COPY --from=builder /gems /gems
24
+ COPY --from=builder /app/.bundle /app/.bundle
25
+ COPY --from=builder /app/Gemfile* /app/
26
+ COPY --from=builder /app/acmesmith.gemspec /app/
27
+
28
+ ENTRYPOINT ["bundle", "exec", "bin/acmesmith"]
29
+
data/Gemfile CHANGED
@@ -2,3 +2,5 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in acmesmith.gemspec
4
4
  gemspec
5
+
6
+ gem 'nokogiri'
data/Gemfile.lock ADDED
@@ -0,0 +1,73 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ acmesmith (2.3.0)
5
+ acme-client (~> 2)
6
+ aws-sdk-acm
7
+ aws-sdk-route53
8
+ aws-sdk-s3
9
+ thor
10
+
11
+ GEM
12
+ remote: https://rubygems.org/
13
+ specs:
14
+ acme-client (2.0.6)
15
+ faraday (>= 0.17, < 2.0.0)
16
+ aws-eventstream (1.1.0)
17
+ aws-partitions (1.312.0)
18
+ aws-sdk-acm (1.30.0)
19
+ aws-sdk-core (~> 3, >= 3.71.0)
20
+ aws-sigv4 (~> 1.1)
21
+ aws-sdk-core (3.95.0)
22
+ aws-eventstream (~> 1, >= 1.0.2)
23
+ aws-partitions (~> 1, >= 1.239.0)
24
+ aws-sigv4 (~> 1.1)
25
+ jmespath (~> 1.0)
26
+ aws-sdk-kms (1.31.0)
27
+ aws-sdk-core (~> 3, >= 3.71.0)
28
+ aws-sigv4 (~> 1.1)
29
+ aws-sdk-route53 (1.34.0)
30
+ aws-sdk-core (~> 3, >= 3.71.0)
31
+ aws-sigv4 (~> 1.1)
32
+ aws-sdk-s3 (1.64.0)
33
+ aws-sdk-core (~> 3, >= 3.83.0)
34
+ aws-sdk-kms (~> 1)
35
+ aws-sigv4 (~> 1.1)
36
+ aws-sigv4 (1.1.3)
37
+ aws-eventstream (~> 1.0, >= 1.0.2)
38
+ diff-lcs (1.3)
39
+ faraday (1.0.1)
40
+ multipart-post (>= 1.2, < 3)
41
+ jmespath (1.4.0)
42
+ mini_portile2 (2.4.0)
43
+ multipart-post (2.1.1)
44
+ nokogiri (1.10.9)
45
+ mini_portile2 (~> 2.4.0)
46
+ rake (13.0.1)
47
+ rspec (3.9.0)
48
+ rspec-core (~> 3.9.0)
49
+ rspec-expectations (~> 3.9.0)
50
+ rspec-mocks (~> 3.9.0)
51
+ rspec-core (3.9.2)
52
+ rspec-support (~> 3.9.3)
53
+ rspec-expectations (3.9.2)
54
+ diff-lcs (>= 1.2.0, < 2.0)
55
+ rspec-support (~> 3.9.0)
56
+ rspec-mocks (3.9.1)
57
+ diff-lcs (>= 1.2.0, < 2.0)
58
+ rspec-support (~> 3.9.0)
59
+ rspec-support (3.9.3)
60
+ thor (1.0.1)
61
+
62
+ PLATFORMS
63
+ ruby
64
+
65
+ DEPENDENCIES
66
+ acmesmith!
67
+ bundler
68
+ nokogiri
69
+ rake
70
+ rspec
71
+
72
+ BUNDLED WITH
73
+ 2.1.4
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2016 sorah (Shota Fukumori)
3
+ Copyright (c) 2016 Sorah Fukumori
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Acmesmith: A simple, effective ACME v2 client to use with many servers and a cloud
2
2
 
3
+ ![ci](https://github.com/sorah/acmesmith/workflows/ci/badge.svg?event=push)
4
+
3
5
  Acmesmith is an [ACME (Automatic Certificate Management Environment)](https://github.com/ietf-wg-acme/acme) client that works perfect on environment with multiple servers. This client saves certificate and keys on cloud services (e.g. AWS S3) securely, then allow to deploy issued certificates onto your servers smoothly. This works well on [Let's encrypt](https://letsencrypt.org).
4
6
 
5
7
  This tool is written in Ruby, but Acmesmith saves certificates in simple scheme, so you can fetch certificate by your own simple scripts.
@@ -31,6 +33,17 @@ Or install it yourself as:
31
33
 
32
34
  $ gem install acmesmith
33
35
 
36
+ ### Docker
37
+
38
+ ```
39
+ docker run -v /path/to/acmesmith.yml:/app/acmesmith.yml:ro sorah/acmesmith:latest
40
+ ```
41
+
42
+ [`Dockerfile`](./Dockerfile) is available. Default confguration file is at `/app/acmesmith.yml`.
43
+
44
+ Pre-built docker images are provided at https://hub.docker.com/r/sorah/acmesmith for your convenience
45
+ Built with GitHub Actions & [sorah-rbpkg/dockerfiles](https://github.com/sorah-rbpkg/dockerfiles).
46
+
34
47
  ## Usage
35
48
 
36
49
  ```
@@ -71,76 +84,61 @@ See `acmesmith help [subcommand]` for more help.
71
84
  See [config.sample.yml](./config.sample.yml) to start. Default configuration file is `./acmesmith.yml`.
72
85
 
73
86
  ``` yaml
74
- directory: https://acme-staging-v02.api.letsencrypt.org/directory
75
- # directory: https://acme-v02.api.letsencrypt.org/directory # production
87
+ directory: https://acme-v02.api.letsencrypt.org/directory # production
76
88
 
77
89
  storage:
78
90
  # configure where to store keys and certificates; described later
91
+ type: s3
92
+ region: 'us-east-1'
93
+ bucket: 'my-acmesmith-bucket'
94
+ prefix: 'prod/'
95
+
79
96
  challenge_responders:
80
97
  # configure how to respond ACME challenges; described later
81
-
82
- account_key_passphrase: password
83
- certificate_key_passphrase: secret
98
+ - route53: {}
84
99
  ```
85
100
 
86
101
  ### Storage
87
102
 
88
- #### S3
89
-
90
- ```
91
- storage:
92
- type: s3
93
- region:
94
- bucket:
95
- # prefix:
96
- # aws_access_key: # aws credentials (optional); If omit, default configuration of aws-sdk use will be used.
97
- # access_key_id:
98
- # secret_access_key:
99
- # session_token:
100
- # use_kms: true
101
- # kms_key_id: # KMS key id (optional); if omit, default AWS managed key for S3 will be used
102
- # kms_key_id_account: # KMS key id for account key (optional); This overrides kms_key_id
103
- # kms_key_id_certificate_key: # KMS key id for private keys for certificates (optional); This oveerides kms_key_id
104
- # pkcs12_passphrase: # (optional) Set passphrase to generate PKCS#12 file (for scripts that reads S3 bucket directly)
105
- # pkcs12_common_names: ['example.org'] # (optional) List of common names to limit certificates for generating PKCS#12 file.
106
- ```
107
-
108
- This saves certificates and keys in the following S3 keys:
109
-
110
- - `{prefix}/account.pem`: Account private key in pem
111
- - `{prefix}/certs/{common_name}/current`: text file contains current version name
112
- - `{prefix}/certs/{common_name}/{version}/cert.pem`: certificate in pem
113
- - `{prefix}/certs/{common_name}/{version}/key.pem`: private key in pem
114
- - `{prefix}/certs/{common_name}/{version}/chain.pem`: CA chain in pem
115
- - `{prefix}/certs/{common_name}/{version}/fullchain.pem`: certificate + CA chain in pem. This is suitable for some server softwares like nginx.
103
+ Storage provider stores issued certificates, private keys and ACME account keys.
116
104
 
117
- #### Filesystem
118
-
119
- This is not recommended. If you're planning to use this, make sure backing up the keys.
120
-
121
- ```
122
- storage:
123
- type: filesystem
124
- path: /path/to/directory/to/store/keys
125
- ```
105
+ - Amazon S3: [s3](./docs/storages/s3.md)
106
+ - Filesystem: [filesystem](./docs/storages/filesystem.md)
107
+ - Google Cloud Storage: [minimum2scp/acmesmith-google-cloud-storage](https://github.com/minimum2scp/acmesmith-google-cloud-storage) _(plugin)_
126
108
 
127
109
  ### Challenge Responders
128
110
 
129
111
  Challenge responders responds to ACME challenges to prove domain ownership to CA.
130
112
 
131
- #### Route53
113
+ - API driven
114
+ - AWS Route 53: [route53](./docs/challenge_responders/route53.md) (`dns-01`)
115
+ - Google Cloud DNS: [nagachika/acmesmith-google-cloud-dns](https://github.com/nagachika/acmesmith-google-cloud-dns) (`dns-01`, _plugin_ )
116
+ - OpenStack Designate v1: [hanazuki/acmesmith-designate](https://github.com/hanazuki/acmesmith-designate) (`dns-01`, _plugin_ )
117
+ - Verisign MDNS REST API: [benkap/acmesmith-verisign](https://github.com/benkap/acmesmith-verisign) (`dns-01`, _plugin_ )
118
+ - Generic
119
+ - Static HTTP: [mipmip/acmesmith-http-path](https://github.com/mipmip/acmesmith-http-path) (`http-01`, _plugin_ )
132
120
 
133
- Route53 responder supports `dns-01` challenge type. This assumes domain NS are managed under Route53 hosted zone.
121
+ #### Common options
134
122
 
135
- ```
123
+ ```yaml
136
124
  challenge_responders:
137
- - route53:
138
- # aws_access_key: # aws credentials (optional); If omit, default configuration of aws-sdk use will be used.
139
- # access_key_id:
140
- # secret_access_key:
141
- # session_token:
142
- # hosted_zone_map: # hosted zone map (optional); This is to specify exactly one hosted zone to use. This will be required when there are multiple hosted zone with same domain name. Usually
143
- # "example.org.": "/hostedzone/DEADBEEF"
125
+ ## Multiple responders are accepted.
126
+ ## The first responder that supports a challenge and applicable for given domain name will be used.
127
+ - {RESPONDER_TYPE}:
128
+ {RESPONDER_OPTIONS}
129
+
130
+ ### Filter (optional)
131
+ filter:
132
+ subject_name_exact:
133
+ - my-app.example.com
134
+ subject_name_suffix:
135
+ - .example.org
136
+ subject_name_regexp:
137
+ - '\Aapp\d+.example.org\z'
138
+
139
+ - {RESPONDER_TYPE}:
140
+ {RESPONDER_OPTIONS}
141
+ ...
144
142
  ```
145
143
 
146
144
  ### Post Issuing Hooks
@@ -150,52 +148,40 @@ when a new certificate has been succesfully issued. The hooks are
150
148
  sequentially executed in the same order as they are configured, and they
151
149
  are configurable per certificate's common-name.
152
150
 
153
- #### `shell`
151
+ - Shell script: [shell](./docs/post_issuing_hooks/shell.md)
152
+ - Amazon Certificate Manager (ACM): [acm](./docs/post_issuing_hooks/acm.md)
154
153
 
155
- Execute specified command on a shell. Environment variable `${COMMON_NAME}` is available.
154
+ ## Vendor dependent notes
156
155
 
157
- ```
158
- post_issuing_hooks:
159
- "test.example.com":
160
- - shell:
161
- command: mail -s "New cert for ${COMMON_NAME} has been issued" user@example.com < /dev/null
162
- - shell:
163
- command: touch /tmp/certs-has-been-issued-${COMMON_NAME}
164
- "admin.example.com":
165
- - shell:
166
- command: /usr/bin/dosomethingelse ${COMMON_NAME}
167
- ```
156
+ - [./docs/vendor/aws.md](./docs/vendor/aws.md): IAM and KMS key policies, and some tips
168
157
 
169
- ### `acm`
158
+ ## Contributing
170
159
 
171
- Import certificate into AWS ACM.
160
+ Bug reports and pull requests are welcome on GitHub at https://github.com/sorah/acmesmith.
172
161
 
173
- ```
174
- post_issuing_hooks:
175
- "test.example.com":
176
- - acm:
177
- region: us-east-1 # required
178
- certificate_arn: arn:aws:acm:... # (optional)
179
- ```
162
+ ### Running tests
180
163
 
181
- 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
182
- will be used. Otherwise, `acm` hook imports as a new certificate with `Acmesmith` tag.
164
+ unit test:
183
165
 
184
- ## 3rd party Plugins
166
+ ```
167
+ bundle exec rspec
168
+ ```
185
169
 
186
- ### Challenge responders
170
+ integration test using [letsencrypt/pebble](https://github.com/letsencrypt/pebble). needs Docker:
187
171
 
188
- - [hanazuki/acmesmith-designate](https://github.com/hanazuki/acmesmith-designate) `dns-01` challenge responder with OpenStack-based DNSaaS (Designate v1 API), e.g. for ConoHa.
189
- - [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/).
190
- - [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.
172
+ ```
173
+ ACMESMITH_CI_START_PEBBLE=1 CI=1 bundle exec -t integration_pebble
174
+ ```
191
175
 
192
- ### Storage
176
+ ## Writing plugins
193
177
 
194
- - [minimum2scp/acmesmith-google-cloud-storage](https://github.com/minimum2scp/acmesmith-google-cloud-storage) storage using [Google Cloud Storage](https://cloud.google.com/storage/)
178
+ Publish as a gem (RubyGems). Files will be loaded automatically from `lib/acmesmith/{plugin_type}/{name}.rb`.
195
179
 
196
- ## Vendor dependent notes
180
+ e.g.
197
181
 
198
- - [./docs/vendor/aws.md](./docs/vendor/aws.md): IAM and KMS key policies, and some tips
182
+ - storage: `lib/acmesmith/storages/perfect_storage.rb` & `Acmesmith::Storages::PerfectStorage`
183
+ - challenge_responder: `lib/acmesmith/challenge_responders/perfect_authority.rb` & `Acmesmith::Storages::PerfectAuthority`
184
+ - post_issuing_hook: `lib/acmesmith/challenge_responders/nice_deploy.rb` & `Acmesmith::Storages::NiceDeploy`
199
185
 
200
186
  ## Development
201
187
 
@@ -203,14 +189,6 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
203
189
 
204
190
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
205
191
 
206
- ### Todos
207
-
208
- - Tests
209
- - Support post actions (notifying servers, deploying to somewhere, etc...)
210
-
211
- ## Contributing
212
-
213
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/acmesmith.
214
192
 
215
193
 
216
194
  ## License