There was an issue with the apt packages where python3-requests-kerberos didn't actually work. Instead of debugging the apt package I switched to using a venv, which should be more robust anyway.
163 lines
6.1 KiB
Python
Executable File
163 lines
6.1 KiB
Python
Executable File
#!/opt/entitlements/env/bin/python3
|
|
|
|
from inspect import getsourcefile
|
|
from os.path import dirname, realpath, abspath
|
|
import argparse
|
|
import configparser
|
|
import logging
|
|
import sys
|
|
|
|
from handlers.LdapHandler import LdapHandler
|
|
from handlers.DaisyHandler import DaisyHandler
|
|
from handlers.UserHandler import UserHandler
|
|
from handlers.UnixHandler import UnixHandler
|
|
from handlers.NoneHandler import NoneHandler
|
|
|
|
from util.EntitlementHandler import EntitlementHandler
|
|
from util.EntmapHandler import EntmapHandler
|
|
|
|
|
|
scriptpath = dirname(realpath(abspath(getsourcefile(lambda:0))))
|
|
|
|
mainhelp = 'Update entitlements in SUKAT according to entmap.conf.'
|
|
parser = argparse.ArgumentParser(description=mainhelp)
|
|
parser.add_argument('--dry-run',
|
|
action='store_true',
|
|
help="Don't make any changes, only print what would be done.")
|
|
parser.add_argument('--debug',
|
|
action='store_true',
|
|
help="Show extra output for debug purposes.")
|
|
group = parser.add_mutually_exclusive_group()
|
|
group.add_argument('--only-add',
|
|
action='store_true',
|
|
help="Only add entitlements, don't remove any.")
|
|
group.add_argument('--only-remove',
|
|
action='store_true',
|
|
help="Only remove entitlements, don't add any.")
|
|
parser.add_argument('entitlements',
|
|
nargs='*',
|
|
metavar='<entitlement>',
|
|
help="If present, only act on these entitlements. \
|
|
If not present, act on all entitlements.")
|
|
args = parser.parse_args()
|
|
|
|
config = configparser.ConfigParser()
|
|
config.read(scriptpath + '/config.ini')
|
|
|
|
loglevel = config['general'].get('log_level', 'INFO')
|
|
if args.debug:
|
|
loglevel = 'DEBUG'
|
|
|
|
log = logging.getLogger(__name__)
|
|
log.addHandler(logging.StreamHandler(sys.stdout))
|
|
log.setLevel(loglevel)
|
|
|
|
if args.dry_run:
|
|
log.info('Dry run requested. No changes will actually be applied.')
|
|
|
|
log.debug('Initializing...')
|
|
config['ldap']['entbase'] = config['general']['entitlement_base']
|
|
config['entitlementAPI']['entbase'] = config['general']['entitlement_base']
|
|
config['entitlementAPI']['cachefile'] = scriptpath + '/ent-cache'
|
|
keytab = config['entitlementAPI']['keytab']
|
|
if not keytab.startswith('/'):
|
|
config['entitlementAPI']['keytab'] = '{}/{}'.format(scriptpath, keytab)
|
|
|
|
ldap = LdapHandler(config['ldap'])
|
|
daisy = DaisyHandler(config['daisyAPI'])
|
|
user = UserHandler()
|
|
unix = UnixHandler(config['unix'])
|
|
none = NoneHandler()
|
|
api = EntitlementHandler(config['entitlementAPI'])
|
|
log.debug('Initialization done.')
|
|
|
|
log.debug('Parsing entitlement map...')
|
|
mapfile = config['general']['entitlement_map']
|
|
if not mapfile.startswith('/'):
|
|
mapfile = '{}/{}'.format(scriptpath, mapfile)
|
|
entmaphandler = EntmapHandler(mapfile)
|
|
entmappings = entmaphandler.read(args.entitlements)
|
|
log.debug('Finished parsing entitlement map.')
|
|
|
|
failed = []
|
|
|
|
log.debug('Updating entitlements:')
|
|
with api.open() as sukat:
|
|
for entitlement, definitions in sorted(entmappings.items()):
|
|
log.info(' Updating %s:', entitlement)
|
|
log.debug(' Getting list of current members...')
|
|
entitled_users = set(ldap.getEntitledUsers(entitlement))
|
|
log.debug(' Found %s current members.', len(entitled_users))
|
|
for username in entitled_users:
|
|
log.debug(' Found %s', username)
|
|
log.debug(' Getting list of expected members...')
|
|
expected_users = set()
|
|
excluded_users = set()
|
|
for (handler, query) in definitions:
|
|
include = True
|
|
if handler.startswith('!'):
|
|
include = False
|
|
handler = handler[1:]
|
|
temp_set = None
|
|
if handler == 'ldap':
|
|
temp_set = ldap.search(query)
|
|
elif handler == 'daisy':
|
|
temp_set = daisy.search(query)
|
|
elif handler == 'user':
|
|
temp_set = user.search(query)
|
|
elif handler == 'unixgroup':
|
|
temp_set = unix.search(query)
|
|
elif handler == 'none':
|
|
temp_set = none.search(query)
|
|
else:
|
|
raise Exception('Unknown handler: {}'.format(handler))
|
|
if include:
|
|
expected_users.update(temp_set)
|
|
else:
|
|
excluded_users.update(temp_set)
|
|
expected_users = expected_users - excluded_users
|
|
log.debug(' Found %s expected members.', len(expected_users))
|
|
for username in expected_users:
|
|
log.debug(' Expecting %s', username)
|
|
users_to_add = expected_users - entitled_users
|
|
users_to_remove = entitled_users - expected_users
|
|
num_to_add = len(users_to_add)
|
|
num_to_remove = len(users_to_remove)
|
|
if num_to_add > 0:
|
|
if not args.only_remove:
|
|
log.info(' Adding %s users...', num_to_add)
|
|
for username in users_to_add:
|
|
log.debug(' %s', username)
|
|
if not args.dry_run:
|
|
try:
|
|
sukat.add(entitlement, username)
|
|
except Exception as e:
|
|
failed.append((entitlement, 'add', username, e))
|
|
else:
|
|
log.info(' %s users can be added.', num_to_add)
|
|
else:
|
|
log.info(' No users to add.')
|
|
if num_to_remove:
|
|
if not args.only_add:
|
|
log.info(' Removing %s users...', num_to_remove)
|
|
for username in users_to_remove:
|
|
log.debug(' %s', username)
|
|
if not args.dry_run:
|
|
try:
|
|
sukat.remove(entitlement, username)
|
|
except Exception as e:
|
|
failed.append(
|
|
(entitlement, 'remove', username, e))
|
|
else:
|
|
log.info(' %s users can be removed.', num_to_remove)
|
|
else:
|
|
log.info(' No users to remove.')
|
|
|
|
if failed:
|
|
log.error('')
|
|
log.error('Problems were encountered with the following actions:')
|
|
for (ent, action, username, error) in failed:
|
|
log.error('%s %s %s\n %s', ent, action, username, error)
|
|
exit(99)
|
|
exit(0)
|