ホスティング環境(rackspace cloud atm)を呼び出してサーバーを一覧表示し、hostsファイルを更新するpuppet関数を作成しようとしています。
私の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
およびhosts.pp
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は定数です)の大文字で始まるものはすべて)。
問題をデバッグするには、puppetmasterの呼び出しに--trace
オプションを使用することをお勧めします。これにより、実際の例外を食べて役に立たないエラーメッセージを表示する代わりに、バックトレースが出力されます。 map
呼び出しで間接参照が山積みになっています。私の推測では、APIから出力されるデータ構造の一部を誤解していて、コードがその誤解につまずいていると思います。デバッガーを起動する(またはコードにputs
をたっぷりと振りかける)と、何が間違っているかがかなり短い順序で表示されます。
この機能を別の方法で分離します。
関数を使用して、ホストリソースのリストを表すハッシュのハッシュに純粋なデータを構築します。
次に、create_resources関数を使用して、そのデータから実際のホストリソースを作成します。
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)
それは理にかなっていますか?
次に、定義された型を回避でき、関数呼び出しですべてのデータ変更を実行してハッシュのハッシュを取得できます。また、データを収集する関数とリソースをインスタンス化する関数を適切に分離できます。
私があなたの問題を正しく理解していれば、これは古典的な反復の必要性を解決するはずです。