puppet的变量类型
puppet变量必须要$符开头,不管是定义还是引用
变量是有作用域的,一个变量的作用域受限于类、模块等 而且引用一个变量,如果不是在当前作用域的变量的话,要引用必须使用它的FQN,而且引用时必须用双冒号隔开
FQN表示:
$::abc
如果在node scope中则加上node名称即可
撤销值:
$abc=undef
正在匹配
只能在几个有限能接受正在的地方才可以定义
比如=~以及!~匹配操作符的位置,才能够使用正在表达式
·属于puppet的非标准数据类型不能赋值给变量,仅能用户有限的几个接受正则表达式的地方
即使用=~ 和 !~ 匹配操作符的位置,通常包括case语句中的selector 以及各节点名称匹配的位置
它们不能传递给函数或者用于资源属性的定义;
·puppet中的正则表达式支持使用(?<ENABLED OPTION>:<SUBPATTERN>)和(?-<DISTABLED OPTION>:<SUBPATTERN>)
两个特殊符号
如果做正则匹配的时候启用选项i(忽略大小写),但是不支持使用m(将.作为换行符)和 x (忽略模式中的空白字符和注释)
例:
以往正在表达式,匹配centos或redhat开头:
^/(centos|redhat)/linux/ig
而puppet则需要以下方式:
(?i:^(Redhat|CentOS))
忽略大小写
(?i-mx:^(Redhat|CentOS))
例:
如果是某个系统则显示某条信息
首先做简单判断
$package = $operatingsystem ?{
/(?i-mx:^(centos|redhat))/ => 'httpd',
/(?i-mx:^(debian|ubuntu))/ => 'apache2',
}
#而后复制完成之后则package则有个值,那么其要么是httpd要么是apache2
#因为会直接返回字符串
现在我们想显示puppet的值:
notify {'notice':
message => "Install$Package",
}
$package = $operatingsystem ?{
/(?i-mx:^(centos|redhat))/ => 'httpd',
/(?i-mx:^(debian|ubuntu))/ => 'apache2',
}
notify {'notice':
message => "Install$Package",
}
puppet的条件判断语句
puppet2.7之后支持3种判断,分别是
if , case , selector
puppet3.0之后支持4种判断,分别是
if , case , selector , unless
if语句
单分支语句:
if condition {
statement
…
}
双分支语句
if condition {
Statement
……
}
else {
statement
}
多分支语句
if condition {
statement
} elsif {
statement
}
else {
statement
}
条件
·变量
·表达式
·有返回值的函数
例:
如果某变量大于30则显示old man 如果小于30则显示youngman
[root@node3 if]# cat test1.pp
$test = 21
if $test > 30 {
notice('old man')
} else {
notice ('young man')
}
[root@node3 if]# puppet applytest1.pp
Notice: Scope(Class[main]): young man
Notice: Compiled catalog fornode3.test.com in environment production in 0.06 seconds
Notice: Finished catalog runin 0.03 seconds
判断当前操作系统如果是redhat系列则显示httpd如果是debian|ubuntu则显示apache2
这里需要用到变量operatingsystem ,其作用是显示当前操作系统的类型
具体可以使用facter命令来查看当前所提供的变量
[root@node3 if]# facter -p |grep ope
operatingsystem => CentOS
[root@node3 if]# cat test2.pp
if $operatingsystem =~/(?imx:^(centos|redhat))/ {
notice 'installed httpd'
} elsif $operatingsystem =~/(?imx:^(debian|ubuntu))/ {
notice 'installed apache2'
} else {
notice 'unkown OS'
}
[root@node3 if]# puppet applytest2.pp
Notice: Scope(Class[main]): installed httpd
Notice: Compiled catalog for node3.test.comin environment production in 0.06 seconds
Notice: Finished catalog runin 0.04 seconds
定义资源引用,将匹配的程序进行安装,完善如下:
[root@node3 if]# cat test3.pp
if $operatingsystem =~/(?imx:^(centos|redhat))/ {
$package = 'httpd'
notice 'installed httpd'
} elsif $operatingsystem =~/(?imx:^(debian|ubuntu))/ {
$package = 'apache2'
notice 'installed apache2'
} else {
notice 'unkown OS'
}
package {"$package": #引用变量
allow_virtual => false,
ensure => installed,
}
[root@node3 if]# puppet applytest3.pp
Notice: Scope(Class[main]):installed httpd
Notice: Compiled catalog fornode3.test.com in environment production in 0.83 seconds
Notice:/Stage[main]/Main/Package[httpd]/ensure: created
Notice: Finished catalog runin 26.86 seconds
类(class)
命名的代码块,可以调用其代码块,类似于shell中的函数
不调用是不会被执行的
类是用于通用目标的一组资源,因此它的命名的代码块,在某位置创建之后可在puppet全局使用,只不过调用的时候,调用类和调用变量是近似的,有的时候是需要定义作用于的
如下所示
class httpd{
package {'httpd':
ensure => installed,
before =>File{'/etc/httpd/conf/httpd.conf'}
}
file{'/etc/httpd/conf/httpd.conf':
ensure => file,
source =>'/backup/httpd/conf/httpd.conf',
mode => 0644,
owner => root,
group => root,
notify => Service['httpd'],
}
service {'httpd':
ensure => running,
#subscribe =>File['/etc/httpd/conf/httpd.conf'],
}
}
include httpd
一个例子
class apache {
package {'httpd':
ensure => installed
}
file {'httpd.conf':
path =>'/etc/httpd/conf/httpd.conf',
ensure => file,
require => Package['httpd'],
}
service {'httpd':
ensure => true,
require => Package['httpd'],
subscribe => File['httpd.conf'],
}
}
声明class
这样声明的好处是因为类可以带参数的
在带参数的类,在传递参数的时候使用类似于资源声明风格的类声明就很有必要了
同样是一个类,比如nginx类,但有时候装的nginx还有另外一个变种叫tengin,虽然名字叫tengin 但是它的服务脚本和配置文件仍然是nginx
[root@node3 class]# cattest2.pp
class httpd {
package {'httpd':
ensure => installed,
before => File['/etc/httpd/conf/httpd.conf'],
}
file {'/etc/httpd/conf/httpd.conf':
ensure => file,
source => '/backup/httpd/conf/httpd.conf',
mode => 0644,
owner => root,
group => root,
notify => Service['httpd'],
}
service {'httpd':
ensure => true,
}
}
class {'httpd':}
相比include,带参数的class 更具灵活性
类的继承
当定义好一个类以后,类给的信息还不够详细的话,则可以在其基础之上再次细化
在原有基础上再新增一些属性或条件判断属性
比如我们需要安装nginx使其做web服务,或做反向代理
例:
class nginx {
package {'nginx':
ensure => installed,
}
}
只安装程序包,那么服务启动和配置安装都没有管理,因为用在反向代理配置中和直接用在webserver中是不一样的,因此在这基础上可以根据各自的需要去丰满它
所以,如下所示:
使用inherits 为继承nginx
[root@node3 class]# catnginx.pp
class nginx {
package {
ensure => installed,
}
}
class nginx::webserverinherits nginx {
file {'/etc/nginx/nginx.conf':
ensure => file,
mode => 0644,
user => root,
group => root,
source => '/backup/nginx/conf',
requrie => Package['ninx'],
}
service{'nginx':
ensure => true,
subscribe => File['/etc/nginx/nginx.conf'],
}
}
class {'nginx':}
如果我们想使其做反向代理,而其有指定的配置文件,那么则需再继承新的类
class nginx {
package {'nginx':
ensure => installed,
}
}
class nginx::web inherits nginx {
file {'/etc/nginx/nginx.conf':
ensure => file,
mode => 0644,
owner => root,
group => root,
source => '/backup/conf/nginx/nginx.conf',
require => Package['nginx'],
}
service {'nginx':
ensure => true,
subscribe => File['/etc/nginx/nginx.conf'],
}
}
include nginx::web
如果我们想让其做proxy的功能,那么可以引用其他类,如下所示:
class nginx {
package {'nginx':
ensure => installed,
}
}
class nginx::web inheritsnginx {
file {'/etc/nginx/nginx.conf':
ensure => file,
mode => 0644,
group => root,
owner => root,
source => '/backup/conf/nginx/nginx-web.conf',
require => Package['nginx'],
}
service {'nginx':
ensure => true,
subscribe =>File['/etc/nginx/nginx.conf'],
}
}
classnginx::proxy inherits nginx {
file {'/etc/nginx/nginx.conf':
ensure => file,
mode => 0644,
owner => root,
group => root,
source =>'/backup/conf/nginx/nginx-web.conf',
require => Package['nginx'],
}
service {'nginx':
ensure => true,
subscribe => File['/etc/nginx/nginx.conf'],
}
}
includenginx::proxy
以上所继承的类完全不一样
假如我们当前节点想安装web则声明web类,如果想安装的是代理服务器那么则声明proxy类
include nginx:: #表示只执行第一个类,而proxy是不会被执行的
include nginx::proxy #表示执行proxy类,同时也会继承父类