diff --git a/.gitignore b/.gitignore index 133e989c..26f3a7e3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .vagrant *.swp *.swo +.*.sw? .bundle vendor/ @@ -12,5 +13,6 @@ Gemfile.lock .rbenv* .rvmrc* .ruby-version +.ruby-gemset spec/fixtures/ diff --git a/Rakefile b/Rakefile index b7934ece..b6c06850 100644 --- a/Rakefile +++ b/Rakefile @@ -10,6 +10,8 @@ rescue LoadError end PuppetLint.configuration.send("disable_80chars") +PuppetLint.configuration.send("disable_documentation") +PuppetLint.configuration.send("disable_arrow_alignment") PuppetLint.configuration.log_format = "%{path}:%{linenumber}:%{check}:%{KIND}:%{message}" PuppetLint.configuration.fail_on_warnings = true diff --git a/manifests/gutterball.pp b/manifests/gutterball.pp new file mode 100644 index 00000000..3a763ae4 --- /dev/null +++ b/manifests/gutterball.pp @@ -0,0 +1,91 @@ +class certs::gutterball( + + $hostname = $::certs::node_fqdn, + $generate = $::certs::generate, + $regenerate = $::certs::regenerate, + $deploy = $::certs::deploy, + $pki_dir = $::certs::pki_dir, + $password_file = $::certs::gutterball_keystore_password_file, + $amqp_truststore = $::certs::gutterball_amqp_truststore, + $amqp_keystore = $::certs::gutterball_amqp_keystore, + $amqp_store_dir = $::certs::gutterball_amqp_store_dir, + +) inherits certs::params { + $keystore_alias = 'gutterball' + $ca_key = $::certs::ca_key + $ca = $::certs::ca_cert_stripped + $key = "${::certs::gutterball_certs_dir}/gutterball.key" + $cert = "${::certs::gutterball_certs_dir}/gutterball.crt" + + $gutterball_keystore_password = cache_data('gutterball_keystore_password', random_password(32)) + + $keypair= 'gutterball-certs' + + cert { $keypair: + ensure => present, + hostname => $hostname, + country => $::certs::country, + state => $::certs::state, + city => $::certs::sity, + org => 'gutterball', + org_unit => $::certs::org_unit, + expiration => $::certs::expiration, + ca => $::certs::default_ca, + generate => $generate, + regenerate => $regenerate, + deploy => $deploy, + password_file => $certs::ca_key_password_file, + } + if $deploy { + file { $certs::gutterball_certs_dir: + ensure => directory, + owner => 'tomcat', + group => $::certs::group, + mode => '0755', + } -> + Cert[$keypair] ~> + privkey { $key: + key_pair => Cert[$keypair] + } ~> + pubkey { $cert: + key_pair => Cert[$keypair] + } -> + file { $password_file: + ensure => file, + content => $gutterball_keystore_password, + owner => $certs::user, + group => $certs::group, + mode => '0440', + } ~> + certs::ssltools::certutil{ 'guterball-amqp-client': + nss_db_dir => $::certs::nss_db_dir, + client_cert => $cert, + } ~> + file { $amqp_store_dir: + ensure => directory, + owner => 'tomcat', + group => $::certs::group, + mode => '0750', + } ~> + certs::ssltools::keytool::import_ca { 'import CA into gutterball truststore': + keystore => $amqp_truststore, + password => $gutterball_keystore_password, + keystore_alias => $keystore_alias, + file => $ca + } ~> + certs::ssltools::keytool::import_keypair{ 'import client certificate into gutterball keystore': + keystore_alias => $keystore_alias, + keystore => $amqp_keystore, + keystore_password => $gutterball_keystore_password, + cert => $cert, + key => $key, + tmp_password_file => $password_file + } ~> + file { $amqp_keystore: + ensure => file, + owner => 'tomcat', + group => $::certs::group, + mode => '0640', + } + } +} diff --git a/manifests/params.pp b/manifests/params.pp index 267b58b6..046377e8 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -19,8 +19,7 @@ $custom_repo = false - $ca_common_name = $::fqdn # we need fqdn as CA common name as candlepin uses it as a ssl cert - + $ca_common_name = $::fqdn # we need fqdn as CA common name as candlepin uses it as a ssl cert $generate = true $generate = true $regenerate = false $regenerate_ca = false @@ -72,6 +71,12 @@ $candlepin_amqp_keystore = "${candlepin_amqp_store_dir}/candlepin.jks" $candlepin_qpid_exchange = 'event' + $gutterball_certs_dir = '/etc/gutterball/certs' + $gutterball_amqp_store_dir = "${gutterball_certs_dir}/amqp/" + $gutterball_amqp_truststore = "${gutterball_amqp_store_dir}/gutterball.truststore" + $gutterball_amqp_keystore = "${gutterball_amqp_store_dir}/gutterball.jks" + $gutterball_keystore_password_file = "${pki_dir}/keystore_password-file-gutterball" + $certs_tar = undef # Settings for uploading packages to Katello $katello_user = undef diff --git a/manifests/ssltools/certutil.pp b/manifests/ssltools/certutil.pp new file mode 100644 index 00000000..c3fc2ac0 --- /dev/null +++ b/manifests/ssltools/certutil.pp @@ -0,0 +1,17 @@ +define certs::ssltools::certutil($cert_name=$title, $nss_db_dir, $client_cert, $refreshonly = true) { + file { $client_cert: + ensure => present + } -> + exec { "delete ${cert_name}": + path => ['/bin', '/usr/bin'], + unless => "certutil -D -d ${nss_db_dir} -n '$cert_name'", + onlyif => "certutil -L -d ${nss_db_dir} | grep '$cert_name'", + refreshonly => $refreshonly, + } -> + exec { $cert_name: + path => ['/bin', '/usr/bin'], + command => "certutil -A -d '${nss_db_dir}' -n '$cert_name' -t ',,' -a -i '${client_cert}'", + unless => "certutil -L -d ${nss_db_dir} | grep '$cert_name'", + refreshonly => $refreshonly, + } +} diff --git a/manifests/ssltools/keytool/convert_pkcs12_to_jks.pp b/manifests/ssltools/keytool/convert_pkcs12_to_jks.pp new file mode 100644 index 00000000..90da9576 --- /dev/null +++ b/manifests/ssltools/keytool/convert_pkcs12_to_jks.pp @@ -0,0 +1,7 @@ +define certs::ssltools::keytool::convert_pkcs12_to_jks( $keystore_alias, $dest_keystore, $src_keystore, $keystore_password, $src_keystore_password, $refreshonly = false){ + exec { $title: + command => "keytool -importkeystore -destkeystore ${dest_keystore} -srckeystore ${src_keystore} -srcstoretype pkcs12 -alias ${keystore_alias} -storepass ${keystore_password} -srcstorepass ${src_keystore_password} -noprompt", + path => ['/bin/', '/usr/bin'], + refreshonly => $refreshonly, + } +} diff --git a/manifests/ssltools/keytool/import_ca.pp b/manifests/ssltools/keytool/import_ca.pp new file mode 100644 index 00000000..59e3c39f --- /dev/null +++ b/manifests/ssltools/keytool/import_ca.pp @@ -0,0 +1,7 @@ +define certs::ssltools::keytool::import_ca($keystore, $password, $keystore_alias, $file){ + exec { $title: + command => "keytool -import -v -keystore ${keystore} -storepass ${password} -alias ${keystore_alias} -file ${file} -noprompt", + creates => $keystore, + path => ['/bin/', '/usr/bin'] + } +} diff --git a/manifests/ssltools/keytool/import_keypair.pp b/manifests/ssltools/keytool/import_keypair.pp new file mode 100644 index 00000000..f39b5c52 --- /dev/null +++ b/manifests/ssltools/keytool/import_keypair.pp @@ -0,0 +1,29 @@ +define certs::ssltools::keytool::import_keypair($keystore_alias, $keystore, $keystore_password, $cert, $key, $tmp_password_file){ + # Stupid keytool doesn't allow you to import a keypair. You can only import a cert. Hence, we have to + # create the store as an PKCS12 and convert to JKS. See http://stackoverflow.com/a/8224863 + + $tmpkeystore = "/tmp/${keystore_alias}keystore.p12" + exec{ "[${title}] signal import if pair has not been imported": + command => 'echo importing keypair', + unless => "keytool -list -keystore ${keystore} -storepass ${keystore_password} -alias ${keystore_alias}", + path => ['/bin/', '/usr/bin'], + } ~> + certs::ssltools::openssl::pkcs12{ "[${title}] convert x509 cert and key to pkcs12": + cert_name => $keystore_alias, + ca_cert => $cert, + ca_name => 'root', + ca_key => $key, + keystore_out => $tmpkeystore, + password_out => $tmp_password_file, + password_in => $keystore_password, + refreshonly => true, + } -> + convert_pkcs12_to_jks{ "[${title}] convert tmp pkcs12 keystore to jks": + keystore_alias => $keystore_alias, + dest_keystore => $keystore, + src_keystore => $tmpkeystore, + keystore_password => $keystore_password, + src_keystore_password => $keystore_password, + refreshonly => true, + } +} diff --git a/manifests/ssltools/openssl/pkcs12.pp b/manifests/ssltools/openssl/pkcs12.pp new file mode 100644 index 00000000..d5444bdf --- /dev/null +++ b/manifests/ssltools/openssl/pkcs12.pp @@ -0,0 +1,13 @@ +define certs::ssltools::openssl::pkcs12 ( $cert_name, $ca_cert, $ca_key, $ca_name, $keystore_out, $password_out, $password_in = undef, $refreshonly = false) { + $password_in_options = $password_in ? { + undef => '', + default => "-passin \"pass:${password_in}\"", + } + exec { $title: + command => "openssl pkcs12 -export -in ${ca_cert} -inkey ${ca_key} -out ${keystore_out} -name ${cert_name} -CAfile ${ca_cert} -caname ${ca_name} -password \"file:${password_out}\" ${password_in_options}", + creates => $keystore_out, + refreshonly => $refreshonly, + path => ['/bin/', '/usr/bin'], + logoutput => true, + } +}