"""
Host definitions.
"""
import pvl.args
import pvl.dns.zone
import configobj
import ipaddr
import optparse
def optparser (parser) :
hosts = optparse.OptionGroup(parser, "Hosts input")
hosts.add_option('--hosts-charset', metavar='CHARSET', default='utf-8',
help="Encoding used for host files")
hosts.add_option('--hosts-domain', metavar='DOMAIN',
help="Default domain for hosts")
return hosts
class Host (object) :
@classmethod
def expand (cls, options, host, range, ip, **opts) :
host = pvl.dns.zone.parse_generate_field(host)
ip = pvl.dns.zone.parse_generate_field(ip)
for i in range :
yield cls.build(options, host(i),
ip = ip(i),
**opts
)
@classmethod
def config (cls, options, host, ip=None, **extra) :
"""
Yield Hosts from a config section's scalars.
"""
if '{' in host :
pre, host = host.split('{', 1)
range, post = host.rsplit('}', 1)
range = pvl.dns.zone.parse_generate_range(range)
host = pre + "$" + post
for host in cls.expand(options, host, range, ip, **extra) :
yield host
else :
yield cls.build(options, host, ip=ip, **extra)
@classmethod
def build (cls, options, host, domain=None, ip=None, owner=None, **extra) :
"""
Return a Host from a config section's scalars.
"""
ethernet = []
alias = []
for attr, value in extra.iteritems() :
if attr.startswith('ethernet') :
ethernet.append(value)
elif attr.startswith('alias') :
alias.append(value)
else :
raise ValueError("Unknown host attr: %s=%s" % (attr, value))
if domain is None :
domain = options.hosts_domain
return cls(host,
domain = domain,
ip = ipaddr.IPAddress(ip) if ip else None,
ethernet = ethernet,
alias = alias,
owner = owner,
)
def __init__ (self, host, domain=None, ip=None, ethernet=(), alias=(), owner=None) :
"""
host - str
domain - str
ip - ipaddr.IPAddress
ethernet - list
alias - list
owner - str: LDAP uid
"""
self.host = host
self.domain = domain
self.ip = ip
self.ethernet = ethernet
self.alias = alias
self.owner = owner
def __str__ (self) :
return str(self.host)
def apply_hosts_file (options, file) :
"""
Load Hosts from a file.
"""
config = configobj.ConfigObj(file,
encoding = options.hosts_charset,
)
for name in config.sections :
for host in Host.config(options, name, **config[name]) :
yield host
def apply_hosts (options, files) :
"""
Load Hosts from files.
"""
for file in files :
for host in apply_hosts_file(options, file) :
yield host
def sort_hosts (options, hosts) :
"""
Yields hosts with a sorting key.
"""
for host in hosts :
if host.ip :
sort = host.ip
else :
# sorts first
sort = ipaddr.IPAddress(0)
yield sort, host
def apply (options, args) :
"""
Load Hosts from arguments.
"""
# without unicode
files = pvl.args.apply_files(args, 'r')
# load configs
hosts = apply_hosts(options, files)
# sort
hosts = list(sort_hosts(options, hosts))
hosts.sort()
hosts = [host for sort, host in hosts]
return hosts