2.10 使用选择器和case语句
虽然可以用if来编写任何条件语句,但Puppet还是提供提供了一些其他的形式来帮助用户更容易地编写表达条件语句:选择器(selecteor)和case语句。
操作步骤
下面是一些关于选择器和case语句的例子。
1. 把下面的代码加入到配置清单中:
$systemtype = $::operatingsystem ? {
'Ubuntu' => 'debianlike',
'Debian' => 'debianlike',
'RedHat' => 'redhatlike',
'Fedora' => 'redhatlike',
'CentOS' => 'redhatlike',
default => 'unknown',
}
notify { "You have a ${systemtype} system": }
2. 把下面的代码加入到清单文件中:
class debianlike {
notify { 'Special manifest for Debian-like systems': }
}
class redhatlike {
notify { 'Special manifest for RedHat-like systems': }
}
case $::operatingsystem {
'Ubuntu',
'Debian': {
include debianlike
}
'RedHat',
'Fedora',
'CentOS': {
include redhatlike
}
default: {
notify { "I don't know what kind of system you have!": }
}
}
工作原理
示例演示了选择器和case语句,接下来分别详细地了解一下它们如何完成这个工作。
选择器
在第一个例子中,使用了一个选择器(?操作符),根据$:: operatingsystem的值为$systemtype变量选择不同的值。这类似于C或Ruby中的三元运算符,但不是仅在两个可能的值之间进行选择,而是可以根据需要有尽可能多的可选值。
Puppet会比较$::operatingsystem和每个所提供的可能的值:Ubuntu、Debian等。这些值可以是正则表达式(例如,部分字符串匹配或通配符匹配),但在此例中,只使用文字字符串(或全字符匹配)。一旦找到了一个匹配的值,选择表达式就会返回任何与匹配的字符串相关联的值。例如,如果$::operatingsystem的值是Fedora,选择器表达式将返回字符串redhatlike并把其分配给变量$systemtype。
case语句
与选择器不同,case语句不返回一个值。case语句非常适合根据某个表达式的值选择执行不同的代码。在第二个例子中,使用case语句时,根据$operatingsystem的值,引入了debianlike类或redhatlike类。
此外,Puppet将$::operatingsystem的值与可能的匹配列表进行比较。这些可以是正则表达式,也可以是字符串,或如例子中一样的用逗号分隔的字符串列表。当它找到某一个匹配的选项时,则执行其对应的大括号之间的相关代码。
因此,如果$::operatingsystem的值是Ubuntu,那么代码include debianlike将被执行。
更多参考
一旦读者掌握了选择器和case语句的基本用法,就可以参考下面列出的有用的技巧。
正则表达式
类似于if语句,用户可以在选择器和case语句中使用正则表达式,还可以捕获匹配组的值,并使用$1、$2等引用它们。
case $::lsbdistdescription {
/Ubuntu (.+)/: {
notify { "You have Ubuntu version ${1}": }
}
/CentOS (.+)/: {
notify { "You have CentOS version ${1}": }
}
default: {}
}
默认值
选择器和case语句都可以指定一个默认值,在没有其他的选项相匹配的情况下会自动选择默认值。
$lunch = 'Burger and fries'
$lunchtype = $lunch ? {
/fries/ => 'unhealthy',
/salad/ => 'healthy',
default => 'unknown',
}
notify { "Your lunch was ${lunchtype}": }
Your lunch was unhealthy