Ruby Listing: configure.rb
Click
here to download a plain-text version of this file.
#!/usr/bin/ruby -w
=begin
/***************************************************************************
* Copyright (C) 2008, Paul Lutus *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
=end
# routines to convert between dotted strings <-> integer IPs
def ip_to_int(ipstring)
v = 0
ipstring.split(".").reverse.each do |s|
v = (v << 8) + (s.to_i)
end
return v
end
def int_to_ip(v)
array = []
n = 4
begin
array << (v % 0x100).to_s
v >>= 8
end while((n -= 1) > 0)
return array.join(".")
end
# routine to convert string characters to int array
# used in SSID encoding
def string_to_int_array(s)
return "[" + s.unpack("c*").join(",") + "]"
end
# check for the presence of a wireless NIC
# users may want to add to the short list of applicable NIC types
# or simply detect the word "wireless" and act accordingly
def has_wireless(sys)
data = `ssh #{sys} /sbin/lspci`
[ "2200","3945","4965" ].each do |wi|
if(data =~ /Wireless\s*#{wi}/i)
return true
end
end
return false
end
# get a list of local network host names and IPs
# this could be replaced by any other way to
# create a hostname/IP hash
def get_ip_list(system_list)
data = File.read("/etc/hosts")
hash = {}
system_list.each do |sys|
addr = data.sub(%r{.*^([\d|\.]+)\s.*?#{sys}$.*}m,"\\1")
hash[sys] = addr
end
return hash
end
# create a tagged type/value pair as a hash
def type_value(type,value)
return { "type" => type, "value" => value }
end
# various data set constructors
def construct_ipv4_spec(ip,gateway,bits,dns_list,dns)
hash = {}
hash["addresses"] = type_value("list","[#{ip_to_int(ip)},#{bits},#{ip_to_int(gateway)}]")
hash["dns"] = type_value("list",dns_list) if dns
hash["method"] = type_value("string","manual")
hash["name"] = type_value("string","ipv4")
hash["routes"] = type_value("list","[]")
return hash
end
def construct_connection_spec(id,autoconnect,type)
hash = {}
hash["autoconnect"] = type_value("booelan",autoconnect)
hash["id"] = type_value("string",id)
hash["type"] = type_value("string",type)
hash["name"] = type_value("string","connection")
return hash
end
def construct_wired_network_spec()
hash = {}
hash["duplex"] = type_value("string","full")
hash["name"] = type_value("string","802-3-ethernet")
return hash
end
def construct_wireless_network_spec(ssid,adhoc)
hash = {}
hash["mode"] = type_value("string",(adhoc)?"adhoc":"infrastructure")
hash["name"] = type_value("string","802-11-wireless")
hash["security"] = type_value("string","802-11-wireless-security")
hash["ssid"] = type_value("list",string_to_int_array(ssid))
return hash
end
def construct_wireless_security_spec(adhoc)
hash = {}
if(adhoc)
hash["key-mgmt"] = type_value("string","none")
hash["auth_alg"] = type_value("string","open")
else
hash["key-mgmt"] = type_value("string","wpa-psk")
end
hash["name"] = type_value("string","802-11-wireless-security")
return hash
end
def construct_wired_tree(sys,ip,gateway,bits,dns_list)
hash = {}
hash["ipv4"] = construct_ipv4_spec(ip,gateway,bits,dns_list,true)
hash["connection"] = construct_connection_spec("Wired eth0",true,"802-3-ethernet")
hash["802-3-ethernet"] = construct_wired_network_spec()
return hash
end
def construct_wireless_tree(sys,ssid,ip,gateway,bits,dns_list,adhoc)
hash = {}
hash["ipv4"] = construct_ipv4_spec(ip,gateway,bits,dns_list,!adhoc)
hash["connection"] = construct_connection_spec("Wireless " + ssid,false,"802-11-wireless")
hash["802-11-wireless"] = construct_wireless_network_spec(ssid,adhoc)
hash["802-11-wireless-security"] = construct_wireless_security_spec(adhoc)
return hash
end
# debugging routines that print out the entire data tree
def mktab(n)
return "\t" * n
end
def show_tree(hash,tab = 0)
hash.keys.sort.each do |key|
if(hash[key].class == Hash)
puts "#{mktab(tab)}#{key}"
show_tree(hash[key],tab+1)
else
puts "#{mktab(tab)}#{key} = #{hash[key]}"
end
end
end
# build connection database
def build_database(system_list,addr_hash,wap_list,dns_list,gateway,bits)
hash = {}
system_list.each do |sys|
hash[sys] = {}
ip = addr_hash[sys]
hash[sys]["Wired_eth0"] = construct_wired_tree(sys,ip,gateway,bits,dns_list)
if(has_wireless(sys))
wap_list.split("\s").each do |wap|
hash[sys]["Wireless_" + wap] = construct_wireless_tree(sys,wap,ip,gateway,bits,dns_list,false)
end
hash[sys]["Wireless_pl-adhoc"] = construct_wireless_tree(sys,"pl-adhoc",ip,ip,bits,dns_list,true)
end
end
return hash
end
# recursive tree traversal to build gconf definition paths
def program_system_recursive(list,hash,path,n)
hash.keys.sort.each do |key|
if(n < 2)
list = program_system_recursive(list,hash[key],path + "/" + key,n+1)
else
type,value = hash[key]["type"],hash[key]["value"]
type_str = "--type #{type}"
type_str += " --list-type int" if(type =~ /list/)
arg = "gconftool-2 #{type_str} --set #{path}/#{key} '#{value}'"
print "."
list += "#{arg};"
end
end
return list
end
# construct the paths and program the gconf database
def program_network(tree,gcp)
tree.keys.sort.each do |sys|
# tell the user what's happening
print "Programming #{sys} "
# erase previous connection entries
com_list = "gconftool-2 --recursive-unset #{gcp};"
# create new entries as a data block
com_list = program_system_recursive(com_list,tree[sys],gcp,0)
puts ""
# send the data block to the target machine
`ssh #{sys} "#{com_list}"`
end
end
# user actions
print "Okay to program network with NetworkManager data (y/N):"
reply = STDIN.readline.chomp
if(reply != "y")
exit 0
end
# get a list of network host names
# again, any way to create a list of hostnames
# could be placed here
system_list=`sysnames.sh`.chomp.split("\s")
# create hash with hostname/IP key/value pairs
addr_hash = get_ip_list(system_list)
# local network specifications
gateway = "192.168.0.96"
dns1 = "xxx.xxx.xxx.xxx"
dns2 = "xxx.xxx.xxx.xxx"
dns3 = "xxx.xxx.xxx.xxx"
bits = "24"
dns_list = "[#{ip_to_int(dns1)},#{ip_to_int(dns2)},#{ip_to_int(dns3)}]"
# wireless access point SSIDs
wap_list= "pl-wireless-a pl-wireless-b pl-wireless-c"
# build the tree of connection data
data_tree = build_database(system_list,addr_hash,wap_list,dns_list,gateway,bits)
# debug display, normally commented out
# show_tree(data_tree)
# base GConf path for NetworkManager
gconf_path = "/system/networking/connections"
# traverse the network, programming each machine
program_network(data_tree,gconf_path)
puts "Done."