Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #20021 - Optionally generate CA public cert with other CAs certs #160

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)
sean797 marked this conversation as resolved.
Show resolved Hide resolved
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