前文我们了解了puppet的file、exec、cron、notify这四种核心资源类型的使用以及资源见定义通知/订阅关系,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/14073437.html;今天我们来了解下puppet中的变量、正则表达式和条件判断的相关话题;

  puppet中的变量

  在puppet中变量的定义和使用都是要加“$”,比如定义变量$webserver=nginx;则表示把nginx这个字符串复制给$webserver这个变量;引用变量直接使用$webserver即可;在puppet中赋值操作符为“=”,表示把等号右边边的值赋给左边的变量,任何正常数据类型(非正则)的值都可以赋予puppet中的变量,比如字符串、数值、布尔值、数组、hash以及特殊的undef值(即变量未赋值);

  puppet中的数据类型

    字符型:非结构化的文本字符串,可以使用引号,也可以不使用引号;单引号表示强引用,双引号表示弱引用;所谓强引用表示变量不会替换,弱引用表示能够进行变量替换;字符型值是支持用转义符;

    数字型:可为整数或浮点数,不过,puppet只有在数值上下文才把数值当作数值型对待,其他情况一律以字符型处理;比如进行加减乘除等运算时,它会把数值型值当作数值进行计算;

    数组:数组值为中括号“[]”中的以逗号分隔的项目列表,最后一个项目后面可以没有逗号;数组中的元素可以为任意可用数据类型,包括hash或其他数组,数组中的元素为数组,我们把这样的数组叫多维数组;数组的索引为从0开始的整数,也可以使用负数索引;

    布尔型:true和false,不能加任何引号;if语句的测试条件和比较表达式都会返回布尔型值,另外,其他数据类型也可以自动转换为布尔型值,如字符串,空串为false,非空则true;数值型就是0为false,非0为true等等;

    undef:从未被声明的变量的值类型即为undef;也可手动为某变量赋予undef值,即直接使用不加引号的undef字符串;有点类似shell中的unset;

    hash:即为外键值数据类型,键和值之间使用“=>”分隔,键值对定义在“{}”中,彼此间以逗号分隔;其键为字符型数据,而值可以为puppet中支持的任意数据类型;访问hash类型的数据元素要使用“键”当作索引进行访问;

  puppet中变量作用域

  提示:所谓变量作用域表示变量的使用生效的范围,在puppet中作用域可用于限定变量及资源默认属性的作用范围;但不能用于限定资源名称及资源引用的生效范围;任何给定的scope都可以访问它自己的内容,以及接收来自于其父scope、节点scope以及top scope的内容;简单讲就是作用域小的可以引用作用域大的变量,也可以更改作用域大的变量的值;但是作用域大的不能操作作用域小的变量;如上图所示,top scope仅能访问直接的变量和属性默认值;node scope能访问自己的及top scope的变量和属性默认值;example::parent,example::other和example::four能访问自己的以及节点scope和top scope的变量和默认值;如果要访问非当前scope中的变量,则需要通过完全限制名称进行;如$vhostdir=$apache::params::vhostdir;这里需要注意一点,如果top scope的名称为空,如要引用其变量可以使用类似$::sofamily的方式进行引用;

  puppet中的内建变量

  在puppet中变量来源可以从facter,agent,master,解释器以及用户自定义的变量;其中facter是一个工具,它可以收集系统信息,规范化之后存放在一系列变量中,并传递给puppet;facter的各变量是top scope的变量,这意味着,可以在各个manifest中直接通过${fact name}访问所需的fact变量;查看系统fact变量有哪些,可以使用facter -p输出fact变量;agent端的变量常用的有$environment这表示agent端的环境变量,$clientcert表示agent端的证书;$clientversion表示agent puppet的版本信息;master 端常用变量有$servername,该变量表示服务端名称;$serverip服务端ip,$serverversion服务端puppet的版本信息;解释器中的变量$module_name表示正在执行的模块名称;这里需要注意agent和master的内建变量只有在master/agent这种模型中才有效,单机模型无效;

  puppet中常用的操作符

操作符 描述 操作符 描述 操作符 描述
== 等于 =~ 正则模式匹配 +
!= 不等于 !~ 正则模式不匹配 -
< 小于 in 成员关系判定 *
> 大于 and /
<= 小于等于 or << 左移位
>= 大于等于 ! >> 右移位

  puppet中的正则表达式

  正则表达式在puppet中属于非标准的数据类型,不能赋值给变量,仅能用于有限的几个接受正则表达式的地方使用,即接受使用“=~”或“!~”匹配操作符的位置,通常包含case语句中的selector,以及节点名称匹配的位置;它不能传递给函数或用于资源属性定义;

  puppet中正则表达式的两个特殊使用方式

  (?<ENABLED OPTION>:<PATTERN>)和(?-<DISABLED OPTION>:<PATTERN>),其中OPTIONS有i,m,x,其中i表示忽略字符大小写;m表示把“.”点号当作换行符;x表示忽略<PATTERN>中的空白字符;比如(?imx:PATTENR)就表示忽略字符大小写,把PATTERN中的点号当作换行符,并且忽略其中的空白字符;(?i-mx:PATTERN)表示忽略字符大小写,不把pattern中的点号当换行符,也不忽略pattern中的空白字符;

  puppet中的流程控制

  所谓流程控制就是在puppet代码中加入了条件控制语句,如if语句,case语句,selector语句,只有满足了条件才会执行对应的代码;if语句语法如下

  单分支

if  CONDITION {
...
}

  双分支

if  CONDITION {
...
} else {
...
}

  多分支

if  CONDITION {
...
} elsif {
...
} else{
...
}

  提示:条件可以是变量,比较表达式或有返回值的函数;

  示例:通过判断不同操作系统来安装apache

[root@node12 ~]# cat if.pp
if $operatingsystem == "CentOS" {
$webserver = "httpd"
}elsif $operatingsystem == "Ubuntu" {
$webserver = "apache2"
}else{
$webserver = "apahce"
} package{"$webserver":
ensure => installed,
}
[root@node12 ~]#

  提示:以上资源清单表示,通过判断$operatingsystem这个变量的值来赋值$webserver的值;如果对应$operatingsystem的值为CentOS,则$webserver的值就为httpd,如果是Ubuntu $webserver的值就为apache2,如果前两个条件都不满足,则$webserver的值为apache;然后通过$webserver这个变量的值来安装包;

  应用资源清单

[root@node12 ~]# puppet apply -v --noop if.pp
Notice: Compiled catalog for node12.test.org in environment production in 0.65 seconds
Warning: The package type's allow_virtual parameter will be changing its default value from false to true in a future release. If you do not want to allow virtual packages, please explicitly set allow_virtual to false.
(at /usr/share/ruby/vendor_ruby/puppet/type.rb:816:in `set_default')
Info: Applying configuration version '1606994860'
Notice: /Stage[main]/Main/Package[httpd]/ensure: current_value absent, should be present (noop)
Notice: Class[Main]: Would have triggered 'refresh' from 1 events
Notice: Stage[main]: Would have triggered 'refresh' from 1 events
Notice: Finished catalog run in 1.24 seconds
[root@node12 ~]# puppet apply -v if.pp
Notice: Compiled catalog for node12.test.org in environment production in 0.18 seconds
Warning: The package type's allow_virtual parameter will be changing its default value from false to true in a future release. If you do not want to allow virtual packages, please explicitly set allow_virtual to false.
(at /usr/share/ruby/vendor_ruby/puppet/type.rb:816:in `set_default')
Info: Applying configuration version '1606994891'
Notice: /Stage[main]/Main/Package[httpd]/ensure: created
Notice: Finished catalog run in 7.99 seconds
[root@node12 ~]#

  提示:从上述信息中可以看到,当前安装的包上httpd;原因是本机是一个centos系统;$operatingsystem这个变量是一个fact变量,主要保存操作系统名称;

  示例:if语句中使用正则表达式

[root@node12 ~]# cat if.pp
if $operatingsystem =~/(?i-mx:(centos|redhat))/{
$webserver = "httpd"
}elsif $operatingsystem =~ /(?i-mx:(ubuntu|debian))/{
$webserver = "apache2"
}else{
$webserver = "apahce"
} package{"$webserver":
ensure => installed,
}
[root@node12 ~]#

  提示:使用正则表达式需要将正则表达式写在“//”之间;

  卸载httpd,应用资源清单

[root@node12 ~]# rpm -e httpd
[root@node12 ~]# puppet apply -v if.pp
Notice: Compiled catalog for node12.test.org in environment production in 0.18 seconds
Warning: The package type's allow_virtual parameter will be changing its default value from false to true in a future release. If you do not want to allow virtual packages, please explicitly set allow_virtual to false.
(at /usr/share/ruby/vendor_ruby/puppet/type.rb:816:in `set_default')
Info: Applying configuration version '1606995583'
Notice: /Stage[main]/Main/Package[httpd]/ensure: created
Notice: Finished catalog run in 1.86 seconds
[root@node12 ~]#

  提示:可以看到应用清单并没有报错,提示httpd已经创建;

  puppet中的case语句

  语法

case CONTROL_EXPRESSION {
case1: { ... }
case2: { ... }
case3: { ... }
...
default: { ... }
}

  提示:case语句和if语句的作用是类似的,case语句会从多个代码块中选择一个分支执行,只要其中任意一个case的值满足对应的控制表达式,就执行对应case后面的代码块,然后退出;如果所有case都不满足,则执行default对应的代码块;这里的控制表达式可以是变量,可以是比较表达式,也可以是有返回值的函数;case可以是字符串,正则表达式,变量,有返回值的函数和default;

  示例

[root@node12 ~]# cat case.pp
case $osfamily {
"RedHat":{ $webserver="httpd" }
/(?i-mx:debian)/:{ $webserver="apache2" }
default:{ $webserver="apache" }
} package{"$webserver":
ensure => installed,
}
[root@node12 ~]#

  卸载httpd,执行资源清单,看看httpd是否会被安装?

[root@node12 ~]# rpm -e httpd
[root@node12 ~]# puppet apply -v case.pp
Notice: Compiled catalog for node12.test.org in environment production in 0.18 seconds
Warning: The package type's allow_virtual parameter will be changing its default value from false to true in a future release. If you do not want to allow virtual packages, please explicitly set allow_virtual to false.
(at /usr/share/ruby/vendor_ruby/puppet/type.rb:816:in `set_default')
Info: Applying configuration version '1606996150'
Notice: /Stage[main]/Main/Package[httpd]/ensure: created
Notice: Finished catalog run in 1.82 seconds
[root@node12 ~]# rpm -q httpd
httpd-2.4.6-97.el7.centos.x86_64
[root@node12 ~]#

  提示:可以看到httpd可以正常的安装;

  selector语句

  语法

CONTROL_VARIABLE ? {
case1 => value1,
case2 => value2,
...
default => valueN,
}

  提示:整个selector语句会被当作一个单独的值,puppet会将控制变量按列出的次序依次与每个case进行比较,并在遇到一个匹配的case后,将其值作为整个语句的值进行返回,并忽略后面的其他case;控制变量与各case比较的方式和case语句相同,但如果没有任何一个case与控制变量匹配,puppet在编译时将报错,因此,我们在使用selector必须提供一个default case;控制变量只能是一个变量或一个有返回值的函数,不能使用表达式;各个case的值可以是字符串,变量,有返回值的函数,正则表达式或default;

  示例

[root@node12 ~]# cat selector.pp
$pkgname = $operatingsystem ? {
/(?i-mx:(ubuntu|debian))/ => 'apache2',
/(?i-mx:(redhat|fedora|centos))/ => 'httpd',
default => 'apache',
}
package{"$pkgname":
ensure => installed,
}
[root@node12 ~]#

  卸载httpd,应用资源清单

[root@node12 ~]# rpm -e httpd
[root@node12 ~]# puppet apply -v --noop selector.pp
Notice: Compiled catalog for node12.test.org in environment production in 0.18 seconds
Warning: The package type's allow_virtual parameter will be changing its default value from false to true in a future release. If you do not want to allow virtual packages, please explicitly set allow_virtual to false.
(at /usr/share/ruby/vendor_ruby/puppet/type.rb:816:in `set_default')
Info: Applying configuration version '1606997882'
Notice: /Stage[main]/Main/Package[httpd]/ensure: current_value absent, should be present (noop)
Notice: Class[Main]: Would have triggered 'refresh' from 1 events
Notice: Stage[main]: Would have triggered 'refresh' from 1 events
Notice: Finished catalog run in 0.08 seconds
[root@node12 ~]# puppet apply -v selector.pp
Notice: Compiled catalog for node12.test.org in environment production in 0.18 seconds
Warning: The package type's allow_virtual parameter will be changing its default value from false to true in a future release. If you do not want to allow virtual packages, please explicitly set allow_virtual to false.
(at /usr/share/ruby/vendor_ruby/puppet/type.rb:816:in `set_default')
Info: Applying configuration version '1606997889'
Notice: /Stage[main]/Main/Package[httpd]/ensure: created
Notice: Finished catalog run in 1.96 seconds
[root@node12 ~]# rpm -q httpd
httpd-2.4.6-97.el7.centos.x86_64
[root@node12 ~]#

  提示:可以看到httpd通过使用selector的方式定义的资源清单一样可以正常安装;

  puppet中的类

  类是用于同于目标的一组资源,因此,它是命名的代码块,在某一个位置创建之后可在puppet全局使用;puppet中的类和其他编程语言中的类的功能很类似,puppet中的类可被继承,也可以有子类;

  类的定义语法

class class_name($var1=value1,$var2=value2){
... puppet code ...
}

  提示:class是关键字,class_name是类名,类名只能以小写字母开头,可以包含小写字母,数字,下划线;小括号里是定义类的形参,每个形参可以有默认值,也可以没有,多个形参用逗号隔开;大括号里写puppet的代码;

  示例:定义一个apache的类

[root@node12 ~]# cat apache.pp
class apache {
package{"httpd":
ensure => installed,
}
service{"httpd":
ensure => running,
}
}
[root@node12 ~]#

  提示:以上清单中定义了一个apache的类,主要完成了安装包和启动服务;这里需要注意一点,类定义好以后,如果我们不声明类,则它不会执行,有点类似函数一样,要向让类执行,我们需要声明类;

  在puppet中类的声明常用的方式有两种,第一种是使用include关键字+类名;第二种是类似定义资源一样来声明类,其中资源类型为class,title必须为类名,这种方式通常用于有参数的类的声明;

  示例:使用include关键字+类名声明类

[root@node12 ~]# cat apache.pp
class apache {
package{"httpd":
ensure => installed,
}
service{"httpd":
ensure => running,
}
} include apache [root@node12 ~]#

  执行清单

[root@node12 ~]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:26379 *:*
LISTEN 0 128 *:22 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 128 *:27017 *:*
LISTEN 0 128 :::22 :::*
LISTEN 0 100 ::1:25 :::*
[root@node12 ~]# puppet apply -v --noop apache.pp
Notice: Compiled catalog for node12.test.org in environment production in 0.26 seconds
Warning: The package type's allow_virtual parameter will be changing its default value from false to true in a future release. If you do not want to allow virtual packages, please explicitly set allow_virtual to false.
(at /usr/share/ruby/vendor_ruby/puppet/type.rb:816:in `set_default')
Info: Applying configuration version '1607005266'
Notice: /Stage[main]/Apache/Service[httpd]/ensure: current_value stopped, should be running (noop)
Info: /Stage[main]/Apache/Service[httpd]: Unscheduling refresh on Service[httpd]
Notice: Class[Apache]: Would have triggered 'refresh' from 1 events
Notice: Stage[main]: Would have triggered 'refresh' from 1 events
Notice: Finished catalog run in 0.13 seconds
[root@node12 ~]# puppet apply -v apache.pp
Notice: Compiled catalog for node12.test.org in environment production in 0.27 seconds
Warning: The package type's allow_virtual parameter will be changing its default value from false to true in a future release. If you do not want to allow virtual packages, please explicitly set allow_virtual to false.
(at /usr/share/ruby/vendor_ruby/puppet/type.rb:816:in `set_default')
Info: Applying configuration version '1607005272'
Notice: /Stage[main]/Apache/Service[httpd]/ensure: ensure changed 'stopped' to 'running'
Info: /Stage[main]/Apache/Service[httpd]: Unscheduling refresh on Service[httpd]
Notice: Finished catalog run in 0.22 seconds
[root@node12 ~]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:26379 *:*
LISTEN 0 128 *:22 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 128 *:27017 *:*
LISTEN 0 128 :::80 :::*
LISTEN 0 128 :::22 :::*
LISTEN 0 100 ::1:25 :::*
[root@node12 ~]#

  提示:可以看到httpd服务已经启动;

  示例:定义带参类

[root@node12 ~]# cat class1.pp
class dbserver ($pkg='mariadb-server',$svr='mariadb'){
package{"$pkg":
ensure => latest,
}
service{"$svr":
ensure => running,
enable => true,
}
} if $operatingsystem == "CentOS" or $operatingsystem == "RedHat"{
case $operatingsystemmajrelease {
'7': { $pkgname='mariadb-server' $svrname='mariadb' }
default: { $pkgname='mysql-server' $svrname='mysqld' }
}
} class{"dbserver":
pkg => $pkgname,
svr => $svrname,
}
[root@node12 ~]#

  提示:以上清单主要完成对于不同版本的centos,安装和启动不同的服务;在centos7上安装mariadb-server,启动mariadb服务;其他版本的centos安装mysql-server,启动mysqld服务;这里需要注意一点,声明类中的行参不能带$,我们可以理解为行参就是类的一个属性;

  执行清单

[root@node12 ~]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:26379 *:*
LISTEN 0 128 *:22 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 128 *:27017 *:*
LISTEN 0 128 :::80 :::*
LISTEN 0 128 :::22 :::*
LISTEN 0 100 ::1:25 :::*
[root@node12 ~]# puppet apply -v --noop class1.pp
Notice: Compiled catalog for node12.test.org in environment production in 0.27 seconds
Warning: The package type's allow_virtual parameter will be changing its default value from false to true in a future release. If you do not want to allow virtual packages, please explicitly set allow_virtual to false.
(at /usr/share/ruby/vendor_ruby/puppet/type.rb:816:in `set_default')
Info: Applying configuration version '1607007562'
Notice: /Stage[main]/Dbserver/Service[mariadb]/ensure: current_value stopped, should be running (noop)
Info: /Stage[main]/Dbserver/Service[mariadb]: Unscheduling refresh on Service[mariadb]
Notice: Class[Dbserver]: Would have triggered 'refresh' from 1 events
Notice: Stage[main]: Would have triggered 'refresh' from 1 events
Notice: Finished catalog run in 0.47 seconds
[root@node12 ~]# puppet apply -v class1.pp
Notice: Compiled catalog for node12.test.org in environment production in 0.27 seconds
Warning: The package type's allow_virtual parameter will be changing its default value from false to true in a future release. If you do not want to allow virtual packages, please explicitly set allow_virtual to false.
(at /usr/share/ruby/vendor_ruby/puppet/type.rb:816:in `set_default')
Info: Applying configuration version '1607007569'
Notice: /Stage[main]/Dbserver/Service[mariadb]/ensure: ensure changed 'stopped' to 'running'
Info: /Stage[main]/Dbserver/Service[mariadb]: Unscheduling refresh on Service[mariadb]
Notice: Finished catalog run in 2.76 seconds
[root@node12 ~]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:26379 *:*
LISTEN 0 128 *:22 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 128 *:27017 *:*
LISTEN 0 50 *:3306 *:*
LISTEN 0 128 :::80 :::*
LISTEN 0 128 :::22 :::*
LISTEN 0 100 ::1:25 :::*
[root@node12 ~]# systemctl is-enabled mariadb.service
enabled
[root@node12 ~]#

  提示:可以看到在当前系统上执行清单,启动了mariadb;

  类的继承

  类的继承是子类继承父类中的所有功能代码,它可以对父类中的所有属性进行修改,其定义语法如下

class childer_class_name inherits parent_class_name{
...puppet code ...
}

  提示:子类名称需使用完全限定名称,比如父类是apache,子类名可以写成apache::web;类似这种;inherits是关键字表示继承之意,后面加父类名称;

  示例

[root@node12 ~]# cat redis.pp
class redis{
package{"redis":
ensure => installed,
}
service{"redis":
ensure => running,
enable => true,
hasrestart => true,
restart => 'service redis restart',
}
} class redis::master inherits redis {
file{"/etc/redis.conf":
ensure => file,
source => '/root/redis-master.conf',
}
Service["redis"]{
subscribe => File["/etc/redis.conf"],
restart => 'systemctl restart redis'
}
} include redis::master
[root@node12 ~]#

  提示:以上清单定义了两个类,一个是父类名为reids,另一个为子类名为redis::master;子类继承父类,并在其基础上新增了file资源以及增加了service资源的订阅关系;

  本地redis-master.conf配置文件内容

[root@node12 ~]# cat /root/redis-master.conf
bind 0.0.0.0
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile /var/log/redis/redis.log
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /var/lib/redis
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes
[root@node12 ~]#

  执行清单,看看redis是否会监听在本机所有地址的6379端口?

[root@node12 ~]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:22 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 128 *:27017 *:*
LISTEN 0 50 *:3306 *:*
LISTEN 0 128 :::80 :::*
LISTEN 0 128 :::22 :::*
LISTEN 0 100 ::1:25 :::*
[root@node12 ~]# puppet apply -v --noop redis.pp
Notice: Compiled catalog for node12.test.org in environment production in 0.32 seconds
Warning: The package type's allow_virtual parameter will be changing its default value from false to true in a future release. If you do not want to allow virtual packages, please explicitly set allow_virtual to false.
(at /usr/share/ruby/vendor_ruby/puppet/type.rb:816:in `set_default')
Info: Applying configuration version '1607008817'
Notice: /Stage[main]/Redis::Master/File[/etc/redis.conf]/content: current_value {md5}cb9ab7d298a50a0de20077de143e3f73, should be {md5}12e59b058c0ef61ad52bcfa2d4de58ff (noop)
Info: /Stage[main]/Redis::Master/File[/etc/redis.conf]: Scheduling refresh of Service[redis]
Notice: Class[Redis::Master]: Would have triggered 'refresh' from 1 events
Notice: /Stage[main]/Redis/Service[redis]/ensure: current_value stopped, should be running (noop)
Info: /Stage[main]/Redis/Service[redis]: Unscheduling refresh on Service[redis]
Notice: Class[Redis]: Would have triggered 'refresh' from 1 events
Notice: Stage[main]: Would have triggered 'refresh' from 2 events
Notice: Finished catalog run in 0.18 seconds
[root@node12 ~]# puppet apply -v redis.pp
Notice: Compiled catalog for node12.test.org in environment production in 0.33 seconds
Warning: The package type's allow_virtual parameter will be changing its default value from false to true in a future release. If you do not want to allow virtual packages, please explicitly set allow_virtual to false.
(at /usr/share/ruby/vendor_ruby/puppet/type.rb:816:in `set_default')
Info: Applying configuration version '1607008824'
Info: /Stage[main]/Redis::Master/File[/etc/redis.conf]: Filebucketed /etc/redis.conf to puppet with sum cb9ab7d298a50a0de20077de143e3f73
Notice: /Stage[main]/Redis::Master/File[/etc/redis.conf]/content: content changed '{md5}cb9ab7d298a50a0de20077de143e3f73' to '{md5}12e59b058c0ef61ad52bcfa2d4de58ff'
Info: /Stage[main]/Redis::Master/File[/etc/redis.conf]: Scheduling refresh of Service[redis]
Notice: /Stage[main]/Redis/Service[redis]/ensure: ensure changed 'stopped' to 'running'
Info: /Stage[main]/Redis/Service[redis]: Unscheduling refresh on Service[redis]
Notice: Finished catalog run in 0.13 seconds
[root@node12 ~]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:6379 *:*
LISTEN 0 128 *:22 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 128 *:27017 *:*
LISTEN 0 50 *:3306 *:*
LISTEN 0 128 :::80 :::*
LISTEN 0 128 :::22 :::*
LISTEN 0 100 ::1:25 :::*
[root@node12 ~]#

  提示:可以看到redis监听在本机任何地址的6379端口;

  模板

  puppet中的模板和ansible中的模板功能很类似,主要用在为一些服务提供配置文件模板,不同于ansible中的模板,puppet中的模板使用的erb模板语言,ansible使用的是jinja2模板语言;在puppet中使用模板的语法如下

file{'title':
ensure => file,
content => template('/PATH/TO/ERB_FILE'),
}

  提示:在复制配置文件时,指定源需使用content来指定,并且调用内建函数template来指定要复制的源文件,通常这个源文件就是一个模板配置文件;

  在模板文件中使用内嵌的变量替换机制,其语法如下

<%= @VARIABLE_NAME %>

  提示:我们需要把要替换的值用上述变量的方式代替即可;

  示例:替换redis监听地址

[root@node12 ~]# grep ^bind redis-master.conf.erb
bind <%= @ipaddress %>
[root@node12 ~]#

  提示:以上内容表示bind 后面的值为ipaddress这个变量的值;这个变量是fact变量,主要用于存放本机ip地址;

  定义资源清单

[root@node12 ~]# cat redis.pp
class redis{
package{"redis":
ensure => installed,
}
service{"redis":
ensure => running,
enable => true,
hasrestart => true,
restart => 'service redis restart',
}
} class redis::master inherits redis {
file{"/etc/redis.conf":
ensure => file,
content => template('/root/redis-master.conf.erb'),
}
Service["redis"]{
subscribe => File["/etc/redis.conf"],
restart => 'systemctl restart redis'
}
} include redis::master
[root@node12 ~]#

  提示:以上清单在定义配置文件源文件时,指定content属性为内建函数template调用/root/redis-master.conf.erb;表示使用这个模板文件覆盖/etc/redis.conf文件内容;

  执行清单,看看对应redis是否监听在本机192.168.0.52这个地址上呢?

[root@node12 ~]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:6379 *:*
LISTEN 0 128 *:22 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 128 *:27017 *:*
LISTEN 0 50 *:3306 *:*
LISTEN 0 128 :::80 :::*
LISTEN 0 128 :::22 :::*
LISTEN 0 100 ::1:25 :::*
[root@node12 ~]# puppet apply -v --noop redis.pp
Notice: Compiled catalog for node12.test.org in environment production in 0.33 seconds
Warning: The package type's allow_virtual parameter will be changing its default value from false to true in a future release. If you do not want to allow virtual packages, please explicitly set allow_virtual to false.
(at /usr/share/ruby/vendor_ruby/puppet/type.rb:816:in `set_default')
Info: Applying configuration version '1607010053'
Notice: /Stage[main]/Redis::Master/File[/etc/redis.conf]/content: current_value {md5}12e59b058c0ef61ad52bcfa2d4de58ff, should be {md5}52397ae299aa46fe4103654abd62f5fd (noop)
Info: /Stage[main]/Redis::Master/File[/etc/redis.conf]: Scheduling refresh of Service[redis]
Notice: Class[Redis::Master]: Would have triggered 'refresh' from 1 events
Notice: /Stage[main]/Redis/Service[redis]: Would have triggered 'refresh' from 1 events
Notice: Class[Redis]: Would have triggered 'refresh' from 1 events
Notice: Stage[main]: Would have triggered 'refresh' from 2 events
Notice: Finished catalog run in 0.12 seconds
[root@node12 ~]# puppet apply -v redis.pp
Notice: Compiled catalog for node12.test.org in environment production in 0.33 seconds
Warning: The package type's allow_virtual parameter will be changing its default value from false to true in a future release. If you do not want to allow virtual packages, please explicitly set allow_virtual to false.
(at /usr/share/ruby/vendor_ruby/puppet/type.rb:816:in `set_default')
Info: Applying configuration version '1607010059'
Info: FileBucket got a duplicate file {md5}12e59b058c0ef61ad52bcfa2d4de58ff
Info: /Stage[main]/Redis::Master/File[/etc/redis.conf]: Filebucketed /etc/redis.conf to puppet with sum 12e59b058c0ef61ad52bcfa2d4de58ff
Notice: /Stage[main]/Redis::Master/File[/etc/redis.conf]/content: content changed '{md5}12e59b058c0ef61ad52bcfa2d4de58ff' to '{md5}52397ae299aa46fe4103654abd62f5fd'
Info: /Stage[main]/Redis::Master/File[/etc/redis.conf]: Scheduling refresh of Service[redis]
Notice: /Stage[main]/Redis/Service[redis]: Triggered 'refresh' from 1 events
Notice: Finished catalog run in 0.15 seconds
[root@node12 ~]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 192.168.0.52:6379 *:*
LISTEN 0 128 *:22 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 128 *:27017 *:*
LISTEN 0 50 *:3306 *:*
LISTEN 0 128 :::80 :::*
LISTEN 0 128 :::22 :::*
LISTEN 0 100 ::1:25 :::*
[root@node12 ~]# grep ^bind /etc/redis.conf
bind 192.168.0.52
[root@node12 ~]#

  提示:可以看到对应redis已经监听在192.168.0.52这个地址,并且配置文件中的bing的值也是192.168.0.52;

  在模板中使用自定义变量

[root@node12 ~]# grep -Ei "^bind|port" redis-master.conf.erb
bind <%= @redis_bindip%>
port <%= @redis_port %>
[root@node12 ~]#

  在资源中定义变量

[root@node12 ~]# cat redis.pp
class redis{
package{"redis":
ensure => installed,
}
service{"redis":
ensure => running,
enable => true,
hasrestart => true,
restart => 'service redis restart',
}
} class redis::master($redis_bindip='0.0.0.0',$redis_port='6379') inherits redis {
file{"/etc/redis.conf":
ensure => file,
content => template('/root/redis-master.conf.erb'),
}
Service["redis"]{
subscribe => File["/etc/redis.conf"],
restart => 'systemctl restart redis'
}
} class{"redis::master":
redis_port => '16379',
}
[root@node12 ~]#

  提示;在该资源中声明类时,传递了redis_port这个形参的值为16379,默认的redis_bindip为0.0.0.0;

  执行清单,看看redis是否监听在本机所有地址的16379端口?

[root@node12 ~]# puppet apply -v  redis.pp
Warning: Config file /etc/puppet/hiera.yaml not found, using Hiera defaults
Notice: Compiled catalog for node12.test.org in environment production in 0.38 seconds
Warning: The package type's allow_virtual parameter will be changing its default value from false to true in a future release. If you do not want to allow virtual packages, please explicitly set allow_virtual to false.
(at /usr/share/ruby/vendor_ruby/puppet/type.rb:816:in `set_default')
Info: Applying configuration version '1607010599'
Info: /Stage[main]/Redis::Master/File[/etc/redis.conf]: Filebucketed /etc/redis.conf to puppet with sum 52397ae299aa46fe4103654abd62f5fd
Notice: /Stage[main]/Redis::Master/File[/etc/redis.conf]/content: content changed '{md5}52397ae299aa46fe4103654abd62f5fd' to '{md5}13a04cb20de2d787e0e18c1c13560cab'
Info: /Stage[main]/Redis::Master/File[/etc/redis.conf]: Scheduling refresh of Service[redis]
Notice: /Stage[main]/Redis/Service[redis]: Triggered 'refresh' from 1 events
Notice: Finished catalog run in 0.15 seconds
[root@node12 ~]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:22 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 128 *:16379 *:*
LISTEN 0 128 *:27017 *:*
LISTEN 0 50 *:3306 *:*
LISTEN 0 128 :::80 :::*
LISTEN 0 128 :::22 :::*
LISTEN 0 100 ::1:25 :::*
[root@node12 ~]# grep -Ei "^bind|port" /etc/redis.conf
bind 0.0.0.0
port 16379
[root@node12 ~]#

  提示:可以看到对应redis监听在本机所有地址的16379端口,并且对应配置文件也发生了相应的变量替换;

  以上就是puppet中的变量、正则表达式、流程控制、类和模板的使用和演示;有了这些基本编程元素的存在,使得puppet的资源清单变得灵活和通用,我们可以写一个资源清单适用几乎所有的不同的系统;

自动化运维工具之Puppet变量、正则表达式、流程控制、类和模板的更多相关文章

  1. 自动化运维工具之Puppet基础入门

    一.简介 puppet是什么?它能做什么? puppet是一个IT基础设施自动化运维工具,它能够帮助系统管理员管理基础设施的整个生命周期:比如,安装服务,提供配置文件,启动服务等等一系列操作:基于pu ...

  2. 自动化运维工具之Puppet模块

    前文我们了解来puppet的变量.流程控制.正则表达式.类和模板的相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/14079208.html:今天我们来 ...

  3. 自动化运维工具之Puppet常用资源(二)

    前文我们了解了部分puppet的资源的使用,以及资源和资源的依赖关系的定义,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/14071459.html:今天我们继 ...

  4. 自动化运维工具之Puppet常用资源(一)

    前文我们聊到了puppet的架构,单机模型和master/agent模型的工作流程以及puppet的基础使用,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/14 ...

  5. 自动化运维工具之Puppet master/agent模型、站点清单和puppet多环境设定

    前文我们了解了puppe中模块的使用,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/14086315.html:今天我来了解下puppet的master/age ...

  6. 企业级自动化运维工具应用实战ansible

    公司计划在年底做一次大型市场促销活动,全面冲刺下交易额,为明年的上市做准备.公司要求各业务组对年底大促做准备,运维部要求所有业务容量进行三倍的扩容,并搭建出多套环境可以共开发和测试人员做测试,运维老大 ...

  7. 自动化运维工具-Ansible之1-基础

    自动化运维工具-Ansible之1-基础 目录 自动化运维工具-Ansible之1-基础 Ansible 基本概述 定义 特点 架构 工作原理 任务执行模式 命令执行过程 Ansible 安装 Ans ...

  8. 自动化运维工具Ansible详细部署 (转载)

    自动化运维工具Ansible详细部署 标签:ansible 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://sofar.blog. ...

  9. 自动化运维工具之ansible

    自动化运维工具之ansible   一,ansible简介 ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet.cfengine.chef.func.fab ...

随机推荐

  1. trie 树(字典树)

    目录 简述 trie 实现 前言 初始化 插入 检索 代码实现 例题 · 前缀统计 异或对 前言 贪心证明 代码实现 例题 · 最长异或值路径 可持久化 trie 树 简介 原理 代码实现 例题 总结 ...

  2. swjtuoj2433 Magic Mirror

    描述 Magic Mirror is an artificial intelligence system developed by TAL AI LAB,It can determine human ...

  3. JMeter100个线程竟然只模拟出1个并发

    线程组,是说到 JMeter 会第一时间想到的东西,也是我认为 JMeter 最难理解的知识点.因为项目让你做个压测,首先就是要考虑并发,用 JMeter 就是用多线程 来模拟多并发.但在看到线程组编 ...

  4. leetcode 43:construct-binary-tree-from-inorder

    题目描述 给出一棵树的中序遍历和后序遍历,请构造这颗二叉树 注意: 保证给出的树中不存在重复的节点 Given inorder and postorder traversal of a tree, c ...

  5. 庐山真面目之三微服务架构Consul版本实现

    庐山真面目之三微服务架构Consul版本实现 一.简介           在上一篇文章<庐山真面目之二微服务架构NGINX版本实现>中,我们已经探讨了如何搭建基于Nginx 网关的微服务 ...

  6. Spark Standalone模式 高可用部署

      本文使用Spark的版本为:spark-2.4.0-bin-hadoop2.7.tgz. spark的集群采用3台机器进行搭建,机器分别是server01,server02,server03. 其 ...

  7. vue 格式化日期

    cnpm install moment --save 摘自:https://www.cnblogs.com/zwq20134/p/11718034.html <el-table-column l ...

  8. 安装使用Pycharm及Anaconda最全教程

    网上安装anaconda和pycharm的教程很多,然而很少有人能够很详细地讲解,特别是对于pycharm的虚拟环境相关的说明很少,我也是懵逼的用了两年多,经常发现之前pycharm安装的第三方库,明 ...

  9. 线程安全的SimpleDateFormat

    import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; imp ...

  10. 80%人会答错的JS基础面试题

    这套题第一道题难度最大,我第一遍的回答居然也错的,我悲观估计80%的JavaScript从业人员都答不完全准确 []==![] 得到什么? false, 你还需要看看基础 true, 恭喜你答对了,你 ...