木偶导出资源以获取.erb文件变量?


8

场景:我的配置文件由.erb包含以下代码段的文件定义。

<% backupclients.each do |backup_files| -%>
Job {
  Name = "Server"
  JobDefs = "DefaultJob"
  Client = <%= backup_files %>-fd
  Pool = TeraMonth
  Write Bootstrap = "/var/lib/bacula/<%= backup_files %>.bsr"
}
<% end -%>

服务器的配置文件需要为每个客户端主机重复输入。如果我要创建一个简单的数组,则可以正常工作。但是,我想要做的是让每个主机自己注册,然后使用<<| |>>类似于对nagios_*类型的用法进行编译的方式收集数据。

为此的标准示例涉及导出类型。

class ssh {
  @@sshkey { $hostname: type => dsa, key => $sshdsakey }
  Sshkey <<| |>>
}

但是,我不太清楚如何编写类型或引用类型,以允许我从.erb模板读取该值数组。有没有一种方法可以结合.erb文件中的变量循环使用导出的资源?


他们真的需要以同一文件结尾吗?我喜欢将每个主机放在单独的文件中。像/etc/bacula/clientdefs/*.conf之类的东西。这应该更容易处理。
Zoredache

Answers:


5

因此,直接回答您的问题,我认为直接从erb 获取导出资源列表是不可能的。这是由于出口资源的性质。对于Puppet来说,它们只是需要在主机上创建的更多资源。

但是,有一种方法可以完成您想要的工作。我在环境中的几个地方都这样做。

在这里,我们创建一个文件目录,对于要标记为“ bacula_client”的每个主机,都有一个目录。我们使用purgeforcerecurse选项删除不受木偶管理的文件(例如,如果你想从这个“清单”中删除系统)。

class bacula::client {

  @@file { "/etc/bacula_clients/$fqdn":
    ensure => present,
    content => "",
    require => File['/etc/bacula_clients'],
    tag => "bacula_client",
  }

}

class bacula::server {

  #
  # .. include whatever else the server requires, like package {} file {} service {}
  #

  file { "/etc/bacula_clients":
    ensure => directory,
    purge => true,
    recurse => true,
    force => true,
  }

  # Populate directory of client files.
  File <<| tag == "bacula_client" |>>

}

接下来,我们在.erb中使用一些Ruby代码来扫描此目录中的文件,并对它们执行操作:

<% 
bacula_clients_dir = '/etc/bacula_clients'
d = Dir.open(bacula_clients_dir)

# Remove directories from the list of entries in the directory (specifically '.' and '..'):
backupclients = d.entries.delete_if { |e| File.directory? "#{bacula_clients_dir}/#{e}" }

backupclients.each do |backup_files| 
-%>
Job {
  Name = "Server"
  JobDefs = "DefaultJob"
  Client = <%= backup_files %>-fd
  Pool = TeraMonth
  Write Bootstrap = "/var/lib/bacula/<%= backup_files %>.bsr"
}
<% end -%>

现在我很难过,因为我两天前完成了脚本的编写,而且格式非常接近……也就是说,我将让您选择您是否觉得自己的答案或我的答案更适合我接受。
杰夫·弗兰

我想说,如果应用程序支持配置目录或通配符包含(如bacula看来),则您的答案更合适。我已经在我的环境中将此用于脚本,这些脚本将文件移动到一组目标主机。因此,bash脚本可以做到ls /path/to/flag/files|while read hostname; do ssh $hostname ..; done
凯尔·史密斯

4

好吧,首先我放弃了,并设置@@了实际的文件类型。好处是,它仍在使用客户端主机上的变量。

class bacula-client ($database = false) {
    @@file { "${hostname}-bacula-client.conf":
            mode => 600,
            owner => bacula,
            group => root,
            path => "/etc/bacula/conf.d/${hostname}-client.conf",
            content => template("bacula-dir-cliententry.erb"),
            tag => 'bacula-client',
            notify => Service[bacula-director]
    }

    ...
}

这使我可以使用erb文件中的条目,例如:

<% if has_variable?("database") and database== "true" %>
    ...
<% end -%>

和我的site.pp文件中的声明,例如: class { bacula-client: database => "true" }

要处理目录本身:

class bacula-director {
        file { '/etc/bacula/conf.d':
            ensure => directory,
            owner => bacula,
            group => root,
            mode => 600,
            purge => true,
            recurse => true
        }

        ...
}

清除和递归清除所有未定义的内容。当我使主机脱机时,puppetstoredconfigclean $hostname将清理事实,并且在控制器上进行的下一个伪装运行将适当地重置配置。

最后,Bacula导向器软件本身允许我在bacula-dir.conf文件的末尾执行以下操作:

@|"sh -c 'for f in /etc/bacula/conf.d/*.conf ; do echo @${f} ; done'"

因此,似乎还没有直接的方法可以使用ERB模板来收集一组资源,但是可以收集一种类型。这可能包括将所有内容填充到一个文件中的Augeas类型,或者是将文件收集到配置中的黑客行为。不过,它还没有包括我在这个问题上想要的内容。


1

我已经找到了一种使用PuppetDB服务的方法,这种方法在这种情况下效果很好,尽管有点黑。要使用此功能,您将需要使PuppetDB可操作(在使用导出的资源时应该已经具备),并且需要从puppetmaster(本地主机)中查询PuppetDB API。

然后,您需要将所有希望收集的资源导出到文件系统上专用目录中的阵列中。此目录路径将用于唯一标识目标资源。

然后,在您的模板中,执行以下操作:

    require 'rest_client'
    require 'json'
    resources=JSON.parse(RestClient.get("http://localhost:8080/v2/nodes/#{nodename}/resources", {:accept => :json}))

    retVal = Array.new
    resources.each do |resource|
       if resource["title"] =~ /^#{pathRegex}$/
           retVal.push(resource["title"])
       end
    end

其中nodename是服务器的FQDN,pathRegex是上述搜索路径,格式为Ruby Regex,而retVal是完整的数组。这样可以利用在puppetmaster上处理模板,因此不需要特殊的API凭据。这也假定资源namevar是目标文件的标准路径,如果您具有复杂的namevars并使用path属性,则将需要更复杂的逻辑。另请注意,这将返回所有已导出和本地资源。返回的数据具有许多属性,可以根据需要将其用于更复杂的逻辑。

有点古怪,但效果很好。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.