I'm trying to write a puppet function that calls my hosting environment (rackspace cloud atm) to list servers, then update my hosts file.
My get_hosts function is currently this:
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
And I have a hosts.pp that calls this and 'should' write it to /etc/hosts.
class hosts::us {
$hosts = get_hosts("us")
hostentry { $hosts: }
}
define hostentry() {
host{ $name: ip => $name[ip], host_aliases => $name[aliases] }
}
As you can imagine, this isn't currently working and I'm getting a 'Symbol as array index at /etc/puppet/manifests/hosts.pp:2' error. I imagine, once I've realised what I'm currently doing wrong there will be more errors to come.
Is this a good idea? Can someone help me work out how to do this?
Update
Finally managed to get this working (with help from the comments) ! Here is my 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
and the 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 }
}
It's quite nasty marshalling the namevar like that, but it was the only way I could seem to get it to work. Any improvements welcome.