mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-07-04 08:02:02 +02:00
Optimized logic for user generation
This commit is contained in:
parent
cb6fbba8f4
commit
9d1b44319c
@ -9,7 +9,7 @@ from collections import OrderedDict
|
|||||||
|
|
||||||
def build_users(defs, primary_domain, start_id, become_pwd):
|
def build_users(defs, primary_domain, start_id, become_pwd):
|
||||||
"""
|
"""
|
||||||
Build user entries with auto-incremented uid/gid and default username/email.
|
Build user entries with auto-incremented uid/gid, default username/email, and optional description.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
defs (OrderedDict): Keys are user IDs, values are dicts with optional overrides.
|
defs (OrderedDict): Keys are user IDs, values are dicts with optional overrides.
|
||||||
@ -19,16 +19,62 @@ def build_users(defs, primary_domain, start_id, become_pwd):
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
OrderedDict: Merged user definitions with full fields.
|
OrderedDict: Merged user definitions with full fields.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
ValueError: If duplicate override uids/gids or conflicts in generated values.
|
||||||
"""
|
"""
|
||||||
users = OrderedDict()
|
users = OrderedDict()
|
||||||
next_id = start_id
|
used_uids = set()
|
||||||
|
used_gids = set()
|
||||||
|
|
||||||
|
# Pre-collect any provided uids/gids and check for duplicates
|
||||||
|
for key, overrides in defs.items():
|
||||||
|
if 'uid' in overrides:
|
||||||
|
uid = overrides['uid']
|
||||||
|
if uid in used_uids:
|
||||||
|
raise ValueError(f"Duplicate uid {uid} for user '{key}'")
|
||||||
|
used_uids.add(uid)
|
||||||
|
if 'gid' in overrides:
|
||||||
|
gid = overrides['gid']
|
||||||
|
if gid in used_gids:
|
||||||
|
raise ValueError(f"Duplicate gid {gid} for user '{key}'")
|
||||||
|
used_gids.add(gid)
|
||||||
|
|
||||||
|
next_free = start_id
|
||||||
|
def allocate_free_id():
|
||||||
|
nonlocal next_free
|
||||||
|
# find next free id not in used_uids
|
||||||
|
while next_free in used_uids:
|
||||||
|
next_free += 1
|
||||||
|
free = next_free
|
||||||
|
used_uids.add(free)
|
||||||
|
used_gids.add(free)
|
||||||
|
next_free += 1
|
||||||
|
return free
|
||||||
|
|
||||||
|
# Build entries
|
||||||
for key, overrides in defs.items():
|
for key, overrides in defs.items():
|
||||||
username = overrides.get('username', key)
|
username = overrides.get('username', key)
|
||||||
email = overrides.get('email', f"{username}@{primary_domain}")
|
email = overrides.get('email', f"{username}@{primary_domain}")
|
||||||
uid = overrides.get('uid', next_id)
|
description = overrides.get('description')
|
||||||
gid = overrides.get('gid', next_id)
|
|
||||||
is_admin = overrides.get('is_admin', False)
|
# UID assignment
|
||||||
|
if 'uid' in overrides:
|
||||||
|
uid = overrides['uid']
|
||||||
|
else:
|
||||||
|
uid = allocate_free_id()
|
||||||
|
|
||||||
|
# GID assignment
|
||||||
|
if 'gid' in overrides:
|
||||||
|
gid = overrides['gid']
|
||||||
|
else:
|
||||||
|
# if gid not provided, default to uid (and ensure uniqueness)
|
||||||
|
if uid in used_gids:
|
||||||
|
# already added in allocate_free_id or pre-collect
|
||||||
|
gid = uid
|
||||||
|
else:
|
||||||
|
gid = uid
|
||||||
|
used_gids.add(gid)
|
||||||
|
|
||||||
entry = {
|
entry = {
|
||||||
'username': username,
|
'username': username,
|
||||||
@ -37,11 +83,30 @@ def build_users(defs, primary_domain, start_id, become_pwd):
|
|||||||
'uid': uid,
|
'uid': uid,
|
||||||
'gid': gid
|
'gid': gid
|
||||||
}
|
}
|
||||||
if is_admin:
|
if description is not None:
|
||||||
|
entry['description'] = description
|
||||||
|
if overrides.get('is_admin', False):
|
||||||
entry['is_admin'] = True
|
entry['is_admin'] = True
|
||||||
|
|
||||||
users[key] = entry
|
users[key] = entry
|
||||||
next_id += 1
|
|
||||||
|
# Validate uniqueness of username, email, and gid
|
||||||
|
seen_usernames = set()
|
||||||
|
seen_emails = set()
|
||||||
|
seen_gids = set()
|
||||||
|
for key, entry in users.items():
|
||||||
|
un = entry['username']
|
||||||
|
em = entry['email']
|
||||||
|
gd = entry['gid']
|
||||||
|
if un in seen_usernames:
|
||||||
|
raise ValueError(f"Duplicate username '{un}' in merged users")
|
||||||
|
if em in seen_emails:
|
||||||
|
raise ValueError(f"Duplicate email '{em}' in merged users")
|
||||||
|
if gd in seen_gids:
|
||||||
|
raise ValueError(f"Duplicate gid '{gd}' in merged users")
|
||||||
|
seen_usernames.add(un)
|
||||||
|
seen_emails.add(em)
|
||||||
|
seen_gids.add(gd)
|
||||||
|
|
||||||
return users
|
return users
|
||||||
|
|
||||||
@ -134,12 +199,16 @@ def main():
|
|||||||
print(f"Error merging user definitions: {e}", file=sys.stderr)
|
print(f"Error merging user definitions: {e}", file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
users = build_users(
|
try:
|
||||||
defs=user_defs,
|
users = build_users(
|
||||||
primary_domain=primary_domain,
|
defs=user_defs,
|
||||||
start_id=args.start_id,
|
primary_domain=primary_domain,
|
||||||
become_pwd=become_pwd
|
start_id=args.start_id,
|
||||||
)
|
become_pwd=become_pwd
|
||||||
|
)
|
||||||
|
except ValueError as e:
|
||||||
|
print(f"Error building user entries: {e}", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
default_users = {'default_users': users}
|
default_users = {'default_users': users}
|
||||||
plain_data = dictify(default_users)
|
plain_data = dictify(default_users)
|
||||||
|
@ -1,50 +0,0 @@
|
|||||||
default_users:
|
|
||||||
administrator:
|
|
||||||
username: administrator
|
|
||||||
email: administrator@{{ primary_domain }}
|
|
||||||
password: '{{ ansible_become_password }}'
|
|
||||||
uid: 1001
|
|
||||||
gid: 1001
|
|
||||||
is_admin: true
|
|
||||||
blackhole:
|
|
||||||
username: blackhole
|
|
||||||
email: blackhole@{{ primary_domain }}
|
|
||||||
password: '{{ ansible_become_password }}'
|
|
||||||
uid: 1002
|
|
||||||
gid: 1002
|
|
||||||
crm:
|
|
||||||
username: contact
|
|
||||||
email: contact@{{ primary_domain }}
|
|
||||||
password: '{{ ansible_become_password }}'
|
|
||||||
uid: 1003
|
|
||||||
gid: 1003
|
|
||||||
bounce:
|
|
||||||
username: bounce
|
|
||||||
email: bounce@{{ primary_domain }}
|
|
||||||
password: '{{ ansible_become_password }}'
|
|
||||||
uid: 1004
|
|
||||||
gid: 1004
|
|
||||||
newsletter:
|
|
||||||
username: newsletter
|
|
||||||
email: newsletter@{{ primary_domain }}
|
|
||||||
password: '{{ ansible_become_password }}'
|
|
||||||
uid: 1005
|
|
||||||
gid: 1005
|
|
||||||
no-reply:
|
|
||||||
username: no-reply
|
|
||||||
email: no-reply@{{ primary_domain }}
|
|
||||||
password: '{{ ansible_become_password }}'
|
|
||||||
uid: 1006
|
|
||||||
gid: 1006
|
|
||||||
sld:
|
|
||||||
username: '{{ primary_domain.split(''.'')[0] }}'
|
|
||||||
email: '{{ primary_domain.split(''.'')[0] }}@{{ primary_domain }}'
|
|
||||||
password: '{{ ansible_become_password }}'
|
|
||||||
uid: 1007
|
|
||||||
gid: 1007
|
|
||||||
tld:
|
|
||||||
username: '{{ primary_domain.split(''.'')[1] }}'
|
|
||||||
email: '{{ primary_domain.split(''.'')[1] }}@{{ primary_domain }}'
|
|
||||||
password: '{{ ansible_become_password }}'
|
|
||||||
uid: 1008
|
|
||||||
gid: 1008
|
|
Loading…
x
Reference in New Issue
Block a user