diff --git a/ucs-school-umc-exam/share/exam-and-room-cleanup b/ucs-school-umc-exam/share/exam-and-room-cleanup index bcfdcc7..4328baf 100755 --- a/ucs-school-umc-exam/share/exam-and-room-cleanup +++ b/ucs-school-umc-exam/share/exam-and-room-cleanup @@ -33,17 +33,15 @@ import os import grp import shutil import traceback -import httplib import optparse import univention.debug as ud import univention.config_registry import univention.uldap import univention.admin.uldap from ucsschool.lib.schoolldap import SchoolSearchBase -from univention.lib.umc_connection import UMCConnection +from univention.lib.umc import Client, ConnectionError, HTTPError from univention.admin.uexceptions import noObject from ldap.filter import escape_filter_chars -from socket import error as SocketError from ldap import LDAPError @@ -73,28 +71,22 @@ class ExamCleanupHelper(object): def get_UMCP_connection(self): ud.debug(ud.MAIN, ud.INFO, 'Opening UMCP connection to %s with machine account' % (self.hostname,)) - con = UMCConnection(self.hostname) - username = '%s$' % self.hostname try: - with open('/etc/machine.secret') as machine_file: - password = machine_file.readline().strip() - con.auth(username, password) - except (OSError, IOError) as exc: - ud.debug(ud.MAIN, ud.ERROR, 'Could not read /etc/machine.secret: %s' % exc) - sys.exit(1) - except (httplib.HTTPException, SocketError) as exc: + client = Client(self.hostname) + client.authenticate_with_machine_account() + except (ConnectionError, HTTPError) as exc: ud.debug(ud.MAIN, ud.ERROR, 'Could not connect to UMC on %s: %s' % (self.hostname, exc)) sys.exit(1) - return con + return client def running_exam_iter(self): ou_list = self.lo.search(filter='(objectClass=ucsschoolOrganizationalUnit)') for ou_dn, ou_attrs in ou_list: ou_name = ou_attrs.get('ou')[0] try: - room_list = self.umcp.request('computerroom/rooms', {'school': ou_name}) - except httplib.HTTPException, ex: - ud.debug(ud.MAIN, ud.ERROR, 'Cannot get room list for OU %r:\n%s' % (ou_name, ex)) + room_list = self.umcp.umc_command('computerroom/rooms', {'school': ou_name}).result + except (ConnectionError, HTTPError) as exc: + ud.debug(ud.MAIN, ud.ERROR, 'Cannot get room list for OU %r:\n%s' % (ou_name, exc)) continue for room in room_list: ud.debug(ud.MAIN, ud.INFO, '%s: %r' % (ou_name, room)) @@ -115,14 +107,14 @@ class ExamCleanupHelper(object): continue try: - result = self.umcp.request( + result = self.umcp.umc_command( 'schoolexam/exam/finish', - {'exam': room.get('exam'), 'room': room.get('id')}) + {'exam': room.get('exam'), 'room': room.get('id')}).result ud.debug(ud.MAIN, ud.INFO, 'result of schoolexam/exam/finish: %r' % (result,)) - except httplib.HTTPException, ex: + except (ConnectionError, HTTPError) as exc: ud.debug( ud.MAIN, ud.ERROR, - 'Cannot stop exam %r in room %r:\n%s' % (room.get('exam'), room.get('id'), ex)) + 'Cannot stop exam %r in room %r:\n%s' % (room.get('exam'), room.get('id'), exc)) continue def remove_exam_user(self): diff --git a/ucs-school-umc-exam/umc/python/schoolexam/__init__.py b/ucs-school-umc-exam/umc/python/schoolexam/__init__.py index 5d393fb..8b4e7d6 100644 --- a/ucs-school-umc-exam/umc/python/schoolexam/__init__.py +++ b/ucs-school-umc-exam/umc/python/schoolexam/__init__.py @@ -52,7 +52,7 @@ from univention.management.console.modules.schoolexam import util from univention.lib.i18n import Translation -from univention.lib.umc_connection import UMCConnection +from univention.lib.umc import Client, ConnectionError, HTTPError from ucsschool.lib.schoolldap import LDAP_Connection, SchoolBaseModule, SchoolSearchBase, SchoolSanitizer from ucsschool.lib import internetrules @@ -215,17 +215,20 @@ def _thread(): os.chown(itarget, 0, 0) # open a new connection to the master UMC - connection = UMCConnection.get_machine_connection() - if not connection: - MODULE.error('Could not connect to UMC on %s' % (ucr.get('ldap/master'))) + try: + master = ucr['ldap/master'] + client = Client(master) + client.authenticate_with_machine_account() + except (ConnectionError, HTTPError) as exc: + MODULE.error('Could not connect to UMC on %s: %s' % (master, exc)) raise UMC_Error(_('Could not connect to master server %s.') % ucr.get('ldap/master')) # mark the computer room for exam mode progress.component(_('Preparing the computer room for exam mode...')) - connection.request('schoolexam-master/set-computerroom-exammode', dict( + client.umc_command('schoolexam-master/set-computerroom-exammode', dict( school=request.options['school'], roomdn=request.options['room'], - )) + )).result # FIXME: no error handling progress.add_steps(5) # read all recipients and fetch all user objects @@ -254,13 +257,13 @@ def _thread(): for iuser in users: progress.info('%s, %s (%s)' % (iuser.lastname, iuser.firstname, iuser.username)) try: - ires = connection.request('schoolexam-master/create-exam-user', dict( + ires = client.umc_command('schoolexam-master/create-exam-user', dict( school=request.options['school'], userdn=iuser.dn - )) + )).result examUsers.add(ires.get('examuserdn')) MODULE.info('Exam user has been created: %s' % ires.get('examuserdn')) - except (HTTPException, SocketError) as exc: + except (ConnectionError, HTTPError) as exc: MODULE.warn('Could not create exam user account for %r: %s' % (iuser.dn, exc)) # indicate the the user has been processed @@ -332,31 +335,32 @@ def _thread(): # second step: adjust room settings progress.component(_('Prepare room settings')) try: - userConnection = UMCConnection('localhost', username=self.username, password=self.password) - except (HTTPException, SocketError) as exc: + user_client = Client(None, self.username, self.password) + except (ConnectionError, HTTPError) as exc: + MODULE.warn('Authentication failed: %s' % (exc,)) raise UMC_Error(_('Could not connect to local UMC server.')) room = request.options['room'] MODULE.info('Acquire room: %s' % (room,)) - userConnection.request('computerroom/room/acquire', dict( + user_client.umc_command('computerroom/room/acquire', dict( room=request.options['room'], - )) + )).result progress.add_steps(1) MODULE.info('Adjust room settings:\n%s' % '\n'.join([' %s=%s' % (k, v) for k, v in request.options.iteritems()])) - userConnection.request('computerroom/exam/start', dict( + user_client.umc_command('computerroom/exam/start', dict( room=room, examDescription=request.options['name'], exam=directory, examEndTime=request.options.get('examEndTime'), - )) + )).result progress.add_steps(4) - userConnection.request('computerroom/settings/set', dict( + user_client.umc_command('computerroom/settings/set', dict( room=room, internetRule=request.options['internetRule'], customRule=request.options.get('customRule'), shareMode=request.options['shareMode'], printMode='default', - )) + )).result progress.add_steps(5) def _finished(thread, result, request): @@ -441,19 +445,22 @@ def _thread(): progress.add_steps(10) # open a new connection to the master UMC - connection = UMCConnection.get_machine_connection() - if not connection: - MODULE.error('Could not connect to UMC on %s' % (ucr.get('ldap/master'))) - raise UMC_Error(_('Could not connect to master server %s.') % ucr.get('ldap/master')) + master = ucr['ldap/master'] + try: + client = Client(master) + client.authenticate_with_machine_account() + except (ConnectionError, HTTPError) as exc: + MODULE.error('Could not connect to UMC on %s: %s' % (master, exc)) + raise UMC_Error(_('Could not connect to master server %s.') % (master,)) school = SchoolSearchBase.getOU(request.options['room']) # unset exam mode for the given computer room progress.component(_('Configuring the computer room...')) - connection.request('schoolexam-master/unset-computerroom-exammode', dict( + client.umc_command('schoolexam-master/unset-computerroom-exammode', dict( roomdn=request.options['room'], school=school, - )) + )).result progress.add_steps(5) # delete exam users accounts @@ -476,10 +483,10 @@ def _thread(): shutil.rmtree(iuser.unixhome, ignore_errors=True) # remove LDAP user entry - connection.request('schoolexam-master/remove-exam-user', dict( + client.umc_command('schoolexam-master/remove-exam-user', dict( userdn=iuser.dn, school=school, - )) + )).result MODULE.info('Exam user has been removed: %s' % iuser.dn) else: MODULE.process('Cannot remove the user account %s as it is registered for the running exam "%s", as well' % (iuser.dn, parallelUsers[iuser.username])) diff --git a/ucs-school-umc-installer/umc/python/schoolinstaller/__init__.py b/ucs-school-umc-installer/umc/python/schoolinstaller/__init__.py index bc55983..e024cc2 100644 --- a/ucs-school-umc-installer/umc/python/schoolinstaller/__init__.py +++ b/ucs-school-umc-installer/umc/python/schoolinstaller/__init__.py @@ -44,7 +44,6 @@ import fcntl import select import errno -from httplib import HTTPException import notifier import notifier.threads @@ -53,7 +52,7 @@ import ldap from univention.lib.package_manager import PackageManager -from univention.lib.umc_connection import UMCConnection +from univention.lib.umc import Client, ConnectionError, HTTPError, Forbidden from univention.admin.uexceptions import noObject from univention.management.console.base import Base, UMC_Error from univention.management.console.log import MODULE @@ -135,10 +134,10 @@ def get_master_dns_lookup(): return '' -def umc(username, password, master, path='', options=None, flavor=None, command='command'): - connection = UMCConnection(master, username, password, error_handler=MODULE.warn) - MODULE.info('Executing on %r: %r %r flavor=%r options=%r' % (master, command, path, flavor, options)) - return connection.request(path or '', options, flavor, command=command) +def umc(username, password, master, path, options=None, flavor=None): + MODULE.info('Executing on %r: %r %r flavor=%r options=%r' % (master, path, flavor, options)) + client = Client(master, username, password) + return client.umc_command(path, options, flavor) def create_ou_local(ou, display_name): @@ -165,7 +164,7 @@ def create_ou_remote(master, username, password, ou, display_name, educational_s options['dc_name_administrative'] = administrative_slave try: umc(username, password, master, 'schoolwizards/schools/create', [{'object': options}], 'schoolwizards/schools') - except (EnvironmentError, HTTPException) as exc: + except (ConnectionError, HTTPError) as exc: raise SchoolInstallerError('Failed creating OU: %s' % (exc,)) @@ -457,11 +456,10 @@ def get_metainfo_master(self): def _umc_master(self, username, password, master, uri, data=None): try: - try: - return umc(username, password, master, uri, data) - except NotImplementedError: - raise HTTPException(_('Make sure ucs-school-umc-installer is installed on the DC Master and all join scripts are executed.')) - except (EnvironmentError, HTTPException) as exc: + return umc(username, password, master, uri, data) + except Forbidden: + raise SchoolInstallerError(_('Make sure ucs-school-umc-installer is installed on the DC Master and all join scripts are executed.')) + except (ConnectionError, HTTPError) as exc: raise SchoolInstallerError(_('Could not connect to the DC Master %s: %s') % (master, exc)) # TODO: set status, message, result @sanitize(