1. 程式人生 > >Puppet 之 流程控制介紹

Puppet 之 流程控制介紹

if case selector

1 概述


puppet流程控制語句有四種,if,case,selector,unless(3.7版本後引入),由於unless是if單分支語句取反,因此,本文重點介紹if,case,selector三種語法的使用

備註:本文的相關內容摘自文章:https://www.dwhd.org/20150609_155030.html


2 if語句


if語句有三種分支的表示

2.1 if單分支

if  CONDITION {
...
statement
....
}

2.2 if雙分支

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

其中,CONDITION的給定方式:

(1) 變量

(2) 比較表達式

(3) 有返回值的函數

例子

安裝apache服務包,判斷系統的版本,其中osfamily這個變量是在factor裏獲得

vim installpkg.pp
if $osfamily == 'RedHat' {
    $apachename = 'httpd'
} else {
    $apachename = 'httpd'
}
package {"$apachename":
    ensure => latest,
}

2.3 if多分支

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

例子

vim installpkg.pp
if $osfamily == 'RedHat' {
    $apachename = 'httpd'
} elsif $osfamily == 'Windows' {
    $apachename = 'apache'
} else {
    $apachename = 'httpd'
}
package {"$apachename":
    ensure => latest,
}

綜合例子:正則表達式匹配

以下例子表示osfamily變量是否匹配debian

vim regex.pp
if $osfamily =~ /(?i-mx:debian)/ {
    $webserver = 'apache2'
} else {
    $webserver = 'httpd'
}
package {"$webserver":
    ensure => installed,
    before => [File['httpd.conf'],Service['httpd']],
}
file {'httpd.conf':
    path => '/etc/httpd/conf/httpd.conf',
    source => '/root/httpd.conf',
    ensure => file,
}
service {'httpd':
    ensure => running,
    path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin',
    enable => true,
    restart => 'systemctl restart httpd.service',
    subscribe => File['httpd.conf'],
}

3 case語句


每一個分支都是一個完整的代碼段

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

類似if語句,case語句會從多個代碼塊中選擇一個分支執行,這跟 其他語言中的case語句功能一致

case語句會接受一個控制表達式和一組case代碼塊,並執行打一個匹配到的控制表達式的塊

1)、控制表達式可以是puppet代碼中的任何代碼片段(可以是單個變量,可以是一個表達式例如算法表達式,可以是一個有返回值的函數)

2)、各case分支可以是一個直接值、可以是個變量、可以是一個有返回單個值的函數、可以是一個正則表達式、可以是默認值default

CONTROL_EXPRESSION:

(1) 變量

(2) 表達式

(3) 有返回值的函數

各case的給定方式:

(1) 直接字串;

(2) 變量

(3) 有返回值的函數

(4) 正則表達式模式;

(5) default

例子

根據變量operatingsystem返回不同的通知

vim  case.pp
case $operatingsystem {
    'Solaris':          {notice("Welcome to Solaris")}
    'RedHat','CentOS':  {notice("Welcome to RedHat osfamily")}
    /^(Debian|Ubuntu)$/:{notice("Welcom to $1 linux")}
    default:            {notice("Welcome,alien *_*")}
}

例子

判斷osfamily變量,安裝web服務,復制配置文件並啟動服務。

vim case.pp
case $osfamily {
    "RedHat":{$webserver='httpd'}
    /(?i-mx:debian)/: {$webserver='apache2'}
    default : {$webserver='httpd'}
}
package {"$webserver":
    ensure => installed,
    before => [File['httpd.conf'],Service['httpd']],
}
file {'httpd.conf':
    path => '/etc/httpd/conf/httpd.conf',
    source => '/root/httpd.conf',
    ensure => file,
}
service {'httpd':
    ensure => running,
    path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin',
    enable => true,
    restart => 'systemctl restart httpd.service',
    subscribe => File['httpd.conf'],
}


4 selector語句


和case的區別是selector的每一個分支是一個返回的值,而case每一個分支是完整的代碼

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

selector只能用於期望出現直接值(planin value)的地方,這包括變量賦值、資源屬性、函數參數、資源標題、其他selector的值及表達式

selector不能用於一個已經嵌套於selector的case中,也不能用於一個已經嵌套於case的case語句中

(1)、整個selector語句會被當作一個單獨的值,puppet會將控制變量按列出的次序與每個case進行比較,並在遇到一個匹配的case後,將其值作為整個語句的值進行返回,並忽略後其他的case

(2)、控制變量與各case比較的方式與case遇見相同,但如果沒有任何一個case與控制變量匹配時,puppet在編譯時會將返回一個錯誤,因此實踐中其必須提供defeat case

(3)、selector的控制變量只能是變量或有返回值的函數,切記不能使用表達式

(4)、其各case可以是直接值(需加引號)、 變量、能調用返回值的函數、正則表達式模式或default

(5)、但與case語句所不同的是 selector的各case不能使用列表

(6)、selector的各case的值可以是一個除了hash以外的直接值、變量、能調用返回值的函數或其他selector

例子

以下是不一樣的方法,case和selector的對比

#use case
case $osfamily {
    "RedHat":{$webserver='httpd'}
    /(?i-mx:debian)/: {$webserver='apache2'}
    default : {$webserver='httpd'}
}
#use selector
$webserver = $osfamily ?{
    "RedHat" => 'httpd',
    /(?i-mx:debian)/ => 'apache2',
    default => 'httpd',
}
package {"$webserver":
    ensure => installed,
}

CONTROL_VARIABLE的給定方法:

(1) 變量

(2) 有返回值的函數

各case的給定方式:

(1) 直接字串;

(2) 變量

(3) 有返回值的函數

(4) 正則表達式模式;

(5) default

註意:不能使用列表格式;但可以是其它的selecor;

$pkgname = $operatingsystem ? {
/(?i-mx:(ubuntu|debian))/       => 'apache2',
/(?i-mx:(redhat|fedora|centos))/        => 'httpd',
default => 'httpd',
}
package{"$pkgname":
ensure  => installed,
}

示例2:

$webserver = $osfamily ? {
"Redhat" => 'httpd',
/(?i-mx:debian)/ => 'apache2',
default => 'httpd',
}
package{"$webserver":
ensure  => installed,
before  => [ File['httpd.conf'], Service['httpd'] ],
}
file{'httpd.conf':
path    => '/etc/httpd/conf/httpd.conf',
source  => '/root/manifests/httpd.conf',
ensure  => file,
}
service{'httpd':
ensure  => running,
enable  => true,
restart => 'systemctl restart httpd.service',
subscribe => File['httpd.conf'],
}


5 unless語句


unless語句等價於和if單分支語句取反

語法

unless  CONDITION {
....
statement
....
}

等價於如下的語句

if ! CONDITION {
...
statement
....
}



Puppet 之 流程控制介紹