无法在定义的类型中创建文件

我想在定义的类型中创建文件。 我已经尝试了几种方法,但无法解决问题。 让我解释一下我的情况。

我正在使用temapltes创建一些文件,我可以完美地完成该操作。 我使用下面的ruby函数来收集文件名,位置类型的数据

require 'rexml/document' include REXML module Puppet::Parser::Functions newfunction(:getConfigFileDetails, :type => :rvalue ) do |args| fileDetails= [] doc = REXML::Document.new args[0] doc.elements.each("node/congfigurations/config") { |config| fileName= config.elements["@fileName"].value fileLocation= config.elements["@location"].value fileDetails < fileName, 'filelocation'=> fileLocation} } return fileDetails end end 

我在我的puppet类中使用这个函数,它对我来说很好

 define fill_templates() { $fileName = $name["filename"] $fileLocation = $name['filelocation'] file { "${fileLocation}/${fileName}/": ensure => present, owner => 'root', group => 'root', mode => '0777', content => template("config/${fileName}.erb"), require => Exec["unzip_pack"], } 

}

 $configFileDetails = getConfigFileDetails($allConfigurations['configurations']) fill_templates { $configFileDetails: } 

然后我尝试使用我自己的内容创建文件,而不是从模板中获取数据。 以下是我的rubyfunction

  require 'rexml/document' include REXML module Puppet::Parser::Functions newfunction(:getCreateFileDetails, :type => :rvalue ) do |args| fileDetails= [] doc = REXML::Document.new args[0] doc.elements.each("node/create/file") { |filedata| fileName= filedata.elements["filename"].text fileLocation= filedata.elements["location"].text fileContent= filedata.elements["content"].text fileDetails < fileName, 'filelocation'=> fileLocation, 'filecontent'=> fileContent } } return fileDetails end end 

我在我的木偶课中使用它如下

 define create_files() { $fileName = $name["filename"] $fileLocation = $name['filelocation'] $fileContent = $name['filecontent'] file { "${fileLocation}/${fileName}/": ensure => present, owner => 'root', group => 'root', content => "$fileContent", } } $createFileDetails = getCreateFileDetails($allConfigurations['configurations']) create_files { $createFileDetails: } 

但它总是给我错误

 Could not retrieve catalog from remote server: Could not intern from pson: Could not convert from pson: Could not find relationship target 

我无法意识到这个问题的原因。 前一个模板工作的原因是什么,后一个模板不工作的原因是什么。

谢谢你对此的了解

我甚至不会试图了解你的第一种方法是如何工作的。 它违背了Puppet清单语义的一些基本规则。

基本上,如果要导入数据结构(从任何地方,实际上)并从中生成资源(通过已定义或本机类型),它应该被构造为哈希:

 { 'resource-name1' => { 'attribute-name1' => 'value', 'attribute-name2' => 'value', ... }, 'resource-name2' => { ... } }, ... 

构建一个类似的数组

 [ { attribute1 => value, attribute2 => value, ... }, { ... }, ] 

并且每个作为资源的名称传递都是无效的。

要解决您的问题,请使自定义函数返回适当的哈希值。 (重命名以避免骆驼案例 – 不是Puppet自定义。)

 require 'rexml/document' include REXML module Puppet::Parser::Functions newfunction(:get_config_file_details, :type => :rvalue ) do |args| result = {} doc = REXML::Document.new args[0] doc.elements.each("node/create/file") { |filedata| name = filedata.elements["filename"].text location = filedata.elements["location"].text conent = filedata.elements["content"].text result[name] = { 'fileLocation' => location, 'fileContent' => content, } } result end end 

您定义的类型需要接受实际参数。 (旁白: create_files是一个非常糟糕的类型名称 – 类型名称应该是单数,并描述每个资源实例代表的内容。)

 define my_config_file($fileName=$name, $fileLocation, $fileContent) { file { "${fileLocation}/${fileName}/": ... } 

最后,要从哈希创建适当的实例,请使用create_resources函数。

 $my_config_file_data = get_config_file_details($xml) create_resources('my_config_files', $my_config_file_data) 

最后建议:如果可能,请以适当的YAML或JSON格式而不是XML序列化数据。 您可以将它们提供给Hiera并通过hiera()函数直接加载它们 – 不需要自定义Ruby代码。

Interesting Posts