Puppet自定义功能获取客户端的ipaddress

时间:2016-01-20 01:24:02

标签: puppet

有没有办法从>>木偶自定义函数获取ipaddress<< ?

我正在尝试在自定义端点上使用Puppet::FileServing::Content.indirection.find,如下所示:

[secret]
path /var/lib/puppet/secret/%H
allow *

使用Puppet::FileServing::Content.indirection.find('puppet:///secret/file')时,路径的%H部分将替换为puppetmaster主机名而不是客户端。在破解代码之后,我发现你必须传递节点主机名,ipaddress和这样的环境。

content = Puppet::FileServing::Content.indirection.find(
  'puppet:///secret/file',
  :node => lookupvar('fqdn'),
  :ip => lookupvar('ipaddress'),
  :environment => environment
)
return content.full_path() # this will be /var/lib/puppet/secret/clientnode

但是,我发现使用lookupvar('fqdn')lookupvar('ipaddress')不可靠,因为节点可以使用export FACTER_fqdn=whatever轻松覆盖这些值。

使用lookupvar('clientcert')似乎是获取主机名的方法,因为这是由puppet本身插入的。

修改

我正在构建的功能是将puppet:url指向加密文件转换为另一个木偶:url指向解密文件。

用例:

file{ '/tmp/test'
  source => eyaml_decrypt('puppet:///modules/profile/some_file')
}

在puppet文件中,modules/profile/files/some_file.enc处可能存在一些加密文件,表示给定文件的加密版本。通过这种方式,我们可以与所有人共享我们的puppet文件,而不会有泄露敏感信息的风险。然后,该函数将返回一个类似puppet:///private/some_file的私人傀儡网址,该网址将解析为/var/lib/puppet/private/FQDN/some_file

这是我的解密功能:

module Puppet::Parser::Functions
  newfunction(:eyaml_decrypt, :type => :rvalue, :doc => <<-EOS
Decrypt the given file with `eyaml decrypt -f filepath.enc > filepath`\n
If the target file already exist, the filepath is directly returned. No decryption occurs.\n
 [0] - filepath\n
returns filepath\n
EOS
  ) do |args|

    require 'puppet/file_serving'
    require 'puppet/file_serving/content'
    require 'puppet/file_serving/configuration'
    require 'fileutils'
    require 'digest'

    # Check if file is a puppet url.
    if not args[0].start_with?('puppet:///')
      # This does not mean that there is an error. It could be because in dev, we use a direct path from a node instead of a puppetmaster path.
      Puppet::notice("eyaml_decrypt: The file '#{args[0]}' does not look like a puppet url therefore, no decrypt occurs.")
      return args[0]
    end

    # Check if we already have the unencrypted form of the file in the fileserver
    unencrypted_content = Puppet::FileServing::Content.indirection.find(args[0], :node => lookupvar('clientcert'), :ip => lookupvar('ipaddress'), :environment => environment)
    if unencrypted_content
      return args[0]
    end

    # Check if we have the encrypted form of the file in the fileserver
    encrypted_content = Puppet::FileServing::Content.indirection.find(args[0] + '.enc', :node => lookupvar('clientcert'), :ip => lookupvar('ipaddress'), :environment => environment)
    if not encrypted_content
      # This happens when the unencrypted file is not present AND the encrypted file is not present aswell.
      # This is most likely a mistake from a fully qualified puppetlord and will probably result in a puppet error because the file args[0] won't exist.
      return args[0]
    end
    encrypted_filepath = encrypted_content.full_path()

    # If the hiera specify the box-is-vagrant, no decryption can occurs because the private key is not accessible.
    # If a vagrant box (most likely dev or intg) tries to decrypt a file, it is most propbably a mistake because encrypted data are restricted to prod and accp
    use_hiera_eyaml = function_hiera(['use_hiera_eyaml', false])
    if not use_hiera_eyaml
      Puppet::notice("eyaml_decrypt: no decryption occured for '#{args[0]}.enc' because use_hiera_eyaml is set to false")
      Puppet::notice("eyaml_decrypt: this most likely mean that there is a mistake in the puppet logic. A vagrant box should not have to access private encrypted file")
      return args[0] + '.enc'
    end

    # Check that the private mount does indeed exist.
    private_mount = Puppet::FileServing::Configuration.configuration.find_mount('private', environment)
    if not private_mount
      Puppet::err("eyaml_decrypt: The mount point 'private' is unavailable or does not exist. Check your fileserver.conf")
      return args[0]
    end

    # Prepare the private unencrypted file
    private_filename = Digest::MD5.hexdigest(args[0]) + '-' + File::basename(args[0])
    private_filepath = private_mount.path(lookupvar('clientcert')) + '/' + private_filename
    private_directory_path = File.dirname(private_filepath)
    if not File.directory?(private_directory_path)
      FileUtils.mkdir_p(private_directory_path)
    end

    # use eyaml to decrypt the encrypted file to the private file
    `eyaml decrypt -f #{encrypted_filepath} > #{private_filepath}`
    Puppet::notice("eyaml_decrypt: file '#{encrypted_filepath}' decrypted to '#{private_filepath}'")

    # return the private url for the unencrypted file
    return 'puppet:///private/' + private_filename
  end
end

我希望puppet有一个API可以向我发送有关ssl证书和ip地址等连接节点的可靠信息。

1 个答案:

答案 0 :(得分:0)

您可能需要完全从开发环境中删除敏感信息。也许你可以使用&#34;环境&#34; (puppet config environment默认为production)作为查找秘密文件的字符串的一部分。 r10k有助于使这种事情自动发生

如果在开发环境中,那么生产秘密将无法使用