Puppet 4.10 中的自定义函数仅返回哈希中的第一个数组项
Custom function in Puppet 4.10 only returning first array item in hash
Puppet 中的一个自定义函数,它从数据库中读取 SSL 证书,returns它的结果是一个散列数组。此功能用于使我们的代理服务器上的 SSL 证书保持最新。
创建代理虚拟主机时,我们会读取 SSL 证书以确定虚拟主机应该对哪些主机处于活动状态。为此,我们从证书中检索 "subject alternative names" 并将它们解析为一个数组。
以下代码提取 SAN:
def subject_alt_names
san = @x509.extensions.find { |e| e.oid == 'subjectAltName' }
san.value.split(',').map { |name| name.strip.sub!('DNS:', '') }
end
@x509
变量包含 OpenSSL::X509::Certificate.new
的实例,subject_alt_names
生成证书中预期的名称数组。
到目前为止一切顺利!
现在,在收集所有证书时,我们会根据从数据库中检索到的结果创建一个哈希数组。
代码类似于:
Puppet::Functions.create_function(:'certificates') do
dispatch :up do
end
def up
# Omitted DB calls
mappings.map { |mapping|
certificate = Certificate.new(
OpenSSL::X509::Certificate.new(mapping['certificate']),
OpenSSL::PKey::RSA.new(mapping['private_key']),
mapping['intermediates']
)
{
'common_name' => certificate.common_name,
'domains' => certificate.subject_alt_names,
'private_key' => certificate.private_key,
'certificate' => certificate.x509,
'intermediates' => certificate.chain
}
}
end
end
在 Puppet 中调用函数时,散列中的 domains
数组仅包含一个条目 ("domain.tld") 而不是两个条目 ("domain.tld" 和 "www.domain.tld")。数据库中的大多数 SSL 证书包含两个 SAN 名称。
一个非常简单的测试函数产生了我们期望的结果:
Puppet::Functions.create_function(:'certificates_test') do
dispatch :up do
end
def up
test = "DNS:domain.tld, DNS:www.domain.tld, DNS: www2.domain.tld"
domains = test.split(',').map { |name| name.strip.sub!('DNS:', '') }
{
'domains' => domains
}
end
end
输出:
{
"domains" => ["domain.tld", "www.domain.tld"]
}
在 Puppet 中执行代码时,仅返回 "domains" 数组中的第一个条目。该函数在 Puppet 中的调用方式与以下类似:
certificates().each |$certificate| {
$domains = $certificate['domains']
# Omitted defining of hosts based on $certificate
}
运行 在 CentOS 上的 Puppet 4.10.12(服务器 2.8.1)上。
facter rubysitedir rubyversion
的输出:
rubysitedir => /opt/puppetlabs/puppet/lib/ruby/site_ruby/2.1.0
rubyversion => 2.1.9
如有任何帮助,我们将不胜感激!
通过更新证书 class 的 "subject_alt_names" 方法解决了这个问题。我认为 Puppet 有时会使开发扩展变得困难,因为自定义函数是使用 JRuby 执行的(这有其不同之处)。在这种情况下,我使用的 OpenSSL 扩展不会 return 一个字符串中的所有 SAN 名称,而是将其拆分并使其成为一个哈希数组。
以下代码适用于 JRuby 和 Ruby 的 OpenSSL 扩展(其中 x509
参数是 OpenSSL::X509::Certificate
的一个实例):
def subject_alt_names x509
names = []
x509.extensions.each do |e|
next if e.oid != 'subjectAltName'
names << e.value.split(',').map { |name|
name.strip.sub!('DNS:', '')
}
end
names
end
感谢所有评论!它真的帮助我解决了这个问题:)
Puppet 中的一个自定义函数,它从数据库中读取 SSL 证书,returns它的结果是一个散列数组。此功能用于使我们的代理服务器上的 SSL 证书保持最新。
创建代理虚拟主机时,我们会读取 SSL 证书以确定虚拟主机应该对哪些主机处于活动状态。为此,我们从证书中检索 "subject alternative names" 并将它们解析为一个数组。
以下代码提取 SAN:
def subject_alt_names
san = @x509.extensions.find { |e| e.oid == 'subjectAltName' }
san.value.split(',').map { |name| name.strip.sub!('DNS:', '') }
end
@x509
变量包含 OpenSSL::X509::Certificate.new
的实例,subject_alt_names
生成证书中预期的名称数组。
到目前为止一切顺利!
现在,在收集所有证书时,我们会根据从数据库中检索到的结果创建一个哈希数组。
代码类似于:
Puppet::Functions.create_function(:'certificates') do
dispatch :up do
end
def up
# Omitted DB calls
mappings.map { |mapping|
certificate = Certificate.new(
OpenSSL::X509::Certificate.new(mapping['certificate']),
OpenSSL::PKey::RSA.new(mapping['private_key']),
mapping['intermediates']
)
{
'common_name' => certificate.common_name,
'domains' => certificate.subject_alt_names,
'private_key' => certificate.private_key,
'certificate' => certificate.x509,
'intermediates' => certificate.chain
}
}
end
end
在 Puppet 中调用函数时,散列中的 domains
数组仅包含一个条目 ("domain.tld") 而不是两个条目 ("domain.tld" 和 "www.domain.tld")。数据库中的大多数 SSL 证书包含两个 SAN 名称。
一个非常简单的测试函数产生了我们期望的结果:
Puppet::Functions.create_function(:'certificates_test') do
dispatch :up do
end
def up
test = "DNS:domain.tld, DNS:www.domain.tld, DNS: www2.domain.tld"
domains = test.split(',').map { |name| name.strip.sub!('DNS:', '') }
{
'domains' => domains
}
end
end
输出:
{
"domains" => ["domain.tld", "www.domain.tld"]
}
在 Puppet 中执行代码时,仅返回 "domains" 数组中的第一个条目。该函数在 Puppet 中的调用方式与以下类似:
certificates().each |$certificate| {
$domains = $certificate['domains']
# Omitted defining of hosts based on $certificate
}
运行 在 CentOS 上的 Puppet 4.10.12(服务器 2.8.1)上。
facter rubysitedir rubyversion
的输出:
rubysitedir => /opt/puppetlabs/puppet/lib/ruby/site_ruby/2.1.0
rubyversion => 2.1.9
如有任何帮助,我们将不胜感激!
通过更新证书 class 的 "subject_alt_names" 方法解决了这个问题。我认为 Puppet 有时会使开发扩展变得困难,因为自定义函数是使用 JRuby 执行的(这有其不同之处)。在这种情况下,我使用的 OpenSSL 扩展不会 return 一个字符串中的所有 SAN 名称,而是将其拆分并使其成为一个哈希数组。
以下代码适用于 JRuby 和 Ruby 的 OpenSSL 扩展(其中 x509
参数是 OpenSSL::X509::Certificate
的一个实例):
def subject_alt_names x509
names = []
x509.extensions.each do |e|
next if e.oid != 'subjectAltName'
names << e.value.split(',').map { |name|
name.strip.sub!('DNS:', '')
}
end
names
end
感谢所有评论!它真的帮助我解决了这个问题:)