lecli 0.2.2 → 0.2.4

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
  SHA1:
3
- metadata.gz: 4808b041d83a611a2a5b133ab485d3e59aabfaaf
4
- data.tar.gz: b5781570c2e72e9bf34f4649e32ac77a0d206256
3
+ metadata.gz: da9e05e9c2100f24c17b18b0102812c9a1ef4de5
4
+ data.tar.gz: 0ded86f70fab0543811022364e58f83b30114df7
5
5
  SHA512:
6
- metadata.gz: cba07c13f72fd47dcde7b9dd3a73300ea37cda6ba249ee4fc87b73a1cdc2e3f3bfc8669d6812d63835b06d384f4f7ca213d0119afb3d451120b1703f29554d20
7
- data.tar.gz: 06a9eea65ae077421593d8414208b4c68a2bd0c1be656ad15c430cbfa782349692ef23493cc9074bfb2f6c0c6a287dc56ff967c7fa2e3a589ef579e2800b1861
6
+ metadata.gz: 94b3f4c61d97431798588137ff64b0a48fba6f906e07396e1908428af9e46f0c883f950d759de42f451b8f51c19eb21100e3d02a8a2698b5ed32fcc8505734af
7
+ data.tar.gz: 2b9669dded2a38d7bfceb0b6b5f9bffcf806908ed7b4d303815f2d4407734c203a9234a8a7d2f7c0678acefe87492a16beec8445d9499e27dfd418a5c582c6f6
data/.gitignore CHANGED
@@ -9,3 +9,5 @@
9
9
 
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
+
13
+ .lecli.yml
@@ -0,0 +1,13 @@
1
+ Metrics/MethodLength:
2
+ Max: 20
3
+ Metrics/ClassLength:
4
+ Max: 150
5
+ Metrics/BlockLength:
6
+ Exclude:
7
+ - 'Rakefile'
8
+ - '**/*.rake'
9
+ - 'spec/**/*.rb'
10
+ Style/ExpandPathArguments:
11
+ Enabled: false
12
+ Style/WordArray:
13
+ Enabled: false
@@ -1,5 +1,10 @@
1
+ dist: trusty
1
2
  sudo: false
2
3
  language: ruby
3
4
  rvm:
5
+ - 2.3.1
4
6
  - 2.4.2
7
+ - 2.5.1
5
8
  before_install: gem install bundler -v 1.16.0
9
+ script:
10
+ - bundle exec rake spec
data/Gemfile CHANGED
@@ -1,6 +1,6 @@
1
- source "https://rubygems.org"
1
+ source 'https://rubygems.org'
2
2
 
3
- git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
3
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
4
 
5
5
  # Specify your gem's dependencies in lecli.gemspec
6
6
  gemspec
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- lecli (0.2.2)
4
+ lecli (0.2.4)
5
5
  acme-client (~> 2.0.0)
6
6
  thor (~> 0.20.0)
7
7
 
@@ -11,8 +11,10 @@ GEM
11
11
  acme-client (2.0.0)
12
12
  faraday (~> 0.9, >= 0.9.1)
13
13
  diff-lcs (1.3)
14
+ docile (1.3.1)
14
15
  faraday (0.15.2)
15
16
  multipart-post (>= 1.2, < 3)
17
+ json (2.1.0)
16
18
  multipart-post (2.0.0)
17
19
  rake (10.5.0)
18
20
  rspec (3.7.0)
@@ -28,6 +30,11 @@ GEM
28
30
  diff-lcs (>= 1.2.0, < 2.0)
29
31
  rspec-support (~> 3.7.0)
30
32
  rspec-support (3.7.1)
33
+ simplecov (0.16.1)
34
+ docile (~> 1.1)
35
+ json (>= 1.8, < 3)
36
+ simplecov-html (~> 0.10.0)
37
+ simplecov-html (0.10.2)
31
38
  thor (0.20.0)
32
39
 
33
40
  PLATFORMS
@@ -38,6 +45,7 @@ DEPENDENCIES
38
45
  lecli!
39
46
  rake (~> 10.0)
40
47
  rspec (~> 3.0)
48
+ simplecov (~> 0.16.1)
41
49
 
42
50
  BUNDLED WITH
43
51
  1.16.0
data/README.md CHANGED
@@ -1,38 +1,92 @@
1
- # Lecli
1
+ # lecli
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/lecli`. To experiment with that code, run `bin/console` for an interactive prompt.
4
-
5
- TODO: Delete this and the text above, and describe your gem
3
+ lecli is a gem that provides a CLI to generate Let's Encrypt certificates. It wraps around the [ACME protocol Client gem](https://github.com/unixcharles/acme-client). It pairs well with cron jobs and the [whenever gem](https://github.com/javan/whenever) for a tighter grip on automation/scripting customization.
6
4
 
7
5
  ## Installation
8
6
 
9
- Add this line to your application's Gemfile:
7
+ $ gem install lecli
8
+
9
+ ## Getting started
10
+
11
+ The CLI will use the Let's Encrypt staging endpoint unless explicitly passed with the `--production` flag. All other configuration data is managed by a config file - `.lecli.yml`. To help understand the available options you can run the following in your terminal and a sample YAML file will be generated for you
10
12
 
11
- ```ruby
12
- gem 'lecli'
13
+ ```
14
+ $ lecli yaml
13
15
  ```
14
16
 
15
- And then execute:
17
+ Now let's see what's inside
16
18
 
17
- $ bundle
19
+ ### `lecli.yml`
18
20
 
19
- Or install it yourself as:
21
+ ```
22
+ ---
23
+ domains:
24
+ - example.com
25
+ common_name: Let's Encrypt
26
+ account_email: test@account.com
27
+ request_key: request.pem
28
+ certificate_key: certificate.pem
29
+ challenges_relative_path: challenges
30
+ success_callback_script: deploy.sh
31
+ ```
20
32
 
21
- $ gem install lecli
33
+ Most entries are optional, except those that specify the domains you are requesting and "identity fields". Meaning that at least **domains** (list of entries), **common_name** and **account_email** should always appear in order to perform a valid request.
22
34
 
23
- ## Usage
35
+ ### The flow
24
36
 
25
- TODO: Write usage instructions here
37
+ From the two available types of validation requests only HTTP (and not DNS) is supported [yet](#contributing). This means you'll need to serve a token (lecli will create them) behind each domain in the **list of domain addresses** requested, on a certain **port**.
26
38
 
27
- ## Development
39
+ The tokens are written to a single **challenges_relative_path** and need to be served behind each domain you are requesting, i.e. `example.com/.well-known/acme-challenge/#{token_filename}`. If requesting multiple domains at once you will need additional setup to route from each domain requested to where the tokens are persisted. When working with a single domain, for example, you can just make this relative path write the tokens on `/usr/share/nginx/html/.well-known/acme-challenge/` if working with an nginx server.
40
+
41
+ ![alt text](https://github.com/fdoxyz/lecli/blob/master/lecli_diagram.png)
42
+
43
+ After Let's Encrypt is able to access both tokens on the list of domain addresses requested the certificates can be issued. The resulting certificate will be identified by the **email** and under the **common_name** provided. The name of the `.pem` files can be customized with **request_key** and **certificate_key**.
44
+
45
+ Optionally you can specify a script filename with **success_callback_script**. This script will function as a "callback hook" and it will be run after successfully exporting the domains' certificate.
46
+
47
+ In this section you've read about all `lecli.yml` options available (keywords in **bold**). Now, if you've made sure you: (1) Customized the options in this file to create the desired certificate, and (2) made sure the **success_callback_script** path is available for a public internet. You are now ready to kick off the validation process by executing the following on your terminal
48
+
49
+ ```
50
+ lecli generate
51
+ ```
28
52
 
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
53
+ ### Making use of the result Certificates
30
54
 
31
- 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).
55
+ A simple example `nginx.conf` excerpt to make use of the result certificates could be the following
56
+
57
+ ```
58
+ server {
59
+ listen 443 ssl;
60
+ server_name example.com;
61
+
62
+ ssl_certificate /etc/nginx/ssl/request.pem;
63
+ ssl_certificate_key /etc/nginx/ssl/certificate.pem;
64
+
65
+ ...
66
+ }
67
+ ```
68
+
69
+ You can script a server restart if needed, or any other setup that you require to make use of the newly created certificates. Just make sure to point the **success_callback_script** path in your config file so the CLI can automatically execute it if the request result was success.
70
+
71
+ If you pair the CLI with a cron-job (specially using the [whenever](https://github.com/javan/whenever) gem) you've essentially put together a Let's Encrypt bot and can now leverage scripting for complex deployments. Your certificates will be renewed periodically. When using **whenever** you'll have lecli CLI in your crontab as easy as:
72
+
73
+ ```
74
+ every :month, at: '4am' do
75
+ command "lecli --production -f /path/to/config/file.yml"
76
+ end
77
+ ```
78
+
79
+ Be sure to run `lecli help` for more details.
80
+
81
+ ## Development
82
+
83
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. To install this gem onto your local machine, run `bundle exec rake install`.
32
84
 
33
85
  ## Contributing
34
86
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/lecli.
87
+ Bug reports and pull requests are welcome on GitHub at https://github.com/fdoxyz/lecli.
88
+
89
+ Please include tests if new features are added and make sure rubocop styling guide is met.
36
90
 
37
91
  ## License
38
92
 
data/Rakefile CHANGED
@@ -1,6 +1,6 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
3
 
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
 
6
- task :default => :spec
6
+ task default: :spec
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "bundler/setup"
4
- require "lecli"
3
+ require 'bundler/setup'
4
+ require 'lecli'
5
5
 
6
6
  # You can add fixtures and/or initialization code here to make experimenting
7
7
  # with your gem easier. You can also use a different console, if you like.
8
8
 
9
9
  # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
10
+ # require 'pry'
11
11
  # Pry.start
12
12
 
13
- require "irb"
13
+ require 'irb'
14
14
  IRB.start(__FILE__)
data/exe/lecli CHANGED
@@ -1,60 +1,55 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "thor"
4
- require "yaml"
5
- require "lecli"
3
+ require 'thor'
4
+ require 'yaml'
5
+ require 'lecli'
6
6
 
7
+ # Class in charge of the CLI functionallity powered by Thor
7
8
  class LECLIRunner < Thor
8
-
9
- YAML_FILENAME = ".lecli.yml"
10
-
11
- desc "version", "Prints out the gem version"
9
+ desc 'version', 'Prints out the gem version'
12
10
  def version
13
- puts "v#{LECLI::VERSION}"
11
+ puts LECLI::VERSION
14
12
  end
15
13
 
16
- desc "yaml", "Generates the #{YAML_FILENAME} file with all default options"
14
+ desc 'yaml', 'Generates the options file with defaults to customize'
17
15
  option :override,
18
- type: :boolean,
19
- aliases: [:o],
20
- desc: "Overrides the existing #{YAML_FILENAME} if any exist."
16
+ type: :boolean,
17
+ aliases: [:o],
18
+ desc: 'Overrides the existing options file the defaults.'
21
19
  def yaml
22
- if !File.file?(YAML_FILENAME) || options[:override]
23
- hash = LECLI::CertificateBuilder.default_options_yaml
24
- File.write(YAML_FILENAME, hash.to_yaml)
25
- puts YAML_FILENAME
26
- else
27
- puts "ERROR: #{YAML_FILENAME} file already exists. Try `lecli help yaml`"
28
- end
20
+ LECLI::CertificateBuilder.persist_defaults_file(
21
+ override: options[:override]
22
+ )
29
23
  end
30
24
 
31
- desc "generate", "Requests and outputs Let's Encrypt SSL Certificates"
25
+ desc 'generate', 'Requests and outputs Let\'s Encrypt SSL Certificates'
32
26
  option :production,
33
- type: :boolean,
34
- aliases: [:p],
35
- desc: "Use Let's Encrypt production API endpoint."
27
+ type: :boolean,
28
+ aliases: [:p],
29
+ desc: 'Use Let\'s Encrypt production API endpoint.'
30
+ option :config_file,
31
+ default: '.lecli.yml',
32
+ aliases: [:f],
33
+ desc: 'Specify the path of the configuration file.'
36
34
  def generate
37
- begin
38
- # Load defaults and merge with the config file data
39
- hash = LECLI::CertificateBuilder.default_options_yaml
40
- if File.file?(YAML_FILENAME)
41
- hash = hash.merge(YAML.load_file(YAML_FILENAME))
42
- end
43
- rescue
44
- puts "ERROR: Invalid format for file #{YAML_FILENAME}"
45
- return 1
35
+ puts "LOL: #{options[:config_file]}"
36
+ return
37
+ opts = LECLI::CertificateBuilder.load_options(config_file: config_file)
38
+ if opts.nil? # Bail if options can't be loaded properly
39
+ puts 'Unable to locate .lecli.yml file. Try `lecli help generate`'
40
+ return
46
41
  end
47
42
 
48
- hash["production"] = options[:production]
49
- LECLI::CertificateBuilder.generate_certs(hash)
50
-
51
- puts "Certificates generated successfully!"
52
-
53
- script_path = hash["success_callback_script"]
54
- if File.file?(script_path)
55
- puts "Execution attempt of success callback script `#{script_path}`"
56
- `./#{script_path}`
43
+ builder = LECLI::CertificateBuilder.new do |b|
44
+ b.production = options[:production]
57
45
  end
46
+ builder.generate_certs(opts)
47
+ puts 'Certificates generated successfully!'
48
+
49
+ script_path = File.expand_path(opts['success_callback_script'])
50
+ return if File.file?(script_path)
51
+ puts "Executing now success callback script `#{script_path}`..."
52
+ `./#{script_path}`
58
53
  end
59
54
  end
60
55
 
@@ -1,31 +1,30 @@
1
-
2
- lib = File.expand_path("../lib", __FILE__)
1
+ lib = File.expand_path('../lib', __FILE__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require "lecli/version"
3
+ require 'lecli/version'
5
4
 
6
5
  Gem::Specification.new do |spec|
7
- spec.name = "lecli"
6
+ spec.name = 'lecli'
8
7
  spec.version = LECLI::VERSION
9
- spec.authors = ["Fernando Valverde Arredondo"]
10
- spec.email = ["fdov88@gmail.com"]
8
+ spec.authors = ['Fernando Valverde Arredondo']
9
+ spec.email = ['fdov88@gmail.com']
11
10
 
12
- spec.summary = "Let's Encrypt CLI to generate certificates"
13
- spec.description = "Let's Encrypt CLI to generate certificates"
14
- spec.homepage = "https://github.com/fdoxyz/lecli"
15
- spec.license = "MIT"
11
+ spec.summary = 'CLI to generate Let\'s Encrypt certificates'
12
+ spec.description = 'CLI to generate Let\'s Encrypt certificates'
13
+ spec.homepage = 'https://github.com/fdoxyz/lecli'
14
+ spec.license = 'MIT'
16
15
 
17
16
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
17
  f.match(%r{^(test|spec|features)/})
19
18
  end
20
- spec.bindir = "exe"
19
+ spec.bindir = 'exe'
21
20
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
- spec.require_paths = ["lib"]
23
-
24
- spec.add_dependency "thor", "~> 0.20.0"
25
- spec.add_dependency "acme-client", "~> 2.0.0"
21
+ spec.require_paths = ['lib']
26
22
 
27
- spec.add_development_dependency "bundler", "~> 1.16"
28
- spec.add_development_dependency "rake", "~> 10.0"
29
- spec.add_development_dependency "rspec", "~> 3.0"
23
+ spec.add_dependency 'acme-client', '~> 2.0.0'
24
+ spec.add_dependency 'thor', '~> 0.20.0'
30
25
 
26
+ spec.add_development_dependency 'bundler', '~> 1.16'
27
+ spec.add_development_dependency 'rake', '~> 10.0'
28
+ spec.add_development_dependency 'rspec', '~> 3.0'
29
+ spec.add_development_dependency 'simplecov', '~> 0.16.1'
31
30
  end
Binary file
@@ -1,5 +1,6 @@
1
- require "lecli/version"
2
- require "lecli/certificate_builder"
1
+ require 'lecli/version'
2
+ require 'lecli/certificate_builder'
3
3
 
4
+ # Gem module where all the logic is implemented
4
5
  module LECLI
5
6
  end
@@ -1,92 +1,143 @@
1
- require "thor"
2
- require "acme-client"
3
- require "uri"
4
- require "fileutils"
1
+ require 'thor'
2
+ require 'acme-client'
3
+ require 'uri'
4
+ require 'fileutils'
5
5
 
6
6
  module LECLI
7
+ # Helper class to generate certs and access the default options
7
8
  class CertificateBuilder
9
+ attr_accessor :production
8
10
 
9
- def self.default_options_yaml
11
+ YAML_FILENAME = '.lecli.yml'.freeze
12
+
13
+ def initialize
14
+ @challenges = []
15
+ @production = false
16
+
17
+ # Pass a block to edit the new object for prod/staging or other options
18
+ yield self if block_given?
19
+
20
+ prod_url = 'https://acme-v02.api.letsencrypt.org/directory'
21
+ staging_url = 'https://acme-staging-v02.api.letsencrypt.org/directory'
22
+ @endpoint = @production ? prod_url : staging_url
23
+ end
24
+
25
+ def self.default_options
10
26
  {
11
- "port" => 3333,
12
- "domains" => [ "example.com" ],
13
- "common_name" => "Let's Encrypt",
14
- "account_email" => "test@account.com",
15
- "request_key" => "request.pem",
16
- "certificate_key" => "certificate.pem",
17
- "challenges_relative_path" => "challenges",
18
- "success_callback_script" => "deploy.sh"
27
+ 'domains' => ['example.com'],
28
+ 'common_name' => 'Let\'s Encrypt',
29
+ 'account_email' => 'test@account.com',
30
+ 'request_key' => 'request.pem',
31
+ 'certificate_key' => 'certificate.pem',
32
+ 'challenges_relative_path' => 'challenges',
33
+ 'success_callback_script' => 'deploy.sh'
19
34
  }
20
35
  end
21
36
 
22
- def self.generate_certs(options)
23
- if options["production"]
24
- endpoint = "https://acme-v02.api.letsencrypt.org/directory"
37
+ def self.load_options(config_file:)
38
+ opts = LECLI::CertificateBuilder.default_options
39
+ opts.merge(YAML.load_file(config_file)) if File.file?(config_file)
40
+ end
41
+
42
+ def self.persist_defaults_file(override:)
43
+ opts = LECLI::CertificateBuilder.default_options
44
+ if !File.file?(YAML_FILENAME) || override
45
+ File.write(YAML_FILENAME, opts.to_yaml)
46
+ puts YAML_FILENAME
25
47
  else
26
- endpoint = "https://acme-staging-v02.api.letsencrypt.org/directory"
48
+ puts "#{YAML_FILENAME} already exists. Try `lecli help yaml`"
27
49
  end
50
+ end
51
+
52
+ def generate_certs(options)
53
+ request_challenges(options: options)
54
+ sleep(3) # We are unaware of challenge hosting, better give them some time
28
55
 
29
- account_pkey = OpenSSL::PKey::RSA.new(4096)
30
- client = Acme::Client.new(private_key: account_pkey, directory: endpoint)
56
+ request_challenge_validation
57
+ request_key = finalize_order(
58
+ domains: options['domains'],
59
+ title: options['common_name']
60
+ )
61
+
62
+ write_certificate(
63
+ cert: @order.certificate, relative_path: options['certificate_key']
64
+ )
65
+ write_certificate(
66
+ cert: request_key, relative_path: options['request_key']
67
+ )
68
+ end
69
+
70
+ private
71
+
72
+ def request_challenges(options:)
73
+ create_order(email: options['account_email'], domains: options['domains'])
74
+ setup_challenges_dir(relative_path: options['challenges_relative_path'])
75
+ persist_challenge_tokens
76
+ end
77
+
78
+ def write_certificate(cert:, relative_path:)
79
+ full_path = File.expand_path(relative_path)
80
+ File.write(full_path, cert)
81
+ end
82
+
83
+ def finalize_order(domains:, title:)
84
+ request_key = OpenSSL::PKey::RSA.new(4096)
85
+ csr = Acme::Client::CertificateRequest.new(
86
+ private_key: request_key,
87
+ names: domains.values,
88
+ subject: { common_name: title }
89
+ )
90
+ @order.finalize(csr: csr)
91
+ sleep(1) while @order.status == 'processing'
92
+ request_key
93
+ end
94
+
95
+ def create_order(email:, domains:)
96
+ pkey = OpenSSL::PKey::RSA.new(4096)
97
+ client = Acme::Client.new(private_key: pkey, directory: @endpoint)
31
98
  client.new_account(
32
- contact: "mailto:#{options["account_email"]}",
33
- terms_of_service_agreed: true
34
- )
35
- order = client.new_order(identifiers: options["domains"])
36
-
37
- # Setup if necessary & clear challenges directory
38
- challenges_dir = File.expand_path(options["challenges_relative_path"])
39
- FileUtils.mkdir_p(challenges_dir)
40
- FileUtils.rm(Dir[File.join(challenges_dir, "*")])
41
-
42
- challenges = []
43
- order.authorizations.each do |authorization|
44
- challenge = authorization.http
45
- token_path = File.join(challenges_dir, challenge.token)
46
- File.write(token_path, challenge.file_content)
47
- challenges << challenge
48
- end
99
+ contact: "mailto:#{email}",
100
+ terms_of_service_agreed: true
101
+ )
102
+ @order = client.new_order(identifiers: domains)
103
+ end
49
104
 
50
- sleep(1)
105
+ def setup_challenges_dir(relative_path:)
106
+ @challenges_dir = File.expand_path(relative_path)
107
+ FileUtils.mkdir_p(@challenges_dir)
108
+ FileUtils.rm(Dir[File.join(@challenges_dir, '*')])
109
+ end
51
110
 
111
+ def request_challenge_validation
52
112
  wait_time = 5
53
113
  pending = true
54
114
  while pending
55
- challenges.each do |challenge|
115
+ @challenges.each do |challenge|
56
116
  begin
57
117
  challenge.request_validation
58
118
  rescue Acme::Client::Error::Malformed
59
- print "."
119
+ print '.'
60
120
  end
61
121
  end
62
122
 
63
- status = challenges.map(&:status)
64
- pending = status.include?("pending")
65
-
66
- if pending
67
- puts "At least one challenge still pending, waiting #{wait_time}s ..."
68
- sleep(wait_time)
123
+ status = @challenges.map(&:status)
124
+ pending = status.include?('pending')
69
125
 
70
- # Gradually increment wait times before retrying (max ~10min)
71
- wait_time *= 2 if wait_time < 640
72
- end
126
+ next unless pending
127
+ puts "At least one challenge still pending, waiting #{wait_time}s ..."
128
+ sleep(wait_time)
129
+ wait_time *= 2 if wait_time < 640 # Gradually increment retry max ~10min
73
130
  end
74
- puts "Challenges are all valid now!"
75
-
76
- request_key = OpenSSL::PKey::RSA.new(4096)
77
- csr = Acme::Client::CertificateRequest.new(
78
- private_key: request_key,
79
- names: domains.values,
80
- subject: { common_name: options["common_name"] }
81
- )
82
- order.finalize(csr: csr)
83
- sleep(1) while order.status == "processing"
84
-
85
- certificate_path = File.expand_path(options["certificate_key"])
86
- File.write(certificate_path, order.certificate)
87
- request_path = File.expand_path(options["request_key"])
88
- File.write(request_path, request_key)
131
+ puts 'Challenges are all valid now!'
89
132
  end
90
133
 
134
+ def persist_challenge_tokens
135
+ @order.authorizations.each do |authorization|
136
+ challenge = authorization.http
137
+ token_path = File.join(@challenges_dir, challenge.token)
138
+ File.write(token_path, challenge.file_content)
139
+ @challenges << challenge
140
+ end
141
+ end
91
142
  end
92
143
  end
@@ -1,3 +1,3 @@
1
1
  module LECLI
2
- VERSION = "0.2.2"
2
+ VERSION = '0.2.4'.freeze
3
3
  end
metadata CHANGED
@@ -1,43 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lecli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fernando Valverde Arredondo
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-07-13 00:00:00.000000000 Z
11
+ date: 2018-07-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: thor
14
+ name: acme-client
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.20.0
19
+ version: 2.0.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.20.0
26
+ version: 2.0.0
27
27
  - !ruby/object:Gem::Dependency
28
- name: acme-client
28
+ name: thor
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 2.0.0
33
+ version: 0.20.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 2.0.0
40
+ version: 0.20.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: bundler
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -80,7 +80,21 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '3.0'
83
- description: Let's Encrypt CLI to generate certificates
83
+ - !ruby/object:Gem::Dependency
84
+ name: simplecov
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.16.1
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.16.1
97
+ description: CLI to generate Let's Encrypt certificates
84
98
  email:
85
99
  - fdov88@gmail.com
86
100
  executables:
@@ -90,6 +104,7 @@ extra_rdoc_files: []
90
104
  files:
91
105
  - ".gitignore"
92
106
  - ".rspec"
107
+ - ".rubocop.yml"
93
108
  - ".travis.yml"
94
109
  - Gemfile
95
110
  - Gemfile.lock
@@ -100,6 +115,7 @@ files:
100
115
  - bin/setup
101
116
  - exe/lecli
102
117
  - lecli.gemspec
118
+ - lecli_diagram.png
103
119
  - lib/lecli.rb
104
120
  - lib/lecli/certificate_builder.rb
105
121
  - lib/lecli/version.rb
@@ -126,5 +142,5 @@ rubyforge_project:
126
142
  rubygems_version: 2.6.14
127
143
  signing_key:
128
144
  specification_version: 4
129
- summary: Let's Encrypt CLI to generate certificates
145
+ summary: CLI to generate Let's Encrypt certificates
130
146
  test_files: []