refs #702 implement CrearImagen()
parent
178d724ec0
commit
2dc264a187
|
@ -3,6 +3,7 @@ import os
|
|||
import logging
|
||||
import json
|
||||
import subprocess
|
||||
import base64
|
||||
|
||||
## FLASK_APP=/path/to/ogcore-mock.py FLASK_ENV=development FLASK_RUN_CERT=adhoc sudo --preserve-env flask run --host 192.168.1.249 --port 443
|
||||
|
||||
|
@ -14,8 +15,7 @@ logging.basicConfig(level=logging.INFO)
|
|||
|
||||
@app.route('/opengnsys/rest/ogagent/<cucu>', methods=['POST'])
|
||||
def og_agent(cucu):
|
||||
c = request
|
||||
logging.info(f"{request.get_json()}")
|
||||
logging.info(f'{request.get_json()}')
|
||||
return jsonify({})
|
||||
|
||||
|
||||
|
@ -24,20 +24,19 @@ def og_agent(cucu):
|
|||
|
||||
@app.route('/opengnsys/rest/__ogAdmClient/InclusionCliente', methods=['POST'])
|
||||
def inclusion_cliente():
|
||||
c = request
|
||||
logging.info(f"{request.get_json()}")
|
||||
logging.info(f'{request.get_json()}')
|
||||
#procesoInclusionCliente() or { return (jsonify { 'res': 0 }) }
|
||||
j = request.get_json(force=True)
|
||||
iph = j['iph'] ## Toma ip
|
||||
cfg = j['cfg'] ## Toma configuracion
|
||||
logging.info(f"iph ({iph}) cfg ({cfg})")
|
||||
logging.info(f'iph ({iph}) cfg ({cfg})')
|
||||
|
||||
# dbi->query (sprintf "SELECT ordenadores.*,aulas.idaula,centros.idcentro FROM ordenadores INNER JOIN aulas ON aulas.idaula=ordenadores.idaula INNER JOIN centros ON centros.idcentro=aulas.idcentro WHERE ordenadores.ip = '%s'", iph);
|
||||
# if (!dbi_result_next_row(result)) { log_error ('client does not exist in database') }
|
||||
# log_debug (sprintf 'Client %s requesting inclusion', iph);
|
||||
|
||||
idordenador = 42 #dbi_result_get_uint(result, "idordenador")
|
||||
nombreordenador = "hal9000" #dbi_result_get_string(result, "nombreordenador");
|
||||
nombreordenador = 'hal9000' #dbi_result_get_string(result, "nombreordenador");
|
||||
cache = 42 #dbi_result_get_uint(result, "cache");
|
||||
idproautoexec = 42 #dbi_result_get_uint(result, "idproautoexec");
|
||||
idaula = 42 #dbi_result_get_uint(result, "idaula");
|
||||
|
@ -81,19 +80,18 @@ def _recorreProcedimientos(parametros, fileexe, idp):
|
|||
|
||||
@app.route('/opengnsys/rest/__ogAdmClient/AutoexecCliente', methods=['POST'])
|
||||
def autoexec_client():
|
||||
c = request
|
||||
logging.info(f"{request.get_json()}")
|
||||
logging.info(f'{request.get_json()}')
|
||||
j = request.get_json(force=True)
|
||||
iph = j['iph'] ## Toma dirección IP del cliente
|
||||
exe = j['exe'] ## Toma identificador del procedimiento inicial
|
||||
logging.info(f"iph ({iph}) exe ({exe})")
|
||||
logging.info(f'iph ({iph}) exe ({exe})')
|
||||
|
||||
fileautoexec = '/tmp/Sautoexec-{}'.format(iph)
|
||||
logging.info ("fileautoexec ({})".format (fileautoexec));
|
||||
logging.info ('fileautoexec ({})'.format (fileautoexec));
|
||||
try:
|
||||
fileexe = open (fileautoexec, 'w')
|
||||
except Exception as e:
|
||||
logging.error ("cannot create temporary file: {}".format (e))
|
||||
logging.error ('cannot create temporary file: {}'.format (e))
|
||||
return jsonify({})
|
||||
|
||||
if (_recorreProcedimientos ('', fileexe, exe)):
|
||||
|
@ -106,13 +104,14 @@ def autoexec_client():
|
|||
|
||||
@app.route('/opengnsys/rest/__ogAdmClient/enviaArchivo', methods=['POST'])
|
||||
def envia_archivo():
|
||||
c = request
|
||||
logging.info(f"{request.get_json()}")
|
||||
logging.info(f'{request.get_json()}')
|
||||
j = request.get_json(force=True)
|
||||
nfl = j['nfl'] ## Toma nombre completo del archivo
|
||||
logging.info(f"nfl ({nfl})")
|
||||
logging.info(f'nfl ({nfl})')
|
||||
|
||||
return jsonify({'contents': subprocess.run (['cat', nfl], capture_output=True).stdout.decode('utf-8')})
|
||||
contents = subprocess.run (['cat', nfl], capture_output=True).stdout
|
||||
b64 = base64.b64encode (contents).decode ('utf-8')
|
||||
return jsonify({'contents': b64})
|
||||
|
||||
def clienteExistente(iph):
|
||||
## esto queda totalmente del lado del servidor, no lo implemento en python
|
||||
|
@ -132,17 +131,16 @@ def buscaComandos(ido):
|
|||
|
||||
@app.route('/opengnsys/rest/__ogAdmClient/ComandosPendientes', methods=['POST'])
|
||||
def comandos_pendientes():
|
||||
c = request
|
||||
logging.info(f"{request.get_json()}")
|
||||
logging.info(f'{request.get_json()}')
|
||||
j = request.get_json(force=True)
|
||||
iph = j['iph'] ## Toma dirección IP
|
||||
ido = j['ido'] ## Toma identificador del ordenador
|
||||
logging.info(f"iph ({iph}) ido ({ido})")
|
||||
logging.info(f'iph ({iph}) ido ({ido})')
|
||||
|
||||
idx = clienteExistente(iph) ## Busca índice del cliente
|
||||
if not idx:
|
||||
## que devuelvo?? pongamos un 404...
|
||||
abort(404, "Client does not exist")
|
||||
abort(404, 'Client does not exist')
|
||||
|
||||
param = buscaComandos(ido) ## Existen comandos pendientes, buscamos solo uno
|
||||
if param is None:
|
||||
|
@ -154,44 +152,50 @@ def comandos_pendientes():
|
|||
|
||||
@app.route('/opengnsys/rest/__ogAdmClient/DisponibilidadComandos', methods=['POST'])
|
||||
def disponibilidad_comandos():
|
||||
c = request
|
||||
logging.info(f"{request.get_json()}")
|
||||
logging.info(f'{request.get_json()}')
|
||||
j = request.get_json(force=True)
|
||||
iph = j['iph']
|
||||
tpc = j['tpc']
|
||||
logging.info(f"iph ({iph}) tpc ({tpc})")
|
||||
logging.info(f'iph ({iph}) tpc ({tpc})')
|
||||
|
||||
idx = clienteExistente(iph) ## Busca índice del cliente
|
||||
if not idx:
|
||||
## que devuelvo?? pongamos un 404...
|
||||
abort(404, "Client does not exist")
|
||||
abort(404, 'Client does not exist')
|
||||
|
||||
#strcpy(tbsockets[idx].estado, tpc); ## esto queda totalmente del lado del servidor, no lo implemento en python
|
||||
|
||||
return jsonify({})
|
||||
|
||||
@app.route('/opengnsys/rest/__ogAdmClient/<cucu>', methods=['POST'])
|
||||
def cucu(cucu):
|
||||
c = request
|
||||
j = c.get_json(force=True)
|
||||
logging.info(f"{request.get_json()} {j}")
|
||||
if 'cucu' not in j:
|
||||
abort(400, "missing parameter 'cucu'")
|
||||
@app.route('/opengnsys/rest/__ogAdmClient/recibeArchivo', methods=['POST'])
|
||||
def recibe_archivo():
|
||||
logging.info(f'{request.get_json()}')
|
||||
return jsonify({'anything':'anything'}) ## if we return {}, then we trigger "if not {}" which happens to be true
|
||||
|
||||
return jsonify({'cucu': j['cucu']})
|
||||
@app.route('/opengnsys/rest/__ogAdmClient/<cucu>', methods=['GET', 'POST'])
|
||||
def cucu(cucu):
|
||||
#j = request.get_json(force=True)
|
||||
#logging.info(f'{request.get_json()} {j}')
|
||||
#if 'cucu' not in j:
|
||||
# abort(400, 'missing parameter 'cucu'')
|
||||
#return jsonify({'cucu': j['cucu']})
|
||||
abort (404)
|
||||
|
||||
@app.errorhandler(404)
|
||||
def _page_not_found(e):
|
||||
return render_template_string('''<!DOCTYPE html><html>not found</html>''')
|
||||
if type(e.description) is dict:
|
||||
return jsonify (e.description), e.code
|
||||
else:
|
||||
return render_template_string('''<!DOCTYPE html><html>not found</html>'''), e.code
|
||||
|
||||
@app.errorhandler(500)
|
||||
def _internal_server_error(e):
|
||||
return render_template_string('''<!DOCTYPE html><html>err</html>''')
|
||||
return render_template_string('''<!DOCTYPE html><html>err</html>'''), e.code
|
||||
|
||||
@app.errorhandler(Exception)
|
||||
def _exception(e):
|
||||
print(e)
|
||||
return render_template_string('''<!DOCTYPE html><html>exception</html>''')
|
||||
return render_template_string('''<!DOCTYPE html><html>exception</html>'''), e.code
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(host = '192.168.1.249', port = 443, debug=True)
|
||||
|
|
|
@ -44,6 +44,7 @@ import subprocess
|
|||
import urllib.error
|
||||
import urllib.parse
|
||||
import urllib.request
|
||||
from pathlib import Path
|
||||
|
||||
from configparser import NoOptionError
|
||||
from opengnsys import REST, operations, VERSION
|
||||
|
@ -79,6 +80,85 @@ class ogAdmClientWorker (ServerWorker):
|
|||
#random = None # Random string for secure connections
|
||||
#length = 32 # Random string length
|
||||
|
||||
tbErroresScripts = [
|
||||
"Se han generado errores desconocidos. No se puede continuar la ejecución de este módulo", ## 0
|
||||
"001-Formato de ejecución incorrecto.",
|
||||
"002-Fichero o dispositivo no encontrado",
|
||||
"003-Error en partición de disco",
|
||||
"004-Partición o fichero bloqueado",
|
||||
"005-Error al crear o restaurar una imagen",
|
||||
"006-Sin sistema operativo",
|
||||
"007-Programa o función BOOLEAN no ejecutable",
|
||||
"008-Error en la creación del archivo de eco para consola remota",
|
||||
"009-Error en la lectura del archivo temporal de intercambio",
|
||||
"010-Error al ejecutar la llamada a la interface de administración",
|
||||
"011-La información retornada por la interface de administración excede de la longitud permitida",
|
||||
"012-Error en el envío de fichero por la red",
|
||||
"013-Error en la creación del proceso hijo",
|
||||
"014-Error de escritura en destino",
|
||||
"015-Sin Cache en el Cliente",
|
||||
"016-No hay espacio en la cache para almacenar fichero-imagen",
|
||||
"017-Error al Reducir el Sistema Archivos",
|
||||
"018-Error al Expandir el Sistema Archivos",
|
||||
"019-Valor fuera de rango o no válido.",
|
||||
"020-Sistema de archivos desconocido o no se puede montar",
|
||||
"021-Error en partición de caché local",
|
||||
"022-El disco indicado no contiene una particion GPT",
|
||||
"023-Error no definido",
|
||||
"024-Error no definido",
|
||||
"025-Error no definido",
|
||||
"026-Error no definido",
|
||||
"027-Error no definido",
|
||||
"028-Error no definido",
|
||||
"029-Error no definido",
|
||||
"030-Error al restaurar imagen - Imagen mas grande que particion",
|
||||
"031-Error al realizar el comando updateCache",
|
||||
"032-Error al formatear",
|
||||
"033-Archivo de imagen corrupto o de otra versión de partclone",
|
||||
"034-Error no definido",
|
||||
"035-Error no definido",
|
||||
"036-Error no definido",
|
||||
"037-Error no definido",
|
||||
"038-Error no definido",
|
||||
"039-Error no definido",
|
||||
"040-Error imprevisto no definido",
|
||||
"041-Error no definido",
|
||||
"042-Error no definido",
|
||||
"043-Error no definido",
|
||||
"044-Error no definido",
|
||||
"045-Error no definido",
|
||||
"046-Error no definido",
|
||||
"047-Error no definido",
|
||||
"048-Error no definido",
|
||||
"049-Error no definido",
|
||||
"050-Error en la generación de sintaxis de transferenica unicast",
|
||||
"051-Error en envio UNICAST de una particion",
|
||||
"052-Error en envio UNICAST de un fichero",
|
||||
"053-Error en la recepcion UNICAST de una particion",
|
||||
"054-Error en la recepcion UNICAST de un fichero",
|
||||
"055-Error en la generacion de sintaxis de transferenica Multicast",
|
||||
"056-Error en envio MULTICAST de un fichero",
|
||||
"057-Error en la recepcion MULTICAST de un fichero",
|
||||
"058-Error en envio MULTICAST de una particion",
|
||||
"059-Error en la recepcion MULTICAST de una particion",
|
||||
"060-Error en la conexion de una sesion UNICAST|MULTICAST con el MASTER",
|
||||
"061-Error no definido",
|
||||
"062-Error no definido",
|
||||
"063-Error no definido",
|
||||
"064-Error no definido",
|
||||
"065-Error no definido",
|
||||
"066-Error no definido",
|
||||
"067-Error no definido",
|
||||
"068-Error no definido",
|
||||
"069-Error no definido",
|
||||
"070-Error al montar una imagen sincronizada.",
|
||||
"071-Imagen no sincronizable (es monolitica).",
|
||||
"072-Error al desmontar la imagen.",
|
||||
"073-No se detectan diferencias entre la imagen basica y la particion.",
|
||||
"074-Error al sincronizar, puede afectar la creacion/restauracion de la imagen.",
|
||||
"Error desconocido",
|
||||
]
|
||||
|
||||
def onDeactivation (self):
|
||||
"""
|
||||
Sends OGAgent stopping notification to OpenGnsys server
|
||||
|
@ -193,6 +273,7 @@ class ogAdmClientWorker (ServerWorker):
|
|||
|
||||
def interfaceAdmin (self, method, parametros=[]):
|
||||
exe = '{}/{}'.format (self.pathinterface, method)
|
||||
## for development only. Will be removed when the referenced bash code (/opt/opengnsys/lib/engine/bin/*.lib) is translated into python
|
||||
devel_bash_prefix = '''
|
||||
PATH=/opt/opengnsys/scripts/:$PATH;
|
||||
for I in /opt/opengnsys/lib/engine/bin/*.lib; do source $I; done;
|
||||
|
@ -387,11 +468,11 @@ class ogAdmClientWorker (ServerWorker):
|
|||
|
||||
return True
|
||||
|
||||
def cargaPaginaWeb (url=None):
|
||||
def cargaPaginaWeb (self, url=None):
|
||||
if (not url): url = self.urlMenu
|
||||
os.system ('pkill -9 browser');
|
||||
|
||||
#p = subprocess.Popen (['/opt/opengnsys/bin/browser', '-qws', url])
|
||||
#p = subprocess.Popen (['/opt/opengnsys/bin/browser', '-qws', url]) ## TODO
|
||||
p = subprocess.Popen (['/usr/bin/xeyes'])
|
||||
try:
|
||||
p.wait (2) ## if the process dies before 2 seconds...
|
||||
|
@ -407,6 +488,9 @@ class ogAdmClientWorker (ServerWorker):
|
|||
def muestraMenu (self):
|
||||
self.cargaPaginaWeb()
|
||||
|
||||
def muestraMensaje (self, idx):
|
||||
self.cargaPaginaWeb (f'{self.urlMsg}?idx={idx}')
|
||||
|
||||
def procesaComandos (self):
|
||||
res = self.enviaMensajeServidor ('DisponibilidadComandos', { 'tpc': 'OPG' }) ## Activar disponibilidad
|
||||
logger.debug ('res ({})'.format (res))
|
||||
|
@ -491,8 +575,59 @@ class ogAdmClientWorker (ServerWorker):
|
|||
self.muestraMenu()
|
||||
self.procesaComandos()
|
||||
|
||||
def process_NoComandosPtes(self, path, get_params, post_params, server):
|
||||
logger.warn('in process_NoComandosPtes')
|
||||
## este es una respuesta, y creo que nadie nos va a llamar nunca a este endpoint
|
||||
## curl --insecure https://192.168.1.249:8000/ogAdmClient/NoComandosPtes
|
||||
#def process_NoComandosPtes (self, path, get_params, post_params, server):
|
||||
# logger.warn ('in process_NoComandosPtes')
|
||||
|
||||
def respuestaEjecucionComando (self, cmd, herror, ids):
|
||||
if ids: ## Existe seguimiento
|
||||
cmd['ids'] = ids ## Añade identificador de la sesión
|
||||
|
||||
if 0 == herror: ## el comando terminó con resultado satisfactorio
|
||||
cmd['res'] = 1
|
||||
cmd['der'] = ''
|
||||
else: ## el comando tuvo algún error
|
||||
cmd['res'] = 2
|
||||
cmd['der'] = self.tbErroresScripts[herror] ## XXX
|
||||
|
||||
return cmd
|
||||
|
||||
def InventariandoSoftware (self, dsk, par, sw, nfn):
|
||||
sft_src = f'/tmp/CSft-{self.IPlocal}-{par}'
|
||||
try:
|
||||
self.interfaceAdmin (nfn, [dsk, par, sft_src])
|
||||
herror = 0
|
||||
except:
|
||||
herror = 1
|
||||
|
||||
if herror:
|
||||
logger.warning ('Error al ejecutar el comando')
|
||||
self.muestraMensaje (20)
|
||||
else:
|
||||
if not os.path.exists (sft_src):
|
||||
raise Exception (f'interfaceAdmin({nfn}) returned success but did not create file ({sft_src}) under /tmp')
|
||||
sft_src_contents = Path (sft_src).read_bytes()
|
||||
|
||||
## Envía fichero de inventario al servidor
|
||||
sft_dst = f'/tmp/Ssft-{self.IPlocal}-{par}' ## Nombre que tendra el archivo en el Servidor
|
||||
logger.debug ('sending recibeArchivo to server')
|
||||
res = self.enviaMensajeServidor ('recibeArchivo', { 'nfl': sft_dst, 'contents': base64.b64encode (sft_src_contents).decode ('utf-8') })
|
||||
logger.debug (res)
|
||||
if not res:
|
||||
herror = 12 ## Error de envío de fichero por la red
|
||||
raise Exception ('Ha ocurrido algún problema al enviar un archivo por la red')
|
||||
self.muestraMensaje (19)
|
||||
|
||||
if not sw:
|
||||
cmd = {
|
||||
'nfn': 'RESPUESTA_InventarioSoftware',
|
||||
'par': par,
|
||||
'sft': sft_dst,
|
||||
}
|
||||
return self.respuestaEjecucionComando (cmd, herror, 0);
|
||||
|
||||
return {'true':'true'} ## XXX
|
||||
|
||||
## curl --insecure https://192.168.1.249:8000/ogAdmClient/Actualizar
|
||||
def process_Actualizar (self, path, get_params, post_params, server):
|
||||
|
@ -520,7 +655,51 @@ class ogAdmClientWorker (ServerWorker):
|
|||
logger.warn ('in process_IniciarSesion')
|
||||
|
||||
def process_CrearImagen (self, path, get_params, post_params, server):
|
||||
logger.warn ('in process_CrearImagen')
|
||||
logger.debug ('in process_CrearImagen, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server))
|
||||
logger.debug ('type(post_params) "{}"'.format (type (post_params)))
|
||||
|
||||
logger.debug ('Ejecución de comando');
|
||||
|
||||
for k in ['dsk', 'par', 'cpt', 'idi', 'nci', 'ipr', 'nfn', 'ids']:
|
||||
if k not in post_params:
|
||||
logger.error (f'required parameter ({k}) not in POST params')
|
||||
return {}
|
||||
|
||||
dsk = post_params['dsk'] ## Disco
|
||||
par = post_params['par'] ## Número de partición
|
||||
cpt = post_params['cpt'] ## Código de la partición
|
||||
idi = post_params['idi'] ## Identificador de la imagen
|
||||
nci = post_params['nci'] ## Nombre canónico de la imagen
|
||||
ipr = post_params['ipr'] ## Ip del repositorio
|
||||
nfn = post_params['nfn']
|
||||
ids = post_params['ids']
|
||||
|
||||
self.muestraMensaje (7)
|
||||
|
||||
if self.InventariandoSoftware (dsk, par, False, 'InventarioSoftware'): ## Crea inventario Software previamente
|
||||
self.muestraMensaje (2)
|
||||
try:
|
||||
output = self.interfaceAdmin (nfn, [dsk, par, nci, ipr])
|
||||
self.muestraMensaje (9)
|
||||
herror = 0
|
||||
except Exception as e:
|
||||
logger.warning ('Error al ejecutar el comando')
|
||||
self.muestraMensaje (10)
|
||||
herror = 1
|
||||
else:
|
||||
logger.warning ('Error al ejecutar el comando')
|
||||
|
||||
self.muestraMenu()
|
||||
|
||||
cmd = {
|
||||
'nfn': 'RESPUESTA_CrearImagen',
|
||||
'idi': idi, ## Identificador de la imagen
|
||||
'dsk': dsk, ## Número de disco
|
||||
'par': par, ## Número de partición de donde se creó
|
||||
'cpt': cpt, ## Tipo o código de partición
|
||||
'ipr': ipr, ## Ip del repositorio donde se alojó
|
||||
}
|
||||
return self.respuestaEjecucionComando (cmd, herror, ids)
|
||||
|
||||
def process_CrearImagenBasica (self, path, get_params, post_params, server):
|
||||
logger.warn ('in process_CrearImagenBasica')
|
||||
|
|
Loading…
Reference in New Issue