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

versions
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
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):
name = 'ogAdmClient' # Module name
interface = None # Bound interface for OpenGnsys
@ -122,8 +103,8 @@ class ogAdmClientWorker(ServerWorker):
#servidorAdm = self.service.config.get('ogAdmClient', 'servidorAdm')
#puerto = self.service.config.get('ogAdmClient', 'puerto')
self.pathinterface = self.service.config.get('ogAdmClient', 'pathinterface')
urlMenu = self.service.config.get('ogAdmClient', 'urlMenu')
urlMsg = self.service.config.get('ogAdmClient', 'urlMsg')
#urlMenu = self.service.config.get('ogAdmClient', 'urlMenu')
#urlMsg = self.service.config.get('ogAdmClient', 'urlMsg')
logger.setLevel(loglevel)
except NoOptionError as e:
logger.error("Configuration error: {}".format(e))
@ -170,9 +151,24 @@ class ogAdmClientWorker(ServerWorker):
if (not self.tomaIPlocal()):
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()):
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):
"""
Sends OGAgent stopping notification to OpenGnsys server
@ -303,7 +299,11 @@ with open (subprocs_log, 'ab') as fd: ## TODO improve this logging
@check_secret
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):
# 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)
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):
logger.debug (__name__)
interface = '{}/getIpAddress'.format (self.pathinterface)
try:
self.IPlocal = interfaceAdmin (interface);
self.IPlocal = self.interfaceAdmin ('getIpAddress');
logger.info (self.IPlocal)
except Exception as e:
logger.error (e)
@ -326,7 +338,7 @@ with open (subprocs_log, 'ab') as fd: ## TODO improve this logging
return True
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))
return (parametroscfg)
@ -346,11 +358,64 @@ with open (subprocs_log, 'ab') as fd: ## TODO improve this logging
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):
cfg = self.LeeConfiguracion()
res = self.enviaMensajeServidor ('InclusionCliente', { 'cfg': cfg })
logger.debug ('res ({})'.format (res))
## RESPUESTA_InclusionCliente
if (not res or 0 == res['res']) :
logger.error ('Ha ocurrido algún problema en el proceso de inclusión del cliente')
return False
@ -368,11 +433,46 @@ with open (subprocs_log, 'ab') as fd: ## TODO improve this logging
return True
def process_RESPUESTA_AutoexecCliente(self, path, get_params, post_params, server):
logger.warn('in process_RESPUESTA_AutoexecCliente')
def cuestionCache(self):
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):
logger.warn('in process_RESPUESTA_InclusionCliente')
def autoexecCliente(self):
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):
logger.warn('in process_NoComandosPtes')