我认为在 Puppet 中目前还没有正确的方法可以执行以下操作,但这让我感到很可取。
我希望我的类能够影响另一个类的模板文件的内容,这样我们既可以避免重复信息,又可以将信息放在它所属的位置。
例如,我们有一个“iptables”类和各种服务类,例如“postfix”、“webappfoo”等。
class webappfoo {
$myfwrules +> [ "-A INPUT -p tcp --state NEW -m tcp --dport 80 -j ACCEPT" ]
include apache
}
node webappserver {
include webappfoo
include iptables
}
但这不起作用;$myfwrules 数组仅包含 webappfoo 中的那行。
请注意,一个类可以读取另一个类;例如这里 iptables 可以读取 $iptables::myfwrules;但我不希望 iptables 知道 webappfoo。
答案1
这是一个范围问题。从语言教程:
类、组件和节点引入了新的作用域。Puppet 目前是动态作用域,这意味着作用域层次结构是根据代码的评估位置而不是代码的定义位置创建的。
因此,$myfwrules
它的作用域是它所定义的类。在你的情况下,你将其范围限定在类中webappfoo
,它不知道任何先前定义的$myfwrules
。你可以绕过这个但更好的方法可能是使用定义. 类似这样的内容(未经测试,YMMV 等):
class iptables {
define rule($rule) {
# $title is the 'name' of the resource, like ntpd in service { "ntpd": }
exec { "rule-$title":
command => "/sbin/iptables $rule"
}
}
}
class webappfoo {
include iptables
iptables::rule { "webappfoo":
rule => "-A INPUT -p tcp --state NEW -m tcp --dport 80 -j ACCEPT"
}
}
class postfix {
include iptables
iptables::rule { "postfix":
rule => "-A INPUT -p tcp --state NEW -m tcp --dport 25 -j ACCEPT"
}
}
node foo {
include webappfoo
include postfix
}
这样,您就可以通过一种可重复使用的方式将规则添加到类中,而无需定义变量和担心范围。您最终会得到一堆代表节点规则集的Exec
资源(Exec["rule-webappfoo"]
, Exec["rule-postfix"]
) 。foo
另请参阅现成的 iptables 模块。
编辑:这只是一个示例,用于演示如何使用定义。它并不是一个没有问题的解决方案。首先,存在一些问题,包括规则的应用顺序(也许可以使用before
/ ),以及每次after
调用的效率。/sbin/iptables
答案2
我决定使用模板和多重连接来构建 iptables 规则。例如
define iptables::rules {
file { "$local_rules_file":
ensure => "file",
content => template($iptables_start, "iptables/iptables.$name.erb", $iptables_stop)
}
}
它并不美观,并且需要为每台计算机设置一个专用的 iptables.hostname.erb 文件。但它非常简单。
还请阅读有关 Puppet 的存储配置和多文件连接的信息。
答案3
我已经有一段时间没碰过 Puppet 了,所以我的语法可能有点生疏。“+>”应该是“+=”吗?无论如何,你试过这个吗?
类 webappfoo { 包括 Apache } 类 webappfoo::myfwrules { $webappfoo_myfwrules = [ “-A 输入 -p tcp --state NEW -m tcp --dport 80 -j 接受” ] } 节点 webappserver { 包括 iptables $webapplist = ["webappfoo", "webappbar" ] $webappserver_myfwrules => $iptables::iptables_myfwrules $webappserver_myfwrules += $webapplist?{ webappfoo => $webappfoo::myfwrules::webappfoo_myfwrules, webappbar => $webappbar::myfwrules::webappfoo_myfwrules, } }
答案4
这个 iptables 模块似乎是实现我想要的功能的唯一方法;它基本上是一个脚本,它获取 iptables.d/ 目录中的文件并从中构建 /etc/sysconfig/iptables。这可能是我要使用的;但我觉得这种模式在 Puppet 本身中应该是可行的。