puppet 变量及作用域

Posted abels0025

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了puppet 变量及作用域相关的知识,希望对你有一定的参考价值。

一.puppet variable

1.变量命名

puppet的变量名称须以$开头,复制操作符为=号
格式为:
    $content = "some content\n" 
或这样理解
    $variable = ‘value‘

任何正常数据类型(非正则表达式的)的值都可以赋予puppet中的变量,任何能解析为一个正常值(包括表达式,函数和其他变量)的语句都可以作为value;变量将包含这个语句解析的值而不是语句的引用; 

puppet的变量只能使用他们的短名称来分配,这意味着,在给定范围内不能将外部范围内的value赋值给variable;

例如:
[root@bogon ~]# rpm -q vlock
package vlock is not installed

[root@bogon media]# vim test.pp
$package_vlock = ‘vlock‘
package$package_vlock:
        ensure => installed,


[root@bogon media]# puppet apply test.pp
Notice: Compiled catalog for bogon in environment production in 1.62 seconds
Notice: /Stage[main]/Main/Package[vlock]/ensure: created
Notice: Finished catalog run in 56.07 seconds

[root@bogon media]# rpm -q vlock
vlock-1.3-31.el6.x86_64


在最新版4.5版本中,可以通过数组或hash的方式赋值多个变量,例如:
数组(变量和值必须数量一样):
    [$a, $b, $c] = [1,2,3]      # $a = 1, $b = 2, $c = 3
    [$a, [$b, $c]] = [1,[2,3]]  # $a = 1, $b = 2, $c = 3
    [$a, $b] = [1, [2]]         # $a = 1, $b = [2]
    [$a, [$b]] = [1, [2]]       # $a = 1, $b = 2

hash(key必须匹配对应的变量名):
[$a, $b] = a => 10, b => 20   # $a = 10, $b = 20

官方关于变量的文档:https://docs.puppet.com/puppet/4.5/reference/lang_variables.html

2.puppet data type

puppet语言支持多种数据类型以用于变量个属性的值,以及函数的参数:

2.1字符型

        非结构化的文本字符串,可以使用引号也可以不用;
        单引号中的变量不会替换,而双引号中的能够进行变量替换;
        字符型值也支持使用转义符;

2.2数值型

可为整型或浮点型,不过,puppet只有在有在数值上下文才把数值当数值型对待,其他情况下一律以字符型处理;

2.3数组

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

2.4布尔型

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

2.5undef

        从未被声明的变量的值类型即为undef;
也可以手动为变量父域undef值,即直接使用不加引号的undef字符串;

2.6hash

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

3.正则表达式

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

官方关于数据类型的文档:https://docs.puppet.com/puppet/4.5/reference/lang_data.html

4.facter变量

puppet使用了一个称作facter的工具来收集系统信息,规范化之后将其放进一系列变量中,并传递给puppet;

facter的各变量是top scope的变量,这说明,可以在各manifest中直接通过$fact_name访问所需的fact变量;

centos6.7 x86-64的facter见结尾附录;

例如:
[root@bogon ~]# facter | grep  hostname
hostname => bogon

[root@bogon media]# cat a.txt 
bogon[root@bogon media]# cat test1.pp 
file ‘a.txt‘:
        ensure => present,
        path => ‘/media/a.txt‘,
        content => $hostname,

[root@bogon media]# puppet apply test1.pp
Notice: Compiled catalog for bogon in environment production in 0.73 seconds
Notice: /Stage[main]/Main/File[a.txt]/ensure: created
Notice: Finished catalog run in 0.13 seconds

[root@bogon media]# cat a.txt 
bogon

5.puppet内置变量built-in variable

agent端可用变量:

        $clientcert:节点certname的值(这是自报的,使用$trusted[‘certname‘]来验证证书名称)
        $clientversion:当前puppet agent的版本;
        $clientnoop:节点运行时noop的值(true或false);
        $agent_specified_environment:节点的enviorment设置,如果environment(puppet.conf中或--environment)未设置值,$agent_specified_environment的值将成为undef的(也就是说它不会像设置那样默认生成);

master端可用变量:

        $environment:agent node的environment;
        $serverip:puppet master的IP地址;        
        $servername:puppet master的完全限定性名称;
        $serverversion:当前puppet master上puppet的版本;
        $settings::

详情可以参考:
https://docs.puppet.com/puppet/4.5/reference/lang_facts_and_builtin_vars.html
https://docs.puppet.com/puppet/4.5/reference/configuration.html#certname

6.变量作用域scope

scope是一个特定的代码区域,用于同程序中的其他代码隔离开来;

在puppet中,scope可用于限定变量(variable)及资源默认属性(resource defaults)的作用范围,但不能用于限定资源名称(resource titles)及资源引用的生效范围(resource references);

任何给定作用域都可以访问它自己的内容,也可以接受来自于其父作用域,节点作用域和顶级作用域中的内容
技术图片
在上面的图表中:
        顶级作用域top scope仅能够访问自己的属性默认值;
        节点作用域node scope能够访问自己的及顶级作用域的变量和属性默认值;
        example::parent  example::other和example::four能访问自己的以及节点作用域和顶级作用域的变量和属性默认值;
        example::child能访问自己的,example::parent的作用域,节点作用域和顶级作用域的变量和默认属性值;

注意:
        top scope内声明的变量和属性默认值其他scope都可使用;
        node scope内声明的变量和属性默认值在top scope以外的任何地方都可使用;
        local scope内声明的变量和属性默认值只有该scope和其scope可用

通过完全限制名称可以访问任何命名的scope中变量和属性默认值,其格式为:
$name_of_scope::name_of_variable

例如:
include apache::params
$local_copy = $apache::params::confdir
这个例子会给变量$local_copy设置一个值(该值是apache::params类中变量$confdir的值);

注意:
top scope的名称是空字符串,因此,$::my_variable表示是top scope中变量$my_variable的值,即使$my_variable在local scope中有不同的值;
一定要声明一个class才能访问它的变量;

官方关于scope的文档:https://docs.puppet.com/puppet/4.5/reference/lang_scope.html

二.expressions and operators

1.表达式

表达式可用于如下场景:
        作为另一个表达式的操作数;
        if语句的条件;
        case语句或selector语句的控制段;
        作为值分配给变量;
        资源属性的值;
        函数调用的参数;
        资源的title;
        数组中的条目或hash中的键和值;

表达式不可用于如下场景:
        class名称或定义的类型(如在类或定义语句中);
        变量的名称(变量名称必须为一个文本名称);
        资源类型名称或资源类型;


表达式语法:
        表达式由下面讲到的的操作符构成;
        任何一种表达式都有自己的语法,而且任何语法都可以被()括住;

2.操作符

操作符语法(只列出两种):
        二元操作符:在两个操作符中间出现,如$a = 1 ,5<9 , $operatingsystem != ‘centos‘等;
        一元操作符:出现在一个操作数之前,如*$interface, !$is_virtual等;

2.1顺序操作Order of Operations

运算符的优先级(从高到低):
        ! (一元运算符: 非)
        - (一元运算符: 数值取负)
        * (一元运算符: array splat)
        in
        =~ 和 !~ (正则表达式或数据类型的匹配/不匹配)
        *, /, 和 % (乘,除和取余)
        + 和 - (加法,减法)
        << 和 >> (位左移和位右移)
        == 和 != (等于和不等于)
        >=, <=, >, 和 < (大于等于,小于等于,大于和小于)
        and
        or
        = (赋值) 

2.2比较操作符comparison operators

比较操作符有如下性质:
    多个操作数做比较;
    返回的结果是布尔型值;

        ==(等于):允许如下的数据类型作为操作数:number,string,array,hash,boolean,data_type;

        !=(不等于):$x != $y 和 !($x==$y)相同;

        < (小于):比较的操作数必须是同一类型,允许的操作数类型:number,string和data_type;

        > (大于):同上;

        <= (小于等于):同上;

        >= (大于等于):同上;

        =~ (正则表达式或数据类型匹配):右边的操作数必须是:正则表达式,字符串化的正则表达式("^[<>=]7")或一个数据类型(Integer[1,10]);

        !~ (正则表达式或数据类型不匹配):左边的操作数匹配右边的操作数是返回false,$x !~ $y 等同于!($x =~ $y);

        in:右操作数包含左操作数时返回true;左操作数为:string,正则表达式或data type;右操作数为:string,arry或hash

2.3布尔操作符boolean operators

布尔操作符有如下性质:
    操作符都是布尔类型值;
    返回的也是布尔类型值;

        and:所有的操作数都为真是返回true,否则返回false;

        or:操作数有一个为真时返回true;

        !(not):单目操作符,操作数为真时返回false,为假时返回true;

2.4算术操作符arithmetic operators

算术操作符有如下性质:
    操作数为数值(除了一元操作符-);如果一个操作数是string,将会被转换为数值形式,如果无法转换,操作会失败;
    返回的是数值;
        +(加法):返回两个操作数的和;

        -(减法,负):返回两个操作数之差;一元操作符-表示取负;

        /(除法):返回两个操作数的商;

        *(乘法):返回两个操作数的乘积;不要与只有一个操作数的splat操作符混淆;

        %(取模):返回两数取模运算后的余数;

        <<(左位移):向左位移:Left bitwise shift: shifts the left operand by the number of places specified by the right operand
        >>(右位移):向右位移:Right bitwise shift: shifts the left operand by the number of places specified by the right operand. 
官方参考文文档:
https://docs.puppet.com/puppet/3.8/reference/future_lang_expressions.html
https://docs.puppet.com/puppet/4.5/reference/lang_expressions.html

三.条件语句和表达式

1.if语句

if语句支持如下格式
单分支:
     if condition
        statement
      

双分支:
      if condition
        statement
      
      else
        statement
      

多分支:
    if condition
        statement
    
    elsif condition
        statement
    
    else
        statement
    
if语句的condition包括:
    变量;
    表达式;
    函数;
也可以使用正则表达式作为变量,如:
if $hostname =~ /^www(\d+)\./
  notice("Welcome to web server number $1")

2.unless语句

语法格式(else语句可选):
    umless  condition
        statement
    
    else
        statement
    

3.case语句

语法格式:
    case control_express
          case1,..... :   statement
          case2,..... :  statement 
          default:        statement
    
其中,
control_express可以为:
        变量;
        表达式;
        返回值的函数;

根据case值的数据类型,puppet可以使用如下行为来判断case匹配:
        Most data types(如字符串,布尔值等)和==匹配的control的值做比较,如比较字符串大小写);
        正则表达式和=~匹配的control值做匹配操作;
        Data Types(像Integer)和=~匹配的control值做比较,任意测试值是否属于一个数据类型;
        数组中的值和control值做递归比较,首先检查两者长度是否相等,然后每个相应的元素作比较;
        比较hash的每个键值对;若要匹配,control值和case必须有同样的键;

case语句也可以使用正则表达式:
case $hostname
  /www(d+)/: notice("Welcome to web server number $1"); include role::web
  default:   include role::generic
 

例如:
case $operatingsystem
      ‘Solaris‘:           include role::solaris
      ‘RedHat‘, ‘CentOS‘: include role::redhat  
      /^(Debian|Ubuntu)$/: include role::debian  
      default:             include role::generic

4.selectors

selector表达式和case语句相似,只不过case是执行相应的代码块,它是返回一个值; 

整个selector语句会被当作一个单独的值,puppet会将控制不了按列出的次序与每个case进行比较,并在匹配时将值作为整个语句的值进行返回,并忽略后面的其他case;

selector的控制表达式可以为能返回值的任意表达式,如:
        变量;
        表达式;
        能返回值的函数

各case可以使直接值(加引号),变量,能调用返回值的函数,正则表达式模式或default;

各case的值可以是一个除了hash以外的直接值,变量,能调用返回值的函数或其他的selector;

语法格式:
    condition_variable ?
        case1 => value1
        case2 => value2
        ....
        default => valueN
    


selector也可以使用正则表达式:
$system = $operatingsystem ?
  /(RedHat|Debian)/ => "our system is $1",
  default           => "our system is unknown",


例如:
$rootgroup = $osfamily ?
    ‘Solaris‘          => ‘wheel‘,
    /(Darwin|FreeBSD)/ => ‘wheel‘,
    default            => ‘root‘,

file ‘/etc/passwd‘:
  ensure => file,
  owner  => ‘root‘,
  group  => $rootgroup,

上述的例子中,rootgroup变量的值是osfamily变量值的其中之一;

官方文档:https://docs.puppet.com/puppet/4.5/reference/lang_conditional.html

四.附录

facter变量:
[root@bogon ~]# facter
architecture => x86_64
augeasversion => 1.0.0
bios_release_date => 05/20/2014
bios_vendor => Phoenix Technologies LTD
bios_version => 6.00
blockdevice_sda_model => VMware Virtual S
blockdevice_sda_size => 21474836480
blockdevice_sda_vendor => VMware,
blockdevice_sr0_model => VMware IDE CDR10
blockdevice_sr0_size => 1073741312
blockdevice_sr0_vendor => NECVMWar
blockdevices => sda,sr0
boardmanufacturer => Intel Corporation
boardproductname => 440BX Desktop Reference Platform
boardserialnumber => None
facterversion => 2.4.6
filesystems => ext4,iso9660
fqdn => bogon
gid => root
hardwareisa => x86_64
hardwaremodel => x86_64
hostname => bogon
id => root
interfaces => eth0,lo
ipaddress => 192.168.85.129
ipaddress_eth0 => 192.168.85.129
ipaddress_lo => 127.0.0.1
is_virtual => true
kernel => Linux
kernelmajversion => 2.6
kernelrelease => 2.6.32-573.el6.x86_64
kernelversion => 2.6.32
lsbdistcodename => Final
lsbdistdescription => CentOS release 6.7 (Final)
lsbdistid => CentOS
lsbdistrelease => 6.7
lsbmajdistrelease => 6
lsbminordistrelease => 7
lsbrelease => :base-4.0-amd64:base-4.0-noarch:core-4.0-amd64:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-noarch
macaddress => 00:0C:29:9D:AB:9B
macaddress_eth0 => 00:0C:29:9D:AB:9B
manufacturer => VMware, Inc.
memoryfree => 328.07 MB
memoryfree_mb => 328.07
memorysize => 475.24 MB
memorysize_mb => 475.24
mtu_eth0 => 1500
mtu_lo => 65536
netmask => 255.255.255.0
netmask_eth0 => 255.255.255.0
netmask_lo => 255.0.0.0
network_eth0 => 192.168.85.0
network_lo => 127.0.0.0
operatingsystem => CentOS
operatingsystemmajrelease => 6
operatingsystemrelease => 6.7
os => "release"=>"full"=>"6.7", "minor"=>"7", "major"=>"6", "lsb"=>"release"=>":base-4.0-amd64:base-4.0-noarch:core-4.0-amd64:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-noarch", "distdescription"=>"CentOS release 6.7 (Final)", "distcodename"=>"Final", "minordistrelease"=>"7", "distid"=>"CentOS", "majdistrelease"=>"6", "distrelease"=>"6.7", "name"=>"CentOS", "family"=>"RedHat"
osfamily => RedHat
partitions => "sda1"=>"size"=>"1024000", "filesystem"=>"ext4", "mount"=>"/boot", "uuid"=>"c4303fb9-c526-4dc7-bb1d-d6d726f14839", "sda2"=>"size"=>"40916992", "filesystem"=>"LVM2_member"
path => /usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
physicalprocessorcount => 1
processor0 => AMD E-350 Processor
processorcount => 1
processors => "count"=>1, "physicalcount"=>1, "models"=>["AMD E-350 Processor"]
productname => VMware Virtual Platform
ps => ps -ef
puppetversion => 3.8.7
rubyplatform => x86_64-linux
rubysitedir => /usr/lib/ruby/site_ruby/1.8
rubyversion => 1.8.7
selinux => false
serialnumber => VMware-56 4d 1a 00 90 97 b0 cd-d3 75 56 f6 9f 9d ab 9b
sshdsakey => AAAAB3NzaC1kc3MAAACBALpITUTURsplzmtvhO5Jhg0nZMRZ/vyVsJXPdZm5xjdpiVTr+9eeMBxJ6UyKwcmpc7LWRyqlkw4f8l/Rdhu3MGGgtZQKBYOv9TpWnBq0/63yhz1S/C/JLsncm7PlN7kXwA8foqdTJgaQLtVgp/Dtjrbzm1Op2M7Hglm81uLiwV31AAAAFQDMrPn8qKxpiwvwB3BHDQMGbFoIuwAAAIEAn+MRo6fzEvhli7+SoAqZog0FUM3ZNcC6JpAJWDHH92ekpm9GscnFW5iBIsR6gDCvqwuXY95rYHnEt6CJhqNuSHXjuB0/ZNydBFV3KiZm5mYDSq9R9I/2tmilJM2aNP2rIUWNkfY+j1+atJUoIQ5VTHagFPGIngjeI+eV+Rh8ekwAAACAUVpqU4b9xYBIAKwESa+Dl4OcfX419q9mD91PcKO8kAX5w4DMD3VV0oRQJl+3GAdmRDZ2fC49yAxfkt3/gBxB5Pj1bZvTFsSizUtg2Lx1ey0b/Rh0MI7vZ3b4hSMj5KV9bH6ReLqU9yapYCt5HbLyJEoP+N5FpVbpBDrkEs5QzEw=
sshfp_dsa => SSHFP 2 1 60ac20181d19f0fe6bbba8b5940296994556d6d0
SSHFP 2 2 eb7b499970e1f64145e50d0f2fc09dc8a98e57dc0e780180026c56880f3a0669
sshfp_rsa => SSHFP 1 1 ef372194ae2aa18535ce4de9bf5b776e8248b7ef
SSHFP 1 2 2a92b9b57b2d8e86f6e1b51f0fbc57b624bdb72116c857a767a1680727c193ac
sshrsakey => AAAAB3NzaC1yc2EAAAABIwAAAQEAtHKXsD9vm79cbb7FZpEoNJLJIPhJE/YL9pK5OFcN9wEFcX0nP9zG5k2ZvfU8mH/iB3Lq6jBcyrrBxld84vx6v9TKyQJPbmzdSbTV1XBydGaPYFhXYekAVG8cm9pJPvUYmp55VrvqiApzh9IqhtFKJavNN4G/e5AjuE/WiMAIA1ZJHu09MfnQI6e/cG+EGC6+zU+8Wldt30YWxs+lIb474UtavqgirZ8v53+HTFA9viwDR1O4x8aI+TtCHTuV5dYuQcnjxK3cdLexfZ7HvYReVDP0FKgbbjme+2WEiamG2chHkHeduiB97/nYkQ2NUAOlKVh3rV7nbOhg0yOAjeGqJQ==
swapfree => 1.93 GB
swapfree_mb => 1972.77
swapsize => 1.94 GB
swapsize_mb => 1984.00
system_uptime => "days"=>0, "seconds"=>44336, "hours"=>12, "uptime"=>"12:18 hours"
timezone => CST
type => Other
uniqueid => 007f0100
uptime => 12:18 hours
uptime_days => 0
uptime_hours => 12
uptime_seconds => 44336
uuid => 564D1A00-9097-B0CD-D375-56F69F9DAB9B
virtual => vmware
 
 

以上是关于puppet 变量及作用域的主要内容,如果未能解决你的问题,请参考以下文章

Puppet---自动化运维工具(进阶)

javas基础03——函数的作用域及变量提升

函数作用域及作用域链

执行环境及作用域变量对象作用域链闭包

常量变量及作用域

JavaScript入门第十八章(js作用域及变量预解析 )