#!/usr/bin/python3 # -*- coding: utf-8 -*- # Author: İsmail BAŞARAN # Author: Volkan Şahin import configparser import os import queue import signal import subprocess import sys import threading import time from base.system.system import System from base.Scope import Scope from base.config.ConfigManager import ConfigManager from base.database.AhenkDbService import AhenkDbService from base.deamon.BaseDeamon import BaseDaemon from base.event.EventManager import EventManager from base.execution.ExecutionManager import ExecutionManager from base.logger.AhenkLogger import Logger from base.messaging.MessageResponseQueue import MessageResponseQueue from base.messaging.Messager import Messager from base.messaging.Messaging import Messaging from base.plugin.plugin_manager_factory import PluginManagerFactory from base.registration.Registration import Registration from base.scheduler.scheduler_factory import SchedulerFactory from base.task.TaskManager import TaskManager pidfilePath = '/var/run/ahenk.pid' configFilePath = '/etc/ahenk/ahenk.conf' class AhenkDeamon(BaseDaemon): """docstring for AhenkDeamon""" def reload(self): # reload service here pass def init_logger(self): logger = Logger() logger.info('[AhenkDeamon] Log was set') Scope.getInstance().setLogger(logger) return logger def init_config_manager(self, configFilePath, configfileFolderPath): configManager = ConfigManager(configFilePath, configfileFolderPath) config = configManager.read() Scope.getInstance().setConfigurationManager(config) return config def init_scheduler(self): scheduler_ins = SchedulerFactory.get_intstance() scheduler_ins.initialize() Scope.getInstance().set_scheduler(scheduler_ins) sc_thread = threading.Thread(target=scheduler_ins.run) sc_thread.setDaemon(True) sc_thread.start() return scheduler_ins def init_event_manager(self): eventManager = EventManager() Scope.getInstance().setEventManager(eventManager) return eventManager def init_ahenk_db(self): db_service = AhenkDbService() db_service.connect() db_service.initialize_table() Scope.getInstance().setDbService(db_service) return db_service def init_messaging(self): messageManager = Messaging() Scope.getInstance().setMessageManager(messageManager) return messageManager def init_plugin_manager(self): pluginManager = PluginManagerFactory.get_instance() pluginManager.loadPlugins() Scope.getInstance().setPluginManager(pluginManager) return pluginManager def init_task_manager(self): taskManager = TaskManager() Scope.getInstance().setTaskManager(taskManager) return taskManager def init_registration(self): registration = Registration() Scope.getInstance().setRegistration(registration) return registration def init_execution_manager(self): execution_manager = ExecutionManager() Scope.getInstance().setExecutionManager(execution_manager) return execution_manager def init_messager(self): messenger = Messager() messenger_thread = threading.Thread(target=messenger.connect_to_server) messenger_thread.start() while messenger.is_connected() is False: time.sleep(1) time.sleep(5) Scope.getInstance().setMessager(messenger) return messenger def init_message_response_queue(self): responseQueue = queue.Queue() messageResponseQueue = MessageResponseQueue(responseQueue) messageResponseQueue.setDaemon(True) messageResponseQueue.start() Scope.getInstance().setResponseQueue(responseQueue) return responseQueue def check_registration(self): # TODO get number of attemption max_attemp_number = 50 logger = Scope.getInstance().getLogger() try: while Scope.getInstance().getRegistration().is_registered() is False: max_attemp_number -= 1 logger.debug('[AhenkDeamon] Ahenk is not registered. Attempting for registration') Scope.getInstance().getRegistration().registration_request() if max_attemp_number < 0: logger.warning('[AhenkDeamon] Number of Attempting for registration is over') self.registration_failed() break except Exception as e: logger.error('[AhenkDeamon] Registration failed. Error message: {}'.format(str(e))) def registration_failed(self): # TODO registration fail protocol implement pass def reload_plugins(self): Scope.getInstance().getPluginManager().reloadPlugins() def reload_configuration(self): # Not implemented yet pass def reload_messaging(self): # Not implemented yet pass def reload_logger(self): # Not implemented yet pass def update_plugin_manager(self): # TODO destroy plugin manager here self.init_plugin_manager() def run(self): print('Ahenk running...') globalscope = Scope() globalscope.setInstance(globalscope) configfileFolderPath = '/etc/ahenk/config.d/' # configuration manager must be first load self.init_config_manager(configFilePath, configfileFolderPath) # Logger must be second logger = self.init_logger() self.init_event_manager() logger.info('[AhenkDeamon] Event Manager was set') self.init_ahenk_db() logger.info('[AhenkDeamon] DataBase Service was set') self.init_messaging() logger.info('[AhenkDeamon] Message Manager was set') self.init_plugin_manager() logger.info('[AhenkDeamon] Plugin Manager was set') self.init_task_manager() logger.info('[AhenkDeamon] Task Manager was set') self.init_registration() logger.info('[AhenkDeamon] Registration was set') self.init_execution_manager() logger.info('[AhenkDeamon] Execution Manager was set') self.check_registration() logger.info('[AhenkDeamon] Ahenk is registered') messager = self.init_messager() logger.info('[AhenkDeamon] Messager was set') self.init_message_response_queue() # if registration.is_ldap_registered() is False: # logger.debug('[AhenkDeamon] Attempting to registering ldap') # registration.ldap_registration_request() #TODO work on message logger.info('[AhenkDeamon] LDAP registration of Ahenk is completed') # TODO############### cnfg = configparser.ConfigParser() cnfg.add_section('PID') cnfg.set('PID', 'pid_number', str(os.getpid())) with open(pidfilePath, 'w') as config_file: cnfg.write(config_file) # TODO############## try: signal.signal(signal.SIGALRM, self.signal_handler) logger.info('[AhenkDeamon] Signal handler is set up') except Exception as e: logger.error('[AhenkDeamon] Signal handler could not set up. Error Message: {} '.format(str(e))) messager.send_direct_message('test') while True: if messager.is_connected() is False: logger.debug('reconnecting') Scope.getInstance().getLogger().warning('[AhenkDeamon] Connection is lost. Ahenk is trying for reconnection') messager = self.init_messager() time.sleep(1) def signal_handler(self, num, stack): # TODO###### config = configparser.ConfigParser() config._interpolation = configparser.ExtendedInterpolation() config.read(pidfilePath) event = config.get('PID', 'event') # TODO###### params = event.split() scope = Scope().getInstance() logger = scope.getLogger() plugin_manager = scope.getPluginManager() message_manager = scope.getMessageManager() messenger = scope.getMessager() logger.debug('[AhenkDeamon] Signal handled') if 'login' == str(params[0]): logger.debug('[AhenkDeamon] Signal is :{}'.format(str(params[0]))) login_message = message_manager.login_msg(params[1]) messenger.send_direct_message(login_message) get_policy_message = message_manager.policy_request_msg(params[1]) messenger.send_direct_message(get_policy_message) logger.debug('[AhenkDeamon] login event is handled for user:' + params[1]) elif 'logout' == str(params[0]): logger.debug('[AhenkDeamon] Signal is {}'.format(str(params[0]))) message = message_manager.logout_msg(params[1]) messenger.send_direct_message(message) plugin_manager.process_safe_mode(str(params[1])) logger.debug('[AhenkDeamon] logout event is handled for user:' + params[1]) elif 'exit' == str(params[0]): logger.debug('[AhenkDeamon] Signal is {}'.format(str(params[0]))) messenger.disconnect() # TODO kill thread subprocess.Popen('kill -9 ' + get_pid_number(), shell=True) print('stopping ahenk') else: logger.error('[AhenkDeamon] Unknown command error. Command:' + params[0]) logger.debug('[AhenkDeamon] Processing of handled event is completed') def get_pid_number(): config = configparser.ConfigParser() config._interpolation = configparser.ExtendedInterpolation() config.read(pidfilePath) return config.get('PID', 'pid_number') def set_event(event_param): config = configparser.ConfigParser() config._interpolation = configparser.ExtendedInterpolation() config.read(pidfilePath) config.set('PID', 'event', event_param) with open(pidfilePath, 'w') as conf_file: config.write(conf_file) def clean(): try: config = configparser.ConfigParser() config._interpolation = configparser.ExtendedInterpolation() config.read(configFilePath) db_path = config.get('BASE', 'dbPath') os.remove(db_path) config.set('BASE', 'uid', '') config.set('BASE', 'password', '') with open(configFilePath, 'w') as file: config.write(file) file.close() except Exception as e: print('Error while running clean command. Error Message {}'.format(str(e))) if __name__ == '__main__': ahenkdaemon = AhenkDeamon(pidfilePath) try: if len(sys.argv) == 2: if sys.argv[1] == 'start': print('starting') ahenkdaemon.run() elif sys.argv[1] == 'stop': print('stopping') # TODO ahenkdaemon.stop() elif sys.argv[1] == 'restart': # TODO print('restarting') ahenkdaemon.restart() elif sys.argv[1] == 'status': # TODO print('status') elif sys.argv[1] == 'clean': print('cleaning') clean() else: print('Unknown command. Usage : %s start|stop|restart|status' % sys.argv[0]) sys.exit(2) elif len(sys.argv) == 3: if sys.argv[1] == 'login' or sys.argv[1] == 'logout': print('event:' + str(sys.argv[1])) set_event(str(sys.argv[1]) + ' ' + sys.argv[2]) os.kill(int(get_pid_number()), signal.SIGALRM) else: print('Unknown command. Usage : %s start|stop|restart|status' % sys.argv[0]) sys.exit(2) sys.exit(0) else: print('Usage : %s start|stop|restart|status' % sys.argv[0]) sys.exit(2) except(KeyboardInterrupt, SystemExit): if str(os.getpid()) == get_pid_number(): set_event('exit true') os.kill(int(get_pid_number()), signal.SIGALRM)