设为首页 收藏本站
查看: 1113|回复: 0

[经验分享] 自动化运维工具puppet(二)

[复制链接]

尚未签到

发表于 2018-8-2 08:57:36 | 显示全部楼层 |阅读模式
  一、Puppet作域与变量
  1、作用域
  作域的作就是指定特定的代码与其他的代码进隔离。 变量与默认资源将接受这些限制, 资 源标题、 资源引将不接受这样的限制。 接受范围限制的有:

  •   变量
  •   默认资源
  不接受范围限制的有:

  •   资源标题
  •   资源引
  在任何给定作域内, 可访问在本域中定义的变量或资源默认值, 同时继承作域中的内容, 依 此类推。 因此, 任何局部作域都可访问顶级作域中的内容。 使的范围是从该节点作域内直到 全局作域, 如下图所。
DSC0000.jpg

  从上图可以看到:

  •   在全局作域内只能访问作域的变量及默认值。
  •   节点作域内可以访问其的作域和全局作域的变量和默认值。
  •   example:: parent、 example: : other、 example: : four类可以访问的变量和默认值是属于 、 节点及全局作域的。
  •   example: : child类可以访问的, 以及example: : parent、 节点、 全局作域的变量和默 认值。
  通常我们将全局作域内的变量称为全局变量, 将节点作域内的变量称为节点变量, 将局部作 域的变量称为局部变量。
  下将结合例介绍作域在变量中是如何体现的。
  2、全局作域
  全局作域通常定义在站点件site.pp中, 以便作域下所有代码进引。 在如下测试例中 定义个全局变量$variable, 并赋值为Hi!, 在example类中定义notify资源执变量的引。
# site.pp  
$variable = "Hi!"
  
class example {
  
notify {"Message from elsewhere: $variable":}
  
}
  
include example
  3、节点作域
  节点作域通常定义在节点( Node) 内, 可以在节点内引变量, 也可以引上层作域的变 量。 如果在全局作域下对节点作域内的变量进引, 将会失败。 配置例如下:
# site.pp  
$top_variable = "Available!"
  
node 'puppet.example.com' {
  
$variable = "Hi!"
  
notify {"Message from here: $variable":}
  
notify {"Top scope: $top_variable":}
  
}
  
notify {"Message from top scope: $variable":}
  在以上代码中, 定义全局变量$top_variable与节点变量$variable, 在节点内对这两个变量进引 , 同时在全局作域进节点变量$variable的引。 通过puppet apply site.pp的命令我们可以看到节点作域下的两个变量被成功引, 全局作域下的变量引失败。
  4、局部作域
  局部作域通常定义在类内, 可以引类内的变量, 可以引上层节点作域的变量, 也可以引 全局作域的变量。 如果想在节点作域和全局作域下进局部作域的引, 将会失败。 配置例如下:
# /etc/puppet/modules/scope_example/manifests/init.pp  
class scope_example {
  
$variable = "Hi!"
  
notify {"Message from here: $variable":}
  
notify {"Node scope: $node_variable Top scope: $top_variable":}
  
}
  
# /etc/puppet/manifests/site.pp
  
$top_variable = "Available!"
  
node 'puppet.example.com' {
  
$node_variable = "Available!"
  
include scope_example
  
notify {"Message from node scope: $variable":}
  
}
  
notify {"Message from top scope: $variable":}
  在以上代码中: 定义了局部变量$variable、 全局变量$top_variable及节点变量$node_variable, 在 类内对这三个变量进引, 同时在节点作域及全局作域内对局部变量$variable进引。 通过puppet apply site.pp的应我们可以看到: 节点作域下的两个变量被成功引, 节点作域及全局作域下的变量引失败。
  5、变量覆盖
  如果是同时在全局作域、 节点作域、 局部作域由定义的相同的变量名, Puppet将以局部变量 为准。 如果是同时在全局作域、 节点作域中定义的相同的变量名, 则Puppet以节点作域为准。 示例如下:
# /etc/puppet/modules/scope_example/manifests/init.pp  
class scope_example {
  
$variable = "Hi, I'm local!"
  
notify {"Message from here: $variable":}
  
}
  
# /etc/puppet/manifests/site.pp
  
$variable = "Hi, I'm top!"
  
node 'puppet.example.com' {
  
$variable = "Hi, I'm node!"
  
include scope_example
  
}
  在以上代码中定义了三个变量: 局部变量$variable、 全局变量$variable、 节点变量$variable。 我们 可以看到三个变量名相同, 只是在不同的作域中进了引。 运puppet apply site.pp命令可以看到Puppet只以局部变量为准, 却不报错。
  6、属性合并
  当在不同的作域中定义的同个资源具有不同属性值时, 声明不同的属性将会进合并操作, 只 是冲突属性值将会被覆盖。 通过如下例可以看下Puppet如何处理合并与覆盖操作。
$ /etc/puppet/modules/scope_example/manifests/init.pp  
class scope_example {
  
File { ensure => directory, }
  
file {'/tmp/example':}
  
}
  
$ /etc/puppet/manifests/site.pp
  
File {
  
ensure => file,
  
owner => 'puppet',
  
}
  
include scope_example
  在以上代码中, 定义个件资源, 在全局作域中设置了件资源的默认值enusre=> file, 同时在局域类作域中设置了件资源的默认值ensure=>directory, 根据覆盖原则, file{ '/tmp/example': } 的ensure属性将会是directory。 执命令我们可以看到在客户端创建 了"/tmp/example"录, 其户为"puppet", 节点作域的件属性被覆盖, 两个作域的不同属性被合并。
  二、变量
  变量名以美元符“$”开头, 通过赋值运算符“=”赋值。 任何个正则表达式的数据类型的值都可以 赋值给变量。 变量只能使被分配的短名称。 在指定的作域内不能向作域名外的变量赋值, 即变量只持在作域内赋值。 变量在作域内只能赋值次, 通过“+=”运算符进值追加, 同样赋值也只能是次, 但可以同时赋多个, 也可以使内插法赋值。
  1、变量赋值与引
  举例:
class example {  
$content = "Hi, I'm variable!" #声明了个变量
  
File {'/tmp/testing':
  
content => "{$content}", #直接引这个变量
  
}
  
}
  将两个变量的值以字符串的形式拼接起来, 命令如下:
$value = "${one}${two}"  2、变量内插
  举例:
$rule = "Allow * from ${ipaddress}"  
file { "${homedir}/.vim":
  
ensure => directory,
  

  
}
  Puppet可以解决双引号中的字符串的变量, 这就是所谓的“内插法”。
  3、变量的追加
  举例:
$ssh_users = ['myself', 'someone']  
class test {
  
$ssh_users += ['someone_else']
  
}
  通过“+=”附加操作符进变量追加, 变量$ssh_users现在的值为〔 'myself', 'someone', 'someone_else'〕 。 附加操作符“+=”的值必须为相同数据类型的、 可以接收的值。 这个操作符只能 于字符串、 数组和哈希表, 详细信息如下:

  •   将两个字符串连接起来。
  •   对数组元素进合并。
  •   合并两个哈希表。
  4、变量的作域
  跟其他的开发语有所不同, 在Puppet中, 在给定的作域内变量只能被赋值次, 且不能改变这 个值, 但可以在不同的作域内赋不同的值给同变量。
  约定的变量的作域命名规则如下:
$myvar = $class::params::myvar  举例:
node 'www1.example.com' {  
$myvar = "Node scope value" #变量赋值
  
notice( "from www1: $myvar" ) #直接引变量
  
$myvar = "Local scope value" #不可中途改变其值
  
}
  
class myclass {
  
$myvar = "Local scope value"
  
notice( "from myclass: $myvar" )
  
}
  以上代码在Node节点信息中配置了相同的变量, 试图通过第次对变量myvar进赋值来改变其 值, 这在Puppet中是不允许的, 这点不同于其他程序语。 代码测试执时抛出的错误如下:
Error: Could not retrieve catalog from remote server: Error 400 on SERVER: Cannot reassign variab  我们可以在不同的作域下赋值, 代码如下:
node 'www1.example.com' {  
$myvar = "Node scope value"
  
notice( "from www1: $myvar" )
  
}
  
class myclass {
  
$myvar = "Local scope value" #覆盖Node中定义的变量值
  
notice( "from myclass: $myvar" )
  
}
  以上代码通过在类中定义myvar变量的形式覆盖Node节点中定义的值, 执结果如下:
(Scope(Node[agent.domain.com])) from www1: Node scope value  
(Scope(Class[Test])) from myclass: Local scope value
  
Compiled catalog for agent.domain.com in environment production in 0.04 seconds
  同理, 相同的变量可以存在于不同的节点配置中, 这也是作域的特征:
node 'www1.example.com' {  
$myvar = "Node1 scope value"
  
notice( "from www1: $myvar" )
  
}
  
node 'www2.example.com' {
  
$myvar = "Node2 scope value"
  
notice( "from www2: $myvar" )
  
}
  5、Facts和内置变量
  Puppet提供了些客户端及服务端的内置变量。 Facts即运facter命令收集到的系统信息。 除了内 置的变量外, 我们还可以进定义。
  客户端的内置变量有:

  •   $environment: 节点环境。
  •   $clientcert: 节点名称certname。
  •   $clientversion: 客户端Puppet版本。
  服务端的内置变量有:

  •   $servername: 服务端完整、 合格的域名, 主机名即facter中的fqdn。
  •   $serverip: 服务端IP。
  •   $serverversion: 服务端Puppet版本。
  •   $settings: : <name of setting>: 服务端设置项的值。


  •   $module_name: 模块名称。
  使用举例:
[root@example.com tmp]# vim test7.pp  
file {'/tmp/nginx.conf':
  
        ensure   => file,
  
        content  => "worker_processes $processorcount;\n",
  
}
  
[root@example.com tmp]# puppet apply test7.pp
  
notice: /Stage[main]//File[/tmp/nginx.conf]/content: content changed '{md5}c53bae3bb726fbdb9f38267014545f7b' to '{md5}960f3bee4b6ea036b058cacc20650d67'
  
notice: Finished catalog run in 0.05 seconds
  
[root@example.com tmp]# cat nginx.conf
  
worker_processes 1;
  三、数据类型
  Puppet允许多种数据类型, 包括变量、 属性值、 函数参数。 数据类型也是我们编写代码时需要掌握 的内容。
  1、布尔类型
  布尔类型仅有两个值: true和false。 "if"语句条件与较表达式最后的值都是布尔值。 如果需要个 布尔值进依赖处理, Puppet将会动进转换。注意一定不能加引号!

  •   字符串: 空字符串都是false, 其他字符串为true。 可以使puppetlabs-stdlib模块str2bool函数 进转换。
  •   数字: 所有数字都是true, 包括0和负数。 同样可以使puppetlabs-stdlib 模块num2bool函数 进转换。
  •   未定义: 特殊数据类型的undef都为false。
  •   数组和哈希: 任何数组或哈希表都为true, 包括空数组和空哈希表。
  •   资源引: 任何资源引都是true, 不管资源是否已被引、 资源是否存在、 数据类型是否有 效。
  2、未定义
  Puppet特殊的undef值致相当于( nil) 。 在Ruby中, 从未声明的变量值为undef。 书写undef时 必须是不加引号的。
  undef值通常是有的, 于测试个变量是否已经设置。 它也可以作为个资源属性, 当没有设 置任何值从resource default继承, 或者定义该资源的这个属性不被管理时, 我们也可以使defined 函数来测试个类或资源是否已定义, 同时, 还可以将继承于类的资源属性值反设置( 即清空个之前在类中定义好的资源属性值) , 不再让Puppet管理此项内容。 作为个布尔值, undef是false。
  3、字符串
  字符串是任何长度的结构化本段。 简单来说可以概括为如下四类。
  ( 1) 裸词
  所谓裸词即没有引号, 通常被视为单字符, 或字符串。 必须满以下条件:

  •   不能是保留字。
  •   以字母开头, 只包含字母、 数字、 连接符( -) 、 下划线( _) 。
  前Puppet建议所有的字符串为UTF8, 或许以后Puppet将强制所有字符串的编码必须为UTF8。 特 别是以后和Puppetdb结合更加紧密时, 建议家采UTF8以避免以后升级带来的烦。
  ( 2) 单引号
  表个值或者是定义个资源的名称的时候使单引号。 使单引号时, 字符串不允许变量内 插, 只需要对“’”和“\”转义。
  ( 3) 双引号
  双引号通常于定义个变量的引, 例如: “${ name} ”。 使双引号时, 字符串允许变量内 插, 并持多种转义字符, 例如"\n"代表换。
  ( 4) 换
  在UNIX中换符为\n, 在Windows中为\r\n, 在Puppet 2.7.20及以后版本中, 持在字符串中使 \r \n 作为换符。
  4、资源引
  资源引是通过类型和title来定位个已存在的Puppet资源, 在使关系元参数定义资源间的顺序 依赖时, 需要使资源引。 资源引的使法如下:
subscribe => File['/etc/ntp.conf'],  资源引的格式是:
  资源类型( 字母必须写) +个左括号+资源的标题( 或以逗号分隔列表标题) +个右括 号与变量不同, 资源引与书写顺序关, 在资源定义之前就可以使它的引。 个资源可以同时引多个资源, 配置法如下:
require => File['/etc/apache2/httpd.conf', '/etc/apache2/magic', '/etc/apache2/mime.types'],  也可以使数组的法对多个资源进引:
$my_files = ['/etc/apache2/httpd.conf', '/etc/apache2/magic', '/etc/apache2/mime.types']  
require => File[$my_files]
  5、数字
  Puppet算术表达式只接受整数和浮点数。 数字可以写为个裸词或带引号的字符串, 仅由个可选 的负号( -) 和数点组成, 例如:
$some_number = 8 * -7.992  
$another_number = $some_number / 4
  数字不能包含加号, -1到1之间的数字需要使前缀0, 例如:
$product = 8 * +4 # syntax error  
$product = 8 * 4 # OK
  
$product = 8 * .12 # syntax error
  
$product = 8 * 0.12 # OK
  6、哈希类型
  哈希类型的写法为:
  “括号”+“哈希键”+“=>”+“哈希值”
  如果有多个哈希类型, 采逗号分隔。 哈希键是字符串, 但值可以是任何数据类型, 包括数组或哈 希的哈希值, 例如:
{ key1 => 'val1', key2 => 'val2' }  
# Equivalent:
  
{ key1 => 'val1', key2 => 'val2', }
  使法如下:
$myhash = { key => "some value",  
other_key => "some other value" }
  
notice( $myhash[key] )
  上述代码输出$myhash的值为"some value"。
  7、正则表达式
  正则表达式主要运在判断语句、 case语句、 选择器及节点定义中, 且必须是标准的Ruby正则表达 式。 下笔者列举种常见的正则表达式写法。
  主机名正则匹配写法:
if $host =~ /^www(\d+)\./ {  
notify { "Welcome web server #$1": }
  
}
  if判断语句的匹配写法:
if ( $processor_count > 2 ) and (( $ram >= 16 * $gigabyte ) or ( $disksize > 1000 )) {  
include for_big_irons
  
} else {
  
include for_small_box
  
}
  case语句正则匹配写法:
case $hostname {  
/^j(ack|ill)$/: { include hill } # apply the hill class
  
/^[hd]umpty$/: { include wall } # apply the wall clascf
  
default: { include generic } # apply the generic class
  
}
  selector选择器正则匹配写法:
$owner = $operatingsystem ? {  
/(redhat|debian)/ => 'bin',
  
default => undef,
  
}
  正则表达式的写法与表达式密切相关, 因此在写正则表达式时需要查看6.9节中介绍的关于表达式 的相关内容。
  8、数组
  数组被写成使逗号分隔的列表, 使括号括起来。 个数组中的数值可以是任何数据类型, 包 括哈希类型和多个阵列, 例如:
[ 'one', 'two', 'three' ]  上述代码等价于:
[ 'one', 'two', 'three', ]  访问数组中的数字索引, 从零开始计算, 括号主要于索引, 例如:
$foo = [ 'one', 'two', 'three' ]  
notice( $foo[1] )
  在以上代码中, $foo〔 1〕 将会是two。
  嵌套数组和哈希表也可以通过链接索引进访问, 例如:
$foo = [ 'one', {'second' => 'two', 'third' => 'three'} ]  
notice( $foo[1]['third'] )
  在以上代码中, $foo〔 1〕 将会是three。 其中$foo〔 1〕 是个哈希值, 访问的key的名字 是"third"所对应的值为three。
  Puppetlabs-stdlib模块中包含了些额外的功能, 如

  delete、 grep、 hash、 range、>  注意:数组可变, 可以将新添加的数值分配给未使的索引或现存的索引。 这是个Bug, 建议不要使 , 在Puppet 2.7版本中, 这个错误不会被删除。 哈希与数组都有这个Bug。
  四、表达式
  表达式解析的值, 可以使在需要标准数据类型( 数据类型有: 布尔、 数组、 哈希等) 的地。 表 达式可以和其他表达式进整合进合并成复合表达式。 表达式在Puppet中运较泛, 本节将从表达式、 操作数、 运位置、 操作顺序、 较运算符、 布尔运算符等讲解表达式的应。
  1、什么是表达式
  Puppet表达式般由两个操作数和个运算符组成, 例如==, 但( !) 操作符除外, 它只有个 操作数, 于表操作。
  表达式的格式如下:
  表达式 = ( 操作数 运算符 操作数)
  常见表达式举例如下:
  1) 5<9
  2) $kernel in 〔 'linux', 'solaris'〕
  3) ( $operatingsystem!='Solaris')
  4) ( $operatingsystem=='Centos')

  •   表达式可以使括号括起来, 也可以不使括号。
  •   操作数可以是字值、 变量、 其他表达式、 函数调返回值。
  •   运算符可以是较运算符、 布尔运算符。
  •   每个操作数的数据类型由操作者决定。
  •   当创建复合表达式时使其他表达式作为操作数, 应该使括号括起来, 使代码更加清晰。
  2、运位置
  表达式可以运在以下地:

  •   操作数的表达式
  •   if条件语句
  •   case语句
  •   变量的分配
  •   资源属性值
  •   函数调的参数
  需要注意的是: 表达式不能于选择器或资源标题。
  3、操作顺序
  表达式的操作顺序遵守运算符的优先级, 复合表达式有标准的操作顺序, 使括号将覆盖操作顺 序。 例如, 下表达式的结果是30不是23。
  notice( (7+8)*2 )
  通常我们为了表达更清晰, 使括号将表达式括起来。
  运算符优先级, 从最到最低为:
  1) !( )
  2) in( 在什么)
  3) *、 /( 乘法和除法)
  4) -、 +( 减法和加法)
  5) <<、 >>( 左移、 右移)
  6) ==、 !=( 等于、 不等于)
  7) >=、 <=、 >、 <( 于或等于、 于或等于、 于、 于)
  8) and、 or( 和、 或)
  4、较运算符
  较运算符具有以下特点:

  •   可以接受多种数据类型的操作数;
  •   结果是布尔类型。
  下图中的运算符的各项说明来了解Puppet较运算符的含义。
DSC0001.jpg

  5、布尔运算符
  布尔运算符的特点是: 如果操作数不是布尔类型, Puppet会动将其转化为布尔值。 这个运算符在 创建复合表达式时是最有的。 下图中对各种布尔运算符进了说明。
DSC0002.jpg

  6、算术运算符
  算术运算符主要于进算术运算, 较简单。 下图是对算术运算符的说明。
DSC0003.jpg

  五、条件语句
  Puppet条件语句允许你根据变量值或表达式值的不同来应不同代码。 通常来判断系统、 内存 等, 根据操作系统、 内存的差异应不同的代码, 如Centos采Yum命令, Ubuntu采Aptget命令。 常的条件语句有if、 case、 selector( 选择器) 。 Puppetlabs不推荐在配置代码中使过多的条件判断, 过多的判断会影响Puppet执效率, 也会带来维护性的问题。 当涉及过多的判断时尽可能使模块来实现。 下来介绍条件语句的法。
  1、if语句
  if语句在其他程序语运也常泛, 其配置法也常简单。 if语句在Puppet下的配置法 与其他程序语样:
if $operatingsystem == "Ubuntu" {  
notify { "Ubuntu-type operating system detected": }
  
}
  以上代码判断当前系统是否为Ubuntu( 是通过本地facter命令的operatingsystem变量实现的) , 如 果表达式的结果为真, 则执花括号中的代码, 即判断当前系统是Ubuntu则执notify资源, 输出"Ubuntu-type operating system detected"。 如果表达式的结果不为真呢? 代码中没有任何提。Puppet本也不推荐这么做, 因为代码不完整, 也不漂亮, 当然也不便于维护。
  可以采如下法来解决:
if $operatingsystem == "Ubuntu" {  
notify { "Ubuntu-type operating system detected": }
  
}
  
elsif $operatingsystem == "CentOS" {
  
notify { "CentOS-type operating system detected": }
  
}
  
else {
  
notify { "Some other operating system detected": }
  
}
  在以上代码中进了两次判断, 第次判断系统是不是Ubuntu, 第次判断系统是不是Centos, 如 果既不是Ubuntu也不是Centos则执最后的notify输出。 这也是notify资源最主要的作。
  通过以上两段代码我们可以看到, if语句的语法常简单, 仅包括if关键字、 条件、 花括号及代码。 可以使elsif或else配置多重选择。 如果采elsif, 则判断表达式的结果是否为true, 是则执, 如果采else, 则判断表达式的结果是否为false, 是则执。
  if语句判断表达式返回结果: 如果为真, 则执, 如果为假且有elsif或else, 则需要进次判断, 如果都为假, 执默认判断语句。 如果if语句的判断表达式的返回值不为布尔类型, 则Puppet会动将其转换为布尔类型, 下介绍具体的转换规则

  •   字符串: 空字符串为false, 其他所有的都是true, 包括"false"。 注意前Puppet所有Facts都是 字符串。
  •   数字: 所有的数字都是true, 包括0和负数。
  •   undef: false。
  •   数据和哈希: 默认为true, 同时包括空数组和空哈希。
  •   资源引: 默认为true, 包含所有的资源引。
  在以上5种情况下, Puppet会将表达式返回的值转换成布尔类型。 在进布尔值较运算时, 最常运算符的是等于( ==) 、 不等于( !=) 。
  当同类型的操作系统具有同样特性时, 我们可以采Puppet 2.6版本以上的新特性, 例如:
if $operatingsystem in [ "Ubuntu", "Debian" ] {  
notify { "Ubuntu-type operating system detected": }
  
}
  
elsif $operatingsystem in [ "RedHat", "Fedora", "SuSE", "CentOS"
  
] {
  
notify { "Centos-type operating system detected": }
  
}
  
else {
  
notify { "Some other operating system detected": }
  
}
  上述代码中采的法是system in $OS。 如果system在$OS内, 则执相应的代码。 本例所定义的 $OS采数组的形式, 其优点就是减少更多的判断。
  应用举例:
[root@example.com tmp]# vim test8.pp  
if $operatingsystem == 'CentOS'{
  
        notify {'CentOS': message => "Welcome to CentOS Linux.",}
  
} elsif $operatingsystem == 'RedHat'{
  
        notify {'RedHat': message => "Welcome to RedHat Linux.",}
  
} elsif $operatingsystem == 'Fedora'{
  
        notify {'Fedora': message => "Welcome to Fedora Linux.",}
  
}
  
[root@example.com tmp]# puppet apply test8.pp
  
notice: Welcome to CentOS Linux.
  
notice: /Stage[main]//Notify[CentOS]/message: defined 'message' as 'Welcome to CentOS Linux.'
  
notice: Finished catalog run in 0.03 seconds
  2、case语句
  case语句实现的效果和if语句致, 但case语句没有返回值, 没有notify资源的调。 if语句也可以 没有返回值, 但必须有notify资源的调。 case语句是依赖于表达式的不同值执不同的代码。 case语句会将控制表达式的值与各个case的值对, 并执第个匹配的case对应的语句, 忽略其他的。 如果变量$operatingsystem与系统致, 则执括号中的代码。 case语句需要有个默认值, 使代码更加全、 更健壮。
  case语句配置代码如下:
case $operatingsystem {  
'Solaris': { include role::solaris } # apply the solaris class
  
'RedHat', 'CentOS': { include role::redhat } # apply the redhat class
  
/^(Debian|Ubuntu)$/:{ include role::debian } # apply the debian class
  
default: { include role::generic } # apply the generic class
  
}
  与if语句的不同之处在于, case语句表达式看起来较为复杂, 不够直观, 但实质很简单。
  应用举例:
case $operatingsystem {  
            /^(?i-mx:redhat|centos|fedora)/: { package {'httpd': ensure => present, provider => yum, } }
  
            /^(?i-mx:ubuntu|debian)/: { package {'apache2': ensure => present, provider => apt, } }
  
            default: { notify {'notice': message => "unknown system.", }}
  
        }
  3、selector选择器
  selector是Puppet中的选择器, 类似于case语句, 不过只返回个值, 不是执个代码。 选择器 必须在代码中需要简单值的地, 包括: 变量的赋值、 资源属性、 功能参数、 资源标题、 表达式、 另 个selector中的值。 我们不能在case中使选择器, 也不能将个selector作为另个selector的case, 因为Puppet会认为这不是合法的代码。
  选择器的法是: 先定义变量$rootgroup, 然后通过变量$osfamily判断系统版本, 从将参数传递 给变量$rootgroup。 这点类似于C或Ruby中的三元操作, 只不过选择器从两个选项中选择个值。
$rootgroup = $osfamily ? {  
'Solaris' => 'wheel',
  
/(Darwin|FreeBSD)/ => 'wheel',
  
default => 'root',
  
}
  
file { '/etc/passwd':
  
ensure => file,
  
owner => 'root',
  
group => $rootgroup,
  
}
  Puppet会较我们提供的每种可能, 在以上代码中我们只使字字符串进对, 成功匹配 后, selector中的表达式会返回与之匹配的字符串的值。 如果$osfamily的值为"Solaris", 则selector表达式会返回"wheel"字符串, 这个字符串将赋值给变量$rootgroup。 Puppet在较时可以是字符串、 通配符、 正则表达式等。
  Puppet按照每个case的书写顺序与控制表达式进对, 若找到第个匹配项则返回对应的值, 不 继续匹配。 在对的过程中, 如果case是简单的字符串, 则不会区分写, 如果是正则表达式, 则区分写, 最后的default case会匹配任意值。
  Puppet在发现个匹配的情况时, 会对该值进声明, 即将该值分配给定义的控制变量, 忽略其 余的配置语句。 其中常的较运算符有:

  •   等于: ==( 不区分写) 。
  •   正则表达式: =~操作符( 区分写) 。
  应用举例:
$webserver = $operatingsystem ? {  
        /^(?i-mx:centos|fedora|redhat)/ => 'httpd',
  
        /^(?i-mx:ubuntu|debian)/        => 'apache2',
  
}
  
$webprovider = $operatingsystem ? {
  
        /^(?i-mx:centos|fedora|redhat)/ => 'yum',
  
        /^(?i-mx:ubuntu|debian)/        => 'apt',
  
}
  
package {"$webserver":
  
        ensure   => present,
  
        provider => $webprovider,
  
}

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-545093-1-1.html 上篇帖子: 自动化运维工具puppet(二) 下篇帖子: 自动化运维工具puppet(三)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表