从 CSV 文件导入数据
想要知道更多东西吗?当你需要从表中查找某些值时,可以使用冗长的 case
语句或 selectors
实现,但更整洁的方式是使用 extlookup
函数实现。 在 puppetmaster 上可以使用 extlookup
函数查询外部的 CSV 文件,并返回匹配的数据片段。
将所有数据组织到一个单一的文件并将它从 Puppet 配置清单中分离出来, 可以使维护工作变得更简单,也便于与其他人分享:例如, 一个开发团队通过部署合适的 CSV 文件作为应用程序发布的一部分, 就可以管理 Puppet 需要知道的有关其应用程序的一切。 Puppet 只需要知道在哪里可以找到这个 CSV 文件,剩下的工作交由 extlookup
去完成。
准备工作
使用如下内容创建
/var/www/apps/common.csv
文件:path,/var/www/apps/%{name} railsversion,3 domain,www.%{name}.com
使用如下内容创建
/var/www/apps/myapp.csv
文件:railsversion,2
操作步骤
在你的配置清单中添加如下代码:
$extlookup_datadir = "/var/www/apps/" $extlookup_precedence = [ "%{name}", "common" ] class app( $name ) { $railsversion = extlookup("railsversion") $path = extlookup("path") $domain = extlookup("domain") notify { "App data: Path ${path}, Rails version ${railsversion}, domain ${domain}": } } class { "app": name => "myapp" }
运行 Puppet:
# puppet agent --test info: Retrieving plugin info: Caching catalog for cookbook.bitfieldconsulting.com info: Applying configuration version '1303129760' notice: App data: Path /var/www/apps/myapp, Rails version 2, domain www.myapp.com notice: /Stage[main]/App/Notify[App data: Path /var/www/apps/ myapp, Rails version 2, domain www.myapp.com]/message: defined 'message' as 'App data: Path /var/www/apps/myapp, Rails version 2, domain www.myapp.com' notice: Finished catalog run in 0.58 seconds
工作原理
我们做的第一件事是定义一个变量
$extlookup_datadir
,它告诉extlookup
从哪个目录查找数据文件。你通常会在site.pp
或者在你设置全局变量的文件中设置这个变量:$extlookup_datadir = "/var/www/apps/"
然后,我们告诉
extlookup
在哪里寻找数据文件,以及寻找的优先顺序:$extlookup_precedence = [ "%{name}", "common" ]
这可以是任意长度的数组。当我们生成一个
extlookup
查询时,Puppet 会按顺序扫描每个文件,直到找到请求的值。文件名可以包含变量。 我们期望名为$name
的变量已经被设置,Puppet 将会使用其值作为要查找的第一个文件名。下一步,在
app
类中,调用extlookup
获得一个值:$railsversion = extlookup("railsversion")
现在
extlookup
装置查找一个 CSV 文件并从中读取数据。这个文件保存在$extlookup_datadir
目录(在本例中是/var/www/apps
), 文件名为%{name}.csv
(在本例中是myapp.csv
)。 所以extlookup
读取文件的完整路径是/var/www/apps/myapp.csv
, 此文件包含了railsversion,2
我们已经找到了所需要的值(2),所以
extlookup
将其返回。下一个
extlookup
调用就不那么幸运了:$path = extlookup("path")
extlookup
还是首先查找文件myapp.csv
,但是它找不到匹配path
变量的值。 所以会查找$extlookup_precedence
列表中的下一个文件, 即文件common.csv
:path,/var/www/apps/%{name} railsversion,3 domain,www.%{name}.com
就本例而言返回值为
/var/www/apps/myapp
。
你可以看到,这允许我们在 common.csv
文件中设置一个默认值的集合, 每个应用程序都可以选择其自己的 myapp.csv
文件覆盖 common.csv
文件中的默认值。 extlookup
会依次查询列在 $extlookup_precedence
中的文件,直到其找到请求的值。 由于 myapp.csv
被列在首位,所以设置在其中的任何值都优先于文件 common.csv
中的。
更多用法
你也可以在 extlookup
调用中指定默认值,当在所有的 CSV 文件中都没有找到匹配的数据时就会使用这个默认值:
$path = extlookup("path", "/var/www/misc")
你还可以指定在查找 $extlookup_precedence
所列的文件之前首先要查找的 CSV 文件:
$path = extlookup("path", "/var/www/misc", "paths")
这首先在 paths.csv
文件中查找数据,如果没找到,将会依次查找列在 $extlookup_precedence
中的其他文件。
CSV 文件中的值也可以引用变量,正如我们曾经看到的:
domain,www.%{name}.com
你可以使用当前范围内可用的任何变量,包括 Facter 检测出的 facts
值:
domain,%{fqdn}
R.I. Pienaar 的文章 “Complex data and Puppet” 是对 extlookup
的一个很好的介绍: http://www.devco.net/archives/2009/08/31/complex_data_and_puppet.php 。
Jordan Sissel 曾经写过 “about configuring your whole infrastructure using extlookup”: http://sysadvent.blogspot.com/2010/12/day-12-scaling-operabilitywith-truth.html 。
参见本书
本章的 导入动态信息 一节
第 9 章的 创建 Facter 的自定义 fact 一节