puppet的使用:ERB模板介绍

ERB介绍

全称是Embedded RuBy,意思是嵌入式的Ruby,是一种文本模板技术,用过JSP的话,会发现二者语法很像。
咱们项目中通常用ERB来产生各模块的配置文件。ERB模板也能够用来产生Web页面(以前搞过一段时间ROR开发,模板用的haml),也能够用来产生其余文件。html

<% %>与<%= %>

<%Ruby脚本%>,通常是Ruby的逻辑脚本,可是不会写入到目标文件中。
<%= Ruby脚本%> ,脚本的执行结果会写入到目标文件中。
举例以下(代码来源):
这段代码是从Hash中读取信息建立sql语句保存到文件中。node

require "erb"  
domains = {...}  
sqlTemplate = ERB.new %q{  
<%for organization in domains.keys%>  
    insert into org_domain(Domain, organization) values('<%=domains[organization]%>','<%=organization%>');  
<%end%>  
}  
sqlFile = File.new("./sql.sql", "w")  
sqlFile.puts sqlTemplate.result

使输出紧凑

<%= -%>

You can trim line breaks after expression-printing tags by adding a hyphen to the closing tag delimiter.nginx

  • -%> — If the tag ends a line, trim the following line break.

意思是若是<%= -%>表达式中,-%>是一行的结尾,会忽略后面的换行。web

<%- -%>

You can trim whitespace surrounding a non-printing tag by adding hyphens (-) to the tag delimiters.sql

  • <%- — If the tag is indented, trim the indentation.
  • -%> — If the tag ends a line, trim the following line break.

意思是<%-前面是空白符时,会删除这些空白符;-%> 含义同上。express

puppet中通常怎么使用erb

举例以下:数组

目录结构

~/tmp# tree -L 2 puppet
puppet
├── manifests
│     ├── nodes
│     └── site.pp
└── modules
    ├── xxx
    └── nginx

这里是大的目录结构。ruby


manifests的内容以下:dom

~/tmp/puppet# tree -L 2 manifests
manifests
├── nodes
│   ├── controller-192-41-1-185.pp
│   ├── controller-192-41-1-186.pp
│   ├── controller-192-41-1-187.pp
│   ├── controller-192-41-1-191.pp
│   └── controller-192-41-1-202.pp
└── site.pp

这里每一个.pp文件是对应每一个agent节点的定义,具体内容见下一节。函数


每一个模块下的内容相似,如今只以nginx举例。

~/tmp/puppet/modules# tree -L 3 nginx/
nginx/
├── files
│   ├── xxxClientCert.jks
│   ├──xxxServerCert.jks
│   ├── README.md
│   ├── server.crt
│   └── server.key
├── manifests
│   ├── config.pp
│   ├── init.pp
│   ├── params.pp
│   └── service.pp
└── templates
    └── conf.d
        ├── nginx.conf.erb
        ├── ssl_restart_oms.sh.erb
        ├── web-hedex.xml.erb
        └── web.xml.erb

具体模块的manifests目录下是各个类的定义,templates定义了各个模板,模板会在manifests下的类中被引用。

### 类的定义

~/tmp/puppet/manifests# cat site.pp 
import 'nodes/*.pp'
$puppetserver='controller-192-41-1-191'

下面是一个node的定义:

~/tmp/puppet/manifests/nodes# cat controller-192-41-1-191.pp 
node 'controller-192-41-1-191' {
  $xxx = "true"
 #这里是各类变量的定义
  Class['aaa']->Class['bbb']->Class['ccc']->Class['nginx']->Class['ddd']
  include aaa,bbb,ccc,nginx,ddd
}

模板中使用的变量就是来自这里的定义。


总结以下
nginx/manifests下的各个pp文件是各个类的定义,类的定义中使用了nginx/templates中定义的模板,这些类被controller-192-41-1-191.pp 文件引用,controller-192-41-1-191.pp 文件中定义了模板中使用的变量。

访问puppet 变量

模板能够访问puppet的变量,这是模板的主要数据来源。
一个ERB模板有本身的本地做用域,它的父做用域是引用该模板的类。这意味着,模板可使用短名称访问父类中的变量,可是不能向父类中添加新的变量。
在ERB模板中,有两种方式访问变量。

  • @variable
  • scope['variable'] (旧的形式为:scope.lookupvar('variable'))

@variable

原文:

All variables in the current scope (including global variables) are passed to templates as Ruby instance variables, which begin with “at” signs (@). If you can access a variable by its short name in the surrounding manifest, you can access it in the template by replacing its $ sign with an @. So $os becomes @os, $trusted becomes @trusted, etc.

当前做用域的全部变量(包括全局变量)都会以Ruby实例变量的形式传给模板。若是你在模板中可使用短名称访问一个变量,你就可使用"@"代替"$"。因此,$os就变成了@os,$trusted就变成了@trusted。
这是访问变量最直接清晰的方式,可是这种方式不能访问其余做用域的变量,须要访问其余做用域的变量时,你须要使用下面的方式。

scope['variable'] or scope.lookupvar('variable')

Puppet可使用对象scope来以散列表的方式访问变量。例如,访问$ntp::tinker你可使用scope['ntp::tinker']这种形式。
还有另外一种方式使用scope对象,就是经过它的lookupvar方法来访问变量,该方法须要传入要访问的变量名,例如,scope.lookupvar('ntp::tinker')。这和上面的方式效果是同样的,可是使用起来没有scope['ntp::tinker']更简洁直观。

puppet类型和Ruby类型的对应关系

这部分表格,就不翻译了,直接贴图。

未定义变量

若是一个puppet变量没有定义的话,它的值是undef,意思是,在模板中它的值是nil。
含义是Puppet变量值为undef,对应Ruby变量值为nil。

在模板中使用puppet函数

  • 全部的函数都以scope对象的方法调用;
  • 函数名的开头都必须加上前缀"function_";
  • 函数的参数必须以数组的形式传递,即便只有一个参数。
    例如,在一个模板中引用另外一个模板:

<%= scope.function_template(["my_module/template2.erb"]) %>

参考
Language: Embedded Ruby (ERB) template syntax

相关文章
相关标签/搜索