企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
### 从 CSV 文件导入数据 想要知道更多东西吗?当你需要从表中查找某些值时,可以使用冗长的 case 语句或 selectors 实现,但更整洁的方式是使用 extlookup 函数实现。 在 puppetmaster 上可以使用 extlookup 函数查询外部的 CSV 文件,并返回匹配的数据片段。 将所有数据组织到一个单一的文件并将它从 Puppet 配置清单中分离出来, 可以使维护工作变得更简单,也便于与其他人分享:例如, 一个开发团队通过部署合适的 CSV 文件作为应用程序发布的一部分, 就可以管理 Puppet 需要知道的有关其应用程序的一切。 Puppet 只需要知道在哪里可以找到这个 CSV 文件,剩下的工作交由 extlookup 去完成。 #### 准备工作 1. 使用如下内容创建 /var/www/apps/common.csv 文件: ``` path,/var/www/apps/%{name} railsversion,3 domain,www.%{name}.com ``` 2. 使用如下内容创建 /var/www/apps/myapp.csv 文件: ``` railsversion,2 ``` #### 操作步骤 1. 在你的配置清单中添加如下代码: ``` $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" } ``` 2. 运行 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 ``` #### 工作原理 1. 我们做的第一件事是定义一个变量 $extlookup_datadir,它告诉 extlookup 从哪个目录查找数据文件。你通常会在 site.pp 或者在你设置全局变量的文件中设置这个变量: ``` $extlookup_datadir = "/var/www/apps/" ``` 2. 然后,我们告诉 extlookup 在哪里寻找数据文件,以及寻找的优先顺序: ``` $extlookup_precedence = [ "%{name}", "common" ] ``` 这可以是任意长度的数组。当我们生成一个 extlookup 查询时,Puppet 会按顺序扫描每个文件,直到找到请求的值。文件名可以包含变量。 我们期望名为 $name 的变量已经被设置,Puppet 将会使用其值作为要查找的第一个文件名。 3. 下一步,在 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 将其返回。 4. 下一个 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](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](http://sysadvent.blogspot.com/2010/12/day-12-scaling-operabilitywith-truth.html) 。 #### 参见本书 * 本章的 [导入动态信息](#ch04sec09) 一节 * 第 9 章的 [创建 Facter 的自定义 fact](#ch09sec01) 一节