From 82c6145f2991fd73b2105f25c8c0cef177926332 Mon Sep 17 00:00:00 2001 From: Sean O'Keeffe Date: Fri, 16 Jun 2017 10:33:19 +0100 Subject: [PATCH] Fixes #20021 - Optionally generate CA public cert with other CAs certs --- .travis.yml | 8 ++ Gemfile | 2 +- lib/puppet/provider/ca/katello_ssl_tool.rb | 6 +- lib/puppet/type/ca.rb | 4 + manifests/ca.pp | 2 + manifests/init.pp | 4 + manifests/params.pp | 1 + spec/acceptance/certs_ca_spec.rb | 144 +++++++++++++++++++++ spec/classes/certs_ca_spec.rb | 27 ++++ 9 files changed, 196 insertions(+), 2 deletions(-) create mode 100644 spec/acceptance/certs_ca_spec.rb create mode 100644 spec/classes/certs_ca_spec.rb diff --git a/.travis.yml b/.travis.yml index f890f414..2829b2fd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,5 +9,13 @@ env: - PUPPET_VERSION=4.6 ONLY_OS=redhat-7-x86_64,centos-7-x86_64 matrix: fast_finish: true + include: + # Acceptance tests + - rvm: 2.3.1 + dist: trusty + env: PUPPET_INSTALL_TYPE=agent BEAKER_debug=true BEAKER_set=docker/centos-7 + script: bundle exec rake beaker + services: docker + bundler_args: --without development bundler_args: --without system_tests development sudo: false diff --git a/Gemfile b/Gemfile index aaca82bd..6140ed4f 100644 --- a/Gemfile +++ b/Gemfile @@ -27,7 +27,7 @@ gem 'puppet-blacksmith', '>= 3.1.0', {"groups"=>["development"]} gem 'json', '~> 1.0', {"platforms"=>["ruby_19"], "groups"=>["test"]} gem 'json_pure', '~> 1.0', {"platforms"=>["ruby_19"], "groups"=>["test"]} gem 'beaker-rspec', {"groups"=>["system_tests"]} -gem 'beaker-module_install_helper', {"groups"=>["system_tests"]} +gem 'beaker-module_install_helper', :git => 'https://github.com/puppetlabs/beaker-module_install_helper.git', {"groups"=>["system_tests"]} gem 'beaker-puppet_install_helper', {"groups"=>["system_tests"]} gem 'metadata-json-lint' gem 'kafo_module_lint' diff --git a/lib/puppet/provider/ca/katello_ssl_tool.rb b/lib/puppet/provider/ca/katello_ssl_tool.rb index 62beca22..31ce5d32 100644 --- a/lib/puppet/provider/ca/katello_ssl_tool.rb +++ b/lib/puppet/provider/ca/katello_ssl_tool.rb @@ -6,6 +6,8 @@ protected def generate! + extra_args = [] + extra_args += [ '--other-ca-certs', resource[:other_certs].join(',') ] unless resource[:other_certs].empty? if existing_pubkey FileUtils.mkdir_p(build_path) FileUtils.cp(existing_pubkey, build_path(File.basename(pubkey))) @@ -13,7 +15,8 @@ def generate! '--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]}", @@ -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 diff --git a/lib/puppet/type/ca.rb b/lib/puppet/type/ca.rb index 49193616..453e444e 100644 --- a/lib/puppet/type/ca.rb +++ b/lib/puppet/type/ca.rb @@ -5,4 +5,8 @@ instance_eval(&Certs::CERT_COMMON_PARAMS) + newparam(:other_certs) do + defaultto [] + end + end diff --git a/manifests/ca.pp b/manifests/ca.pp index dfbce101..3374d934 100644 --- a/manifests/ca.pp +++ b/manifests/ca.pp @@ -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: @@ -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] diff --git a/manifests/init.pp b/manifests/init.pp index b09309a8..66223599 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -86,6 +86,9 @@ # $group:: The group who should own the certs # type:String # +# $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 # type:String # @@ -121,6 +124,7 @@ $user = $::certs::params::user, $group = $::certs::params::group, + Array[Stdlib::Absolutepath] $other_default_ca_certs = $::certs::params::other_default_ca_certs, $default_ca_name = $::certs::params::default_ca_name, $server_ca_name = $::certs::params::server_ca_name, ) inherits certs::params { diff --git a/manifests/params.pp b/manifests/params.pp index 5c5d7eff..bb976c04 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -18,6 +18,7 @@ $regenerate_ca = false $deploy = true + $other_default_ca_certs = [] $default_ca_name = 'katello-default-ca' $server_ca_name = 'katello-server-ca' diff --git a/spec/acceptance/certs_ca_spec.rb b/spec/acceptance/certs_ca_spec.rb new file mode 100644 index 00000000..caa8a0f5 --- /dev/null +++ b/spec/acceptance/certs_ca_spec.rb @@ -0,0 +1,144 @@ +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 { 'candlepin': + descr => 'Candlepin: an open source entitlement management system.', + baseurl => "https://fedorapeople.org/groups/katello/releases/yum/${repo}/candlepin/${dist}/\\$basearch/", + gpgkey => 'https://raw.githubusercontent.com/Katello/katello-packaging/master/repos/RPM-GPG-KEY-katello-2015', + gpgcheck => '0', + enabled => '1', + } + + 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 file("/etc/pki/katello-certs-tools/certs/katello-default-ca.crt") do + it { should be_file } + it { expect(shell("/usr/bin/openssl x509 -in /etc/pki/katello-certs-tools/certs/katello-default-ca.crt -noout -subject").stdout).to match(fact('fqdn')) } + end + + describe file("/etc/pki/katello-certs-tools/certs/katello-server-ca.crt") do + it { should be_file } + it { expect(shell("/usr/bin/openssl x509 -in /etc/pki/katello-certs-tools/certs/katello-server-ca.crt -noout -subject").stdout).to match(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, + } + + file { '/root/custom_cert': + ensure => directory, + } ~> + exec { 'Create CA key': + cwd => "/root/custom_cert", + path => ["/usr/bin"], + command => "openssl genrsa -out ca.key 2048", + creates => "/root/custom_cert/ca.key", + } ~> + exec { 'Create CA certficates': + cwd => "/root/custom_cert", + path => ["/usr/bin"], + 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", + path => ["/usr/bin"], + command => "openssl genrsa -out katello.example.com.key 2048", + creates => "/root/custom_cert/katello.example.com.key", + } ~> + exec { 'Create CSR': + cwd => "/root/custom_cert", + path => ["/usr/bin"], + 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", + path => ["/usr/bin"], + 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 { 'candlepin': + descr => 'Candlepin: an open source entitlement management system.', + baseurl => "https://fedorapeople.org/groups/katello/releases/yum/${repo}/candlepin/${dist}/\\$basearch/", + gpgkey => 'https://raw.githubusercontent.com/Katello/katello-packaging/master/repos/RPM-GPG-KEY-katello-2015', + gpgcheck => '0', + enabled => '1', + } + + 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 file("/etc/pki/katello-certs-tools/certs/katello-default-ca.crt") do + it { should be_file } + it { expect(shell("/usr/bin/openssl x509 -in /etc/pki/katello-certs-tools/certs/katello-default-ca.crt -noout -subject").stdout).to match(fact('fqdn')) } + end + + describe file("/etc/pki/katello-certs-tools/certs/katello-server-ca.crt") do + it { should be_file } + it { expect(shell("/usr/bin/openssl x509 -in /etc/pki/katello-certs-tools/certs/katello-server-ca.crt -noout -subject").stdout).to match('CustomKatelloCA') } + end + end +end diff --git a/spec/classes/certs_ca_spec.rb b/spec/classes/certs_ca_spec.rb new file mode 100644 index 00000000..4bb5b4e7 --- /dev/null +++ b/spec/classes/certs_ca_spec.rb @@ -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