通常在使用复杂的 Puppet 模块时,我会在节点级别或类内部设置变量。例如,
node 'foo.com' {
$file_owner = "larry"
include bar
}
class bar {
$file_name = "larry.txt"
include do_stuff
}
class do_stuff {
file { $file_name:
ensure => file,
owner => $file_owner,
}
}
在这种情况下,参数化类如何/何时/为什么会有所帮助?您如何使用参数化类来构建您的 Puppet 模块?
答案1
参数化类是一种语言构造,可帮助您更好地构造代码。它可以防止您过度使用全局变量(如您的示例中所示)。
假设您在节点描述中包含了 20 多个类,并且所有类都需要在清单的全局或节点范围内设置一些变量。此外,参数化类允许您轻松获得默认参数,因此您可以为 提供默认值,而$file_owner
不必larry
在多个不同位置提供相同的值(例如 )。
您的示例代码片段(带有两个附加节点)可以写如下:
node 'example.com' {
class { bar: }
}
node 'example.net' {
class { bar: owner = "harry" }
}
node 'example.net' {
class { bar: file_name = "barry.txt" }
}
class bar($owner = "larry", $file_name = "larry.txt") {
class { do_stuff: owner => $owner, file_name => $file_name }
}
class do_stuff($owner, $file_name) {
file { $file_name:
ensure => file,
owner => $owner,
}
}
使用全局变量时,您需要$owner
在每个节点中声明一个变量,并且无法覆盖$file_name
每个节点的变量/参数。相反,您需要bar
为每个节点声明另一个类。
Puppet 语言演变文档以及语言指南提供了一些关于如何使用参数化类以及这种语言构造背后的原理的很好的例子:
答案2
思考这个问题的最好方法是从头开始,而不是从已经知道的 Puppet 习语开始。
你首先想做什么是将参数传递给类 — 您将向其提供决定如何表现所需的信息,就像将参数传递给函数一样。假设这是 perl,并且您有一个名为 multiply_squares 的函数。您可以像这样调用它multiply_squares(3, 4)
,而不是将一些全局变量设置为 3 和 4,然后从函数内部读取它们!
但从历史上看,Puppet 代码必须使用全局变量或动态范围来实现这一点,因为在语言设计之前就存在这样做的需求。就我个人而言,我认为一旦参数化类得到进一步发展和更广泛部署,它们基本上就会使变量范围问题成为过去,因为拥有合适的工具来完成这项工作将消除一大堆可怕的黑客攻击。