«
Previous
|
Next
»
Revision 7f082050
Added by Ivan Necas over 10 years ago
- ID 7f082050ca4711b7f46fd053801c0a2475ceedf4
- Child c6fafce5
lib/puppet/provider/ca/katello_ssl_tool.rb | ||
---|---|---|
require 'fileutils'
|
||
require File.expand_path('../../katello_ssl_tool', __FILE__)
|
||
|
||
Puppet::Type.type(:ca).provide(:katello_ssl_tool, :parent => Puppet::Provider::KatelloSslTool::Cert) do
|
||
|
||
def self.privkey(name)
|
||
# TODO: just temporarily until we have this changes in katello installer as well
|
||
if name == 'candlepin-ca'
|
||
build_path('candlepin-cert.key')
|
||
else
|
||
target_path("private/#{name}.key")
|
||
end
|
||
end
|
||
|
||
protected
|
||
|
||
def generate_passphrase
|
||
@passphrase ||= generate_random_password
|
||
passphrase_dir = File.dirname(passphrase_file)
|
||
FileUtils.mkdir_p(passphrase_dir) unless File.exists?(passphrase_dir)
|
||
File.open(passphrase_file, 'w') { |f| f << @passphrase }
|
||
return @passphrase
|
||
end
|
||
|
||
def generate!
|
||
passphrase = generate_passphrase
|
||
katello_ssl_tool('--gen-ca',
|
||
'-p', passphrase,
|
||
'--force',
|
||
'--set-common-name', resource[:common_name],
|
||
'--ca-cert', File.basename(pubkey),
|
||
'--ca-key', File.basename(privkey),
|
||
'--ca-cert-rpm', rpmfile_base_name,
|
||
*common_args)
|
||
end
|
||
|
||
def files_to_generate
|
||
[rpmfile, privkey, passphrase_file]
|
||
end
|
||
|
||
def files_to_deploy
|
||
[pubkey]
|
||
end
|
||
|
||
# TODO: just temporarily until we have this changes in katello installer as well
|
||
def rpmfile_base_name
|
||
if resource[:name] == 'candlepin-ca'
|
||
'katello-candlepin-cert-key-pair'
|
||
else
|
||
super
|
||
end
|
||
end
|
||
|
||
def generate_random_password
|
||
size = 20
|
||
# These are quite often confusing ...
|
||
ambiguous_characters = %w(0 1 O I l)
|
||
|
||
# Get allowed characters set ...
|
||
set = ('a' .. 'z').to_a + ('A' .. 'Z').to_a + ('0' .. '9').to_a
|
||
set = set - ambiguous_characters
|
||
|
||
# Shuffle characters in the set at random and return desired number of them ...
|
||
return size.times.collect {|i| set[rand(set.size)] }.join
|
||
end
|
||
|
||
end
|
lib/puppet/provider/cert/katello_ssl_tool.rb | ||
---|---|---|
require 'fileutils'
|
||
require File.expand_path('../../katello_ssl_tool', __FILE__)
|
||
|
||
Puppet::Type.type(:cert).provide(:katello_ssl_tool, :parent => Puppet::Provider::KatelloSslTool::Cert) do
|
||
|
||
def generate!
|
||
resource[:common_name] ||= resource[:hostname]
|
||
purpose = resource[:purpose]
|
||
katello_ssl_tool("--gen-#{purpose}",
|
||
'-p', ca_details[:passphrase],
|
||
'--set-hostname', resource[:hostname],
|
||
'--set-common-name', resource[:common_name],
|
||
'--ca-cert', ca_details[:pubkey],
|
||
'--ca-key', ca_details[:privkey],
|
||
'--server-cert', File.basename(pubkey),
|
||
'--server-key', File.basename(privkey),
|
||
'--server-rpm', rpmfile_base_name,
|
||
*common_args)
|
||
end
|
||
|
||
protected
|
||
|
||
def build_path(file_name)
|
||
self.class.build_path(File.join(resource[:hostname], file_name))
|
||
end
|
||
|
||
def ca_details
|
||
return @ca_details if defined? @ca_details
|
||
if ca_resource = @resource[:ca]
|
||
name = ca_resource.to_hash[:name]
|
||
@ca_details = Puppet::Provider::KatelloSslTool::Cert.details(name)
|
||
else
|
||
raise 'Wanted to generate cert without ca specified'
|
||
end
|
||
end
|
||
end
|
lib/puppet/provider/katello_ssl_tool.rb | ||
---|---|---|
require 'fileutils'
|
||
module Puppet::Provider::KatelloSslTool
|
||
|
||
class Cert < Puppet::Provider
|
||
|
||
initvars
|
||
|
||
commands :rpm => 'rpm'
|
||
commands :katello_ssl_tool => 'katello-ssl-tool'
|
||
|
||
def exists?
|
||
! generate? && ! deploy?
|
||
end
|
||
|
||
def create
|
||
generate! if generate?
|
||
deploy! if deploy?
|
||
end
|
||
|
||
def self.details(cert_name)
|
||
details = { :pubkey => pubkey(cert_name),
|
||
:privkey => privkey(cert_name) }
|
||
|
||
passphrase_file = passphrase_file(cert_name)
|
||
if File.exists?(passphrase_file)
|
||
details[:passphrase] = File.read(passphrase_file).chomp
|
||
end
|
||
|
||
return details
|
||
end
|
||
|
||
def self.pubkey(name)
|
||
# TODO: just temporarily until we have this changes in katello installer as well
|
||
if name == 'candlepin-ca'
|
||
'/usr/share/katello/candlepin-cert.crt'
|
||
else
|
||
target_path("certs/#{name}.crt")
|
||
end
|
||
end
|
||
|
||
def self.privkey(name)
|
||
# TODO: just temporarily until we have this changes in katello installer as well
|
||
if name == 'candlepin-ca'
|
||
build_path('candlepin-cert.key')
|
||
else
|
||
target_path("private/#{name}.key")
|
||
end
|
||
end
|
||
|
||
def self.passphrase_file(name)
|
||
# TODO: just temporarily until we have this changes in katello installer as well
|
||
if name == 'candlepin-ca'
|
||
'/etc/katello/candlepin_ca_password-file'
|
||
else
|
||
build_path("#{name}.pwd")
|
||
end
|
||
end
|
||
|
||
protected
|
||
|
||
def generate?
|
||
return false unless resource[:generate]
|
||
return true if resource[:regenerate]
|
||
return files_to_generate.any? { |file| ! File.exist?(file) }
|
||
end
|
||
|
||
def files_to_generate
|
||
[rpmfile]
|
||
end
|
||
|
||
def deploy?
|
||
return false unless resource[:deploy]
|
||
return true if resource[:regenerate]
|
||
return true if files_to_deploy.any? { |file| ! File.exist?(file) }
|
||
return true if new_version_available?
|
||
end
|
||
|
||
def files_to_deploy
|
||
[pubkey, privkey]
|
||
end
|
||
|
||
def deploy!
|
||
rpm('-Uvh', '--force', rpmfile)
|
||
end
|
||
|
||
def new_version_available?
|
||
current_version = version_from_name(`rpm -q #{rpmfile_base_name}`)
|
||
latest_version = version_from_name(`rpm -pq #{rpmfile}`)
|
||
(latest_version <=> current_version) > 0
|
||
end
|
||
|
||
def version_from_name(rpmname)
|
||
rpmname.scan(/\d+/).map(&:to_i)
|
||
end
|
||
|
||
def common_args
|
||
[ '--set-country', resource[:country],
|
||
'--set-state', resource[:state],
|
||
'--set-city', resource[:city],
|
||
'--set-org', resource[:org],
|
||
'--set-org-unit', resource[:org_unit],
|
||
'--set-email', resource[:email],
|
||
'--cert-expiration', resource[:expiration]]
|
||
end
|
||
|
||
def rpmfile
|
||
rpmfile = Dir[self.build_path("#{rpmfile_base_name}*.noarch.rpm")].max_by do |file|
|
||
version_from_name(file)
|
||
end
|
||
rpmfile ||= self.build_path("#{rpmfile_base_name}.noarch.rpm")
|
||
return rpmfile
|
||
end
|
||
|
||
def rpmfile_base_name
|
||
resource[:name]
|
||
end
|
||
|
||
def pubkey
|
||
self.class.pubkey(resource[:name])
|
||
end
|
||
|
||
def privkey
|
||
self.class.privkey(resource[:name])
|
||
end
|
||
|
||
def passphrase_file
|
||
self.class.passphrase_file(resource[:name])
|
||
end
|
||
|
||
def full_path(file_name)
|
||
self.class.full_path(file_name)
|
||
end
|
||
|
||
def self.target_path(file_name = nil)
|
||
File.join("/etc/pki/tls", file_name)
|
||
end
|
||
|
||
def build_path(file_name)
|
||
self.class.build_path(file_name)
|
||
end
|
||
|
||
def self.build_path(file_name = nil)
|
||
File.join("/root/ssl-build", file_name)
|
||
end
|
||
|
||
end
|
||
|
||
class CertFile < Puppet::Provider
|
||
|
||
include Puppet::Util::Checksums
|
||
|
||
initvars
|
||
|
||
def exists?
|
||
return false unless File.exists?(resource[:path])
|
||
checksum(expected_content) == checksum(current_content)
|
||
end
|
||
|
||
def create
|
||
File.open(resource[:path], "w") { |f| f << expected_content }
|
||
end
|
||
|
||
protected
|
||
|
||
def expected_content
|
||
File.read(source_path)
|
||
end
|
||
|
||
def current_content
|
||
File.read(resource[:path])
|
||
end
|
||
|
||
|
||
def checksum(content)
|
||
md5(content)
|
||
end
|
||
|
||
# what path to copy from
|
||
def source_path
|
||
raise NotImplementedError
|
||
end
|
||
|
||
def cert_details
|
||
return @cert_details if defined? @cert_details
|
||
if cert_resource = @resource[:cert]
|
||
name = cert_resource.to_hash[:name]
|
||
@cert_details = Puppet::Provider::KatelloSslTool::Cert.details(name)
|
||
else
|
||
raise 'Cert was not specified'
|
||
end
|
||
end
|
||
|
||
end
|
||
|
||
end
|
lib/puppet/provider/key_bundle/katello_ssl_tool.rb | ||
---|---|---|
require File.expand_path('../../katello_ssl_tool', __FILE__)
|
||
|
||
Puppet::Type.type(:key_bundle).provide(:katello_ssl_tool, :parent => Puppet::Provider::KatelloSslTool::CertFile) do
|
||
|
||
protected
|
||
|
||
def expected_content
|
||
[privkey, pubkey].map { |f| File.read(f) }.join("\n")
|
||
end
|
||
|
||
def privkey
|
||
resource[:privkey] || cert_details[:privkey]
|
||
end
|
||
|
||
def pubkey
|
||
resource[:pubkey] || cert_details[:pubkey]
|
||
end
|
||
|
||
end
|
lib/puppet/provider/privkey/katello_ssl_tool.rb | ||
---|---|---|
require File.expand_path('../../katello_ssl_tool', __FILE__)
|
||
|
||
Puppet::Type.type(:privkey).provide(:katello_ssl_tool, :parent => Puppet::Provider::KatelloSslTool::CertFile) do
|
||
|
||
protected
|
||
|
||
def source_path
|
||
cert_details[:privkey]
|
||
end
|
||
|
||
end
|
lib/puppet/provider/pubkey/katello_ssl_tool.rb | ||
---|---|---|
require File.expand_path('../../katello_ssl_tool', __FILE__)
|
||
|
||
Puppet::Type.type(:pubkey).provide(:katello_ssl_tool, :parent => Puppet::Provider::KatelloSslTool::CertFile) do
|
||
|
||
protected
|
||
|
||
def source_path
|
||
cert_details[:pubkey]
|
||
end
|
||
|
||
end
|
lib/puppet/type/ca.rb | ||
---|---|---|
require File.expand_path('../certs_common', __FILE__)
|
||
|
||
Puppet::Type.newtype(:ca) do
|
||
desc 'Ca for generating signed certs'
|
||
|
||
instance_eval(&Certs::CERT_COMMON_PARAMS)
|
||
|
||
end
|
lib/puppet/type/cert.rb | ||
---|---|---|
require File.expand_path('../certs_common', __FILE__)
|
||
|
||
Puppet::Type.newtype(:cert) do
|
||
desc 'ca signed cert'
|
||
|
||
instance_eval(&Certs::CERT_COMMON_PARAMS)
|
||
|
||
newparam(:hostname)
|
||
|
||
newparam(:ca) do
|
||
validate do |value|
|
||
unless value.is_a?(Puppet::Resource) && value.resource_type.name == :ca
|
||
raise ArgumentError, "Expected Ca resource"
|
||
end
|
||
end
|
||
end
|
||
|
||
newparam(:purpose) do
|
||
defaultto 'server'
|
||
end
|
||
|
||
autorequire(:ca) do
|
||
if @parameters.has_key?(:ca)
|
||
@parameters[:ca].value.to_hash[:name]
|
||
end
|
||
end
|
||
|
||
end
|
lib/puppet/type/certs_common.rb | ||
---|---|---|
module Certs
|
||
|
||
CERT_COMMON_PARAMS = Proc.new do
|
||
ensurable
|
||
|
||
# make ensure present default
|
||
define_method(:managed?) { true }
|
||
|
||
newparam(:name, :namevar => true)
|
||
|
||
newparam(:common_name)
|
||
|
||
newparam(:email)
|
||
|
||
newparam(:country)
|
||
|
||
newparam(:state)
|
||
|
||
newparam(:city)
|
||
|
||
newparam(:org)
|
||
|
||
newparam(:org_unit)
|
||
|
||
newparam(:expiration)
|
||
|
||
newparam(:generate)
|
||
|
||
newparam(:regenerate)
|
||
|
||
newparam(:deploy)
|
||
end
|
||
|
||
FILE_COMMON_PARAMS = Proc.new do
|
||
ensurable
|
||
|
||
newparam(:path, :namevar => true)
|
||
|
||
# make ensure present default
|
||
define_method(:managed?) { true }
|
||
|
||
newparam(:cert) do
|
||
# TODO: should be required
|
||
validate do |value|
|
||
unless value.is_a?(Puppet::Resource) && [:ca, :cert].include?(value.resource_type.name)
|
||
raise ArgumentError, "Expected Cert or Ca resource"
|
||
end
|
||
end
|
||
end
|
||
|
||
autorequire(:file) do
|
||
@parameters[:path]
|
||
end
|
||
|
||
autorequire(:cert) do
|
||
# TODO: find better way how to determine the type
|
||
if @parameters.has_key?(:cert) &&
|
||
@parameters[:cert].value.resource_type.name == :cert
|
||
@parameters[:cert].value.to_hash[:name]
|
||
end
|
||
end
|
||
|
||
autorequire(:ca) do
|
||
if @parameters.has_key?(:cert) &&
|
||
@parameters[:cert].value.resource_type.name == :ca
|
||
@parameters[:cert].value.to_hash[:name]
|
||
end
|
||
end
|
||
|
||
end
|
||
end
|
lib/puppet/type/key_bundle.rb | ||
---|---|---|
require File.expand_path('../certs_common', __FILE__)
|
||
|
||
Puppet::Type.newtype(:key_bundle) do
|
||
desc 'Stores the public and private key in one file file on a location'
|
||
|
||
instance_eval(&Certs::FILE_COMMON_PARAMS)
|
||
|
||
newparam(:pubkey)
|
||
|
||
newparam(:privkey)
|
||
end
|
lib/puppet/type/privkey.rb | ||
---|---|---|
require File.expand_path('../certs_common', __FILE__)
|
||
|
||
Puppet::Type.newtype(:privkey) do
|
||
desc 'Stores the private key file on a location'
|
||
|
||
instance_eval(&Certs::FILE_COMMON_PARAMS)
|
||
end
|
lib/puppet/type/pubkey.rb | ||
---|---|---|
require File.expand_path('../certs_common', __FILE__)
|
||
|
||
Puppet::Type.newtype(:pubkey) do
|
||
desc 'Stores the public key file on a location'
|
||
|
||
instance_eval(&Certs::FILE_COMMON_PARAMS)
|
||
end
|
manifests/init.pp | ||
---|---|---|
class certs (
|
||
$node_fqdn = $fqdn,
|
||
$generate = true,
|
||
$regenerate = false,
|
||
$regenerate_ca = false,
|
||
$deploy = false,
|
||
$ca_common_name = $certs::params::ca_common_name,
|
||
$country = $certs::params::country,
|
||
$state = $certs::params::state,
|
||
$city = $certs::params::sity,
|
||
$org = $certs::params::org,
|
||
$org_unit = $certs::params::org_unit,
|
||
|
||
$expiration = $certs::params::expiration,
|
||
$ca_expiration = $certs::params::ca_expiration
|
||
) inherits params {
|
||
|
||
$default_ca = Ca['candlepin-ca']
|
||
|
||
ca { 'candlepin-ca':
|
||
ensure => present,
|
||
common_name => $certs::ca_common_name,
|
||
country => $certs::country,
|
||
state => $certs::state,
|
||
city => $certs::city,
|
||
org => $certs::org,
|
||
org_unit => $certs::org_unit,
|
||
expiration => $certs::ca_expiration,
|
||
generate => $certs::generate,
|
||
regenerate => $certs::regenerate_ca,
|
||
deploy => true,
|
||
}
|
||
|
||
}
|
manifests/params.pp | ||
---|---|---|
class certs::params {
|
||
$ca_common_name = $fqdn # we need fqdn as CA common name as candlepin uses it as a ssl cert
|
||
$country = 'US'
|
||
$state = 'North Carolina'
|
||
$city = 'Raleigh'
|
||
$org = 'SomeOrg'
|
||
$org_unit = 'SomeOrgUnit'
|
||
$expiration = '365'
|
||
$ca_expiration = '36500'
|
||
}
|
Also available in: Unified diff
Extract node modules from katello-installer