Commit c0a03c32 authored by Anders Blomdell's avatar Anders Blomdell
Browse files

Version 2013-11-13 12:33

M  src/hostinfo.py
M  src/hostinfo/dhcpd.py
M  src/hostinfo/named.py
M  src/hostinfo/parser.py
M  src/hostinfo/role.py
parent d357511b
......@@ -12,6 +12,7 @@ import hostinfo.pxelinux
import hostinfo.samba
import hostinfo.yp
import hostinfo.role
import hostinfo.util
import argparse
import os
import sys
......@@ -78,6 +79,7 @@ attr_weight = {
('interface', 'ip') : 1,
('interface', 'ether') : 2,
('subnet', 'network') : 1,
('subnet', 'prefix') : 1,
('subnet', 'domain') : 2,
('subnet', 'broadcast') : 3,
('subnet', 'netmask') : 4,
......@@ -85,79 +87,81 @@ attr_weight = {
('subnet', 'name_servers') : 6,
}
#def cmp(a,b):
# if a < b:
# return -1
# elif a == b:
# return 0
# else:
# return 1
class AttributeDict(dict):
__getattr__ = dict.__getitem__
def network_order(a, b):
a_net = hostinfo.util.network(a)
b_net = hostinfo.util.network(b)
if not a_net or not b_net:
return cmp(a,b)
if a_net.version == b_net.version:
return cmp(a_net, b_net)
return cmp(a_net.version, b_net.version)
def host_order(a,b):
def at_top(n):
# Place hosts without ethernet or ip address at top
for i1 in n._interface_:
if i1.ethernet[0]:
return False
for i2 in i1._ip_:
if i2.address[0]:
return False
pass
pass
return True
def at_bottom(n):
# Place hosts with ethernet but without ip address at bottom
result = False
for i1 in n._interface_:
if i1.ethernet[0]:
result = True
for i2 in i1._ip_:
if i2.address[0]:
return False
pass
pass
return result
if (at_top(a) == at_top(b) and at_bottom(a) == at_bottom(b)):
return cmp(a.name[0], b.name[0])
elif at_top(a):
return -1
elif at_top(b):
return 1
elif at_bottom(a):
return 1
elif at_bottom(b):
return -1
else:
raise Exception('Should never happen')
def fqn(host):
n = host.name[0]
return n and n.endswith('.')
def select(f, c):
return [ f(e) for e in c if f(e) ]
def ether(host):
return select(lambda i: i.ethernet[0], host._interface_)
def ip(host):
ipv4 = select(hostinfo.util.address, host._interface_._ip_)
ipv6 = select(hostinfo.util.address, host._interface_._ipv6_)
return ipv4 + ipv6
def no_addr(host):
return not ether(host) and not ip(host)
def all_addr(host):
return ether(host) and ip(host)
# Fully qualified names
if fqn(a) or fqn(b):
if fqn(a) and fqn(b): return cmp(a.name[0], b.name[0])
if fqn(a): return -1
if fqn(b): return 1
pass
# Hosts without ether an ip address (reusable names)
if no_addr(a) or no_addr(b):
if no_addr(a) and no_addr(b): return cmp(a.name[0], b.name[0])
if no_addr(a): return -1
if no_addr(b): return 1
pass
# Hosts with ip and ether (active machines)
if all_addr(a) or all_addr(b):
if all_addr(a) and all_addr(b): return cmp(a.name[0], b.name[0])
if all_addr(a): return -1
if all_addr(b): return 1
pass
# This should be machines with ether but no ip (decommissioned)
if ip(a):
raise hostinfo.util.HostinfoException('Unexpected ip address %s' %
a.name[0], where=a)
if ip(b):
raise hostinfo.util.HostinfoException('Unexpected ip address %s' %
b.name[0], where=b)
return cmp(a.name[0], b.name[0])
tag_weight = {
('hostinfo', 'soa') : (1,
None),
('hostinfo', 'subnet') : (2,
lambda a,b: cmp(a.network[0],b.network[0])),
('hostinfo', 'netgroup') : (3,
('hostinfo', 'soa') : (1, None),
('hostinfo', 'subnet') : (2, network_order),
# lambda a,b: cmp(a.network[0],b.network[0])),
('hostinfo', 'nameserver') : (3, None),
('hostinfo', 'netgroup') : (4,
lambda a,b: cmp(a.name[0],b.name[0])),
('hostinfo', 'host') : (4,
host_order),
('host', 'automount') : (1,
lambda a,b: cmp(a.host[0],b.host[0])),
('host', 'mio') : (2,
None),
('interface', 'kickstart') : (1,
None),
('interface', 'ip') : (2,
None),
('interface', 'alias') : (3,
None),
('interface', 'dhcpserver') : (4,
None),
('interface', 'nameserver') : (5,
None),
('automount', 'entry') : (1,
lambda a,b: cmp(a.key[0],b.key[0])),
('hostinfo', 'host') : (5, host_order),
('host', 'role') : (1, None),
('host', 'automount') : (2, lambda a,b: cmp(a.host[0],b.host[0])),
('host', 'mio') : (3, None),
('interface', 'kickstart') : (1, None),
('interface', 'ip') : (2, None),
('interface', 'alias') : (3, None),
('interface', 'dhcpserver') : (4, None),
('interface', 'nameserver') : (5, None),
('automount', 'entry') : (1, lambda a,b: cmp(a.key[0],b.key[0])),
}
def attr_sort(node, a, b):
......@@ -261,6 +265,10 @@ if __name__ == '__main__':
default=[],
action="append", metavar="ROLE",
help="check if machine has ROLE")
optParser.add_argument("--role-holder",
default=[],
action="store", metavar="ROLE",
help="check which machine currently holding ROLE")
optParser.add_argument("--samba",
action="store", metavar="FILE",
help="generate samba share FILE")
......@@ -331,12 +339,18 @@ if __name__ == '__main__':
result = "<?xml version='1.0' encoding='utf-8'?>\n\n"
result += tree._xml(attr_sort=attr_sort, tag_sort=tag_sort)
print result.encode("utf-8")
sys.exit(0)
if options.role:
roles = hostinfo.role.generate(tree, host, options.role)
# print "Roles:",",".join(roles)
sys.exit(len(roles) != len(options.role))
if options.role_holder:
who = hostinfo.role.holder(tree, options.role_holder)
print who
pass
if options.yp:
for (f, c) in hostinfo.yp.generate(tree, options.yp_auto_domain):
file["%s/%s" % (options.yp, f)] = c
......
......@@ -90,6 +90,10 @@ class "pxeclient" {
} else {
filename "pxelinux.0";
}
}
class "non-pxeclient" {
match if substring (option vendor-class-identifier, 0, 9) != "PXEClient";
ignore booting;
}"""
PXE_DENY="""
......@@ -154,6 +158,9 @@ def generate(tree, options):
|ddns-update-style none;
|get-lease-hostnames true;
|use-host-decl-names on;
|# Windows proxy server/WPAD URL (Stops DHCPINFORM)
|option url-252 code 252 = text;
|option url-252 "\\n\\000";
""")
if get_pxeboot(dhcp) == 'only':
if not options.next_server:
......
......@@ -25,10 +25,7 @@ def generate(tree, options):
conf = util.StringArray()
for h in tree._nameserver_:
for l in re.sub('([{;]\s)', '\g<1>\n', h.conf[0]).split('\n'):
if l[0] == ' ':
l = l[1:]
pass
for l in h._char:
conf.append(l)
pass
pass
......
......@@ -382,7 +382,11 @@ class Node:
result += "%s/>\n" % line
else:
result += "%s>\n" % line
result += xml_escape("".join(self._char))
#result += xml_escape('\n'.join(self._char))
if self._char:
result += '\n'.join(self._char)
result += '\n'
pass
child = self._children
child.sort(TagSortWrapper(self, tag_sort))
for c in child:
......
import hostinfo.util as util
def generate(tree, host, roles):
result = []
by_role = {}
for r in tree._host_._role_:
role = r.name[0]
if host == r.name[1] and role in roles:
result.append(role)
pass
if role in by_role:
raise Exception("Duplicate roles '%s' on %s, %s" %
(role, host, by_role[role]) )
by_role[role] = r.name[1]
pass
by_role = get_all(tree)
for r in roles:
if not r in by_role:
raise Exception("Role '%s' not found in %s" %
(r, by_role.keys()))
return filter(lambda (k,v): k in roles and v == host,
by_role.iteritems())
def holder(tree, role):
return get_all(tree)[role]
def get_all(tree):
result = {}
for r in tree._host_._role_:
name = r.name[0]
if name in result:
raise util.HostinfoException('Duplicate role holders %s' % name,
where=[result[name], r])
result[name] = r.name[1]
pass
return result
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment