refs #524 implement autoexecCliente() and its companion ejecutaArchivo()

pull/6/head
Natalia Serrano 2024-07-26 10:45:02 +02:00
parent 886bf5e616
commit 5f7ca5be15
1 changed files with 130 additions and 30 deletions

View File

@ -73,25 +73,6 @@ def check_secret(fnc):
return wrapper return wrapper
def interfaceAdmin (exe, parametros=[]):
devel_bash_prefix = '''
PATH=/opt/opengnsys/scripts/:$PATH;
for I in /opt/opengnsys/lib/engine/bin/*.lib; do source $I; done;
for i in $(declare -F |cut -f3 -d" "); do export -f $i; done;
'''
if 'nati' == os.environ['USER'] or 'nati' == os.environ['SUDO_USER']: ## DO NOT COMMIT
devel_bash_prefix = '''
PATH=/home/nati/Downloads/work/opengnsys/opengnsys/client/shared/scripts:$PATH;
for I in /home/nati/Downloads/work/opengnsys/opengnsys/client/engine/*.lib; do source $I; done;
for i in $(declare -F |cut -f3 -d" "); do export -f $i; done;
'''
if parametros:
proc = ['bash', '-c', '{} {} {}'.format (devel_bash_prefix, exe, ' '.join (parametros))]
else:
proc = ['bash', '-c', '{} {}'.format (devel_bash_prefix, exe)]
logger.debug ('subprocess.run ("{}", capture_output=True)'.format (proc))
return subprocess.run (proc, capture_output=True).stdout.strip().decode ('utf-8')
class ogAdmClientWorker(ServerWorker): class ogAdmClientWorker(ServerWorker):
name = 'ogAdmClient' # Module name name = 'ogAdmClient' # Module name
interface = None # Bound interface for OpenGnsys interface = None # Bound interface for OpenGnsys
@ -122,8 +103,8 @@ class ogAdmClientWorker(ServerWorker):
#servidorAdm = self.service.config.get('ogAdmClient', 'servidorAdm') #servidorAdm = self.service.config.get('ogAdmClient', 'servidorAdm')
#puerto = self.service.config.get('ogAdmClient', 'puerto') #puerto = self.service.config.get('ogAdmClient', 'puerto')
self.pathinterface = self.service.config.get('ogAdmClient', 'pathinterface') self.pathinterface = self.service.config.get('ogAdmClient', 'pathinterface')
urlMenu = self.service.config.get('ogAdmClient', 'urlMenu') #urlMenu = self.service.config.get('ogAdmClient', 'urlMenu')
urlMsg = self.service.config.get('ogAdmClient', 'urlMsg') #urlMsg = self.service.config.get('ogAdmClient', 'urlMsg')
logger.setLevel(loglevel) logger.setLevel(loglevel)
except NoOptionError as e: except NoOptionError as e:
logger.error("Configuration error: {}".format(e)) logger.error("Configuration error: {}".format(e))
@ -170,9 +151,24 @@ class ogAdmClientWorker(ServerWorker):
if (not self.tomaIPlocal()): if (not self.tomaIPlocal()):
raise Exception ('Se han generado errores. No se puede continuar la ejecución de este módulo') raise Exception ('Se han generado errores. No se puede continuar la ejecución de este módulo')
logger.info ('Inicio de sesion')
logger.info ('Abriendo sesión en el servidor de Administración')
if (not self.inclusionCliente()): if (not self.inclusionCliente()):
raise Exception ('Se han generado errores. No se puede continuar la ejecución de este módulo') raise Exception ('Se han generado errores. No se puede continuar la ejecución de este módulo')
logger.info ('Cliente iniciado')
logger.info ('Procesando caché')
if (not self.cuestionCache()):
raise Exception ('Se han generado errores. No se puede continuar la ejecución de este módulo')
if (self.idproautoexec > 0):
logger.info ('Ejecución de archivo Autoexec')
if (not self.autoexecCliente()):
raise Exception ('Se han generado errores. No se puede continuar la ejecución de este módulo')
#logger.info ('Procesa comandos pendientes')
#logger.info ('Acciones pendientes procesadas')
def onDeactivation(self): def onDeactivation(self):
""" """
Sends OGAgent stopping notification to OpenGnsys server Sends OGAgent stopping notification to OpenGnsys server
@ -303,7 +299,11 @@ with open (subprocs_log, 'ab') as fd: ## TODO improve this logging
@check_secret @check_secret
def process_popup(self, path, get_params, post_params, server): def process_popup(self, path, get_params, post_params, server):
logger.warn('in process_popup, should not happen') logger.debug('in process_popup, path "{}" get_params "{}" post_params "{}" server "{}"'.format(path, get_params, post_params, server))
logger.debug('type(post_params) "{}"'.format(type(post_params)))
## in process_popup, should not happen, path "[]" get_params "{}" post_params "{'title': 'mi titulo', 'message': 'mi mensaje'}" server "<opengnsys.httpserver.HTTPServerHandler object at 0x7fa788cb8fa0>"
## type(post_params) "<class 'dict'>"
return {'debug':'test'}
#def process_client_popup(self, params): #def process_client_popup(self, params):
# logger.warn('in process_client_popup') # logger.warn('in process_client_popup')
@ -313,11 +313,23 @@ with open (subprocs_log, 'ab') as fd: ## TODO improve this logging
## process_client_* are invoked from opengnsys/service.py:123 "v.processClientMessage(message, json.loads(data))" (via opengnsys/workers/server_worker.py) ## process_client_* are invoked from opengnsys/service.py:123 "v.processClientMessage(message, json.loads(data))" (via opengnsys/workers/server_worker.py)
def interfaceAdmin (self, method, parametros=[]):
exe = '{}/{}'.format (self.pathinterface, method)
devel_bash_prefix = '''
PATH=/opt/opengnsys/scripts/:$PATH;
for I in /opt/opengnsys/lib/engine/bin/*.lib; do source $I; done;
for i in $(declare -F |cut -f3 -d" "); do export -f $i; done;
'''
if parametros:
proc = ['bash', '-c', '{} {} {}'.format (devel_bash_prefix, exe, ' '.join (parametros))]
else:
proc = ['bash', '-c', '{} {}'.format (devel_bash_prefix, exe)]
logger.debug ('subprocess.run ("{}", capture_output=True)'.format (proc))
return subprocess.run (proc, capture_output=True).stdout.strip().decode ('utf-8')
def tomaIPlocal(self): def tomaIPlocal(self):
logger.debug (__name__)
interface = '{}/getIpAddress'.format (self.pathinterface)
try: try:
self.IPlocal = interfaceAdmin (interface); self.IPlocal = self.interfaceAdmin ('getIpAddress');
logger.info (self.IPlocal) logger.info (self.IPlocal)
except Exception as e: except Exception as e:
logger.error (e) logger.error (e)
@ -326,7 +338,7 @@ with open (subprocs_log, 'ab') as fd: ## TODO improve this logging
return True return True
def LeeConfiguracion(self): def LeeConfiguracion(self):
parametroscfg = interfaceAdmin ('{}/getConfiguration'.format (self.pathinterface)) ## Configuración de los Sistemas Operativos del cliente parametroscfg = self.interfaceAdmin ('getConfiguration') ## Configuración de los Sistemas Operativos del cliente
logger.debug ('parametroscfg ({})'.format (parametroscfg)) logger.debug ('parametroscfg ({})'.format (parametroscfg))
return (parametroscfg) return (parametroscfg)
@ -346,11 +358,64 @@ with open (subprocs_log, 'ab') as fd: ## TODO improve this logging
return res return res
def ejecutaArchivo(self,fn):
logger.debug ('fn ({})'.format (fn))
## TODO hay que entender este codigo (ogAdmClient.c:2111) para poder traducirlo a python
## en una funcion "ejecutaArchivo" esperaba que se ejecutara un archivo, pero solo hay una llamada a gestionaTrama() que no sé dónde termina
#char* buffer,*lineas[MAXIMAS_LINEAS];
#int i,numlin;
#char modulo[] = "ejecutaArchivo()";
#buffer = leeArchivo(filecmd);
#if (buffer):
# numlin = splitCadena(lineas, buffer, '@');
# initParametros(ptrTrama,0);
# for (i = 0; i < numlin; i++) {
# if(strlen(lineas[i])>0){
# strcpy(ptrTrama->parametros,lineas[i]);
# if(!gestionaTrama(ptrTrama)){ // Análisis de la trama
# errorLog(modulo,39,FALSE);
# //return(FALSE);
# }
# }
# }
#liberaMemoria(buffer);
## voy a probar algo, asumiendo que en el archivo no hay simplemente un bash, sino secuencias de parametros tal que "nfn=Funcion\rparam1=foo\rparam2=bar"
buffer = subprocess.run (['cat', fn], capture_output=True).stdout.strip().decode ('utf-8')
logger.debug ('buffer ({})'.format (buffer.replace('\r', '\\r'))) ## sustituimos \r para que el log tenga sentido
if buffer:
for l in buffer.split('@'):
if not len(l): continue
logger.debug ('line ({})'.format (l))
## en este punto, una opción sería pegar un curl a localhost, pero también podemos parsear los parámetros y llamar localmente a la función que sea:
post_params = {}
for param in l.split("\r"):
k, v = param.split('=')
post_params[k] = v
logger.debug ('post_params "{}"'.format (post_params))
func_name = post_params.pop ('nfn', None)
if func_name is None:
logger.error ('Ha ocurrido algún problema al procesar la trama recibida')
break
func = getattr (self, 'process_' + func_name)
## func ya es una referencia a self.func, de modo que ahora no hay que hacer self.func(...) ni tampoco func(self, ...)
logger.debug ('calling function "{}" with post_params "{}"'.format (func_name, post_params))
output = func ([], {}, post_params, None)
logger.debug ('output "{}"'.format (output))
if not output:
logger.error ('Ha ocurrido algún problema al procesar la trama recibida')
break
def inclusionCliente(self): def inclusionCliente(self):
cfg = self.LeeConfiguracion() cfg = self.LeeConfiguracion()
res = self.enviaMensajeServidor ('InclusionCliente', { 'cfg': cfg }) res = self.enviaMensajeServidor ('InclusionCliente', { 'cfg': cfg })
logger.debug ('res ({})'.format (res)) logger.debug ('res ({})'.format (res))
## RESPUESTA_InclusionCliente
if (not res or 0 == res['res']) : if (not res or 0 == res['res']) :
logger.error ('Ha ocurrido algún problema en el proceso de inclusión del cliente') logger.error ('Ha ocurrido algún problema en el proceso de inclusión del cliente')
return False return False
@ -368,11 +433,46 @@ with open (subprocs_log, 'ab') as fd: ## TODO improve this logging
return True return True
def process_RESPUESTA_AutoexecCliente(self, path, get_params, post_params, server): def cuestionCache(self):
logger.warn('in process_RESPUESTA_AutoexecCliente') return True ## ogAdmClient.c:425
#>>>>>>>>>>>>>>>>>>>>>>>>>>
#try:
# self.interfaceAdmin ('procesaCache', [ self.cache ]);
#except Exception as e:
# logger.error ('Ha habido algún problerma al procesar la caché')
# return False
#
#return True
def process_RESPUESTA_InclusionCliente(self, path, get_params, post_params, server): def autoexecCliente(self):
logger.warn('in process_RESPUESTA_InclusionCliente') res = self.enviaMensajeServidor ('AutoexecCliente', { 'exe': self.idproautoexec })
logger.debug ('res ({})'.format (res))
if (not res):
logger.error ('Ha ocurrido algún problema al enviar una petición de comandos o tareas pendientes al Servidor de Administración')
logger.error ('Ha ocurrido algún problema al recibir una petición de comandos o tareas pendientes desde el Servidor de Administración')
return False
## RESPUESTA_AutoexecCliente
if (not res or 0 == res['res']) :
logger.error ('Ha ocurrido algún problema al procesar la trama recibida')
return False
logger.info (res)
res = self.enviaMensajeServidor ('enviaArchivo', { 'nfl': res['nfl'] })
if (not res):
logger.error ('Ha ocurrido algún problema al enviar una petición de comandos o tareas pendientes al Servidor de Administración')
logger.error ('Ha ocurrido algún problema al recibir un archivo por la red')
return False
fileautoexec = '/tmp/_autoexec_{}'.format (self.IPlocal)
logger.debug ('fileautoexec ({})'.format (fileautoexec))
with open (fileautoexec, 'w') as fd:
fd.write (res['contents'])
self.ejecutaArchivo (fileautoexec);
return True
def process_NoComandosPtes(self, path, get_params, post_params, server): def process_NoComandosPtes(self, path, get_params, post_params, server):
logger.warn('in process_NoComandosPtes') logger.warn('in process_NoComandosPtes')