Skip to content

Commit

Permalink
Fixes #20021 - Optionally generate CA public cert with other CAs certs
Browse files Browse the repository at this point in the history
  • Loading branch information
sean797 committed Feb 12, 2019
1 parent a9a497a commit 28f1427
Show file tree
Hide file tree
Showing 9 changed files with 208 additions and 4 deletions.
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ matrix:
before_install:
- echo '{"ipv6":true,"fixed-cidr-v6":"2001:db8:1::/64"}' | sudo tee /etc/docker/daemon.json
- sudo service docker restart

bundler_args: --without system_tests development
before_install:
- if [ $TRAVIS_RUBY_VERSION = 2.1.9 ] ; then
Expand Down
10 changes: 7 additions & 3 deletions lib/puppet/provider/ca/katello_ssl_tool.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@
protected

def generate!
if existing_pubkey
extra_args = []
extra_args += [ '--other-ca-certs', resource[:other_certs].join(',') ] unless resource[:other_certs].empty?
if existing_pubkey || resource[:other_certs].any?
FileUtils.mkdir_p(build_path)
FileUtils.cp(existing_pubkey, build_path(File.basename(pubkey)))
FileUtils.cp(existing_pubkey, build_path(File.basename(pubkey))) if existing_pubkey
katello_ssl_tool('--gen-ca',
'--ca-cert-dir', target_path('certs'),
'--ca-cert', File.basename(pubkey),
'--ca-cert-rpm', rpmfile_base_name,
'--rpm-only')
'--rpm-only',
extra_args)
else
katello_ssl_tool('--gen-ca',
'-p', "file:#{resource[:password_file]}",
Expand All @@ -23,6 +26,7 @@ def generate!
'--ca-cert', File.basename(pubkey),
'--ca-key', File.basename(privkey),
'--ca-cert-rpm', rpmfile_base_name,
extra_args,
*common_args)

end
Expand Down
10 changes: 10 additions & 0 deletions lib/puppet/provider/katello_ssl_tool.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@ def generate?
return false unless resource[:generate]
return true if resource[:regenerate]
return true if File.exists?(update_file)
return true if needs_generate?
end

def needs_generate?
if resource.class == Puppet::Type::Ca && resource[:other_certs].any?
default_ca = IO.read(pubkey)
resource[:other_certs].each do |cert|
return true unless default_ca.include? IO.read(cert)
end
end
return files_to_generate.any? { |file| ! File.exist?(file) }
end

Expand Down
16 changes: 16 additions & 0 deletions lib/puppet/type/ca.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,20 @@

instance_eval(&Certs::CERT_COMMON_PARAMS)

newparam(:other_certs, :array_matching => :all) do
validate do |value|
unless value.is_a?(Array) || value.is_a?(String) || value.is_a?(Symbol)
raise Puppet::Error, "Puppet::Type::Ca: other_certs parameter must be an array or a string,
got #{value.class.name}."
end
end

munge do |value|
return [value] if value.is_a?(String) || value.is_a?(Symbol)
value
end

defaultto Array.new
end

end
2 changes: 2 additions & 0 deletions manifests/ca.pp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
$ca_cert_stripped = $certs::ca_cert_stripped,
$ca_key_password = $certs::ca_key_password,
$ca_key_password_file = $certs::ca_key_password_file,
$other_default_ca_certs = $::certs::other_default_ca_certs,
) {

file { $ca_key_password_file:
Expand All @@ -42,6 +43,7 @@
generate => $generate,
deploy => $deploy,
password_file => $ca_key_password_file,
other_certs => $other_default_ca_certs,
}
$default_ca = Ca[$default_ca_name]

Expand Down
4 changes: 4 additions & 0 deletions manifests/init.pp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@
#
# $group:: The group who should own the certs
#
# $other_default_ca_certs:: Certificates to be included with ours, Generally this would be
# the Public CA certificates from the other nodes in a Katello cluster
#
# $default_ca_name:: The name of the default CA
#
# $server_ca_name:: The name of the server CA (used for https)
Expand Down Expand Up @@ -98,6 +101,7 @@
String $default_ca_name = $certs::params::default_ca_name,
String $server_ca_name = $certs::params::server_ca_name,
Optional[Stdlib::Absolutepath] $tar_file = $certs::params::tar_file,
Array[Stdlib::Absolutepath] $other_default_ca_certs = $::certs::params::other_default_ca_certs,
) inherits certs::params {

if $server_cert {
Expand Down
1 change: 1 addition & 0 deletions manifests/params.pp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
$regenerate_ca = false
$deploy = true

$other_default_ca_certs = []
$default_ca_name = 'katello-default-ca'
$server_ca_name = 'katello-server-ca'

Expand Down
141 changes: 141 additions & 0 deletions spec/acceptance/certs_ca_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
require 'spec_helper_acceptance'

describe 'certs with default params' do
context 'with default params' do
let(:pp) do
<<-EOS
$repo = 'latest'
$dist = 'el7'
package { 'epel-release':
ensure => installed,
}
yumrepo { 'katello':
descr => 'Katello latest',
baseurl => "https://fedorapeople.org/groups/katello/releases/yum/${repo}/katello/${dist}/\\$basearch/",
gpgkey => 'https://raw.githubusercontent.com/Katello/katello-packaging/master/repos/RPM-GPG-KEY-katello-2015',
gpgcheck => '0',
enabled => '1',
}
class { '::certs':}
EOS
end

it_behaves_like 'a idempotent resource'

describe package('katello-certs-tools') do
it { is_expected.to be_installed }
end

describe x509_certificate('/etc/pki/katello-certs-tools/certs/katello-default-ca.crt') do
it { should be_certificate }
it { should be_valid }
it { should have_purpose 'SSL server CA' }
its(:issuer) { should eq "/C=US/ST=North Carolina/L=Raleigh/O=Katello/OU=SomeOrgUnit/CN=#{fact('fqdn')}" }
its(:subject) { should eq "/C=US/ST=North Carolina/L=Raleigh/O=Katello/OU=SomeOrgUnit/CN=#{fact('fqdn')}" }
end

describe x509_certificate('/etc/pki/katello-certs-tools/certs/katello-server-ca.crt') do
it { should be_certificate }
it { should be_valid }
it { should have_purpose 'SSL server CA' }
its(:issuer) { should eq "/C=US/ST=North Carolina/L=Raleigh/O=Katello/OU=SomeOrgUnit/CN=#{fact('fqdn')}" }
its(:subject) { should eq "/C=US/ST=North Carolina/L=Raleigh/O=Katello/OU=SomeOrgUnit/CN=#{fact('fqdn')}" }
end
end

context 'with custom server certs' do
before(:all) do
beforepp = <<-EOS
# Mark server-ca for update
file { '/root/ssl-build/katello-server-ca.update':
ensure => file,
}
Exec {
path => ['/usr/bin'],
}
file { '/root/custom_cert':
ensure => directory,
} ~>
exec { 'Create CA key':
cwd => "/root/custom_cert",
command => "openssl genrsa -out ca.key 2048",
creates => "/root/custom_cert/ca.key",
} ~>
exec { 'Create CA certficates':
cwd => "/root/custom_cert",
command => 'openssl req -new -x509 -key ca.key -out ca.crt -nodes -x509 -subj "/C=US/ST=North Carolina/L=Raleigh/O=CustomKatelloCA/CN=www.custom-katello-ca.example.com"',
creates => "/root/custom_cert/ca.crt",
} ~>
exec { 'Create custom key':
cwd => "/root/custom_cert",
command => "openssl genrsa -out katello.example.com.key 2048",
creates => "/root/custom_cert/katello.example.com.key",
} ~>
exec { 'Create CSR':
cwd => "/root/custom_cert",
command => 'openssl req -new -key katello.example.com.key -out katello.example.com.csr -nodes -subj "/C=US/ST=North Carolina/L=Raleigh/O=Katello/CN=www.katello.example.com"',
creates => "/root/custom_cert/katello.example.com.csr",
} ~>
exec { 'Sign CSR':
cwd => "/root/custom_cert",
command => 'openssl x509 -req -in katello.example.com.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out katello.example.com.crt',
creates => "/root/custom_cert/katello.example.com.crt",
}
EOS
apply_manifest(beforepp)
end

let(:pp) do
<<-EOS
$repo = 'latest'
$dist = 'el7'
package { 'epel-release':
ensure => installed,
}
yumrepo { 'katello':
descr => 'Katello latest',
baseurl => "https://fedorapeople.org/groups/katello/releases/yum/${repo}/katello/${dist}/\\$basearch/",
gpgkey => 'https://raw.githubusercontent.com/Katello/katello-packaging/master/repos/RPM-GPG-KEY-katello-2015',
gpgcheck => '0',
enabled => '1',
}
class { '::certs':
server_cert => "/root/custom_cert/katello.example.com.crt",
server_ca_cert => "/root/custom_cert/ca.crt",
server_key => "/root/custom_cert/katello.example.com.key",
server_cert_req => "/root/custom_cert/katello.example.com.csr",
}
EOS
end

it_behaves_like 'a idempotent resource'

describe package('katello-certs-tools') do
it { is_expected.to be_installed }
end

describe x509_certificate('/etc/pki/katello-certs-tools/certs/katello-default-ca.crt') do
it { should be_certificate }
it { should be_valid }
it { should have_purpose 'SSL server CA' }
its(:issuer) { should eq "/C=US/ST=North Carolina/L=Raleigh/O=Katello/OU=SomeOrgUnit/CN=#{fact('fqdn')}" }
its(:subject) { should eq "/C=US/ST=North Carolina/L=Raleigh/O=Katello/OU=SomeOrgUnit/CN=#{fact('fqdn')}" }
end


describe x509_certificate('/etc/pki/katello-certs-tools/certs/katello-server-ca.crt') do
it { should be_certificate }
it { should be_valid }
it { should have_purpose 'SSL server CA' }
its(:issuer) { should eq "/C=US/ST=North Carolina/L=Raleigh/O=CustomKatelloCA/CN=www.custom-katello-ca.example.com" }
its(:subject) { should eq "/C=US/ST=North Carolina/L=Raleigh/O=CustomKatelloCA/CN=www.custom-katello-ca.example.com" }
end
end
end
27 changes: 27 additions & 0 deletions spec/classes/certs_ca_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
require 'spec_helper'

describe 'certs::ca' do
let :facts do
on_supported_os['redhat-7-x86_64']
end

context 'without params ' do
let :pre_condition do
"class {'certs':}"
end

describe 'with ca set' do
it { should contain_ca('katello-default-ca').with({ :other_certs => [] }) }
end
end

context 'with params' do
let :pre_condition do
"class {'certs': other_default_ca_certs => ['/tmp/other-default-cert.crt', '/tmp/another-default-cert.crt']}"
end

describe 'with ca set' do
it { should contain_ca('katello-default-ca').with({ :other_certs => ['/tmp/other-default-cert.crt', '/tmp/another-default-cert.crt'] }) }
end
end
end

0 comments on commit 28f1427

Please sign in to comment.