def __init__(self): super(Giedo, self).__init__(settings.GIEDO_SOCKET) self.log = logging.getLogger('giedo') self.last_sync_ts = 0 self.daan, self.cilia, self.moniek, self.hans = None, None, None, None try: self.daan = WhimClient(settings.DAAN_SOCKET) except Exception: self.log.exception("Couldn't connect to daan") try: self.cilia = WhimClient(settings.CILIA_SOCKET) except Exception: self.log.exception("Couldn't connect to cilia") try: self.moniek = WhimClient(settings.MONIEK_SOCKET) except Exception: self.log.exception("Couldn't connect to moniek") try: self.hans = WhimClient(settings.HANS_SOCKET) except Exception: self.log.exception("Couldn't connect to hans") self.mirte = mirte.get_a_manager() self.threadPool = self.mirte.get_a('threadPool') self.operation_lock = threading.Lock() self.ss_actions = ( ('postfix', self.daan, self._gen_postfix), ('postfix-slm', self.daan, self._gen_postfix_slm), ('mailman', self.hans, self._gen_mailman), ('unix', self.cilia, self._gen_unix), ('wiki', self.daan, self._gen_wiki), ('ldap', self.daan, self._gen_ldap), ('wolk', self.cilia, self._gen_wolk))
def __init__(self): super(Giedo, self).__init__(settings.GIEDO_SOCKET) self.l = logging.getLogger('giedo') self.last_sync_ts = 0 self.daan, self.cilia = None, None try: self.daan = WhimClient(settings.DAAN_SOCKET) except: self.l.exception("Couldn't connect to daan") try: self.cilia = WhimClient(settings.CILIA_SOCKET) except: self.l.exception("Couldn't connect to cilia") self.mirte = mirte.get_a_manager() self.threadPool = self.mirte.get_a('threadPool') self.operation_lock = threading.Lock() self.push_changes_event = threading.Event() self.openvpn_lock = threading.Lock() self.threadPool.execute(self.run_change_pusher) if default_storage.exists("villanet.pem"): self.villanet_key = RSA.load_pub_key(default_storage.path( "villanet.pem")) self.ss_actions = ( ('postfix', self.daan, self._gen_postfix), ('postfix-slm', self.daan, self._gen_postfix_slm), ('mailman', self.daan, self._gen_mailman), ('forum', self.daan, self._gen_forum), ('unix', self.cilia, self._gen_unix), ('wiki', self.daan, self._gen_wiki), ('ldap', self.daan, self._gen_ldap), ('wolk', self.cilia, self._gen_wolk), ('quassel', self.daan, self._gen_quassel)) self.push_changes_event.set()
def __init__(self): super(Giedo, self).__init__(settings.GIEDO_SOCKET) self.daan = WhimClient(settings.DAAN_SOCKET) self.cilia = WhimClient(settings.CILIA_SOCKET) self.mirte = mirte.get_a_manager() self.threadPool = self.mirte.get_a('threadPool') self.operation_lock = threading.Lock() self.ss_actions = ( ('postfix', self.daan, self._gen_postfix), ('mailman', self.daan, self._gen_mailman), ('forum', self.daan, self._gen_forum), ('unix', self.cilia, self._gen_unix), ('wiki', self.daan, self._gen_wiki))
def __init__(self): super(Giedo, self).__init__(settings.GIEDO_SOCKET) self.daan = WhimClient(settings.DAAN_SOCKET) self.cilia = WhimClient(settings.CILIA_SOCKET) self.mirte = mirte.get_a_manager() self.threadPool = self.mirte.get_a("threadPool") self.operation_lock = threading.Lock() self.ss_actions = ( ("postfix", self.daan, self._gen_postfix), ("mailman", self.daan, self._gen_mailman), ("forum", self.daan, self._gen_forum), ("unix", self.cilia, self._gen_unix), ("wiki", self.daan, self._gen_wiki), )
def __init__(self): super(Giedo, self).__init__(settings.GIEDO_SOCKET) self.log = logging.getLogger('giedo') self.last_sync_ts = 0 self.daan, self.cilia, self.moniek, self.hans = None, None, None, None try: self.daan = WhimClient(settings.DAAN_SOCKET) except Exception: self.log.exception("Couldn't connect to daan") try: self.cilia = WhimClient(settings.CILIA_SOCKET) except Exception: self.log.exception("Couldn't connect to cilia") try: self.moniek = WhimClient(settings.MONIEK_SOCKET) except Exception: self.log.exception("Couldn't connect to moniek") try: self.hans = WhimClient(settings.HANS_SOCKET) except Exception: self.log.exception("Couldn't connect to hans") self.mirte = mirte.get_a_manager() self.threadPool = self.mirte.get_a('threadPool') self.operation_lock = threading.Lock() self.ss_actions = (('postfix', self.daan, self._gen_postfix), ('postfix-slm', self.daan, self._gen_postfix_slm), ('mailman', self.hans, self._gen_mailman), ('unix', self.cilia, self._gen_unix), ('wiki', self.daan, self._gen_wiki), ('ldap', self.daan, self._gen_ldap), ('wolk', self.cilia, self._gen_wolk))
def __init__(self): super(Giedo, self).__init__(settings.GIEDO_SOCKET) self.daan = WhimClient(settings.DAAN_SOCKET) self.cilia = WhimClient(settings.CILIA_SOCKET) self.mirte = mirte.get_a_manager() self.threadPool = self.mirte.get_a('threadPool') self.operation_lock = threading.Lock() self.push_changes_event = threading.Event() self.threadPool.execute(self.run_change_pusher) if default_storage.exists("villanet.pem"): self.villanet_key = RSA.load_pub_key(default_storage.path( "villanet.pem")) self.ss_actions = ( ('postfix', self.daan, self._gen_postfix), ('mailman', self.daan, self._gen_mailman), ('forum', self.daan, self._gen_forum), ('unix', self.cilia, self._gen_unix), ('wiki', self.daan, self._gen_wiki)) self.push_changes_event.set()
def __init__(self): super(Giedo, self).__init__(settings.GIEDO_SOCKET) self.last_sync_ts = 0 self.daan = WhimClient(settings.DAAN_SOCKET) self.cilia = WhimClient(settings.CILIA_SOCKET) self.mirte = mirte.get_a_manager() self.threadPool = self.mirte.get_a('threadPool') self.operation_lock = threading.Lock() self.push_changes_event = threading.Event() self.threadPool.execute(self.run_change_pusher) if default_storage.exists("villanet.pem"): self.villanet_key = RSA.load_pub_key( default_storage.path("villanet.pem")) self.ss_actions = (('postfix', self.daan, self._gen_postfix), ('postfix-slm', self.daan, self._gen_postfix_slm), ('mailman', self.daan, self._gen_mailman), ('forum', self.daan, self._gen_forum), ('unix', self.cilia, self._gen_unix), ('wiki', self.daan, self._gen_wiki), ('ldap', self.daan, self._gen_ldap)) self.push_changes_event.set()
def __init__(self): super(Giedo, self).__init__() self.log = logging.getLogger('giedo') self.last_sync_ts = 0 self.daan, self.cilia, self.moniek, self.hans = None, None, None, None try: self.daan = daan_pb2_grpc.DaanStub( grpc.insecure_channel('unix:' + settings.DAAN_SOCKET)) except Exception: self.log.exception("Couldn't connect to daan") try: self.cilia = WhimClient(settings.CILIA_SOCKET) except Exception: self.log.exception("Couldn't connect to cilia") try: self.moniek = moniek_pb2_grpc.MoniekStub( grpc.insecure_channel('unix:' + settings.MONIEK_SOCKET)) except Exception: self.log.exception("Couldn't connect to moniek") try: self.hans = hans_pb2_grpc.HansStub( grpc.insecure_channel('unix:' + settings.HANS_SOCKET)) except Exception: self.log.exception("Couldn't connect to hans") self.mirte = mirte.get_a_manager() self.threadPool = self.mirte.get_a('threadPool') self.operation_lock = threading.Lock() self.ss_actions = (('postfix', self.daan.SetPostfixMap, self._gen_postfix), ('postfix-slm', self.daan.SetPostfixSenderLoginMap, self._gen_postfix_slm), ('mailman', self.hans.ApplyChanges, self._gen_mailman), ('unix', self.cilia.send, self._gen_unix), ('wiki', self.daan.ApplyWikiChanges, self._gen_wiki), ('ldap', self.daan.ApplyLDAPChanges, self._gen_ldap), ('wolk', self.cilia.send, self._gen_wolk))
class Giedo(WhimDaemon): def __init__(self): super(Giedo, self).__init__(settings.GIEDO_SOCKET) self.log = logging.getLogger('giedo') self.last_sync_ts = 0 self.daan, self.cilia, self.moniek, self.hans = None, None, None, None try: self.daan = WhimClient(settings.DAAN_SOCKET) except Exception: self.log.exception("Couldn't connect to daan") try: self.cilia = WhimClient(settings.CILIA_SOCKET) except Exception: self.log.exception("Couldn't connect to cilia") try: self.moniek = WhimClient(settings.MONIEK_SOCKET) except Exception: self.log.exception("Couldn't connect to moniek") try: self.hans = WhimClient(settings.HANS_SOCKET) except Exception: self.log.exception("Couldn't connect to hans") self.mirte = mirte.get_a_manager() self.threadPool = self.mirte.get_a('threadPool') self.operation_lock = threading.Lock() self.ss_actions = ( ('postfix', self.daan, self._gen_postfix), ('postfix-slm', self.daan, self._gen_postfix_slm), ('mailman', self.hans, self._gen_mailman), ('unix', self.cilia, self._gen_unix), ('wiki', self.daan, self._gen_wiki), ('ldap', self.daan, self._gen_ldap), ('wolk', self.cilia, self._gen_wolk)) def pre_mainloop(self): super(Giedo, self).pre_mainloop() self.notify_systemd() def _gen_wolk(self): return {'type': 'wolk', 'changes': generate_wolk_changes(self)} def _gen_ldap(self): return {'type': 'ldap', 'changes': generate_ldap_changes(self)} def _gen_postfix_slm(self): return {'type': 'postfix-slm', 'map': generate_postfix_slm_map(self)} def _gen_postfix(self): return {'type': 'postfix', 'map': generate_postfix_map(self)} def _gen_mailman(self): return {'type': 'maillist-apply-changes', 'changes': generate_mailman_changes(self)} def _gen_wiki(self): return {'type': 'wiki', 'changes': generate_wiki_changes(self)} def _gen_unix(self): return {'type': 'unix', 'map': generate_unix_map(self)} def sync(self): update_db_start = time.time() update_db(self) logging.info("update_db %s" % (time.time() - update_db_start)) todo = [len(self.ss_actions)] todo_lock = threading.Lock() todo_event = threading.Event() def _sync_action(func, name, daemon, action): try: func(name, daemon, action) except Exception: logging.exception('uncaught exception in %s (daemon %s)' % (name, daemon)) with todo_lock: todo[0] -= 1 if todo[0] == 0: todo_event.set() def _entry(name, daemon, action): start = time.time() msg = action() elapsed = time.time() - start logging.info("generate %s %.4f" % (name, elapsed)) start = time.time() daemon.send(msg) elapsed = time.time() - start logging.info("send %s %.4f (%s to go)" % (name, elapsed, todo[0] - 1)) for action in self.ss_actions: self.threadPool.execute(_sync_action, _entry, *action) todo_event.wait() self.last_sync_ts = time.time() def handle(self, d): if d['type'] == 'sync': with self.operation_lock: return self.sync() elif d['type'] == 'setpass': with self.operation_lock: u = Es.by_name(d['user']) if u is None: return {'error': 'no such user'} u = u.as_user() if not u.check_password(d['oldpass']): return {'error': 'wrong old password'} u.set_password(d['newpass']) d2 = {'type': 'setpass', 'user': d['user'], 'pass': d['newpass']} self.daan.send(d2) self.cilia.send(d2) return {'success': True} elif d['type'] == 'ping': return {'pong': True} elif d['type'] == 'fotoadmin-scan-userdirs': return self.cilia.send(d) elif d['type'] == 'fotoadmin-move-fotos': with self.operation_lock: ret = self.daan.send(d) if 'success' not in ret: return ret ret = scan_fotos() if 'success' not in ret: return ret return self.cilia.send({ 'type': 'fotoadmin-remove-moved-fotos', 'store': d['store'], 'user': d['user'], 'dir': d['dir']}) elif d['type'] == 'fotoadmin-scan-fotos': with self.operation_lock: return scan_fotos() elif d['type'] == 'update-site-agenda': with self.operation_lock: return update_site_agenda(self) elif d['type'] in ['fotoadmin-create-event']: with self.operation_lock: return self.daan.send(d) elif d['type'] == 'last-synced?': return self.last_sync_ts elif d['type'] in ('fin-get-account', 'fin-get-debitors', 'fin-check-names', 'fin-get-gnucash-object', 'fin-get-years', 'fin-get-errors'): try: return self.moniek.send(d) except IOError as e: return {'error': 'IOError: ' + e.args[0]} elif d['type'] in ('maillist-get-moderated-lists', 'maillist-activate-moderation', 'maillist-get-moderator-cookie', 'maillist-deactivate-moderation'): return self.hans.send(d) else: logging.warn("Unknown command: %s" % d['type'])
class Giedo(WhimDaemon): def __init__(self): super(Giedo, self).__init__(settings.GIEDO_SOCKET) self.last_sync_ts = 0 self.daan = WhimClient(settings.DAAN_SOCKET) self.cilia = WhimClient(settings.CILIA_SOCKET) self.mirte = mirte.get_a_manager() self.threadPool = self.mirte.get_a('threadPool') self.operation_lock = threading.Lock() self.push_changes_event = threading.Event() self.threadPool.execute(self.run_change_pusher) if default_storage.exists("villanet.pem"): self.villanet_key = RSA.load_pub_key( default_storage.path("villanet.pem")) self.ss_actions = (('postfix', self.daan, self._gen_postfix), ('postfix-slm', self.daan, self._gen_postfix_slm), ('mailman', self.daan, self._gen_mailman), ('forum', self.daan, self._gen_forum), ('unix', self.cilia, self._gen_unix), ('wiki', self.daan, self._gen_wiki), ('ldap', self.daan, self._gen_ldap)) self.push_changes_event.set() def _gen_ldap(self): return {'type': 'ldap', 'changes': generate_ldap_changes(self)} def _gen_postfix_slm(self): return {'type': 'postfix-slm', 'map': generate_postfix_slm_map(self)} def _gen_postfix(self): return {'type': 'postfix', 'map': generate_postfix_map(self)} def _gen_mailman(self): return {'type': 'mailman', 'changes': generate_mailman_changes(self)} def _gen_wiki(self): return {'type': 'wiki', 'changes': generate_wiki_changes(self)} def _gen_forum(self): return {'type': 'forum', 'changes': generate_forum_changes(self)} def _gen_unix(self): return {'type': 'unix', 'map': generate_unix_map(self)} def _sync_villanet(self): ret = self.villanet_request({'action': 'listUsers'}) if not ret[0]: return ret = json.loads(ret[1]) users = dict() ulut = dict() for u in Es.users(): ulut[u._id] = str(u.name) member_relations_grouped = dict() for rel in Es.query_relations(_with=Es.by_name('leden'), until=now()): if rel['who'] not in member_relations_grouped: member_relations_grouped[rel['who']] = [] member_relations_grouped[rel['who']].append(rel) for user_id, relations in member_relations_grouped.items(): latest = max(relations, key=lambda x: x['until']) users[ulut[user_id]] = latest['until'].strftime('%Y-%m-%d') vn = set(ret.keys()) kn = set(users.keys()) dt_max = settings.DT_MAX.strftime('%Y-%m-%d') for name in kn - vn: data = { 'username': name, 'password': self.villanet_encrypt_password(pseudo_randstr(16)), } if users[name] != dt_max: data['till'] = users[name] pc = Es.PushChange({ 'system': 'villanet', 'action': 'addUser', 'data': data }) pc.save() for name in vn - kn: logging.info("Stray user %s" % name) for name in vn & kn: remote = (ret[name]['till'][:10] if ret[name]['till'] is not None else '') local = users[name] if users[name] != dt_max else '' if remote != local: pc = Es.PushChange({ 'system': 'villanet', 'action': 'changeUser', 'data': { 'username': name, 'till': local } }) pc.save() self.push_changes_event.set() def sync(self): update_db_start = time.time() update_db(self) logging.info("update_db %s" % (time.time() - update_db_start)) todo = [len(self.ss_actions)] todo_lock = threading.Lock() todo_event = threading.Event() def _sync_action(func, *args): try: func(*args) except Exception as e: logging.exception("Uncaught exception") with todo_lock: todo[0] -= 1 if todo[0] == 0: todo_event.set() def _entry(name, daemon, action): start = time.time() msg = action() elapsed = time.time() - start logging.info("generate %s %s" % (name, elapsed)) start = time.time() daemon.send(msg) elapsed = time.time() - start logging.info("send %s %s" % (name, elapsed)) todo[0] += 1 self.threadPool.execute(_sync_action, self._sync_villanet) for act in self.ss_actions: self.threadPool.execute(_sync_action, _entry, *act) todo_event.wait() self.last_sync_ts = time.time() def handle(self, d): if d['type'] == 'sync': with self.operation_lock: return self.sync() elif d['type'] == 'setpass': with self.operation_lock: u = Es.by_name(d['user']) if u is None: return {'error': 'no such user'} u = u.as_user() if not u.check_password(d['oldpass']): return {'error': 'wrong old password'} u.set_password(d['newpass']) d2 = { 'type': 'setpass', 'user': d['user'], 'pass': d['newpass'] } self.daan.send(d2) self.cilia.send(d2) return {'success': True} elif d['type'] == 'set-villanet-password': with self.operation_lock: u = Es.by_name(d['user']) if u is None: return {'error': 'no such user'} u = u.as_user() if not u.check_password(d['oldpass']): return {'error': 'wrong current password'} pc = Es.PushChange({ 'system': 'villanet', 'action': 'changeUser', 'data': { 'username': d['user'], 'password': self.villanet_encrypt_password(d['newpass']) } }) pc.save() self.push_changes_event.set() return {'success': True} elif d['type'] == 'fotoadmin-move-fotos': with self.operation_lock: # TODO should this block Giedo? ret = self.daan.send(d) if 'success' not in ret: return ret return self.cilia.send({ 'type': 'fotoadmin-remove-moved-fotos', 'user': d['user'], 'dir': d['dir'] }) elif d['type'] == 'openvpn_create': with self.operation_lock: # XXX hoeft niet onder de operation_lock? u = Es.by_name(d['user']) if u is None: return {'error': 'no such user'} u = u.as_user() if d['want'] == 'exe': create_openvpn_installer(self, u) else: create_openvpn_zip(self, u) elif d['type'] == 'update-site-agenda': with self.operation_lock: return update_site_agenda(self) elif d['type'] in [ 'update-knsite', 'update-knfotos', 'fotoadmin-create-event' ]: with self.operation_lock: return self.daan.send(d) elif d['type'] == 'last-synced?': return self.last_sync_ts else: logging.warn("Unknown command: %s" % d['type']) def villanet_encrypt_password(self, password): ctx = self.villanet_key.public_encrypt(password, RSA.pkcs1_padding) return ctx.encode('base64').replace("\n", '') def run_change_pusher(self): while True: self.push_changes_event.wait() self.push_changes_event.clear() for pc in Es.pcol.find(): if pc['system'] == 'villanet': if settings.VILLANET_SECRET_API_KEY == '': logging.warn("VILLANET_SECRET_API_KEY not set") continue params = pc['data'] params['action'] = pc['action'] ret = self.villanet_request(params) if not ret[0]: continue else: logging.warn("Unknown PushChange system %s " % pc['system']) Es.pcol.remove({'_id': pc['_id']}) def villanet_request(self, params): params['apikey'] = settings.VILLANET_SECRET_API_KEY url = "http://www.vvs-nijmegen.nl/knapi.php?" + urlencode(params) ret = urllib2.urlopen(url, timeout=1).read() ret = ret.strip() if ret[:4] == 'OK: ': return (True, ret[4:]) else: return (False, ret)
class Giedo(giedo_pb2_grpc.GiedoServicer): def __init__(self): super(Giedo, self).__init__() self.log = logging.getLogger('giedo') self.last_sync_ts = 0 self.daan, self.cilia, self.moniek, self.hans = None, None, None, None try: self.daan = daan_pb2_grpc.DaanStub( grpc.insecure_channel('unix:' + settings.DAAN_SOCKET)) except Exception: self.log.exception("Couldn't connect to daan") try: self.cilia = WhimClient(settings.CILIA_SOCKET) except Exception: self.log.exception("Couldn't connect to cilia") try: self.moniek = moniek_pb2_grpc.MoniekStub( grpc.insecure_channel('unix:' + settings.MONIEK_SOCKET)) except Exception: self.log.exception("Couldn't connect to moniek") try: self.hans = hans_pb2_grpc.HansStub( grpc.insecure_channel('unix:' + settings.HANS_SOCKET)) except Exception: self.log.exception("Couldn't connect to hans") self.mirte = mirte.get_a_manager() self.threadPool = self.mirte.get_a('threadPool') self.operation_lock = threading.Lock() self.ss_actions = (('postfix', self.daan.SetPostfixMap, self._gen_postfix), ('postfix-slm', self.daan.SetPostfixSenderLoginMap, self._gen_postfix_slm), ('mailman', self.hans.ApplyChanges, self._gen_mailman), ('unix', self.cilia.send, self._gen_unix), ('wiki', self.daan.ApplyWikiChanges, self._gen_wiki), ('ldap', self.daan.ApplyLDAPChanges, self._gen_ldap), ('wolk', self.cilia.send, self._gen_wolk)) def _gen_wolk(self): return {'type': 'wolk', 'changes': generate_wolk_changes(self)} def _gen_ldap(self): return generate_ldap_changes() def _gen_postfix_slm(self): return generate_postfix_slm_map() def _gen_postfix(self): return generate_postfix_map() def _gen_mailman(self): return generate_mailman_changes(self.hans) def _gen_wiki(self): return generate_wiki_changes() def _gen_unix(self): return {'type': 'unix', 'map': generate_unix_map(self)} def sync(self): update_db_start = time.time() update_db(self) logging.info("update_db %s" % (time.time() - update_db_start)) todo = [len(self.ss_actions)] todo_lock = threading.Lock() todo_event = threading.Event() def _sync_action(func, name, daemon, action): try: func(name, daemon, action) except Exception: logging.exception('uncaught exception in %s (daemon %s)' % (name, daemon)) with todo_lock: todo[0] -= 1 if todo[0] == 0: todo_event.set() def _entry(name, send, action): start = time.time() msg = action() elapsed = time.time() - start logging.info("generate %s %.4f" % (name, elapsed)) start = time.time() send(msg) elapsed = time.time() - start logging.info("send %s %.4f (%s to go)" % (name, elapsed, todo[0] - 1)) for action in self.ss_actions: self.threadPool.execute(_sync_action, _entry, *action) todo_event.wait() self.last_sync_ts = time.time() def sync_locked(self): with self.operation_lock: self.sync() def SyncBlocking(self, request, context): self.sync_locked() return common_pb2.Empty() def SyncAsync(self, request, context): self.threadPool.execute(self.sync_locked) return common_pb2.Empty() def LastSynced(self, request, context): return giedo_pb2.LastSyncedResult(time=self.last_sync_ts) def SetPassword(self, request, context): with self.operation_lock: u = Es.by_name(request.user) if u is None: context.set_code(grpc.StatusCode.INVALID_ARGUMENT) context.set_details('no such user') return common_pb2.Empty() u = u.as_user() if not u.check_password(request.oldpass): context.set_code(grpc.StatusCode.INVALID_ARGUMENT) context.set_details('wrong old password') return common_pb2.Empty() u.set_password(request.newpass) self.daan.SetLDAPPassword( daan_pb2.LDAPNewPassword(user=request.user.encode(), password=request.newpass.encode())) self.cilia.send({ 'type': 'setpass', 'user': request.user, 'pass': request.newpass }) return common_pb2.Empty() def FotoadminScanUserdirs(self, request, context): resp = giedo_pb2.FotoadminUserdirs() for path, displayName in self.cilia.send( {'type': 'fotoadmin-scan-userdirs'}): resp.userdirs.append( giedo_pb2.FotoadminUserdir(path=path, displayName=displayName)) return resp def FotoadminCreateEvent(self, request, context): with self.operation_lock: try: self.daan.FotoadminCreateEvent(request) except grpc.RpcError as e: context.set_code(e.code()) context.set_details(e.details()) return common_pb2.Empty() def FotoadminMoveFotos(self, request, context): with self.operation_lock: self.daan.FotoadminMoveFotos(request) scan_fotos() ret = self.cilia.send({ 'type': 'fotoadmin-remove-moved-fotos', 'store': request.store, 'user': request.user, 'dir': request.dir }) if 'success' not in ret: context.set_code(grpc.StatusCode.PERMISSION_DENIED) context.set_details(ret['error']) return common_pb2.Empty() def ScanFotos(self, request, context): with self.operation_lock: scan_fotos() return common_pb2.Empty() def UpdateSiteAgenda(self, request, context): with self.operation_lock: ret = update_site_agenda() if 'success' not in ret: context.set_code(grpc.StatusCode.UNKNOWN) context.set_details(ret['error']) return common_pb2.Empty() def FinGetAccount(self, request, context): return self.moniek.FinGetAccount(request) def FinGetDebitors(self, request, context): return self.moniek.FinGetDebitors(request) def FinCheckNames(self, request, context): return self.moniek.FinCheckNames(request) def FinGetGnuCashObject(self, request, context): return self.moniek.FinGetGnuCashObject(request) def FinGetYears(self, request, context): return self.moniek.FinGetYears(request) def FinGetErrors(self, request, context): return self.moniek.FinGetErrors(request)
class Giedo(WhimDaemon): def __init__(self): super(Giedo, self).__init__(settings.GIEDO_SOCKET) self.daan = WhimClient(settings.DAAN_SOCKET) self.cilia = WhimClient(settings.CILIA_SOCKET) self.mirte = mirte.get_a_manager() self.threadPool = self.mirte.get_a("threadPool") self.operation_lock = threading.Lock() self.ss_actions = ( ("postfix", self.daan, self._gen_postfix), ("mailman", self.daan, self._gen_mailman), ("forum", self.daan, self._gen_forum), ("unix", self.cilia, self._gen_unix), ("wiki", self.daan, self._gen_wiki), ) def _gen_postfix(self): return {"type": "postfix", "map": generate_postfix_map(self)} def _gen_mailman(self): return {"type": "mailman", "changes": generate_mailman_changes(self)} def _gen_wiki(self): return {"type": "wiki", "changes": generate_wiki_changes(self)} def _gen_forum(self): return {"type": "forum", "changes": generate_forum_changes(self)} def _gen_unix(self): return {"type": "unix", "map": generate_unix_map(self)} def sync(self): update_db_start = time.time() update_db(self) logging.info("update_db %s" % (time.time() - update_db_start)) todo = [len(self.ss_actions)] todo_lock = threading.Lock() todo_event = threading.Event() def _entry(name, daemon, action): start = time.time() msg = action() elapsed = time.time() - start logging.info("generate %s %s" % (name, elapsed)) start = time.time() daemon.send(msg) elapsed = time.time() - start logging.info("send %s %s" % (name, elapsed)) with todo_lock: todo[0] -= 1 if todo[0] == 0: todo_event.set() for act in self.ss_actions: self.threadPool.execute(_entry, *act) todo_event.wait() def handle(self, d): with self.operation_lock: if d["type"] == "sync": return self.sync() elif d["type"] == "setpass": u = Es.by_name(d["user"]) if u is None: return {"error": "no such user"} u = u.as_user() if not u.check_password(d["oldpass"]): return {"error": "wrong old password"} u.set_password(d["newpass"]) d2 = {"type": "setpass", "user": d["user"], "pass": d["newpass"]} self.daan.send(d2) self.cilia.send(d2) return {"success": True} elif d["type"] == "fotoadmin-move-fotos": # TODO should this block Giedo? ret = self.daan.send(d) if "success" not in ret: return ret return self.cilia.send({"type": "fotoadmin-remove-moved-fotos", "user": d["user"], "dir": d["dir"]}) elif d["type"] == "openvpn_create": # XXX hoeft niet onder de operation_lock u = Es.by_name(d["user"]) if u is None: return {"error": "no such user"} u = u.as_user() if d["want"] == "exe": create_openvpn_installer(self, u) else: create_openvpn_zip(self, u) elif d["type"] == "update-site-agenda": return update_site_agenda(self) elif d["type"] in ["update-knsite", "update-knfotos", "fotoadmin-create-event"]: return self.daan.send(d) else: print "Unknown command: %s" % d["type"]
class Giedo(WhimDaemon): def __init__(self): super(Giedo, self).__init__(settings.GIEDO_SOCKET) self.daan = WhimClient(settings.DAAN_SOCKET) self.cilia = WhimClient(settings.CILIA_SOCKET) self.mirte = mirte.get_a_manager() self.threadPool = self.mirte.get_a('threadPool') self.operation_lock = threading.Lock() self.push_changes_event = threading.Event() self.threadPool.execute(self.run_change_pusher) if default_storage.exists("villanet.pem"): self.villanet_key = RSA.load_pub_key(default_storage.path( "villanet.pem")) self.ss_actions = ( ('postfix', self.daan, self._gen_postfix), ('mailman', self.daan, self._gen_mailman), ('forum', self.daan, self._gen_forum), ('unix', self.cilia, self._gen_unix), ('wiki', self.daan, self._gen_wiki)) self.push_changes_event.set() def _gen_postfix(self): return {'type': 'postfix', 'map': generate_postfix_map(self)} def _gen_mailman(self): return {'type': 'mailman', 'changes': generate_mailman_changes( self)} def _gen_wiki(self): return {'type': 'wiki', 'changes': generate_wiki_changes(self)} def _gen_forum(self): return {'type': 'forum', 'changes': generate_forum_changes(self)} def _gen_unix(self): return {'type': 'unix', 'map': generate_unix_map(self)} def _sync_villanet(self): ret = self.villanet_request({'action': 'listUsers'}) if not ret[0]: return ret = json.loads(ret[1]) users = dict() ulut = dict() for u in Es.users(): ulut[u._id] = str(u.name) member_relations_grouped = dict() for rel in Es.query_relations(_with=Es.by_name('leden'), until=now()): if rel['who'] not in member_relations_grouped: member_relations_grouped[rel['who']] = [] member_relations_grouped[rel['who']].append(rel) for user_id, relations in member_relations_grouped.items(): latest = max(relations, key=lambda x: x['until']) users[ulut[user_id]] = latest['until'].strftime('%Y-%m-%d') vn = set(ret.keys()) kn = set(users.keys()) dt_max = settings.DT_MAX.strftime('%Y-%m-%d') for name in kn - vn: data = { 'username': name, 'password': self.villanet_encrypt_password( pseudo_randstr(16)), } if users[name] != dt_max: data['till'] = users[name] pc = Es.PushChange({'system': 'villanet', 'action': 'addUser', 'data': data}) pc.save() for name in vn - kn: logging.info("Stray user %s" % name) for name in vn & kn: remote = (ret[name]['till'][:10] if ret[name]['till'] is not None else '') local = users[name] if users[name] != dt_max else '' if remote != local: pc = Es.PushChange({'system': 'villanet', 'action': 'changeUser', 'data': { 'username': name, 'till': local }}) pc.save() self.push_changes_event.set() def sync(self): update_db_start = time.time() update_db(self) logging.info("update_db %s" % (time.time() - update_db_start)) todo = [len(self.ss_actions)] todo_lock = threading.Lock() todo_event = threading.Event() def _sync_action(func, *args): func(*args) with todo_lock: todo[0] -= 1 if todo[0] == 0: todo_event.set() def _entry(name, daemon, action): start = time.time() msg = action() elapsed = time.time() - start logging.info("generate %s %s" % (name, elapsed)) start = time.time() daemon.send(msg) elapsed = time.time() - start logging.info("send %s %s" % (name, elapsed)) todo[0] += 1 self.threadPool.execute(_sync_action, self._sync_villanet) for act in self.ss_actions: self.threadPool.execute(_sync_action, _entry, *act) todo_event.wait() def handle(self, d): with self.operation_lock: if d['type'] == 'sync': return self.sync() elif d['type'] == 'setpass': u = Es.by_name(d['user']) if u is None: return {'error': 'no such user'} u = u.as_user() if not u.check_password(d['oldpass']): return {'error': 'wrong old password'} u.set_password(d['newpass']) d2 = {'type': 'setpass', 'user': d['user'], 'pass': d['newpass']} self.daan.send(d2) self.cilia.send(d2) return {'success': True} elif d['type'] == 'set-villanet-password': u = Es.by_name(d['user']) if u is None: return {'error': 'no such user'} u = u.as_user() if not u.check_password(d['oldpass']): return {'error': 'wrong current password'} pc = Es.PushChange({'system': 'villanet', 'action': 'changeUser', 'data': { 'username': d['user'], 'password': self.villanet_encrypt_password(d['newpass']) }}) pc.save() self.push_changes_event.set() return {'success': True} elif d['type'] == 'fotoadmin-move-fotos': # TODO should this block Giedo? ret = self.daan.send(d) if 'success' not in ret: return ret return self.cilia.send({ 'type': 'fotoadmin-remove-moved-fotos', 'user': d['user'], 'dir': d['dir']}) elif d['type'] == 'openvpn_create': # XXX hoeft niet onder de operation_lock u = Es.by_name(d['user']) if u is None: return {'error': 'no such user'} u = u.as_user() if d['want'] == 'exe': create_openvpn_installer(self, u) else: create_openvpn_zip(self, u) elif d['type'] == 'update-site-agenda': return update_site_agenda(self) elif d['type'] in ['update-knsite', 'update-knfotos', 'fotoadmin-create-event']: return self.daan.send(d) else: logging.warn("Unknown command: %s" % d['type']) def villanet_encrypt_password(self, password): ctx = self.villanet_key.public_encrypt(password, RSA.pkcs1_padding) return ctx.encode('base64').replace("\n", '') def run_change_pusher(self): while True: self.push_changes_event.wait() self.push_changes_event.clear() for pc in Es.pcol.find(): if pc['system'] == 'villanet': if settings.VILLANET_SECRET_API_KEY == '': logging.warn("VILLANET_SECRET_API_KEY not set") continue params = pc['data'] params['action'] = pc['action'] ret = self.villanet_request(params) if not ret[0]: continue else: logging.warn("Unknown PushChange system %s " % pc['system']) Es.pcol.remove({'_id': pc['_id']}) def villanet_request(self, params): params['apikey'] = settings.VILLANET_SECRET_API_KEY url = "http://www.vvs-nijmegen.nl/knapi.php?"+ urlencode(params) ret = urllib2.urlopen(url).read() ret = ret.strip() if ret[:4] == 'OK: ': return (True, ret[4:]) else: return (False, ret)
class Giedo(WhimDaemon): def __init__(self): super(Giedo, self).__init__(settings.GIEDO_SOCKET) self.daan = WhimClient(settings.DAAN_SOCKET) self.cilia = WhimClient(settings.CILIA_SOCKET) self.mirte = mirte.get_a_manager() self.threadPool = self.mirte.get_a('threadPool') self.operation_lock = threading.Lock() self.ss_actions = ( ('postfix', self.daan, self._gen_postfix), ('mailman', self.daan, self._gen_mailman), ('forum', self.daan, self._gen_forum), ('unix', self.cilia, self._gen_unix), ('wiki', self.daan, self._gen_wiki)) def _gen_postfix(self): return {'type': 'postfix', 'map': generate_postfix_map(self)} def _gen_mailman(self): return {'type': 'mailman', 'changes': generate_mailman_changes( self)} def _gen_wiki(self): return {'type': 'wiki', 'changes': generate_wiki_changes(self)} def _gen_forum(self): return {'type': 'forum', 'changes': generate_forum_changes(self)} def _gen_unix(self): return {'type': 'unix', 'map': generate_unix_map(self)} def sync(self): update_db_start = time.time() update_db(self) logging.info("update_db %s" % (time.time() - update_db_start)) todo = [len(self.ss_actions)] todo_lock = threading.Lock() todo_event = threading.Event() def _entry(name, daemon, action): start = time.time() msg = action() elapsed = time.time() - start logging.info("generate %s %s" % (name, elapsed)) start = time.time() daemon.send(msg) elapsed = time.time() - start logging.info("send %s %s" % (name, elapsed)) with todo_lock: todo[0] -= 1 if todo[0] == 0: todo_event.set() for act in self.ss_actions: self.threadPool.execute(_entry, *act) todo_event.wait() def handle(self, d): with self.operation_lock: if d['type'] == 'sync': return self.sync() elif d['type'] == 'setpass': u = Es.by_name(d['user']) if u is None: return {'error': 'no such user'} u = u.as_user() if not u.check_password(d['oldpass']): return {'error': 'wrong old password'} u.set_password(d['newpass']) d2 = {'type': 'setpass', 'user': d['user'], 'pass': d['newpass']} self.daan.send(d2) self.cilia.send(d2) return {'success': True}
def get_giedo_connection(): global __GIEDO if __GIEDO is None: __GIEDO = WhimClient(settings.GIEDO_SOCKET) return __GIEDO
class Giedo(WhimDaemon): def __init__(self): super(Giedo, self).__init__(settings.GIEDO_SOCKET) self.log = logging.getLogger('giedo') self.last_sync_ts = 0 self.daan, self.cilia, self.moniek, self.hans = None, None, None, None try: self.daan = WhimClient(settings.DAAN_SOCKET) except Exception: self.log.exception("Couldn't connect to daan") try: self.cilia = WhimClient(settings.CILIA_SOCKET) except Exception: self.log.exception("Couldn't connect to cilia") try: self.moniek = WhimClient(settings.MONIEK_SOCKET) except Exception: self.log.exception("Couldn't connect to moniek") try: self.hans = WhimClient(settings.HANS_SOCKET) except Exception: self.log.exception("Couldn't connect to hans") self.mirte = mirte.get_a_manager() self.threadPool = self.mirte.get_a('threadPool') self.operation_lock = threading.Lock() self.ss_actions = (('postfix', self.daan, self._gen_postfix), ('postfix-slm', self.daan, self._gen_postfix_slm), ('mailman', self.hans, self._gen_mailman), ('unix', self.cilia, self._gen_unix), ('wiki', self.daan, self._gen_wiki), ('ldap', self.daan, self._gen_ldap), ('wolk', self.cilia, self._gen_wolk)) def pre_mainloop(self): super(Giedo, self).pre_mainloop() self.notify_systemd() def _gen_wolk(self): return {'type': 'wolk', 'changes': generate_wolk_changes(self)} def _gen_ldap(self): return {'type': 'ldap', 'changes': generate_ldap_changes(self)} def _gen_postfix_slm(self): return {'type': 'postfix-slm', 'map': generate_postfix_slm_map(self)} def _gen_postfix(self): return {'type': 'postfix', 'map': generate_postfix_map(self)} def _gen_mailman(self): return { 'type': 'maillist-apply-changes', 'changes': generate_mailman_changes(self) } def _gen_wiki(self): return {'type': 'wiki', 'changes': generate_wiki_changes(self)} def _gen_unix(self): return {'type': 'unix', 'map': generate_unix_map(self)} def sync(self): update_db_start = time.time() update_db(self) logging.info("update_db %s" % (time.time() - update_db_start)) todo = [len(self.ss_actions)] todo_lock = threading.Lock() todo_event = threading.Event() def _sync_action(func, name, daemon, action): try: func(name, daemon, action) except Exception: logging.exception('uncaught exception in %s (daemon %s)' % (name, daemon)) with todo_lock: todo[0] -= 1 if todo[0] == 0: todo_event.set() def _entry(name, daemon, action): start = time.time() msg = action() elapsed = time.time() - start logging.info("generate %s %.4f" % (name, elapsed)) start = time.time() daemon.send(msg) elapsed = time.time() - start logging.info("send %s %.4f (%s to go)" % (name, elapsed, todo[0] - 1)) for action in self.ss_actions: self.threadPool.execute(_sync_action, _entry, *action) todo_event.wait() self.last_sync_ts = time.time() def handle(self, d): if d['type'] == 'sync': with self.operation_lock: return self.sync() elif d['type'] == 'setpass': with self.operation_lock: u = Es.by_name(d['user']) if u is None: return {'error': 'no such user'} u = u.as_user() if not u.check_password(d['oldpass']): return {'error': 'wrong old password'} u.set_password(d['newpass']) d2 = { 'type': 'setpass', 'user': d['user'], 'pass': d['newpass'] } self.daan.send(d2) self.cilia.send(d2) return {'success': True} elif d['type'] == 'ping': return {'pong': True} elif d['type'] == 'fotoadmin-scan-userdirs': return self.cilia.send(d) elif d['type'] == 'fotoadmin-move-fotos': with self.operation_lock: ret = self.daan.send(d) if 'success' not in ret: return ret ret = scan_fotos() if 'success' not in ret: return ret return self.cilia.send({ 'type': 'fotoadmin-remove-moved-fotos', 'store': d['store'], 'user': d['user'], 'dir': d['dir'] }) elif d['type'] == 'fotoadmin-scan-fotos': with self.operation_lock: return scan_fotos() elif d['type'] == 'update-site-agenda': with self.operation_lock: return update_site_agenda(self) elif d['type'] in ['fotoadmin-create-event']: with self.operation_lock: return self.daan.send(d) elif d['type'] == 'last-synced?': return self.last_sync_ts elif d['type'] in ('fin-get-account', 'fin-get-debitors', 'fin-check-names', 'fin-get-gnucash-object', 'fin-get-years', 'fin-get-errors'): try: return self.moniek.send(d) except IOError as e: return {'error': 'IOError: ' + e.args[0]} elif d['type'] in ('maillist-get-moderated-lists', 'maillist-activate-moderation', 'maillist-get-moderator-cookie', 'maillist-deactivate-moderation'): return self.hans.send(d) else: logging.warn("Unknown command: %s" % d['type'])