Timotej Lazar
25bcddede1
Consolidate base system and networking setup into debian role and BGP configuration into frr role. Add facts role to collect data from NetBox once to avoid many slow lookups. Also many other tweaks and cleanups.
58 lines
2.1 KiB
Django/Jinja
58 lines
2.1 KiB
Django/Jinja
#!/usr/bin/python3
|
|
|
|
import collections
|
|
import os
|
|
import re
|
|
|
|
import ldap3
|
|
|
|
{% set password = lookup('passwordstore', "cluster/"+cluster.name, returnall=true) | from_yaml %}
|
|
realm = '{{ hostvars[inventory_hostname]["sync-ldap"] }}'
|
|
ldap_host = '{{ domain }}'
|
|
ldap_user = '{{ password.ldap_user }}'
|
|
ldap_pass = '{{ password.ldap_pass }}'
|
|
ldap_base = '{{ domain | split(".") | map("regex_replace", "^", "dc=") | join(",") }}'
|
|
|
|
# build LDAP query for users
|
|
filters = [
|
|
'(objectClass=user)', # only users
|
|
'(objectCategory=person)', # that are people
|
|
'(schacHomeOrganization=*)', # presumably
|
|
'(!(userAccountControl:1.2.840.113556.1.4.803:=2))' # with enabled accounts
|
|
]
|
|
|
|
# run query
|
|
server = ldap3.Server(ldap_host, use_ssl=True)
|
|
ldap = ldap3.Connection(server, ldap_user, ldap_pass, auto_bind=True)
|
|
ldap.search(ldap_base,
|
|
f'(&{"".join(filters)})', # conjuction (&(…)(…)(…)) of queries
|
|
attributes=['userPrincipalName', 'givenName', 'sn', 'mail', 'memberOf'])
|
|
|
|
# build user and group dicts
|
|
all_users = {}
|
|
all_groups = collections.defaultdict(set)
|
|
for e in ldap.entries:
|
|
user = f'{e.userPrincipalName.value}@{realm}'
|
|
all_users[user] = { k: e[k].value for k in e.entry_attributes }
|
|
for group in e.memberOf:
|
|
if m := re.match(r'^CN=([^,]*)', group.replace('\\,', '-')):
|
|
group = re.sub(r'[^A-Za-z0-9_.-]', '-', m[1])
|
|
all_groups[group].add(user)
|
|
|
|
with open('/etc/pve/user.cfg.new', 'w') as f:
|
|
# user:{username}@{realm}:1:0:{name}:{surname}:{mail}:AD sync::
|
|
for user, info in sorted(all_users.items()):
|
|
print(f'user:{user}:1:0:{info["givenName"]}:{info["sn"]}:{info["mail"]}:AD sync::', file=f)
|
|
|
|
# group:{name}:{users}:AD sync:
|
|
print(f'group:ALL:{",".join(sorted(all_users))}:AD sync:', file=f)
|
|
for group, users in all_groups.items():
|
|
print(f'group:{group}:{",".join(sorted(users))}:AD sync:', file=f)
|
|
|
|
# keep everything not added by us
|
|
for line in open('/etc/pve/user.cfg'):
|
|
if not re.match('^(user|group):.*:AD sync:', line):
|
|
print(line, end='', file=f)
|
|
|
|
os.rename('/etc/pve/user.cfg.new', '/etc/pve/user.cfg')
|