diff --git a/REFERENCE.md b/REFERENCE.md
index 1296999..827c686 100644
--- a/REFERENCE.md
+++ b/REFERENCE.md
@@ -6,22 +6,17 @@
### Classes
-* [`ca_cert`](#ca_cert): This module manages the user defined certificate authority (CA)
-certificates on the server. On OSes that support a distrusted
-folder the module also manages distrusting system default CA certificates.
+* [`ca_cert`](#ca_cert): This module manages the shared system-wide truststore.
### Defined types
-* [`ca_cert::ca`](#ca_cert--ca): Manage a user defined CA Certificate on a system.
-On OSes that support distrusting pre-installed CAs this can be managed as well.
+* [`ca_cert::ca`](#ca_cert--ca): Manage a CA Certificate in the the shared system-wide truststore.
## Classes
### `ca_cert`
-This module manages the user defined certificate authority (CA)
-certificates on the server. On OSes that support a distrusted
-folder the module also manages distrusting system default CA certificates.
+This module manages the shared system-wide truststore.
#### Examples
@@ -60,6 +55,7 @@ The following parameters are available in the `ca_cert` class:
* [`update_cmd`](#-ca_cert--update_cmd)
* [`trusted_cert_dir`](#-ca_cert--trusted_cert_dir)
* [`distrusted_cert_dir`](#-ca_cert--distrusted_cert_dir)
+* [`ca_certificates_conf`](#-ca_cert--ca_certificates_conf)
* [`install_package`](#-ca_cert--install_package)
* [`package_ensure`](#-ca_cert--package_ensure)
* [`package_name`](#-ca_cert--package_name)
@@ -95,6 +91,15 @@ Default provided by Hiera for supported Operating Systems.
Default value: `undef`
+##### `ca_certificates_conf`
+
+Data type: `Optional[Stdlib::Absolutepath]`
+
+Some distros use a configuration file to mark distrusted certificates.
+Default provided by Hiera for supported Operating Systems.
+
+Default value: `undef`
+
##### `install_package`
Data type: `Boolean`
@@ -198,8 +203,7 @@ Default value: `{}`
### `ca_cert::ca`
-Manage a user defined CA Certificate on a system.
-On OSes that support distrusting pre-installed CAs this can be managed as well.
+Manage a CA Certificate in the the shared system-wide truststore.
#### Examples
@@ -215,55 +219,53 @@ ca_cert::ca { 'globalsign_org_intermediate':
The following parameters are available in the `ca_cert::ca` defined type:
-* [`ca_text`](#-ca_cert--ca--ca_text)
-* [`source`](#-ca_cert--ca--source)
* [`ensure`](#-ca_cert--ca--ensure)
-* [`verify_https_cert`](#-ca_cert--ca--verify_https_cert)
+* [`content`](#-ca_cert--ca--content)
+* [`source`](#-ca_cert--ca--source)
+* [`allow_insecure_source`](#-ca_cert--ca--allow_insecure_source)
* [`checksum`](#-ca_cert--ca--checksum)
* [`checksum_type`](#-ca_cert--ca--checksum_type)
-##### `ca_text`
+##### `ensure`
-Data type: `Optional[String]`
+Data type: `Enum['present', 'absent', 'trusted', 'distrusted']`
-The text of the CA certificate to install. Required if text is the source
-(default). If a different source is specified this parameter is ignored.
+Whether or not the CA certificate should be on a system or not.
+- `present`/`absent` is used to manage local/none default CAs.
+- `trusted`/`distrusted` is used to manage system CAs.
-Default value: `undef`
+Default value: `'present'`
-##### `source`
+##### `content`
-Data type: `String`
+Data type: `Optional[String[1]]`
-Where the CA certificate should be retrieved from. text, http, https, ftp,
-file, and puppet protocols/sources are supported. If text, then the ca_text parameter
-is also required. Defaults to text.
+PEM formatted certificate content
+This attribute is mutually exclusive with `source`
-Default value: `'text'`
+Default value: `undef`
-##### `ensure`
+##### `source`
-Data type: `Enum['present', 'trusted', 'distrusted', 'absent']`
+Data type: `Optional[String[1]]`
-Whether or not the CA certificate should be on a system or not. Valid
-values are trusted, present, distrusted, and absent. Note: untrusted is
-not supported on Debian based systems - using it will log a warning
-and treat it the same as absent. (defaults to trusted)
+A source certificate, which will be copied into place on the local system.
+This attribute is mutually exclusive with `content`
+Uri support, see puppet-archive.
-Default value: `'trusted'`
+Default value: `undef`
-##### `verify_https_cert`
+##### `allow_insecure_source`
Data type: `Boolean`
-When retrieving a certificate whether or not to validate the CA of the
-source. (defaults to true)
+Wether to allow insecure download or not.
-Default value: `true`
+Default value: `false`
##### `checksum`
-Data type: `Optional[String]`
+Data type: `Optional[String[1]]`
The checksum of the file. (defaults to undef)
diff --git a/data/Archlinux-family.yaml b/data/Archlinux-family.yaml
index a03beb4..8d929ec 100644
--- a/data/Archlinux-family.yaml
+++ b/data/Archlinux-family.yaml
@@ -1,4 +1,4 @@
---
ca_cert::update_cmd: 'trust extract-compat'
-ca_cert::trusted_cert_dir: '/etc/ca-certificates/trust-source/anchors/'
-ca_cert::distrusted_cert_dir: '/etc/ca-certificates/trust-source/blacklist'
+ca_cert::trusted_cert_dir: '/etc/ca-certificates/trust-source/anchors'
+ca_cert::distrusted_cert_dir: '/etc/ca-certificates/trust-source/blocklist'
diff --git a/data/Debian-family.yaml b/data/Debian-family.yaml
index 42a81c8..39191cb 100644
--- a/data/Debian-family.yaml
+++ b/data/Debian-family.yaml
@@ -1,3 +1,4 @@
---
-ca_cert::update_cmd: 'update-ca-certificates'
-ca_cert::trusted_cert_dir: '/usr/local/share/ca-certificates'
+ca_cert::update_cmd: 'update-ca-certificates'
+ca_cert::trusted_cert_dir: '/usr/local/share/ca-certificates'
+ca_cert::ca_certificates_conf: '/etc/ca-certificates.conf'
diff --git a/data/RedHat-family-9.yaml b/data/RedHat-family-9.yaml
new file mode 100644
index 0000000..a006784
--- /dev/null
+++ b/data/RedHat-family-9.yaml
@@ -0,0 +1,2 @@
+---
+ca_cert::distrusted_cert_dir: '/etc/pki/ca-trust/source/blocklist'
diff --git a/manifests/ca.pp b/manifests/ca.pp
index edb544f..a8fe87f 100644
--- a/manifests/ca.pp
+++ b/manifests/ca.pp
@@ -1,30 +1,27 @@
# @summary
-# Manage a user defined CA Certificate on a system.
-# On OSes that support distrusting pre-installed CAs this can be managed as well.
+# Manage a CA Certificate in the the shared system-wide truststore.
#
# @example
# ca_cert::ca { 'globalsign_org_intermediate':
# source => 'http://secure.globalsign.com/cacert/gsorganizationvalsha2g2r1.crt',
# }
#
-# @param ca_text
-# The text of the CA certificate to install. Required if text is the source
-# (default). If a different source is specified this parameter is ignored.
+# @param ensure
+# Whether or not the CA certificate should be on a system or not.
+# - `present`/`absent` is used to manage local/none default CAs.
+# - `trusted`/`distrusted` is used to manage system CAs.
#
-# @param source
-# Where the CA certificate should be retrieved from. text, http, https, ftp,
-# file, and puppet protocols/sources are supported. If text, then the ca_text parameter
-# is also required. Defaults to text.
+# @param content
+# PEM formatted certificate content
+# This attribute is mutually exclusive with `source`
#
-# @param ensure
-# Whether or not the CA certificate should be on a system or not. Valid
-# values are trusted, present, distrusted, and absent. Note: untrusted is
-# not supported on Debian based systems - using it will log a warning
-# and treat it the same as absent. (defaults to trusted)
+# @param source
+# A source certificate, which will be copied into place on the local system.
+# This attribute is mutually exclusive with `content`
+# Uri support, see puppet-archive.
#
-# @param verify_https_cert
-# When retrieving a certificate whether or not to validate the CA of the
-# source. (defaults to true)
+# @param allow_insecure_source
+# Wether to allow insecure download or not.
#
# @param checksum
# The checksum of the file. (defaults to undef)
@@ -33,99 +30,85 @@
# The type of file checksum. (defauts to undef)
#
define ca_cert::ca (
- Enum['present', 'trusted', 'distrusted', 'absent'] $ensure = 'trusted',
- String $source = 'text',
- Boolean $verify_https_cert = true,
- Optional[String] $ca_text = undef,
- Optional[String] $checksum = undef,
+ Enum['present', 'absent', 'trusted', 'distrusted'] $ensure = 'present',
+ Boolean $allow_insecure_source = false,
+ Optional[String[1]] $source = undef,
+ Optional[String[1]] $content = undef,
+ Optional[String[1]] $checksum = undef,
Optional[String[1]] $checksum_type = undef,
) {
include ca_cert
- if ($ensure == 'trusted' or $ensure == 'distrusted') and $source == 'text' and !$ca_text {
- fail('ca_text is required if source is set to text')
- }
-
- # Since Debian based OSes don't have explicit distrust directories
- if $facts['os']['family'] == 'Debian' and $ensure == 'distrusted' {
- warning("Cannot explicitly set CA distrust on ${facts['os']['name']}.")
- warning("Ensuring that ${name} CA is absent from the trusted list.")
- $adjusted_ensure = 'absent'
- }
- else {
- $adjusted_ensure = $ensure
- }
-
# Determine Full Resource Name
$resource_name = "${name}.${ca_cert::ca_file_extension}"
- $ca_cert = $adjusted_ensure ? {
- 'distrusted' => "${ca_cert::distrusted_cert_dir}/${resource_name}",
- default => "${ca_cert::trusted_cert_dir}/${resource_name}",
+ case $ensure {
+ 'present', 'absent': {
+ $ca_cert = "${ca_cert::trusted_cert_dir}/${resource_name}"
+ }
+ 'trusted', 'distrusted': {
+ $ca_cert = "${ca_cert::distrusted_cert_dir}/${resource_name}"
+ }
+ default: {}
}
- case $adjusted_ensure {
- 'present', 'trusted', 'distrusted': {
- $source_array = split($source, ':')
- $protocol_type = $source_array[0]
- case $protocol_type {
- 'puppet': {
- file { $resource_name:
- ensure => 'file',
- source => $source,
- path => $ca_cert,
- owner => 'root',
- group => $ca_cert::ca_file_group,
- mode => $ca_cert::ca_file_mode,
- notify => Exec['ca_cert_update'],
- }
- }
- 'ftp', 'https', 'http': {
+ # On Debian we trust/distrust Os provided CAs in config
+ if $facts['os']['family'] == 'Debian' and member(['trusted', 'distrusted'], $ensure) {
+ if $ensure == 'trusted' {
+ exec { "trust ca ${resource_name}":
+ command => "sed -ri \'s|!(.*)${resource_name}|\\1${resource_name}|\' ${ca_cert::ca_certificates_conf}",
+ onlyif => "grep -q ${resource_name} ${ca_cert::ca_certificates_conf} && grep -q \'^!.*${resource_name}\' ${ca_cert::ca_certificates_conf}",
+ path => ['/bin','/usr/bin'],
+ notify => Exec['ca_cert_update'],
+ }
+ } else {
+ exec { "distrust ca ${resource_name}":
+ command => "sed -ri \'s|(.*)${resource_name}|!\\1${resource_name}|\' ${ca_cert::ca_certificates_conf}",
+ onlyif => "grep -q ${resource_name} ${ca_cert::ca_certificates_conf} && grep -q \'^[^!].*${resource_name}\' ${ca_cert::ca_certificates_conf}",
+ path => ['/bin','/usr/bin'],
+ notify => Exec['ca_cert_update'],
+ }
+ }
+ }
+ else {
+ case $ensure {
+ 'present', 'distrusted': {
+ if $source {
archive { $ca_cert:
ensure => 'present',
source => $source,
checksum => $checksum,
checksum_type => $checksum_type,
- allow_insecure => !$verify_https_cert,
+ allow_insecure => $allow_insecure_source,
notify => Exec['ca_cert_update'],
}
- }
- 'file': {
- $source_path = $source_array[1]
- file { $resource_name:
+ -> file { $ca_cert:
ensure => 'file',
- source => $source_path,
- path => $ca_cert,
owner => 'root',
group => $ca_cert::ca_file_group,
mode => $ca_cert::ca_file_mode,
notify => Exec['ca_cert_update'],
}
- }
- 'text': {
- file { $resource_name:
+ } elsif $content {
+ file { $ca_cert:
ensure => 'file',
- content => $ca_text,
- path => $ca_cert,
+ content => $content,
owner => 'root',
group => $ca_cert::ca_file_group,
mode => $ca_cert::ca_file_mode,
notify => Exec['ca_cert_update'],
}
- }
- default: {
- fail('Protocol must be puppet, file, http, https, ftp, or text.')
+ } else {
+ fail('Either `source` or `content` is required')
}
}
- }
- 'absent': {
- file { $ca_cert:
- ensure => absent,
- notify => Exec['ca_cert_update'],
+ 'absent', 'trusted': {
+ file { $ca_cert:
+ ensure => absent,
+ notify => Exec['ca_cert_update'],
+ }
}
- }
- default: {
- fail("Ca_cert::Ca[${name}] - ensure must be set to present, trusted, distrusted, or absent.")
+ default: {}
}
}
}
diff --git a/manifests/init.pp b/manifests/init.pp
index 0598e73..58ec5d7 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -1,7 +1,5 @@
# @summary
-# This module manages the user defined certificate authority (CA)
-# certificates on the server. On OSes that support a distrusted
-# folder the module also manages distrusting system default CA certificates.
+# This module manages the shared system-wide truststore.
#
# @example Basic usage
# class { 'ca_cert': }
@@ -34,6 +32,10 @@
# Absolute directory path to the folder containing distrusted certificates.
# Default provided by Hiera for supported Operating Systems.
#
+# @param ca_certificates_conf
+# Some distros use a configuration file to mark distrusted certificates.
+# Default provided by Hiera for supported Operating Systems.
+#
# @param install_package
# Whether or not this module should install the ca_certificates package.
# The package contains the system default (typically Mozilla) CA
@@ -82,6 +84,7 @@
String[1] $update_cmd,
Stdlib::Absolutepath $trusted_cert_dir,
Optional[Stdlib::Absolutepath] $distrusted_cert_dir = undef,
+ Optional[Stdlib::Absolutepath] $ca_certificates_conf = undef,
Boolean $install_package = true,
Stdlib::Ensure::Package $package_ensure = 'installed',
String[1] $package_name = 'ca-certificates',
diff --git a/spec/acceptance/ca_cert_ca_spec.rb b/spec/acceptance/ca_cert_ca_spec.rb
index b63405c..45a5c19 100644
--- a/spec/acceptance/ca_cert_ca_spec.rb
+++ b/spec/acceptance/ca_cert_ca_spec.rb
@@ -2,31 +2,36 @@
case host_inventory['facter']['os']['family']
when 'Debian'
- trusted_ca_file_remote = '/usr/local/share/ca-certificates/Globalsign_Org_Intermediate.crt'
- absent_ca_file_remote = '/etc/pki/ca-trust/source/blacklist/CACert.crt'
+ trusted_ca_file_remote = '/usr/local/share/ca-certificates/DigiCert_G5_TLS_ECC_SHA384_2021_CA1.crt'
trusted_ca_file_text = '/usr/local/share/ca-certificates/InCommon.crt'
+ ca_certificates_conf = '/etc/ca-certificates.conf'
+ ca_certificates_bundle = '/etc/ssl/certs/ca-certificates.crt'
when 'RedHat'
- trusted_ca_file_remote = '/etc/pki/ca-trust/source/anchors/Globalsign_Org_Intermediate.crt'
- untrusted_ca_file_remote = '/etc/pki/ca-trust/source/blacklist/CACert.crt'
+ trusted_ca_file_remote = '/etc/pki/ca-trust/source/anchors/DigiCert_G5_TLS_ECC_SHA384_2021_CA1.crt'
trusted_ca_file_text = '/etc/pki/ca-trust/source/anchors/InCommon.crt'
+ untrusted_ca_file_remote = if host_inventory['facter']['os']['release']['major'] < '9'
+ '/etc/pki/ca-trust/source/blacklist/DigiCert_Global_Root_G3.crt'
+ else
+ '/etc/pki/ca-trust/source/blocklist/DigiCert_Global_Root_G3.crt'
+ end
+ ca_certificates_bundle = '/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem'
when 'Archlinux'
- trusted_ca_file_remote = '/etc/ca-certificates/trust-source/anchors/Globalsign_Org_Intermediate.crt'
- untrusted_ca_file_remote = '/etc/ca-certificates/trust-source/blacklist/CACert.crt'
+ trusted_ca_file_remote = '/etc/ca-certificates/trust-source/anchors/DigiCert_G5_TLS_ECC_SHA384_2021_CA1.crt'
trusted_ca_file_text = '/etc/ca-certificates/trust-source/anchors/InCommon.crt'
+ untrusted_ca_file_remote = '/etc/ca-certificates/trust-source/blocklist/DigiCert_Global_Root_G3.crt'
+ ca_certificates_bundle = '/etc/ca-certificates/extracted/tls-ca-bundle.pem'
end
describe 'ca_cert::ca' do
- context 'with some normal usage' do
+ context 'add local trusted ca certificates' do
let(:manifest) do
<<~EOS
- include ::ca_cert
+ ca_cert::ca { 'DigiCert_G5_TLS_ECC_SHA384_2021_CA1':
+ source => 'https://cacerts.digicert.com/DigiCertG5TLSECCSHA3842021CA1-1.crt.pem',
+ }
- ca_cert::ca { 'Globalsign_Org_Intermediate':
- source => 'http://secure.globalsign.com/cacert/gsorganizationvalsha2g2r1.crt',
- }
-
- ca_cert::ca { 'InCommon':
- ca_text => '-----BEGIN CERTIFICATE-----
+ ca_cert::ca { 'InCommon':
+ content => '-----BEGIN CERTIFICATE-----
MIIEwzCCA6ugAwIBAgIQf3HB06ImsNKxE/PmgWdkPjANBgkqhkiG9w0BAQUFADBv
MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk
ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF
@@ -54,12 +59,7 @@
kGGmSavOPN/mymTugmU5RZUWukEGAJi6DFZh5MbGhgHPZqkiKQLWPc/EKo2Z3vsJ
FJ4O0dXG14HdrSSrrAcF4h1ow3BmX9M=
-----END CERTIFICATE-----',
- }
-
- ca_cert::ca { 'CACert':
- source => 'http://www.cacert.org/certs/root.crt',
- ensure => 'distrusted',
- }
+ }
EOS
end
@@ -73,15 +73,112 @@
it { is_expected.to be_file }
end
+ describe file(ca_certificates_bundle) do
+ its(:content) do
+ # DigiCert_G5_TLS_ECC_SHA384_2021_CA1
+ is_expected.to match %r{IvZuhDckSAkMNGICMQD4lvGyMGMQirgiqAaMdybUTpcDTLtRQPKiGVZOoSaRtq8o}
+ # InCommon
+ is_expected.to match %r{kGGmSavOPN/mymTugmU5RZUWukEGAJi6DFZh5MbGhgHPZqkiKQLWPc/EKo2Z3vsJ}
+ # DigiCert_Global_Root_G3
+ is_expected.to match %r{oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8}
+ end
+ end
+ end
+
+ context 'distrust a os provided ca certificate' do
+ let(:manifest) do
+ <<~EOS
+ ca_cert::ca { 'DigiCert_Global_Root_G3':
+ source => 'https://cacerts.digicert.com/DigiCertGlobalRootG3.crt.pem',
+ ensure => 'distrusted',
+ }
+ EOS
+ end
+
+ it_behaves_like 'an idempotent resource'
+
case host_inventory['facter']['os']['family']
when 'Debian'
- describe file(absent_ca_file_remote) do
- it { is_expected.not_to be_file }
+ describe file(ca_certificates_conf) do
+ its(:content) { is_expected.to match %r{^!.*DigiCert_Global_Root_G3.crt} }
end
else
describe file(untrusted_ca_file_remote) do
it { is_expected.to be_file }
end
end
+
+ describe file(ca_certificates_bundle) do
+ its(:content) do
+ # DigiCert_Global_Root_G3
+ is_expected.not_to match %r{oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8}
+ end
+ end
+ end
+
+ context 'trust a os provided ca certificate' do
+ let(:manifest) do
+ <<~EOS
+ ca_cert::ca { 'DigiCert_Global_Root_G3':
+ source => 'https://cacerts.digicert.com/DigiCertGlobalRootG3.crt.pem',
+ ensure => 'trusted',
+ }
+ EOS
+ end
+
+ it_behaves_like 'an idempotent resource'
+
+ case host_inventory['facter']['os']['family']
+ when 'Debian'
+ describe file(ca_certificates_conf) do
+ its(:content) { is_expected.to match %r{^[^!].*DigiCert_Global_Root_G3.crt} }
+ end
+ else
+ describe file(untrusted_ca_file_remote) do
+ it { is_expected.not_to exist }
+ end
+ end
+
+ describe file(ca_certificates_bundle) do
+ its(:content) do
+ # DigiCert_Global_Root_G3
+ is_expected.to match %r{oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8}
+ end
+ end
+ end
+
+ context 'remove local trusted ca certificates' do
+ let(:manifest) do
+ <<~EOS
+ ca_cert::ca { 'DigiCert_G5_TLS_ECC_SHA384_2021_CA1':
+ ensure => 'absent',
+ }
+
+ ca_cert::ca { 'InCommon':
+ ensure => 'absent',
+ }
+ EOS
+ end
+
+ it_behaves_like 'an idempotent resource'
+
+ describe file(trusted_ca_file_remote) do
+ it { is_expected.not_to exist }
+ end
+
+ describe file(trusted_ca_file_text) do
+ it { is_expected.not_to exist }
+ end
+
+ describe file(ca_certificates_bundle) do
+ its(:content) do
+ # DigiCert_G5_TLS_ECC_SHA384_2021_CA1
+ is_expected.not_to match %r{IvZuhDckSAkMNGICMQD4lvGyMGMQirgiqAaMdybUTpcDTLtRQPKiGVZOoSaRtq8o}
+ # InCommon
+ is_expected.not_to match %r{kGGmSavOPN/mymTugmU5RZUWukEGAJi6DFZh5MbGhgHPZqkiKQLWPc/EKo2Z3vsJ}
+ # DigiCert_Global_Root_G3
+ is_expected.to match %r{oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8}
+ end
+ end
end
end
diff --git a/spec/classes/ca_cert_spec.rb b/spec/classes/ca_cert_spec.rb
index cb8b461..73d667b 100644
--- a/spec/classes/ca_cert_spec.rb
+++ b/spec/classes/ca_cert_spec.rb
@@ -9,7 +9,7 @@
trusted_cert_dir = '/etc/pki/ca-trust/source/anchors'
update_cmd = 'update-ca-trust extract'
when 'Archlinux'
- trusted_cert_dir = '/etc/ca-certificates/trust-source/anchors/'
+ trusted_cert_dir = '/etc/ca-certificates/trust-source/anchors'
update_cmd = 'trust extract-compat'
when 'Suse'
trusted_cert_dir = '/etc/pki/trust/anchors'
@@ -63,8 +63,10 @@
it { is_expected.to contain_ca_cert__ca('ca1') } # from ./spec/fixtures/hiera
it { is_expected.to contain_ca_cert__ca('ca2') } # from ./spec/fixtures/hiera
- it { is_expected.to contain_file('ca1.crt').with_source('puppet:///modules/ca_cert/ca1.pem') }
- it { is_expected.to contain_file('ca2.crt').with_source('puppet:///modules/ca_cert/ca2.pem') }
+ it { is_expected.to contain_archive("#{trusted_cert_dir}/ca1.crt").with_source('puppet:///modules/ca_cert/ca1.pem') }
+ it { is_expected.to contain_archive("#{trusted_cert_dir}/ca2.crt").with_source('puppet:///modules/ca_cert/ca2.pem') }
+ it { is_expected.to contain_file("#{trusted_cert_dir}/ca1.crt").with_ensure('file') }
+ it { is_expected.to contain_file("#{trusted_cert_dir}/ca2.crt").with_ensure('file') }
context 'with always_update_certs set to true' do
let(:params) { { always_update_certs: true } }
diff --git a/spec/defines/ca_spec.rb b/spec/defines/ca_spec.rb
index 8703639..ee5d8d3 100644
--- a/spec/defines/ca_spec.rb
+++ b/spec/defines/ca_spec.rb
@@ -2,7 +2,11 @@
describe 'ca_cert::ca', type: :define do
let(:title) { 'Globalsign_Org_Intermediate' }
- let(:pre_condition) { 'class {"ca_cert": }' }
+ let(:pre_condition) do
+ 'class {"ca_cert":
+ ca_certs => {},
+ }'
+ end
on_supported_os.sort.each do |os, facts|
# define os specific defaults
@@ -11,10 +15,14 @@
trusted_cert_dir = '/usr/local/share/ca-certificates'
when 'RedHat'
trusted_cert_dir = '/etc/pki/ca-trust/source/anchors'
- distrusted_cert_dir = '/etc/pki/ca-trust/source/blacklist'
+ distrusted_cert_dir = if facts[:os]['release']['major'] < '9'
+ '/etc/pki/ca-trust/source/blacklist'
+ else
+ '/etc/pki/ca-trust/source/blocklist'
+ end
when 'Archlinux'
- trusted_cert_dir = '/etc/ca-certificates/trust-source/anchors/'
- distrusted_cert_dir = '/etc/ca-certificates/trust-source/blacklist'
+ trusted_cert_dir = '/etc/ca-certificates/trust-source/anchors'
+ distrusted_cert_dir = '/etc/ca-certificates/trust-source/blocklist'
when 'Suse'
trusted_cert_dir = '/etc/pki/trust/anchors'
distrusted_cert_dir = '/etc/pki/trust/blacklist'
@@ -29,28 +37,21 @@
let(:facts) { facts }
context 'with default values for parameters' do
- it { expect { is_expected.to contain_class(:subject) }.to raise_error(Puppet::Error, %r{ca_text is required if source is set to text}) }
+ it { is_expected.to compile.and_raise_error(%r{Either `source` or `content` is required}) }
end
- context 'with ca_text set to valid value' do
- let(:params) { { ca_text: 'testing' } }
-
- it { is_expected.to compile }
+ context 'with content set to valid value' do
+ let(:params) { { content: 'testing' } }
- it { is_expected.to contain_ca_cert__ca('ca1') }
- it { is_expected.to contain_ca_cert__ca('ca2') }
it { is_expected.to contain_exec('ca_cert_update') }
it { is_expected.to contain_file('trusted_certs') }
- it { is_expected.to contain_file('ca1.crt') }
- it { is_expected.to contain_file('ca2.crt') }
it { is_expected.to contain_package('ca-certificates') }
it do
- is_expected.to contain_file("Globalsign_Org_Intermediate.#{ca_file_extension}").only_with(
+ is_expected.to contain_file("#{trusted_cert_dir}/#{title}.#{ca_file_extension}").only_with(
{
'ensure' => 'file',
'content' => 'testing',
- 'path' => "#{trusted_cert_dir}/Globalsign_Org_Intermediate.#{ca_file_extension}",
'owner' => 'root',
'group' => ca_file_group,
'mode' => ca_file_mode,
@@ -60,157 +61,102 @@
end
end
- context 'with source set to valid string "puppet:///testing.crt"' do
- let(:params) { { source: 'puppet:///testing.crt' } }
-
- it do
- is_expected.to contain_file("Globalsign_Org_Intermediate.#{ca_file_extension}").only_with(
- {
- 'ensure' => 'file',
- 'source' => 'puppet:///testing.crt',
- 'path' => "#{trusted_cert_dir}/Globalsign_Org_Intermediate.#{ca_file_extension}",
- 'owner' => 'root',
- 'group' => ca_file_group,
- 'mode' => ca_file_mode,
- 'notify' => 'Exec[ca_cert_update]',
- }
- )
- end
- end
-
- context 'with source set to valid string "puppet:///testing.pem"' do
- let(:params) { { source: 'puppet:///testing.pem' } }
-
- it do
- is_expected.to contain_file("Globalsign_Org_Intermediate.#{ca_file_extension}").only_with(
- {
- 'ensure' => 'file',
- 'source' => 'puppet:///testing.pem',
- 'path' => "#{trusted_cert_dir}/Globalsign_Org_Intermediate.#{ca_file_extension}",
- 'owner' => 'root',
- 'group' => ca_file_group,
- 'mode' => ca_file_mode,
- 'notify' => 'Exec[ca_cert_update]',
- }
- )
- end
- end
-
- %w[ftp https http].each do |protocol|
- context "with source set to valid string \"#{protocol}://testing.crt\"" do
- let(:params) { { source: "#{protocol}://testing.crt" } }
+ {
+ 'puppet' => { 'hostname' => nil, 'path' => 'testing.crt' },
+ 'file' => { 'hostname' => nil, 'path' => 'testing.pem' },
+ 'ftp' => { 'hostname' => 'ftp.myorg.com', 'path' => 'testing.crt' },
+ 'http' => { 'hostname' => 'www.myorg.com', 'path' => 'testing.pem' },
+ }.each do |key, values|
+ context "with source set to \"#{key}://#{values['hostname']}/#{values['path']}\"" do
+ let(:params) { { source: "#{key}://#{values['hostname']}/#{values['path']}" } }
it do
- is_expected.to contain_archive("#{trusted_cert_dir}/Globalsign_Org_Intermediate.#{ca_file_extension}").only_with(
+ is_expected.to contain_archive("#{trusted_cert_dir}/#{title}.#{ca_file_extension}").only_with(
{
'ensure' => 'present',
- 'source' => "#{protocol}://testing.crt",
+ 'source' => "#{key}://#{values['hostname']}/#{values['path']}",
'checksum' => nil,
'checksum_type' => nil,
'allow_insecure' => false,
+ 'before' => ["File[#{trusted_cert_dir}/#{title}.#{ca_file_extension}]"],
'notify' => 'Exec[ca_cert_update]',
}
)
- end
- end
-
- context "with source set to valid string \"#{protocol}://testing.pem\"" do
- let(:params) { { source: "#{protocol}://testing.pem" } }
-
- it do
- is_expected.to contain_archive("#{trusted_cert_dir}/Globalsign_Org_Intermediate.#{ca_file_extension}").only_with(
+ is_expected.to contain_file("#{trusted_cert_dir}/#{title}.#{ca_file_extension}").only_with(
{
- 'ensure' => 'present',
- 'source' => "#{protocol}://testing.pem",
- 'checksum' => nil,
- 'checksum_type' => nil,
- 'allow_insecure' => false,
- 'notify' => 'Exec[ca_cert_update]',
+ 'ensure' => 'file',
+ 'owner' => 'root',
+ 'group' => ca_file_group,
+ 'mode' => ca_file_mode,
+ 'notify' => 'Exec[ca_cert_update]',
}
)
end
end
end
- context 'with source set to valid string "file:/testing.crt"' do
- let(:params) { { source: 'file:/testing.crt' } }
+ context 'with ensure set to "trusted"' do
+ let(:params) { { ensure: 'trusted' } }
- it do
- is_expected.to contain_file("Globalsign_Org_Intermediate.#{ca_file_extension}").only_with(
- {
- 'ensure' => 'file',
- 'source' => '/testing.crt',
- 'path' => "#{trusted_cert_dir}/Globalsign_Org_Intermediate.#{ca_file_extension}",
- 'owner' => 'root',
- 'group' => ca_file_group,
- 'mode' => ca_file_mode,
- 'notify' => 'Exec[ca_cert_update]',
- }
- )
- end
- end
+ it { is_expected.not_to contain_archive("#{distrusted_cert_dir}/#{title}.#{ca_file_extension}") }
- context 'with source set to valid string "file:/testing.pem"' do
- let(:params) { { source: 'file:/testing.pem' } }
+ case facts[:os]['family']
+ when 'Debian'
+ it { is_expected.to contain_exec("trust ca #{title}.#{ca_file_extension}") }
+ it { is_expected.not_to contain_file("#{distrusted_cert_dir}/#{title}.#{ca_file_extension}") }
+ else
+ it { is_expected.not_to contain_exec("#{title}.#{ca_file_extension}") }
- it do
- is_expected.to contain_file("Globalsign_Org_Intermediate.#{ca_file_extension}").only_with(
- {
- 'ensure' => 'file',
- 'source' => '/testing.pem',
- 'path' => "#{trusted_cert_dir}/Globalsign_Org_Intermediate.#{ca_file_extension}",
- 'owner' => 'root',
- 'group' => ca_file_group,
- 'mode' => ca_file_mode,
- 'notify' => 'Exec[ca_cert_update]',
- }
- )
+ it do
+ is_expected.to contain_file("#{distrusted_cert_dir}/#{title}.#{ca_file_extension}").only_with(
+ {
+ 'ensure' => 'absent',
+ 'notify' => 'Exec[ca_cert_update]',
+ }
+ )
+ end
end
end
- context 'with ensure set to valid string "present"' do
- let(:params) { { ensure: 'present' } }
+ context 'with ensure set to "distrusted" and no source or content' do
+ let(:params) { { ensure: 'distrusted' } }
- it do
- is_expected.to contain_file("Globalsign_Org_Intermediate.#{ca_file_extension}").only_with(
- {
- 'ensure' => 'file',
- 'content' => nil,
- 'path' => "#{trusted_cert_dir}/Globalsign_Org_Intermediate.#{ca_file_extension}",
- 'owner' => 'root',
- 'group' => ca_file_group,
- 'mode' => ca_file_mode,
- 'notify' => 'Exec[ca_cert_update]',
- }
- )
+ case facts[:os]['family']
+ when 'Debian'
+ it { is_expected.to contain_exec("distrust ca #{title}.#{ca_file_extension}") }
+ it { is_expected.not_to contain_archive("#{distrusted_cert_dir}/#{title}.#{ca_file_extension}") }
+ it { is_expected.not_to contain_file("#{distrusted_cert_dir}/#{title}.#{ca_file_extension}") }
+ else
+ it { is_expected.to compile.and_raise_error(%r{Either `source` or `content` is required}) }
end
end
- context 'with ensure set to valid string "distrusted"' do
- let(:params) { { ensure: 'distrusted' } }
+ context 'with ensure set to "distrusted" and valid source' do
+ let(:params) { { ensure: 'distrusted', source: 'puppet:///testing.crt' } }
- it { expect { is_expected.to contain_class(:subject) }.to raise_error(Puppet::Error, %r{ca_text is required if source is set to text}) }
- end
-
- context 'with ensure set to valid string "distrusted" when source is "file:/dummy.pem"' do
- let(:params) { { ensure: 'distrusted', source: 'file:/dummy.pem' } }
+ case facts[:os]['family']
+ when 'Debian'
+ it { is_expected.to contain_exec("distrust ca #{title}.#{ca_file_extension}") }
+ it { is_expected.not_to contain_archive("#{distrusted_cert_dir}/#{title}.#{ca_file_extension}") }
+ it { is_expected.not_to contain_file("#{distrusted_cert_dir}/#{title}.#{ca_file_extension}") }
+ else
+ it { is_expected.not_to contain_exec("distrust ca #{title}.#{ca_file_extension}") }
- if facts[:os]['family'] == 'Debian'
it do
- is_expected.to contain_file("#{trusted_cert_dir}/Globalsign_Org_Intermediate.#{ca_file_extension}").only_with(
+ is_expected.to contain_archive("#{distrusted_cert_dir}/#{title}.#{ca_file_extension}").only_with(
{
- 'ensure' => 'absent',
- 'notify' => 'Exec[ca_cert_update]',
+ 'ensure' => 'present',
+ 'source' => 'puppet:///testing.crt',
+ 'checksum' => nil,
+ 'checksum_type' => nil,
+ 'allow_insecure' => false,
+ 'before' => ["File[#{distrusted_cert_dir}/#{title}.#{ca_file_extension}]"],
+ 'notify' => 'Exec[ca_cert_update]',
}
)
- end
- else
- it do
- is_expected.to contain_file("Globalsign_Org_Intermediate.#{ca_file_extension}").only_with(
+ is_expected.to contain_file("#{distrusted_cert_dir}/#{title}.#{ca_file_extension}").only_with(
{
'ensure' => 'file',
- 'source' => '/dummy.pem',
- 'path' => "#{distrusted_cert_dir}/Globalsign_Org_Intermediate.#{ca_file_extension}",
'owner' => 'root',
'group' => ca_file_group,
'mode' => ca_file_mode,
@@ -221,40 +167,11 @@
end
end
- context 'with ensure set to valid string "distrusted" when ca_text is "testing"' do
- let(:params) { { ensure: 'distrusted', ca_text: 'testing' } }
-
- if facts[:os]['family'] == 'Debian'
- it do
- is_expected.to contain_file("#{trusted_cert_dir}/Globalsign_Org_Intermediate.#{ca_file_extension}").only_with(
- {
- 'ensure' => 'absent',
- 'notify' => 'Exec[ca_cert_update]',
- }
- )
- end
- else
- it do
- is_expected.to contain_file("Globalsign_Org_Intermediate.#{ca_file_extension}").only_with(
- {
- 'ensure' => 'file',
- 'content' => 'testing',
- 'path' => "#{distrusted_cert_dir}/Globalsign_Org_Intermediate.#{ca_file_extension}",
- 'owner' => 'root',
- 'group' => ca_file_group,
- 'mode' => ca_file_mode,
- 'notify' => 'Exec[ca_cert_update]',
- }
- )
- end
- end
- end
-
- context 'with ensure set to valid string "absent"' do
+ context 'with ensure set to "absent"' do
let(:params) { { ensure: 'absent' } }
it do
- is_expected.to contain_file("#{trusted_cert_dir}/Globalsign_Org_Intermediate.#{ca_file_extension}").only_with(
+ is_expected.to contain_file("#{trusted_cert_dir}/#{title}.#{ca_file_extension}").only_with(
{
'ensure' => 'absent',
'notify' => 'Exec[ca_cert_update]',
@@ -263,24 +180,22 @@
end
end
- %w[ftp https http].each do |protocol|
- context "with verify_https_cert set to valid false when source set to valid string \"#{protocol}://testing.pem\"" do
- let(:params) { { verify_https_cert: false, source: "#{protocol}://testing.pem" } }
+ context 'with allow_insecure_source set to true' do
+ let(:params) { { allow_insecure_source: true, source: 'https://www.myorg.com/testing.pem' } }
- it { is_expected.to contain_archive("#{trusted_cert_dir}/Globalsign_Org_Intermediate.#{ca_file_extension}").with_allow_insecure(true) }
- end
+ it { is_expected.to contain_archive("#{trusted_cert_dir}/#{title}.#{ca_file_extension}").with_allow_insecure(true) }
+ end
- context "with checksum set to valid value when source set to valid string \"#{protocol}://testing.pem\"" do
- let(:params) { { checksum: 'testing', source: "#{protocol}://testing.pem" } }
+ context 'with checksum' do
+ let(:params) { { checksum: 'testing', source: 'https://www.myorg.com/testing.pem' } }
- it { is_expected.to contain_archive("#{trusted_cert_dir}/Globalsign_Org_Intermediate.#{ca_file_extension}").with_checksum('testing') }
- end
+ it { is_expected.to contain_archive("#{trusted_cert_dir}/#{title}.#{ca_file_extension}").with_checksum('testing') }
+ end
- context "with checksum_type set to valid value when source set to valid string \"#{protocol}://testing.pem\"" do
- let(:params) { { checksum_type: 'testing', source: "#{protocol}://testing.pem" } }
+ context 'with checksum_type' do
+ let(:params) { { checksum_type: 'testing', source: 'https://www.myorg.com/testing.pem' } }
- it { is_expected.to contain_archive("#{trusted_cert_dir}/Globalsign_Org_Intermediate.#{ca_file_extension}").with_checksum_type('testing') }
- end
+ it { is_expected.to contain_archive("#{trusted_cert_dir}/#{title}.#{ca_file_extension}").with_checksum_type('testing') }
end
end
end