]> git.uio.no Git - python-TSD.git/blame - lib/TSD/common.py
ip2host: added more flexibility
[python-TSD.git] / lib / TSD / common.py
CommitLineData
40d8bc65
PR
1import ldap
2import ldap.sasl
3
4ldapurl = 'ldap://tsd-dc01.tsd.usit.no'
5ldapbase = 'DC=tsd,DC=usit,DC=no'
f021027f
PR
6
7# use 2 to debug ldap connections.
8trace_level = 0
9
a2948e2d 10def ldap_uri():
2ca7ff37 11 return ldapurl
f021027f
PR
12
13def ldap_base():
14 return ldapbase
40d8bc65
PR
15
16def ldap_connect():
a2948e2d 17 lref = ldap.initialize(ldap_uri(), trace_level=trace_level)
40d8bc65
PR
18
19 auth_tokens = ldap.sasl.gssapi()
20 lref.sasl_interactive_bind_s('', auth_tokens)
21 return lref
22
40d8bc65 23def ldap_unbind(lref):
d6fc5f2b 24 lref.unbind()
8c00a9a1 25
dff7f8d5
PR
26def computermatch(enabled = None):
27 enablematch = '(userAccountControl:1.2.840.113556.1.4.803:=2)'
28 if enabled is None:
29 match = '(objectclass=computer)'
30 elif enabled:
31 match = '(&(objectclass=computer)(!%s))' % enablematch
32 else:
33 match = '(&(objectclass=computer)%s)' % enablematch
34 return match
35
36def role2hosts(lref, rolename, enabled = None):
d6fc5f2b
PR
37 """
38Look up all hosts with a given role.
39 """
8c00a9a1
PR
40 hosts = {}
41 policybase = 'OU=hostpolicies,' + ldap_base()
42 rolebase = 'OU=roles,' + policybase
43 atombase = 'OU=atoms,' + policybase
44
45 # First look up host members in role
46 roleres = lref.search_s(rolebase, ldap.SCOPE_SUBTREE,
47 '(&(objectclass=group)(name=%s))' % rolename,
48 ['member'])
49
50 # Next, look up FQDN of host members
dff7f8d5 51 match = computermatch(enabled)
8c00a9a1
PR
52 for roledn, roleentry in roleres:
53 if 'member' in roleentry:
54 for memberdn in roleentry['member']:
55 hostres = lref.search_s(memberdn, ldap.SCOPE_BASE,
dff7f8d5 56 match , ['dNSHostName'])
8c00a9a1
PR
57 for hostdn, hostent in hostres:
58 hosts[hostent['dNSHostName'][0]] = memberdn;
59 return hosts.keys()
d6fc5f2b
PR
60
61def role4host(lref, hostname):
62 """
63Look up all roles of a given host
64 """
65 roles = {}
66 policybase = 'OU=hostpolicies,' + ldap_base()
67 rolebase = 'OU=roles,' + policybase
68
69 # First look up hostname
70 hostres = lref.search_s(ldap_base(), ldap.SCOPE_SUBTREE, \
71 '(&(objectclass=computer)(dNSHostName=%s))' % hostname.lower(), \
72 ['memberOf'])
73
74 # FIXME fail if more than one host is returned
75
76 for hostdn, hostentry in hostres:
77 if 'memberOf' in hostentry:
78 for roledn in hostentry['memberOf']:
79 # look up the role name
80 entry = lref.search_s(roledn, ldap.SCOPE_BASE, \
81 '(objectclass=group)', \
82 ['name'])
83 for dn, roleent in entry:
84 roles[roleent['name'][0]] = 1
85 return roles.keys()
86
ad3fe95f 87
dff7f8d5 88def atom2hosts(lref, atomname, enabled = None):
a9ff88cb
PR
89 """
90Look up all hosts affected by a given cfengine atom (via role)
91 """
92 hosts = {}
93 policybase = 'OU=hostpolicies,' + ldap_base()
94 rolebase = 'OU=roles,' + policybase
95 atombase = 'OU=atoms,' + policybase
96
97 # First look up role members in the atom
98 atomres = lref.search_s(atombase, ldap.SCOPE_SUBTREE,
99 '(&(objectclass=group)(name=%s))' % atomname,
100 ['member'])
101
102 # Next, look up FQDN of host members
dff7f8d5 103 match = computermatch(enabled)
a9ff88cb
PR
104 for atomdn, atomentry in atomres:
105 if 'member' in atomentry:
106 for roledn in atomentry['member']:
107 roleres = lref.search_s(roledn, ldap.SCOPE_BASE,
108 '(objectclass=group)',
109 ['member'])
110 for roledn, roleentry in roleres:
111 if 'member' in roleentry:
112 for memberdn in roleentry['member']:
113 hostres = lref.search_s(memberdn, ldap.SCOPE_BASE,
dff7f8d5 114 match, ['dNSHostName'])
a9ff88cb
PR
115 for hostdn, hostent in hostres:
116 hosts[hostent['dNSHostName'][0]] = memberdn;
117 return hosts.keys()
118
ad3fe95f
PR
119def host2project(lref, fqdn):
120 """
121Find computer object and its project based on FQDN.
122 """
722fb4f1 123 res = lref.search_s(ldap_base(), ldap.SCOPE_SUBTREE, \
ad3fe95f
PR
124 '(&(objectclass=computer)(dnshostname=%s))' % fqdn,
125 ['dn'])
126 for dn, entry in res:
127 if None is not dn:
128 projectdn = ",".join((dn.split(","))[2:])
cfc0d263 129 projectnum = (dn.split(","))[-5].replace("OU=p", "")
ad3fe95f
PR
130 return (projectnum, dn)
131 return (None, None)
132
dcb3a3ad
MB
133def ip2host(lref, hostname):
134 """
135Find network information about a host
136 """
137 network = {}
138 dnsinfo = socket.getaddrinfo(hostname, None)
139 for (family, socktype, proto, canonname, sockaddr) in dnsinfo:
140 if socket.AF_INET == family:
141 ipv4addr['ipv4addr'] = sockaddr[0]
142 elif socket.AF_INET6 == family:
143 ipv6addr['ipv6addr'] = sockaddr[0]
144 hostres = lref.search_s(ldap_base(), ldap.SCOPE_SUBTREE, \
145 '(&(objectclass=computer)(dNSHostName=%s))' % hostname.lower(), \
146 ['networkAddress'])
147 for hostdn, hostaddr in hostres:
148 if 'networkAddress' in hostaddr:
b93ed7f2
MB
149 for i in hostaddr['networkAddress']:
150 if ":" in i:
151 ipv6 = i
152 elif "." in i:
153 ipv4 = i
518cf84d
MB
154 if "/" in ipv4:
155 vlan4, network4, prefix4 = ipv4.split("/")
156 network['vlan'] = vlan4
157 network['ipv4prefix'] = prefix4
158 network['ipv4network'] = network4
159 if "/" in ipv6:
160 vlan6, network6, prefix6 = ipv6.split("/")
161 network['ipv6prefix'] = prefix6
162 network['ipv6network'] = network6
163 network['vlan'] = vlan6
dcb3a3ad
MB
164 return network
165
a64f83d0 166def testfuncs():
d6fc5f2b
PR
167 l = ldap_connect()
168 print "All hosts with role autoinstall_virtual_host"
169 print role2hosts(l, 'autoinstall_virtual_host');
dff7f8d5 170 print role2hosts(l, 'autoinstall_virtual_host', enabled=True);
d6fc5f2b
PR
171 print "all roles of host tsd-prism.tsd.usit.no"
172 print role4host(l, 'tsd-prism.tsd.usit.no')
ad3fe95f
PR
173 print "project number for host tsd-prism.tsd.usit.no"
174 print host2project(l, 'tsd-prism.tsd.usit.no')
a9ff88cb 175 print atom2hosts(l, 'root_for_dba')
dff7f8d5 176 print atom2hosts(l, 'root_for_dba', enabled=False)
d6fc5f2b 177 ldap_unbind(l)
a64f83d0
PR
178
179if __name__ == "__main__":
180 testfuncs()