puppet(2)


Metaparamters:

多个彼此间均存在先后次序的资源,可使用“->”,定义为次序链的形式:

Package['nginx'] -> File['/etc/nginx/conf.d/default.conf'] -> Service['nginx']


多个彼此间均存在先后次序的资源,可使用“~>”,定义为通知链的形式:

Package['nginx'] ~> File['/etc/nginx/conf.d/default.conf'] ~> Service['nginx']
package{'nginx':
ensure=> installed,
provider => rpm,
source=> '/tmp/nginx-1.6.2-1.el6.ngx.x86_64.rpm',
} ->
file {'/etc/nginx/conf.d/default.conf':
ensure=> file,
source=> '/tmp/default.conf',
} ~>
service{'nginx':
ensure=> running,
enable=> true,
require=> Package['nginx'],
restart=> '/etc/rc.d/init.d/nginx reload',
}


puppet变量及变量作用域:


变量名均应该以$开头,赋值符号为=;

任何非正则表达式类型的数据都可直接赋值给变量名;


数据类型:

布尔型:true以及false;

undef:从未被声明过的变量的值的类型;

字符型:非结构化文本字符串;引用可有可无,单引号为强引用,双引号为弱引用;

数值型:整数或浮点数;默认为字符型,只有在特定上下文才被当作数值;

数组:在中括号[]中以逗号分隔的item列表,形如[item1,item2,...,],其item可以为任意可用的数据类型,包括数组及hash等;索引从0开始计数,也可以负数;例如:[Package['nginx'],File['nginx.conf'],File['default.conf'],];

hash:定义在{}中,以逗号分隔的"key => value"列表即为hash类型数据;其中的key为字符类型,value可以puppet支持的任意数据类型;引用时,其索引为key;


正则表达式:

语法结构:

/(?<ENABLED OPTION>:<SUBPATTERN>)/
/(?-<DISABLED OPTION>:<SUBPATTERN>)/


OPTION:

i: 忽略字符大小写

m: 把点号当换行符使用

x:忽略模式中的空白字符和注释


惯常用法:(?i-mx:PATTERN)

$webpackage=$operatingsystem? {
       /(?i-mx:ubuntu|debian)/ => 'apache2',
       /(?i-mx:fedora|redhat|centos)/  => 'httpd',
}


puppet表达式:

比较操作符:==, !=, <, <=, >, >=, =~, !~, in

逻辑运算符:and, or, !

算术操作符:+, -, *, /, >>, <<


作用域:

即变量生效的代码范围;

在puppet中,scope可用于限定变量及资源默认属性的作用范围,但不能用于限定资源名称及资源引用的生效范围


作用域的分类:

top scope:顶级作用域,生效范围为全局

node scope: 节点作用域,生效范围为单个节点

class scope:

parent scope

child scope


引用非当前作用域可访问变量,必须使用FQN格式的进行:

$::c1::c2::webpackage


puppet中可以使用的变量的种类:

自定义变量:$webpackage

facter变量:“facter -p”命令执行结果中显示出的变量均可直接引用;

内置变量:

客户端内置:

$clientcert

$clientversion

服务器端内置:

$servername

$serverip

$serverversion

$module_name


变量的追加赋值:+=

$users = ['user1','user2',]
$users += ['user3',]


注意:支持追加赋值的数据类型:

字符串:字符串连接

数组:数组合并

hash:hash合并


puppet的条件判断:

条件语句:if, case, selector, unless


(1) if语句

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


可用的CONDITION:

变量

表达式

有返回值的函数

if $operatingsystem =~ /^(?i-mx:(Ubuntu|RedHat))/ {
       notice("Welcome to $1 linux distribution.")
} else {
       notice("Welcome to unkown world.")
}


(2) case

语法结构:

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


CONTROL_EXPRESSION:

变量、表达式、有返回值的函数


各case的可用数据类型:

字符串(引用)、变量、有单个返回值的函数、正则表达式模式或default; 


case $operatingsystem {
'CentOS','Redhat','Fedora': { notice("Welcome to RedHat OS Family.") }
/^(i-mx:(ubuntu|debian))/: { notice("Welcome to $1 Linux distribution.") }
default: { notice("Alien.") }


(3) selector

类似于case,但不同于case匹配到某分支后执行相应的代码段的是,selector在匹配到某分支后直接返回一个值;


语法结构:

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


CONTROL_VARIABLES: 变量或有返回值的函数;

各case的可用数据类型:

字符串(引用)、变量、有单个返回值的函数、正则表达式模式或default; 


注意:selector的case不能使用列表;


各case的value可用的数据类型:

除了hash以外的直接值、变量、能调用返回值的函数或其它的selector;


puppet中的class:


用于公共目的的一组资源,即命名的代码块;创建后可以在puppet全局进行调用;类可以被继承;


语法格式:

class name {
... puppet code ...
}


定义过的类只有被调用(声明)才会执行;

class nginxsrv {
   package{'nginx':
ensure=> installed,
provider => rpm,
source=> '/tmp/nginx-1.6.2-1.el6.ngx.x86_64.rpm',
   } ->
   file {'/etc/nginx/conf.d/default.conf':
ensure=> file,
source=> '/tmp/default.conf',
   } ~>
   service{'nginx':
ensure=> running,
enable=> true,
require=> Package['nginx'],
restart=> '/etc/rc.d/init.d/nginx reload',
   } 
}
include nginxsrv


注意:(1) 类名可以包含小写字母、数字和下划线,但只能小写字母开头;

    (2) 类会引入新的变量作用域;


类的声明方法:

(1) 使用include关键字;

include base::subclass
include class1, class2, ...
(2) 使用require关键字;
(3) 使用类似资源声明的方式;
(a) class {'class_name':}
(b) class {'class_name':
argu1=> value1,
argu2=> value2,
...
}


类继承:

主要目标在于继承已有类的,并在其基础之上可以新增额外puppet代码;

还可以实现覆盖资源属性、追加资源属性值;

class base {
...puppet code...
}
class base::subclass_name inherits base {
...puppet code...
}


注意,类继承场景中:

(1) 声明子类时,其父类会被自动先进行声明;

(2) 基类即成为子类的父作用域,基于类定义的变量以及属性的默认值会被子类复制一份;

(3) 子类会覆盖基类同一资源相同属性的值;

class nginx {
       package{'nginx':
               ensure  => present,
               provider => rpm,
               source  => '/tmp/nginx-1.6.2-1.el6.ngx.x86_64.rpm',
       }
}
class nginx::websrv inherits nginx {
       file {'/etc/nginx/conf.d/default.conf':
               ensure  => file,
               source  => '/tmp/default.conf',
               require => Package['nginx'],
       }
       service {'nginx':
               ensure  => running,
               enable  => true,
               subscribe => File['/etc/nginx/conf.d/default.conf'],
       }
}
include nginx::websrv


注意:子类可以覆盖父类资源的属性值:通过引用父类中定义的资源,并为其某属性定义新值实现,在子类中使用类似如下格式:

Type['title'] {
attribute1 => value1,
attribute2=> value2,
...
}


示例:

class nginx {
       package{'nginx':
               ensure  => present,
               provider => rpm,
               source  => '/tmp/nginx-1.6.2-1.el6.ngx.x86_64.rpm',
       }
}
class nginx::websrv inherits nginx {
       Package['nginx'] {
               provider => yum,
       }
       file {'/etc/nginx/conf.d/default.conf':
               ensure  => file,
               source  => '/tmp/default.conf',
               require => Package['nginx'],
       }
       service {'nginx':
               ensure  => running,
               enable  => true,
               subscribe => File['/etc/nginx/conf.d/default.conf'],
       }
}
include nginx::websrv

注意:子类可以覆盖父类资源的属性值:通过引用父类中定义的资源,并为其某属性定义新值实现,在子类中使用类似如下格式:

Type['title'] {
attribute1 => value1,
attribute2=> value2,
...
}


示例:

class nginx {
       package{'nginx':
               ensure  => present,
               provider => rpm,
               source  => '/tmp/nginx-1.6.2-1.el6.ngx.x86_64.rpm',
       }
}
class nginx::websrv inherits nginx {
       Package['nginx'] {
               provider => yum,
       }
       file {'/etc/nginx/conf.d/default.conf':
               ensure  => file,
               source  => '/tmp/default.conf',
               require => Package['nginx'],
       }
       service {'nginx':
               ensure  => running,
               enable  => true,
               subscribe => File['/etc/nginx/conf.d/default.conf'],
       }
}
include nginx::websrv


注意:也可以在子类中引用父类中的资源,通过为某属性使用“+>”为其追加新值

class nginx {
       package{'nginx':
               ensure  => present,
               provider => rpm,
               source  => '/tmp/nginx-1.6.2-1.el6.ngx.x86_64.rpm',
       }
       file {'/etc/nginx/conf.d/default.conf':
               ensure  => file,
               source  => '/tmp/default.conf',
               require => Package['nginx'],
       }
       service {'nginx':
               ensure  => running,
               enable  => true,
               subscribe => File['/etc/nginx/conf.d/default.conf'],
       }
}
class nginx::websrv inherits nginx {
       file {'/etc/nginx/nginx.conf':
               ensure  => file,
               source  => '/tmp/nginx.conf',
               require => Package['nginx'],
       }
       Service['nginx'] {
               #subscribe => [File['/etc/nginx/conf.d/default.conf'],File['/etc/nginx/nginx.conf']],
               subscribe +> File['/etc/nginx/nginx.conf'],
       }
}
include nginx::websrv


参接受参数的类:

class class_name($argu1='value1',...) {
...puppet code...
}
class mysql($conf='/etc/my.cnf') {
       package{'mysql-server':
               ensure  => present,
       }
       file{"$conf":
               source  => '/tmp/my.cnf',
               ensure  => file,
       }
}
class {'mysql':
       conf    => '/etc/mysql/my.cnf',
}


puppet中的template:


模板:基于ERB(Embedded RuBy)模板语言,在静态文件中使用变量等编程元素生成适用于多种不同环境的文本文件;

ERB: 用于在文本文件中内嵌ruby代码,原来的文本信息不会被改动,而ruby代码则会被执行,且执行结果作为新内容替换在ruby代码所在处;


<%= Ruby Expression %>:替换为表达式值;

<% Ruby code %>:仅执行其中的代码,不执行任何替换;

<%# comment %>:注释信息;

<%% 或 %%>:转义符,分别用于输入<%和%>;

<%- Ruby code %>:忽略空白字符;

<% Ruby code -%>: 忽略空白行;


在模板中可以调用puppet中的任意变量,但变量名要以@开头;

迭代:

<% @ArrayName.echo do | Varaible_Name | -%>
Some Text with <%= Varialbe_Name %>
<% end %>


注意:模板语言中对变量算术运算的方法:

<%= @processorcount.to_i - 2 %>
<%= Integer(@processorcount) - 2 %>