Created
November 12, 2010 20:29
-
-
Save ohadlevy/674623 to your computer and use it in GitHub Desktop.
script to automate creation of machines, including dns, dhcp, tftp, foreman and puppet
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/ruby | |
require "rubygems" | |
require "rest_client" | |
require "json" | |
require "uri" | |
fqdn = ARGV[0] || raise("Must define a fqdn") | |
mac = ARGV[1] || raise("Must define a mac") | |
start = Time.now | |
dhcp_server = "http://192.168.100.254:4567/dhcp" | |
tftp_server_ip = "192.168.100.254" | |
tftp_server = "http://#{tftp_server_ip}:4567" | |
dns_server = tftp_server | |
foreman_url = "http://192.168.100.254" | |
foreman_user = "admin" | |
foreman_pass = "changeme" | |
puppet_env = "production" | |
host_arch = "x86_64" | |
media_name = "Fedora Mirror" | |
# define defaults for restful connectivity to Foreman | |
@foreman = RestClient::Resource.new foreman_url,{ :user => foreman_user, :password => foreman_pass, | |
:headers => { :accept => :json, :content_type => :json }} | |
# fetch availavble networks on DHCP server | |
t=Time.now | |
print "fetching subnets from dhcp server via REST... " | |
networks= JSON.parse(RestClient.get("#{dhcp_server}/.json").body) | |
printf "done in %5.2f seconds\n", Time.now - t | |
# Use the first one | |
network = networks.first["network"] | |
puts "Selected #{network} Subnet" | |
print "checking if record already exists on #{network} subnet..." | |
t=Time.now | |
# find if the record already exists on the dhcp server | |
begin | |
record= JSON.parse(RestClient.get("#{dhcp_server}/#{network}/#{mac}.json").body) | |
rescue | |
record = nil | |
end | |
printf "done in %5.2f seconds\n", Time.now - t | |
if record | |
puts "skipping DHCP creation as record already exists" | |
ip = record["ip"] | |
else | |
t=Time.now | |
print "Checking for next unused IP Address on #{network}..." | |
# find the next free IP | |
ip = RestClient.get("#{dhcp_server}/#{network}/unused_ip").body | |
printf "done in %5.2f seconds\n", Time.now - t | |
print "About to create DHCP record using the free IP #{ip}..." | |
options = { | |
:network => network, | |
:ip => ip, | |
:mac => mac, | |
:name => fqdn, | |
:nextserver => tftp_server_ip, | |
:filename => "pxelinux.0" | |
} | |
t=Time.now | |
# create the DHCP reservation | |
RestClient.post "#{dhcp_server}/#{options[:network]}", options | |
printf "done in %5.2f seconds\n", Time.now - t | |
end | |
print "Creating DNS records..A.." | |
RestClient.post "#{dns_server}/dns", {:fqdn => fqdn, :value => ip} | |
print "done...PTR..." | |
RestClient.post "#{dns_server}/dns", {:fqdn => fqdn, :type => "PTR", | |
:value => ip.split(".").reverse.join(".") + ".in-addr.arpa" } | |
puts "done" | |
# Add the host to Foreman | |
# | |
# | |
def helper(url, title, args = %w{ name id }) | |
t=Time.now | |
print "Asking Foreman for a(n) #{title}..." | |
hash = JSON.parse(@foreman[URI.escape(url)].get.body) | |
printf "done in %5.2f seconds\n", Time.now - t | |
hash = hash.is_a?(Array) ? hash.first[title] : hash[title] | |
args.collect {|arg| hash[arg]} | |
end | |
env, env_id = helper("/environments/#{puppet_env}", "environment") | |
#rhel5 | |
os, os_id = helper("/operatingsystems/2", "operatingsystem") | |
#ubuntu | |
os, os_id = helper("/operatingsystems/3", "operatingsystem") | |
arch, arch_id = helper("/architectures/x86_64","architecture") | |
#redhat default | |
#media, media_id = helper("/medias/1","media") | |
# ubuntu default | |
media, media_id = helper("/medias/4","media") | |
domain, domain_id = helper("/domains/lab","domain") | |
# redhat default | |
#ptable, ptable_id = helper("/ptables","ptable") | |
# ubuntu default | |
ptable, ptable_id = helper("/ptables/2","ptable") | |
hostgroup, hostgroup_id = helper("/hostgroups/1", "hostgroup") | |
payload = {:host => { | |
:name => fqdn, :mac => mac, :ip => ip, | |
:environment_id => env_id, :architecture_id => arch_id, :domain_id => domain_id, :media_id => media_id, | |
:operatingsystem_id => os_id, :ptable_id => ptable_id, | |
:host_parameters_attributes => { Time.now.to_i => {:name => "activation_key", :value =>"123123xxxxxxx", :nested =>""}}, | |
:hostgroup_id => hostgroup_id, :comment => "Added via Batch" | |
}}.to_json | |
begin | |
t=Time.now | |
print "Creating the Host at Foreman..." | |
@foreman["/hosts"].post payload | |
printf "done in %5.2f seconds\n", Time.now - t | |
rescue => e | |
warn "ERROR: #{e.response}" | |
end | |
# enable the host for installation | |
t=Time.now | |
print "Enabling Foreman to build the host..." | |
@foreman["/hosts/#{fqdn}/setBuild"].get.body | |
printf "done in %5.2f seconds\n", Time.now - t | |
# | |
# Create the TFTP setup | |
# | |
# First make sure the TFTP media is in place (kernel initrd) | |
# | |
# | |
puts "Setting up TFTP\n" | |
bootfiles_url = URI.escape("operatingsystems/#{os_id}/bootfiles?media=#{media}&architecture=#{arch}") | |
t=Time.now | |
print "asking Foreman for our PXE boot files..." | |
files = JSON.parse(@foreman[bootfiles_url].get.body) | |
printf "done in %5.2f seconds\n", Time.now - t | |
puts "asking our tftp server to fetch the following files" | |
files.each do |file| | |
file.each do |prefix, path| | |
t=Time.now | |
print "#{prefix} - #{path}..." | |
RestClient.post "#{tftp_server}/tftp/fetch_boot_file", {:prefix => prefix, :path => path} | |
printf "done in %5.2f seconds\n", Time.now - t | |
end | |
end | |
t=Time.now | |
print "quering Foreman for #{fqdn} TFTP configuation..." | |
config = @foreman["hosts/#{fqdn}/pxe_config"].get.body | |
printf "done in %5.2f seconds\n", Time.now - t | |
# TODO cleanup the entry after the machine sucsefully installed | |
# this will be done internally in foreman, so should not be a problem | |
# | |
t=Time.now | |
print "And asking our TFTP server to apply it..." | |
RestClient.post "#{tftp_server}/tftp/#{mac}", {:syslinux_config => config} | |
printf "done in %5.2f seconds\n", Time.now - t | |
puts | |
printf "Created everything in %5.2f seconds\n", Time.now - start | |
olevy@super:~/git/foreman(develop)$ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment