使用hiera访问另一个节点的事实

我们要做的是为iptables生成防火墙规则(puppetlabs /防火墙)。 我们的节点如此概念分组:

-- site1 ---- shared1 ------ specific1 ------ specific2 ---- shared2 ------ specific3 ------ specific4 

节点“specific4”将始终需要访问“shared2”上的端口8080和“site1”上的端口10000。 “specific1”同样需要访问“shared1”上的8080。 每个节点的规则总是相同的,但他们将依赖于他们分开的组。

我正在努力寻找一种方法来代表这个没有重复的地域。 是否有可能从一个完全独立的节点获得事实?

我想我想能够做到这样(简化):

 -- hosts: host specific4: rules: rule: port: 8080 ip: get_ip(get_my_shared()) 

但显然,你不能从yaml文件中调用函数。 最好的办法是使用自定义事实吗? 我还没有真正使用hiera,所以我不确定最佳实践,不知道什么。 任何温柔的推动正确的方向将是最感激的。

编辑:

这是我走了的解决scheme,但如果我可以使用导出的资源,我可以删除对puppetdb查询的依赖。

 # helper for creating rules from an array define firewall_rules($port, $service_type) { $source = $name firewall { "$port $service_type $source": proto => 'tcp', dport => $port, state => 'NEW', source => "$source", action => 'accept' } } class profile::specific inherits profile { $site = hiera('site') $shared = hiera('shared') $query = "site=\"$site\" and shared=\"$shared\"" $shared_hosts = query_nodes($query) $specific_port = hiera('specific_ports', '8080') firewall_rules { $shared_hosts: port => $specific_port, service_type => 'SPECIFIC' } } 

然后导出site并基于hiera数据shared事实,并使用puppet-stdlib从主机上的file资源加载它们。

 class profile::facts { $site = hiera('site', 'none') $shared = hiera('shared', 'none') $specific = hiera('specific', 'none') $role = hiera('role', 'none') $grouping = "site=$site\nshared=$shared\nspecific=$specific\nrole=$role" notify { "facts being set: $grouping ": } file { ['/etc/facter/', '/etc/facter/facts.d/']: ensure => directory, owner => 'root', group => 'root' }-> file { '/etc/facter/facts.d/grouping.txt': ensure => file, owner => 'root', group => 'root', mode => '0775', content => $grouping } } 

正如我所说,这工作,但我更喜欢使用导出的资源,如果可能的话。 我遇到的问题是执行导出的资源不能导出自己的IP /主机进行收集。 也许我错过了一些东西,但我不认为这是可能的,因为导出发生在资源被parsing时,而不是当包含资源的节点被实现时。

所以你想让某些主机从另一个主机的事实中获取信息,但是事实来自哪个主机将取决于特定主机的configuration。 那是对的吗?

如果是这样,我也build议使用导出的资源并使用标签来指定要使用的特定资源。 这样做的原因是主持人基本上有两种方式来获取另一个主持人的事实。 两者都需要启用商店configuration。 一个是傀儡大师明确查询你的storeconfigs后端是什么; 我不知道封装这个的任何模块,所以你可能必须写自己的。 另一个是源主机输出包含事实的资源; 这更容易,我将在下面描述。

如果您使自己的资源types包装防火墙规则,这将更容易。 这可以防止任何其他碰巧导出防火墙规则的类。

 define site_firewall ($ipaddr) { firewall { '500 allow site access': chain => 'OUTPUT', destination => $ipaddr, proto => 'tcp', port => 10000, } } 

接下来,您的每个网站都应该为site_firewall导出自己的定义:

 @@site_firewall { $hostname: ipaddr => $ipaddress, } 

在hiera中,您可以在层次结构中的某个位置定义每个主机所属的站点:

 sitename: site1 

然后在您的宿主类中,实例化相应的site_firewall定义:

 Site_firewall <<| name == hiera('sitename', 'default') |>> 

类似的设置将适用于共享主机。

如果您需要在站点和共享主机上使用防火墙规则,则应使用标记而不是名称,因为对于给定的主机将有多个防火墙规则。 在特定主机上:

 @@firewall { "500 allow site traffic from ${hostname}": tag => hiera('sitename', 'default-site'), source => $ipaddress, proto => 'tcp', port => 10000, } @@firewall { "500 allow shared traffic from ${hostname}": tag => hiera('sharedname', 'default-shared'), source => $ipaddress, proto => 'tcp', port => 8080, } 

在站点主机上,您只需要收集这些主机的防火墙规则:

 Firewall <<| tag == $hostname |>> 

编辑:啊哈。 我想我已经发现你遇到的出口资源问题。 至less这是我将在这里logging的一个好办法。

如果您有一个具有默认参数的资源,并且在不显式设置这些参数的情况下导出该资源,则参数缺省值由实现该资源的主机提供,而不是导出该资源的资源。

换句话说,如果你有这个资源types定义:

 define foo ($bar = $fqdn) { notice($bar) } 

你从主机baz.example.com输出它:

 @@foo { 'title': } 

而你在主机quux.example.com上意识到这一点:

 Foo <<| |>> 

那么$bar的值就是“quux.example.com”。

如果,而不是像这样从baz.example.com导出它:

 @@foo { 'title': bar => $fqdn } 

那么$bar的值确实是“baz.example.com”。

那么,我认为你的用例的一个好的select是启用“storeconfigs”,然后使用“导出的资源”。 在这里你可以find关于这个主题的一些文档,包括一些例子: http ://docs.puppetlabs.com/guides/exported_resources.html

http://www.masterzen.fr/2009/03/08/all-about-puppet-storeconfigs/