jekyll-gitlab-letsencrypt 0.0.1
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 +9 -0
- data/.rspec +2 -0
- data/.travis.yml +7 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +24 -0
- data/README.md +126 -0
- data/Rakefile +6 -0
- data/jekyll-gitlab-letsencrypt.gemspec +28 -0
- data/lib/jekyll/commands/gitlab/letsencrypt.rb +17 -0
- data/lib/jekyll/gitlab/letsencrypt.rb +17 -0
- data/lib/jekyll/gitlab/letsencrypt/acme.rb +43 -0
- data/lib/jekyll/gitlab/letsencrypt/committer.rb +76 -0
- data/lib/jekyll/gitlab/letsencrypt/configuration.rb +80 -0
- data/lib/jekyll/gitlab/letsencrypt/process.rb +130 -0
- data/lib/jekyll/gitlab/letsencrypt/version.rb +7 -0
- metadata +171 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: fa8f3feb5f7a37e1c6d6dc0333149e93b3de8886
|
4
|
+
data.tar.gz: 41f642d68eb70f572c443d88065de1ee1cff3211
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1e254b34b02b3791ec81a70e017ac13237b25fd98f0ac092e9dab70676d73730e497e3ebfe45d17c4b97cddc730a07e7f517ed6085e573d027514c061b6cbd6b
|
7
|
+
data.tar.gz: 86ea2abcec1da067c639d63b748a2a60cc6fa661c180de1a8fcd4f556d2e87ae4ed846b7e3b938034a57b49c4f496d79959f27ab8c054d560e015a1f55c7d5c3
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
The MIT License (MIT), with added prohibitions loosely based on http://neveragain.tech/
|
2
|
+
|
3
|
+
Copyright (c) 2017 Justin Aiken
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
- The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
- Use in any kind of the following use cases is expressly prohibited:
|
15
|
+
- Creation of databases of identifying information for the United States government to target individuals based on race, religion, or national origin.
|
16
|
+
- Collection and retention of data that would facilitate ethnic or religious targeting
|
17
|
+
|
18
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
19
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
20
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
21
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
22
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
23
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
24
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
[](http://travis-ci.org/JustinAiken/jekyll-gitlab-letsencrypt) [](https://coveralls.io/r/JustinAiken/jjekyll-gitlab-letsencrypt?branch=master) [](https://codeclimate.com/github/JustinAiken/jekyll-gitlab-letsencrypt)
|
2
|
+
|
3
|
+
# jekyll-gitlab-letsencrypt
|
4
|
+
|
5
|
+
This plugin automagically does 90% of the letsencrypt process for your gitlab-hosted jekyll blog.
|
6
|
+
|
7
|
+
- *(automatic)* It registers your email to the letsencrypt server
|
8
|
+
- *(automatic)* It generates a challenge file, and commits it directly via the gitlab API
|
9
|
+
- *(automatic)* It sleeps until the challenge file is live on the internet
|
10
|
+
- *(automatic)* It asks letsencrypt to verify it
|
11
|
+
- *(automatic)* It spits out the certificate chain and private key
|
12
|
+
- *(manual)* You have to go to the URL provided and manually copy/paste them
|
13
|
+
- This step must be manual since there is no API through Gitlab for this step
|
14
|
+
|
15
|
+
## Usage
|
16
|
+
|
17
|
+
### Prerequisites
|
18
|
+
|
19
|
+
You must have:
|
20
|
+
- A jekyll blog
|
21
|
+
- Hosted on gitlab pages
|
22
|
+
- With a domain name set up and working
|
23
|
+
- Gitlab CI setup such that when you push to `master` (or your preferred branch), your changes are deployed live
|
24
|
+
|
25
|
+
Versions supported:
|
26
|
+
- Jekyll 3+
|
27
|
+
- Ruby 2.1+
|
28
|
+
|
29
|
+
### Installation
|
30
|
+
|
31
|
+
- Add to your Gemfile:
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
group :jekyll_plugins do
|
35
|
+
gem 'jekyll-emojis'
|
36
|
+
gem 'jekyll-more-emojis'
|
37
|
+
++ gem 'jekyll-gitlab-letsencrypt'
|
38
|
+
end
|
39
|
+
```
|
40
|
+
|
41
|
+
and run `bundle install`
|
42
|
+
|
43
|
+
## First-time Configuration
|
44
|
+
|
45
|
+
- Get a personal access token: https://gitlab.com/profile/personal_access_tokens
|
46
|
+
|
47
|
+
Add a `gitlab-letsencrypt` to your `_config.yml`:
|
48
|
+
|
49
|
+
```yaml
|
50
|
+
gitlab-letsencrypt:
|
51
|
+
# Gitlab settings:
|
52
|
+
personal_access_token: 'MUCH SECRET' # Gotten from the step above ^^
|
53
|
+
gitlab_repo: 'gitlab_user/gitlab_repo' # Namespaced repository identifier
|
54
|
+
|
55
|
+
# Domain settings:
|
56
|
+
email: 'example@example.com' # Let's Encrypt email address
|
57
|
+
domain: 'example.com' # Domain that the cert will be issued for
|
58
|
+
|
59
|
+
# Jekyll settings:
|
60
|
+
base_path: './' # Where you want the file to go
|
61
|
+
pretty_url: false # Add a "/" on the end of the URL... set to `true` if you use permalink_style: pretty
|
62
|
+
filename: 'letsencrypt.html' # What to call the generated challenge file
|
63
|
+
|
64
|
+
# Delay settings:
|
65
|
+
initial_delay: 120 # How long to wait for Gitlab CI to push your changes before it starts checking
|
66
|
+
delay_time: 15 # How long to wait between each check once it starts looking for the file
|
67
|
+
|
68
|
+
# Optional settings you probably don't need:
|
69
|
+
endpoint: 'https://somewhere' # if you're doing the ACME thing outside of letsencrypt
|
70
|
+
branch: 'master' # Defaults to master, but you can use a different branch
|
71
|
+
layout: 'null' # Layout to use for challenge file - defaults to null, but you can change if needed
|
72
|
+
```
|
73
|
+
|
74
|
+
### Running
|
75
|
+
|
76
|
+
- Just type `jekyll letsencrypt`
|
77
|
+
|
78
|
+
```shell
|
79
|
+
$ jekyll letsencrypt
|
80
|
+
Registering example@example.com to https://acme-v01.api.letsencrypt.org/...
|
81
|
+
Pushing file to Gitlab
|
82
|
+
Commiting challenge file as lets.html
|
83
|
+
Done Commiting! Check https://gitlab.com/gitlab_user/gitlab_repo/commits/master
|
84
|
+
Going to check http://example.com/.well-known/acme-challenge/lots_of_numbers/ for the challenge to be present...
|
85
|
+
Waiting 120 seconds before we start checking for challenge..
|
86
|
+
Got response code 404, waiting 15 seconds...
|
87
|
+
Got response code 404, waiting 15 seconds...
|
88
|
+
Got response code 200, file is present!
|
89
|
+
Requesting verification...
|
90
|
+
Challenge status = valid
|
91
|
+
Challenge is valid!
|
92
|
+
Certificate retrieved!
|
93
|
+
Go to https://gitlab.com/gitlab_user/gitlab_repo/pages
|
94
|
+
- If you already have an existing entry for example.com, remove it
|
95
|
+
- Then click + New Domain and enter the following:
|
96
|
+
|
97
|
+
Domain: example.com
|
98
|
+
|
99
|
+
Certificate (PEM):
|
100
|
+
-----BEGIN CERTIFICATE-----
|
101
|
+
...
|
102
|
+
-----END CERTIFICATE-----
|
103
|
+
-----BEGIN CERTIFICATE-----
|
104
|
+
...
|
105
|
+
-----END CERTIFICATE-----
|
106
|
+
|
107
|
+
Key (PEM):
|
108
|
+
-----BEGIN RSA PRIVATE KEY-----
|
109
|
+
...
|
110
|
+
-----END RSA PRIVATE KEY-----
|
111
|
+
|
112
|
+
|
113
|
+
|
114
|
+
|
115
|
+
... hit save, wait a bit, and your new SSL will be live!
|
116
|
+
```
|
117
|
+
|
118
|
+
# License
|
119
|
+
|
120
|
+
MIT
|
121
|
+
|
122
|
+
# Credits/thanks
|
123
|
+
|
124
|
+
- :heart: Gitlab for free page hosting, free repos, and free CI!
|
125
|
+
- :heart: the Jekyll team for the easy-to-use blogging engine!
|
126
|
+
- Inspired by the excellent [gitlab-letsencrypt](https://github.com/rolodato/gitlab-letsencrypt) npm package.
|
data/Rakefile
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'jekyll/gitlab/letsencrypt/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "jekyll-gitlab-letsencrypt"
|
7
|
+
spec.version = Jekyll::Gitlab::Letsencrypt::VERSION
|
8
|
+
spec.authors = ["Justin Aiken"]
|
9
|
+
spec.email = ["60tonangel@gmail.com"]
|
10
|
+
|
11
|
+
spec.summary = %q{Automate letsencrypt renewals for gitlab pages.}
|
12
|
+
spec.description = %q{Automate letsencrypt renewals for gitlab pages.}
|
13
|
+
spec.homepage = "https://github.com/JustinAiken/jekyll-gitlab-letsencrypt"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match %r{^(spec)/} }
|
17
|
+
spec.require_paths = ["lib"]
|
18
|
+
|
19
|
+
spec.add_development_dependency "bundler", ">= 1.13"
|
20
|
+
spec.add_development_dependency "rake", ">= 10.0"
|
21
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
22
|
+
spec.add_development_dependency "jekyll", ">= 3.0"
|
23
|
+
spec.add_development_dependency "vcr", "~> 3.0.3"
|
24
|
+
spec.add_development_dependency "coveralls"
|
25
|
+
|
26
|
+
spec.add_dependency "activesupport", ">= 3.0.0"
|
27
|
+
spec.add_dependency "acme-client", "~> 0.5.0"
|
28
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Jekyll
|
2
|
+
module Commands
|
3
|
+
module Gitlab
|
4
|
+
class Letsencrypt < ::Jekyll::Command
|
5
|
+
def self.init_with_program(prog)
|
6
|
+
prog.command(:letsencrypt) do |c|
|
7
|
+
c.description "Setup/Renew letsencrypt certificate"
|
8
|
+
|
9
|
+
c.action do |_args, _opts|
|
10
|
+
Jekyll::Gitlab::Letsencrypt::Process.process!
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
require 'active_support/core_ext/module/delegation'
|
3
|
+
|
4
|
+
require 'jekyll/gitlab/letsencrypt/version'
|
5
|
+
require 'jekyll/gitlab/letsencrypt/configuration'
|
6
|
+
require 'jekyll/gitlab/letsencrypt/acme'
|
7
|
+
require 'jekyll/gitlab/letsencrypt/process'
|
8
|
+
require 'jekyll/gitlab/letsencrypt/committer'
|
9
|
+
|
10
|
+
module Jekyll
|
11
|
+
module Gitlab
|
12
|
+
module Letsencrypt
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'jekyll/commands/gitlab/letsencrypt'
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'acme-client'
|
3
|
+
|
4
|
+
module Jekyll
|
5
|
+
module Gitlab
|
6
|
+
module Letsencrypt
|
7
|
+
class Acme
|
8
|
+
|
9
|
+
delegate :email, :endpoint, :domain, to: Configuration
|
10
|
+
|
11
|
+
attr_accessor :registration
|
12
|
+
|
13
|
+
def register!
|
14
|
+
Jekyll.logger.info "Registering #{email} to #{endpoint}..."
|
15
|
+
@registration = client.register contact: "mailto:#{email}"
|
16
|
+
@registration.agree_terms
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def authorized?
|
21
|
+
authorization.status == 'valid'
|
22
|
+
end
|
23
|
+
|
24
|
+
def challenge
|
25
|
+
@challenge ||= authorization.http01
|
26
|
+
end
|
27
|
+
|
28
|
+
def client
|
29
|
+
@client ||= begin
|
30
|
+
private_key = OpenSSL::PKey::RSA.new(4096)
|
31
|
+
::Acme::Client.new private_key: private_key, endpoint: endpoint, connection_options: { request: { open_timeout: 5, timeout: 5 } }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def authorization
|
38
|
+
@authorization ||= client.authorize(domain: domain)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
|
3
|
+
module Jekyll
|
4
|
+
module Gitlab
|
5
|
+
module Letsencrypt
|
6
|
+
class Commiter
|
7
|
+
|
8
|
+
attr_accessor :content
|
9
|
+
|
10
|
+
delegate :filename, :personal_access_token, :gitlab_repo, :branch, to: Configuration
|
11
|
+
|
12
|
+
def initialize(content)
|
13
|
+
@content = content
|
14
|
+
end
|
15
|
+
|
16
|
+
def commit!
|
17
|
+
create_branch! unless branch_exists?
|
18
|
+
commit_file!
|
19
|
+
end
|
20
|
+
|
21
|
+
def create_branch!
|
22
|
+
Jekyll.logger.info "Creating branch #{branch}.."
|
23
|
+
connection.post do |req|
|
24
|
+
req.url "projects/#{repo_id}/repository/branches"
|
25
|
+
req.body = {
|
26
|
+
branch_name: branch,
|
27
|
+
ref: 'master'
|
28
|
+
}.to_json
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def commit_file!
|
33
|
+
Jekyll.logger.info "Commiting challenge file as #{filename}"
|
34
|
+
connection.run_request(request_method, nil, nil, nil) do |req|
|
35
|
+
req.url "projects/#{repo_id}/repository/files"
|
36
|
+
req.body = {
|
37
|
+
file_path: filename,
|
38
|
+
commit_message: "Automated Let's Encrypt renewal",
|
39
|
+
branch_name: branch,
|
40
|
+
content: content
|
41
|
+
}.to_json
|
42
|
+
end
|
43
|
+
Jekyll.logger.info "Done Commiting! Check https://gitlab.com/#{gitlab_repo}/commits/#{branch}"
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def branch_exists?
|
49
|
+
response = connection.get "projects/#{repo_id}/repository/branches"
|
50
|
+
JSON.parse(response.body).any? { |json| json['name'] == branch }
|
51
|
+
end
|
52
|
+
|
53
|
+
def request_method
|
54
|
+
response = connection.get "projects/#{repo_id}/repository/files?ref=#{branch}&file_path=#{filename}"
|
55
|
+
response.status == 404 ? :post : :put
|
56
|
+
end
|
57
|
+
|
58
|
+
def repo_id
|
59
|
+
@repo_id ||= begin
|
60
|
+
repo_name = gitlab_repo.gsub "/", "%2f"
|
61
|
+
response = connection.get "projects/#{repo_name}"
|
62
|
+
JSON.parse(response.body)['id']
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def connection
|
67
|
+
@connection ||= Faraday.new(url: 'https://gitlab.com/api/v3/') do |faraday|
|
68
|
+
faraday.adapter Faraday.default_adapter
|
69
|
+
faraday.headers['Content-Type'] = 'application/json'
|
70
|
+
faraday.headers['PRIVATE-TOKEN'] = personal_access_token
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module Jekyll
|
2
|
+
module Gitlab
|
3
|
+
module Letsencrypt
|
4
|
+
class Configuration
|
5
|
+
|
6
|
+
DEFAULT_FILENAME = 'letsencrypt_challenge.html'
|
7
|
+
DEFAULT_ENDPOINT = 'https://acme-v01.api.letsencrypt.org/'
|
8
|
+
DEFAULT_BRANCH = 'master'
|
9
|
+
DEFAULT_LAYOUT = 'null'
|
10
|
+
DEFAULT_INITIAL_DELAY = 120
|
11
|
+
DEFAULT_DELAY_TIME = 15
|
12
|
+
|
13
|
+
REQUIRED_KEYS = %w{gitlab_repo personal_access_token email domain}
|
14
|
+
|
15
|
+
class << self
|
16
|
+
|
17
|
+
def valid?
|
18
|
+
REQUIRED_KEYS.all? { |key| jekyll_config.has_key? key }
|
19
|
+
end
|
20
|
+
|
21
|
+
def endpoint
|
22
|
+
jekyll_config['endpoint'] || DEFAULT_ENDPOINT
|
23
|
+
end
|
24
|
+
|
25
|
+
def gitlab_repo
|
26
|
+
jekyll_config['gitlab_repo']
|
27
|
+
end
|
28
|
+
|
29
|
+
def base_path
|
30
|
+
jekyll_config['base_path'] || ''
|
31
|
+
end
|
32
|
+
|
33
|
+
def pretty_url?
|
34
|
+
!!jekyll_config['pretty_url']
|
35
|
+
end
|
36
|
+
|
37
|
+
def layout
|
38
|
+
jekyll_config['layout'] || DEFAULT_LAYOUT
|
39
|
+
end
|
40
|
+
|
41
|
+
def personal_access_token
|
42
|
+
jekyll_config['personal_access_token']
|
43
|
+
end
|
44
|
+
|
45
|
+
def email
|
46
|
+
jekyll_config['email']
|
47
|
+
end
|
48
|
+
|
49
|
+
def domain
|
50
|
+
jekyll_config['domain']
|
51
|
+
end
|
52
|
+
|
53
|
+
def branch
|
54
|
+
jekyll_config['branch'] || DEFAULT_BRANCH
|
55
|
+
end
|
56
|
+
|
57
|
+
def filename
|
58
|
+
jekyll_config['filename'] || DEFAULT_FILENAME
|
59
|
+
end
|
60
|
+
|
61
|
+
def initial_delay
|
62
|
+
jekyll_config['initial_delay'] || DEFAULT_INITIAL_DELAY
|
63
|
+
end
|
64
|
+
|
65
|
+
def delay_time
|
66
|
+
jekyll_config['delay_time'] || DEFAULT_DELAY_TIME
|
67
|
+
end
|
68
|
+
|
69
|
+
def reset!
|
70
|
+
@jekyll_config = nil
|
71
|
+
end
|
72
|
+
|
73
|
+
def jekyll_config
|
74
|
+
@jekyll_config ||= (Jekyll.configuration({})['gitlab-letsencrypt'] || {})
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
|
3
|
+
module Jekyll
|
4
|
+
module Gitlab
|
5
|
+
module Letsencrypt
|
6
|
+
class Process
|
7
|
+
|
8
|
+
attr_accessor :client
|
9
|
+
|
10
|
+
def self.process!
|
11
|
+
client = Acme.new.register!
|
12
|
+
self.new(client).process!
|
13
|
+
end
|
14
|
+
|
15
|
+
delegate :base_path, :gitlab_repo, :pretty_url?, :layout, :domain, :initial_delay, :delay_time, to: Configuration
|
16
|
+
|
17
|
+
def initialize(client)
|
18
|
+
@client = client
|
19
|
+
end
|
20
|
+
|
21
|
+
def process!
|
22
|
+
Jekyll.logger.abort_with "Client is already authorized." if client.authorized?
|
23
|
+
|
24
|
+
commit_to_gitlab!
|
25
|
+
wait_until_challenge_is_present
|
26
|
+
request_verification!
|
27
|
+
await_verification_confirmation
|
28
|
+
display_certificate
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def commit_to_gitlab!
|
34
|
+
Jekyll.logger.info "Pushing file to Gitlab"
|
35
|
+
Commiter.new(challenge_content).commit!
|
36
|
+
end
|
37
|
+
|
38
|
+
def wait_until_challenge_is_present
|
39
|
+
Jekyll.logger.info "Going to check #{challenge_url} for the challenge to be present..."
|
40
|
+
Jekyll.logger.info "Waiting #{initial_delay} seconds before we start checking for challenge.."
|
41
|
+
sleep initial_delay
|
42
|
+
|
43
|
+
loop do
|
44
|
+
response = Faraday.get challenge_url
|
45
|
+
if response.success?
|
46
|
+
Jekyll.logger.info "Got response code #{response.status}, file is present!"
|
47
|
+
return
|
48
|
+
end
|
49
|
+
Jekyll.logger.info "Got response code #{response.status}, waiting #{delay_time} seconds..."
|
50
|
+
sleep delay_time
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def request_verification!
|
55
|
+
Jekyll.logger.info "Requesting verification..."
|
56
|
+
challenge.request_verification
|
57
|
+
end
|
58
|
+
|
59
|
+
def await_verification_confirmation
|
60
|
+
tries = 0
|
61
|
+
loop do
|
62
|
+
tries = tries + 1
|
63
|
+
if challenge.authorization.verify_status == 'valid'
|
64
|
+
Jekyll.logger.info "Challenge is valid!"
|
65
|
+
return
|
66
|
+
end
|
67
|
+
Jekyll.logger.info "Challenge status = #{challenge.authorization.verify_status}"
|
68
|
+
Jekyll.logger.abort_with "Challenge failed to verify" if tries >= 3
|
69
|
+
sleep delay_time
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def display_certificate
|
74
|
+
Jekyll.logger.info "Certifcate retrieved!"
|
75
|
+
Jekyll.logger.info "Go to https://gitlab.com/#{gitlab_repo}/pages"
|
76
|
+
Jekyll.logger.info " - If you already have an existing entry for #{domain}, remove it"
|
77
|
+
Jekyll.logger.info " - Then click + New Domain and enter the following:"
|
78
|
+
Jekyll.logger.info ""
|
79
|
+
Jekyll.logger.info "Domain: #{domain}"
|
80
|
+
Jekyll.logger.info ""
|
81
|
+
Jekyll.logger.info "Certificate (PEM): "
|
82
|
+
Jekyll.logger.info certificate.fullchain_to_pem
|
83
|
+
Jekyll.logger.info "\n"
|
84
|
+
Jekyll.logger.info "Key (PEM): "
|
85
|
+
Jekyll.logger.info certificate.request.private_key.to_pem
|
86
|
+
Jekyll.logger.info ""
|
87
|
+
Jekyll.logger.info ""
|
88
|
+
Jekyll.logger.info "... hit save, wait a bit, and your new SSL will be live!"
|
89
|
+
end
|
90
|
+
|
91
|
+
def challenge_content
|
92
|
+
permalink = ""
|
93
|
+
permalink += base_path if base_path
|
94
|
+
permalink += challenge.filename
|
95
|
+
permalink += "/" if pretty_url?
|
96
|
+
|
97
|
+
content = "---\n"
|
98
|
+
content += "layout: #{layout}\n"
|
99
|
+
content += "permalink: #{permalink}\n"
|
100
|
+
content += "---\n"
|
101
|
+
content += "\n"
|
102
|
+
content += challenge.file_content
|
103
|
+
content += "\n"
|
104
|
+
|
105
|
+
content
|
106
|
+
end
|
107
|
+
|
108
|
+
def challenge_url
|
109
|
+
@challenge_url ||= begin
|
110
|
+
url = "http://#{domain}/"
|
111
|
+
url += challenge.filename
|
112
|
+
url += "/" if pretty_url?
|
113
|
+
url
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def challenge
|
118
|
+
@challenge ||= client.challenge
|
119
|
+
end
|
120
|
+
|
121
|
+
def certificate
|
122
|
+
@certificate ||= begin
|
123
|
+
csr = ::Acme::Client::CertificateRequest.new names: Array(domain)
|
124
|
+
client.client.new_certificate csr
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
metadata
ADDED
@@ -0,0 +1,171 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jekyll-gitlab-letsencrypt
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Justin Aiken
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-02-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.13'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.13'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: jekyll
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: vcr
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 3.0.3
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 3.0.3
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: coveralls
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: activesupport
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 3.0.0
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 3.0.0
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: acme-client
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.5.0
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 0.5.0
|
125
|
+
description: Automate letsencrypt renewals for gitlab pages.
|
126
|
+
email:
|
127
|
+
- 60tonangel@gmail.com
|
128
|
+
executables: []
|
129
|
+
extensions: []
|
130
|
+
extra_rdoc_files: []
|
131
|
+
files:
|
132
|
+
- ".gitignore"
|
133
|
+
- ".rspec"
|
134
|
+
- ".travis.yml"
|
135
|
+
- Gemfile
|
136
|
+
- LICENSE.txt
|
137
|
+
- README.md
|
138
|
+
- Rakefile
|
139
|
+
- jekyll-gitlab-letsencrypt.gemspec
|
140
|
+
- lib/jekyll/commands/gitlab/letsencrypt.rb
|
141
|
+
- lib/jekyll/gitlab/letsencrypt.rb
|
142
|
+
- lib/jekyll/gitlab/letsencrypt/acme.rb
|
143
|
+
- lib/jekyll/gitlab/letsencrypt/committer.rb
|
144
|
+
- lib/jekyll/gitlab/letsencrypt/configuration.rb
|
145
|
+
- lib/jekyll/gitlab/letsencrypt/process.rb
|
146
|
+
- lib/jekyll/gitlab/letsencrypt/version.rb
|
147
|
+
homepage: https://github.com/JustinAiken/jekyll-gitlab-letsencrypt
|
148
|
+
licenses:
|
149
|
+
- MIT
|
150
|
+
metadata: {}
|
151
|
+
post_install_message:
|
152
|
+
rdoc_options: []
|
153
|
+
require_paths:
|
154
|
+
- lib
|
155
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
161
|
+
requirements:
|
162
|
+
- - ">="
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
version: '0'
|
165
|
+
requirements: []
|
166
|
+
rubyforge_project:
|
167
|
+
rubygems_version: 2.6.6
|
168
|
+
signing_key:
|
169
|
+
specification_version: 4
|
170
|
+
summary: Automate letsencrypt renewals for gitlab pages.
|
171
|
+
test_files: []
|