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 ...@@ -12,6 +12,7 @@ import hostinfo.pxelinux
import hostinfo.samba import hostinfo.samba
import hostinfo.yp import hostinfo.yp
import hostinfo.role import hostinfo.role
import hostinfo.util
import argparse import argparse
import os import os
import sys import sys
...@@ -78,6 +79,7 @@ attr_weight = { ...@@ -78,6 +79,7 @@ attr_weight = {
('interface', 'ip') : 1, ('interface', 'ip') : 1,
('interface', 'ether') : 2, ('interface', 'ether') : 2,
('subnet', 'network') : 1, ('subnet', 'network') : 1,
('subnet', 'prefix') : 1,
('subnet', 'domain') : 2, ('subnet', 'domain') : 2,
('subnet', 'broadcast') : 3, ('subnet', 'broadcast') : 3,
('subnet', 'netmask') : 4, ('subnet', 'netmask') : 4,
...@@ -85,79 +87,81 @@ attr_weight = { ...@@ -85,79 +87,81 @@ attr_weight = {
('subnet', 'name_servers') : 6, ('subnet', 'name_servers') : 6,
} }
#def cmp(a,b):
# if a < b:
# return -1
# elif a == b:
# return 0
# else:
# return 1
class AttributeDict(dict): class AttributeDict(dict):
__getattr__ = dict.__getitem__ __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 host_order(a,b):
def at_top(n): def fqn(host):
# Place hosts without ethernet or ip address at top n = host.name[0]
for i1 in n._interface_: return n and n.endswith('.')
if i1.ethernet[0]: def select(f, c):
return False return [ f(e) for e in c if f(e) ]
for i2 in i1._ip_: def ether(host):
if i2.address[0]: return select(lambda i: i.ethernet[0], host._interface_)
return False def ip(host):
pass ipv4 = select(hostinfo.util.address, host._interface_._ip_)
pass ipv6 = select(hostinfo.util.address, host._interface_._ipv6_)
return True return ipv4 + ipv6
def at_bottom(n): def no_addr(host):
# Place hosts with ethernet but without ip address at bottom return not ether(host) and not ip(host)
result = False def all_addr(host):
for i1 in n._interface_: return ether(host) and ip(host)
if i1.ethernet[0]:
result = True # Fully qualified names
for i2 in i1._ip_: if fqn(a) or fqn(b):
if i2.address[0]: if fqn(a) and fqn(b): return cmp(a.name[0], b.name[0])
return False if fqn(a): return -1
pass if fqn(b): return 1
pass pass
return result
if (at_top(a) == at_top(b) and at_bottom(a) == at_bottom(b)): # Hosts without ether an ip address (reusable names)
return cmp(a.name[0], b.name[0]) if no_addr(a) or no_addr(b):
elif at_top(a): if no_addr(a) and no_addr(b): return cmp(a.name[0], b.name[0])
return -1 if no_addr(a): return -1
elif at_top(b): if no_addr(b): return 1
return 1 pass
elif at_bottom(a):
return 1 # Hosts with ip and ether (active machines)
elif at_bottom(b): if all_addr(a) or all_addr(b):
return -1 if all_addr(a) and all_addr(b): return cmp(a.name[0], b.name[0])
else: if all_addr(a): return -1
raise Exception('Should never happen') 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 = { tag_weight = {
('hostinfo', 'soa') : (1, ('hostinfo', 'soa') : (1, None),
None), ('hostinfo', 'subnet') : (2, network_order),
('hostinfo', 'subnet') : (2, # lambda a,b: cmp(a.network[0],b.network[0])),
lambda a,b: cmp(a.network[0],b.network[0])), ('hostinfo', 'nameserver') : (3, None),
('hostinfo', 'netgroup') : (3, ('hostinfo', 'netgroup') : (4,
lambda a,b: cmp(a.name[0],b.name[0])), lambda a,b: cmp(a.name[0],b.name[0])),
('hostinfo', 'host') : (4, ('hostinfo', 'host') : (5, host_order),
host_order), ('host', 'role') : (1, None),
('host', 'automount') : (1, ('host', 'automount') : (2, lambda a,b: cmp(a.host[0],b.host[0])),
lambda a,b: cmp(a.host[0],b.host[0])), ('host', 'mio') : (3, None),
('host', 'mio') : (2, ('interface', 'kickstart') : (1, None),
None), ('interface', 'ip') : (2, None),
('interface', 'kickstart') : (1, ('interface', 'alias') : (3, None),
None), ('interface', 'dhcpserver') : (4, None),
('interface', 'ip') : (2, ('interface', 'nameserver') : (5, None),
None), ('automount', 'entry') : (1, lambda a,b: cmp(a.key[0],b.key[0])),
('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): def attr_sort(node, a, b):
...@@ -261,6 +265,10 @@ if __name__ == '__main__': ...@@ -261,6 +265,10 @@ if __name__ == '__main__':
default=[], default=[],
action="append", metavar="ROLE", action="append", metavar="ROLE",
help="check if machine has 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", optParser.add_argument("--samba",
action="store", metavar="FILE", action="store", metavar="FILE",
help="generate samba share FILE") help="generate samba share FILE")
...@@ -331,12 +339,18 @@ if __name__ == '__main__': ...@@ -331,12 +339,18 @@ if __name__ == '__main__':
result = "<?xml version='1.0' encoding='utf-8'?>\n\n" result = "<?xml version='1.0' encoding='utf-8'?>\n\n"
result += tree._xml(attr_sort=attr_sort, tag_sort=tag_sort) result += tree._xml(attr_sort=attr_sort, tag_sort=tag_sort)
print result.encode("utf-8") print result.encode("utf-8")
sys.exit(0)
if options.role: if options.role:
roles = hostinfo.role.generate(tree, host, options.role) roles = hostinfo.role.generate(tree, host, options.role)
# print "Roles:",",".join(roles) # print "Roles:",",".join(roles)
sys.exit(len(roles) != len(options.role)) 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: if options.yp:
for (f, c) in hostinfo.yp.generate(tree, options.yp_auto_domain): for (f, c) in hostinfo.yp.generate(tree, options.yp_auto_domain):
file["%s/%s" % (options.yp, f)] = c file["%s/%s" % (options.yp, f)] = c
......
...@@ -90,6 +90,10 @@ class "pxeclient" { ...@@ -90,6 +90,10 @@ class "pxeclient" {
} else { } else {
filename "pxelinux.0"; filename "pxelinux.0";
} }
}
class "non-pxeclient" {
match if substring (option vendor-class-identifier, 0, 9) != "PXEClient";
ignore booting;
}""" }"""
PXE_DENY=""" PXE_DENY="""
...@@ -154,6 +158,9 @@ def generate(tree, options): ...@@ -154,6 +158,9 @@ def generate(tree, options):
|ddns-update-style none; |ddns-update-style none;
|get-lease-hostnames true; |get-lease-hostnames true;
|use-host-decl-names on; |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 get_pxeboot(dhcp) == 'only':
if not options.next_server: if not options.next_server:
......
...@@ -25,10 +25,7 @@ def generate(tree, options): ...@@ -25,10 +25,7 @@ def generate(tree, options):
conf = util.StringArray() conf = util.StringArray()
for h in tree._nameserver_: for h in tree._nameserver_:
for l in re.sub('([{;]\s)', '\g<1>\n', h.conf[0]).split('\n'): for l in h._char:
if l[0] == ' ':
l = l[1:]
pass
conf.append(l) conf.append(l)
pass pass
pass pass
......
...@@ -382,7 +382,11 @@ class Node: ...@@ -382,7 +382,11 @@ class Node:
result += "%s/>\n" % line result += "%s/>\n" % line
else: else:
result += "%s>\n" % line 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 = self._children
child.sort(TagSortWrapper(self, tag_sort)) child.sort(TagSortWrapper(self, tag_sort))
for c in child: for c in child:
......
import hostinfo.util as util
def generate(tree, host, roles): def generate(tree, host, roles):
result = [] by_role = get_all(tree)
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
for r in roles: for r in roles:
if not r in by_role: if not r in by_role:
raise Exception("Role '%s' not found in %s" % raise Exception("Role '%s' not found in %s" %
(r, by_role.keys())) (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 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