Showing with 428 additions and 93 deletions.
  1. +3 −0 .fixtures.yml
  2. +2 −0 .travis.yml
  3. +13 −1 CHANGELOG.md
  4. +4 −2 Gemfile
  5. +20 −2 README.md
  6. +1 −1 Rakefile
  7. +21 −11 manifests/certonly.pp
  8. +2 −10 manifests/config.pp
  9. +23 −0 manifests/config/ini.pp
  10. +44 −24 manifests/init.pp
  11. +65 −0 manifests/install.pp
  12. +13 −5 manifests/params.pp
  13. +6 −2 metadata.json
  14. +89 −0 spec/classes/letsencrypt_install_spec.rb
  15. +110 −23 spec/classes/letsencrypt_spec.rb
  16. +12 −12 spec/defines/letsencrypt_certonly_spec.rb
3 changes: 3 additions & 0 deletions .fixtures.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
fixtures:
repositories:
epel:
repo: 'https://github.com/stahnma/puppet-module-epel.git'
ref: '1.2.2'
inifile:
repo: 'https://github.com/puppetlabs/puppetlabs-inifile.git'
ref: '1.4.2'
Expand Down
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ rvm:
- 2.1
script: bundle exec rake test
env:
- PUPPET_VERSION="~> 3.4.0"
- PUPPET_VERSION="~> 3.4"
- PUPPET_VERSION="~> 4.0.0"
- PUPPET_VERSION="~> 4.1.0"
- PUPPET_VERSION="~> 4.2.0"
Expand Down
14 changes: 13 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. This projec

## [Unreleased][unreleased]

## [1.0.0] - 2016-02-22
## Added
- Backwards compatibility with Puppet >= 3.4
- Ability to select the `letsencrypt` install method using the `install_method` parameter. Current supported options are `package` and `vcs`.
- The `manage_install` parameter now lets the user select whether they want to manage the installation of `letsencrypt` with this module.
- The `configure_epel` parameter now lets the user manage the EPEL repository on EL systems. It is set to `true` by default. The `stahnma/epel` module is now a dependency.

## Breaking
- Removed the `letsencrypt_path` parameter in `letsencrypt::certonly` in favor of `letsencrypt_command` in order to support the `package` based installation method.
- The default installation method has changed for RedHat, Debian `>= 9`, and Ubuntu `>= 16.04` from `vcs` to `package`.

## [0.4.0] - 2016-01-31
### Added
- Ability to renew automatically via cron with `manage_cron` parameter.
Expand Down Expand Up @@ -38,7 +49,8 @@ All notable changes to this project will be documented in this file. This projec
## [0.1.0] - 2015-12-03
Initial Release

[unreleased]: https://github.com/danzilio/puppet-letsencrypt/compare/v0.4.0...HEAD
[unreleased]: https://github.com/danzilio/puppet-letsencrypt/compare/v1.0.0...HEAD
[1.0.0]: https://github.com/danzilio/puppet-letsencrypt/compare/v0.4.0...v1.0.0
[0.4.0]: https://github.com/danzilio/puppet-letsencrypt/compare/v0.3.2...v0.4.0
[0.3.2]: https://github.com/danzilio/puppet-letsencrypt/compare/v0.3.1...v0.3.2
[0.3.1]: https://github.com/danzilio/puppet-letsencrypt/compare/v0.3.0...v0.3.1
Expand Down
6 changes: 4 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ source 'https://rubygems.org'

group :test do
gem 'rake'
gem 'puppet', ENV['PUPPET_VERSION'] || '~> 4.3.0'
gem 'puppet', ENV['PUPPET_VERSION'] || ['>= 3.4', '< 5']
gem 'puppet-lint'
gem 'rspec-puppet'
gem 'puppet-syntax'
gem 'puppetlabs_spec_helper'
gem 'metadata-json-lint'
gem 'puppet-strings', git: 'git://github.com/puppetlabs/puppetlabs-strings.git'
unless ENV['PUPPET_VERSION'] == '~> 3.4.0'
gem 'puppet-strings', git: 'git://github.com/puppetlabs/puppetlabs-strings.git'
end
gem 'puppet-lint-absolute_classname-check'
gem 'puppet-lint-alias-check'
gem 'puppet-lint-empty_string-check'
Expand Down
22 changes: 20 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,17 @@ This module installs the Let's Encrypt client from source and allows you to requ

## Support

This module requires Puppet >= 4.0. and is currently only written to work on
Debian and RedHat based operating systems.
This module requires Puppet >= 3.4. and is currently only written to work on
Debian and RedHat based operating systems, although it may work on others.

## Dependencies

On EL (Red Hat, CentOS etc.) systems, the EPEL repository needs to be enabled
for the Let's Encrypt client package.

The module can integrate with [stahnma/epel](https://forge.puppetlabs.com/stahnma/epel)
to set up the repo by setting the `configure_epel` parameter to `true` and
installing the module.

## Usage

Expand All @@ -18,6 +27,15 @@ class { ::letsencrypt:
}
```

If using EL7 without EPEL-preconfigured, add `configure_epel`:

```puppet
class { ::letsencrypt:
configure_epel => true,
email => 'foo@example.com',
}
```

This will install the Let's Encrypt client and its dependencies, agree to the
Terms of Service, initialize the client, and install a configuration file for
the client.
Expand Down
2 changes: 1 addition & 1 deletion Rakefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
require 'puppetlabs_spec_helper/rake_tasks'
require 'puppet-lint/tasks/puppet-lint'
require 'puppet-syntax/tasks/puppet-syntax'
require 'puppet-strings/rake_tasks'
require 'rubocop/rake_task'

RuboCop::RakeTask.new
Expand All @@ -10,6 +9,7 @@ RuboCop::RakeTask.new
# on Travis with --without development
begin
require 'puppet_blacksmith/rake_tasks'
require 'puppet-strings/rake_tasks'
rescue LoadError
end

Expand Down
32 changes: 21 additions & 11 deletions manifests/certonly.pp
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,35 @@
# Required if using `plugin => 'webroot'`. If `domains` and
# `webroot_paths` are not the same length, `webroot_paths`
# will cycle to make up the difference.
# [*letsencrypt_path*]
# The path to the letsencrypt installation.
# [*letsencrypt_command*]
# Command to run letsencrypt
# [*additional_args*]
# An array of additional command line arguments to pass to the
# `letsencrypt-auto` command.
# [*manage_cron*]
# Boolean indicating whether or not to schedule cron job for renewal.
# Runs daily but only renews if near expiration, e.g. within 10 days.
# Runs daily but only renews if near expiration, e.g. within 10 days.
#
define letsencrypt::certonly (
Array[String] $domains = [$title],
Enum['apache', 'standalone', 'webroot'] $plugin = 'standalone',
Optional[Array[String]] $webroot_paths = undef,
String $letsencrypt_path = $letsencrypt::path,
Optional[Array[String]] $additional_args = undef,
Boolean $manage_cron = false,
$domains = [$title],
$plugin = 'standalone',
$webroot_paths = undef,
$letsencrypt_command = $letsencrypt::command,
$additional_args = undef,
$manage_cron = false,
) {
validate_array($domains)
validate_re($plugin, ['^apache$', '^standalone$', '^webroot$'])
if $webroot_paths {
validate_array($webroot_paths)
}
validate_string(letsencrypt_path)
if $additional_args {
validate_array($additional_args)
}
validate_bool($manage_cron)

$command_start = "${letsencrypt_path}/letsencrypt-auto --agree-tos certonly -a ${plugin} "
$command_start = "${letsencrypt_command} --agree-tos certonly -a ${plugin} "
$command_domains = $plugin ? {
'webroot' => inline_template('<%= @domains.zip(@webroot_paths.cycle).map { |domain| "--webroot-path #{domain[1]} -d #{domain[0]}"}.join(" ") %>'),
default => inline_template('-d <%= @domains.join(" -d ")%>'),
Expand All @@ -47,7 +57,7 @@
creates => $live_path,
require => Class['letsencrypt'],
}

if $manage_cron {
$renewcommand = "${command_start}--keep-until-expiring ${command_domains}${command_end}"
$cron_hour = fqdn_rand(24, $title) # 0 - 23, seed is title plus fqdn
Expand Down
12 changes: 2 additions & 10 deletions manifests/config.pp
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,7 @@
}
}

$_config.each |$setting, $value| {
ini_setting { "${config_file} ${setting} ${value}":
ensure => present,
path => $config_file,
section => '',
setting => $setting,
value => $value,
require => File['/etc/letsencrypt'],
}
}
$_config_joined = join_keys_to_values($_config, '=')
letsencrypt::config::ini { $_config_joined: }

}
23 changes: 23 additions & 0 deletions manifests/config/ini.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# == Define: letsencrypt::client::ini
#
# This configures a single setting in the LE INI file. This is a private resource.
#
define letsencrypt::config::ini () {

assert_private()

$name_split = split($name, '=')
$setting = $name_split[0]
$value = $name_split[1]
$config_file = $::letsencrypt::config::config_file

ini_setting { "${config_file} ${setting} ${value}":
ensure => present,
path => $config_file,
section => '',
setting => $setting,
value => $value,
require => File['/etc/letsencrypt'],
}

}
68 changes: 44 additions & 24 deletions manifests/init.pp
Original file line number Diff line number Diff line change
Expand Up @@ -12,55 +12,75 @@
# [*repo*]
# A Git URL to install the Let's encrypt client from.
# [*version*]
# The Git ref (tag, sha, branch) to check out when installing the client.
# The Git ref (tag, sha, branch) to check out when installing the client with
# the `vcs` method.
# [*package_ensure*]
# The value passed to `ensure` when installing the client with the `package`
# method.
# [*config_file*]
# The path to the configuration file for the letsencrypt cli.
# [*config*]
# A hash representation of the letsencrypt configuration file.
# [*manage_config*]
# A feature flag to toggle the management of the letsencrypt configuration
# file.
# [*manage_install*]
# A feature flag to toggle the management of the letsencrypt client
# installation.
# [*manage_dependencies*]
# A feature flag to toggle the management of the letsencrypt dependencies.
# [*configure_epel*]
# A feature flag to include the 'epel' class and depend on it for package
# installation.
# [*install_method*]
# Method to install the letsencrypt client, either package or vcs.
# [*agree_tos*]
# A flag to agree to the Let's Encrypt Terms of Service.
# [*unsafe_registration*]
# A flag to allow using the 'register-unsafely-without-email' flag.
#
class letsencrypt (
Optional[String] $email = undef,
String $path = $letsencrypt::params::path,
String $repo = $letsencrypt::params::repo,
String $version = $letsencrypt::params::version,
String $config_file = $letsencrypt::params::config_file,
Hash[String, Any] $config = $letsencrypt::params::config,
Boolean $manage_config = $letsencrypt::params::manage_config,
Boolean $manage_dependencies = $letsencrypt::params::manage_dependencies,
Boolean $agree_tos = $letsencrypt::params::agree_tos,
Boolean $unsafe_registration = $letsencrypt::params::unsafe_registration,
$email = undef,
$path = $letsencrypt::params::path,
$repo = $letsencrypt::params::repo,
$version = $letsencrypt::params::version,
$package_ensure = $letsencrypt::params::package_ensure,
$config_file = $letsencrypt::params::config_file,
$config = $letsencrypt::params::config,
$manage_config = $letsencrypt::params::manage_config,
$manage_install = $letsencrypt::params::manage_install,
$manage_dependencies = $letsencrypt::params::manage_dependencies,
$configure_epel = $letsencrypt::params::configure_epel,
$install_method = $letsencrypt::params::install_method,
$agree_tos = $letsencrypt::params::agree_tos,
$unsafe_registration = $letsencrypt::params::unsafe_registration,
) inherits letsencrypt::params {
validate_string($path, $repo, $version, $config_file)
if $email {
validate_string($email)
}
validate_bool($manage_config, $manage_install, $manage_dependencies, $configure_epel, $agree_tos, $unsafe_registration)
validate_hash($config)
validate_re($install_method, ['^package$', '^vcs$'])

if $manage_install {
contain letsencrypt::install
Class['letsencrypt::install'] ~> Exec['initialize letsencrypt']
}

if $manage_dependencies {
$dependencies = ['python', 'git']
ensure_packages($dependencies)
Package[$dependencies] -> Vcsrepo[$path]
$command = $install_method ? {
'package' => 'letsencrypt',
'vcs' => "${path}/letsencrypt-auto",
}

if $manage_config {
contain letsencrypt::config
Class['letsencrypt::config'] -> Exec['initialize letsencrypt']
}

vcsrepo { $path:
ensure => present,
provider => git,
source => $repo,
revision => $version,
notify => Exec['initialize letsencrypt'],
}

exec { 'initialize letsencrypt':
command => "${path}/letsencrypt-auto -h",
command => "${command} -h",
path => $::path,
refreshonly => true,
}
}
65 changes: 65 additions & 0 deletions manifests/install.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# == Class: letsencrypt::install
#
# This class installs the Let's Encrypt client. This is a private class.
#
# === Parameters:
#
# [*manage_install*]
# A feature flag to toggle the management of the letsencrypt client
# installation.
# [*manage_dependencies*]
# A feature flag to toggle the management of the letsencrypt dependencies.
# [*configure_epel*]
# A feature flag to include the 'epel' class and depend on it for package
# installation.
# [*install_method*]
# Method to install the letsencrypt client, either package or vcs.
# [*path*]
# The path to the letsencrypt installation.
# [*repo*]
# A Git URL to install the Let's encrypt client from.
# [*version*]
# The Git ref (tag, sha, branch) to check out when installing the client with
# the `vcs` method.
# [*package_ensure*]
# The value passed to `ensure` when installing the client with the `package`
# method.
#
class letsencrypt::install (
$manage_install = $letsencrypt::manage_install,
$manage_dependencies = $letsencrypt::manage_dependencies,
$configure_epel = $letsencrypt::configure_epel,
$install_method = $letsencrypt::install_method,
$package_ensure = $letsencrypt::package_ensure,
$path = $letsencrypt::path,
$repo = $letsencrypt::repo,
$version = $letsencrypt::version,
) {
validate_bool($manage_install, $manage_dependencies, $configure_epel)
validate_re($install_method, ['^package$', '^vcs$'])
validate_string($path, $repo, $version)

if $install_method == 'vcs' {
if $manage_dependencies {
$dependencies = ['python', 'git']
ensure_packages($dependencies)
Package[$dependencies] -> Vcsrepo[$path]
}

vcsrepo { $path:
ensure => present,
provider => git,
source => $repo,
revision => $version,
}
} else {
package { 'letsencrypt':
ensure => $package_ensure,
}

if $configure_epel {
include ::epel
Class['epel'] -> Package['letsencrypt']
}
}
}
Loading