我试图写一个木偶函数,调用我的托pipe环境(rackspace云atm)列出服务器,然后更新我的主机文件。
我的get_hosts函数目前是这样的:
require 'rubygems' require 'cloudservers' module Puppet::Parser::Functions newfunction(:get_hosts, :type => :rvalue) do |args| unless args.length == 1 raise Puppet::ParseError, "Must provide the datacenter" end DC = args[0] USERNAME = DC == "us" ? "..." : "..." API_KEY = DC == "us" ? "..." : "..." AUTH_URL = DC == "us" ? CloudServers::AUTH_USA : CloudServers::AUTH_UK DOMAIN = "..." cs = CloudServers::Connection.new(:username => USERNAME, :api_key => API_KEY, :auth_url => AUTH_URL) cs.list_servers_detail.map {|server| server.map {|s| { s[:name] + "." + DC + DOMAIN => { :ip => s[:addresses][:private][0], :aliases => s[:name] }}} } end end
而且我有一个hosts.pp调用这个,并且'应该'把它写到/ etc / hosts。
class hosts::us { $hosts = get_hosts("us") hostentry { $hosts: } } define hostentry() { host{ $name: ip => $name[ip], host_aliases => $name[aliases] } }
正如你可以想象的,这是目前没有工作,我得到一个符号数组索引/etc/puppet/manifests/hosts.pp:2错误。 我想,一旦我意识到自己现在做错了,就会有更多的错误来临。
这是一个好主意吗? 有人可以帮我解决这个问题吗?
更新
最后设法得到这个工作(在评论的帮助下)! 这是我的get_hosts.rb:
require 'rubygems' require 'cloudservers' module Puppet::Parser::Functions newfunction(:get_hosts, :type => :rvalue) do |args| unless args.length == 1 raise Puppet::ParseError, "Must provide the datacenter" end dc = args[0] username = dc == "us" ? "..." : "..." api_key = dc == "us" ? "..." : "..." auth_url = dc == "us" ? CloudServers::AUTH_USA : CloudServers::AUTH_UK domain = "...." cs = CloudServers::Connection.new(:username => username, :api_key => api_key, :auth_url => auth_url) cs.list_servers_detail.map {|server| server[:name] + "." + dc + domain + "," + server[:addresses][:private][0] + "," + server[:name] } end end
和主机
class hosts::us { $hosts = get_hosts("us") hostentry { $hosts: } } define hostentry() { $parts = split($name, ',') $address = $parts[0] $ip = $parts[1] $aliases = $parts[2] host{ $address: ip => $ip, host_aliases => $aliases } }
像这样编组namevar是相当讨厌的,但这是我看起来能够实现的唯一方法。 任何改进的欢迎。
我不会说这是一个坏主意,但是你真的需要停止在你的代码中使用常量(任何在Ruby中以大写字母开头的东西都是常量)。
为了debugging你的问题,你可能需要在puppetmaster调用中使用--trace
选项,所以它会打印一个回溯,而不是吃真正的exception,并给你一个无用的错误信息。 你的map
调用中有大量的解引用; 我的猜测是,你误解了API的一部分数据结构,你的代码正在绊倒这个误解。 启动一个debugging器(或者通过你的代码自由地puts
),你会看到你的错误很短的顺序。
我会分开这个function。
使用你的函数来构build代表主机资源列表的散列哈希中的纯数据。
然后使用create_resources函数从数据中创build实际的主机资源:
http://docs.puppetlabs.com/references/2.7.12/function.html#createresources
那里的例子应该足够让你走了:
# A hash of user resources: $myusers = { 'nick' => { uid => '1330', group => allstaff, groups => ['developers', 'operations', 'release'], } 'dan' => { uid => '1308', group => allstaff, groups => ['developers', 'prosvc', 'release'], } } create_resources(user, $myusers)
那有意义吗?
然后你可以避免定义的types,并且你可以在你的函数调用中完成所有的数据处理以得到散列的散列,并且在收集数据的函数和实例化资源的函数之间有很好的分离。
这应该解决任何需要经典的迭代,如果我正确理解你的问题。