]>
Commit | Line | Data |
---|---|---|
40d8bc65 PR |
1 | import ldap |
2 | import ldap.sasl | |
3 | ||
4 | ldapurl = 'ldap://tsd-dc01.tsd.usit.no' | |
5 | ldapbase = 'DC=tsd,DC=usit,DC=no' | |
f021027f PR |
6 | |
7 | # use 2 to debug ldap connections. | |
8 | trace_level = 0 | |
9 | ||
a2948e2d | 10 | def ldap_uri(): |
2ca7ff37 | 11 | return ldapurl |
f021027f PR |
12 | |
13 | def ldap_base(): | |
14 | return ldapbase | |
40d8bc65 PR |
15 | |
16 | def 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 | 23 | def ldap_unbind(lref): |
d6fc5f2b | 24 | lref.unbind() |
8c00a9a1 | 25 | |
dff7f8d5 PR |
26 | def 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 | ||
36 | def role2hosts(lref, rolename, enabled = None): | |
d6fc5f2b PR |
37 | """ |
38 | Look 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 | |
61 | def role4host(lref, hostname): | |
62 | """ | |
63 | Look 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 | 88 | def atom2hosts(lref, atomname, enabled = None): |
a9ff88cb PR |
89 | """ |
90 | Look 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 |
119 | def host2project(lref, fqdn): |
120 | """ | |
121 | Find 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 |
133 | def ip2host(lref, hostname): |
134 | """ | |
135 | Find 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 | 166 | def 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 | |
179 | if __name__ == "__main__": | |
180 | testfuncs() |