From ba681a81166dc1ff85a3268862b439e86c866979 Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Thu, 19 Sep 2024 14:33:09 +0200 Subject: [PATCH] refs #708 split CloningEngine stuff off ogAdmClient module, restore stock config --- ogcore-mock.py | 36 +- src/cfg/ogagent.cfg | 16 +- .../modules/server/CloningEngine/__init__.py | 314 ++++++++++++++++++ .../modules/server/ogAdmClient/__init__.py | 167 +--------- 4 files changed, 348 insertions(+), 185 deletions(-) create mode 100644 src/opengnsys/modules/server/CloningEngine/__init__.py diff --git a/ogcore-mock.py b/ogcore-mock.py index 8762d49..765ba5e 100644 --- a/ogcore-mock.py +++ b/ogcore-mock.py @@ -20,9 +20,9 @@ def og_agent(cucu): -## agente oglive +## agente oglive: modulo ogAdmClient -@app.route('/opengnsys/rest/__ogAdmClient/InclusionCliente', methods=['POST']) +@app.route('/opengnsys/rest/ogAdmClient/InclusionCliente', methods=['POST']) def inclusion_cliente(): logging.info(f'{request.get_json()}') #procesoInclusionCliente() or { return (jsonify { 'res': 0 }) } @@ -78,7 +78,7 @@ def _recorreProcedimientos(parametros, fileexe, idp): return 1 -@app.route('/opengnsys/rest/__ogAdmClient/AutoexecCliente', methods=['POST']) +@app.route('/opengnsys/rest/ogAdmClient/AutoexecCliente', methods=['POST']) def autoexec_client(): logging.info(f'{request.get_json()}') j = request.get_json(force=True) @@ -102,7 +102,7 @@ def autoexec_client(): fileexe.close() return res -@app.route('/opengnsys/rest/__ogAdmClient/enviaArchivo', methods=['POST']) +@app.route('/opengnsys/rest/ogAdmClient/enviaArchivo', methods=['POST']) def envia_archivo(): logging.info(f'{request.get_json()}') j = request.get_json(force=True) @@ -129,7 +129,7 @@ def buscaComandos(ido): ## convertirlo a json, aqui lo pongo a capon #return jsonify ({ 'nfn': 'popup', 'title': 'my title', 'message': 'my message', 'ids': ids }) -@app.route('/opengnsys/rest/__ogAdmClient/ComandosPendientes', methods=['POST']) +@app.route('/opengnsys/rest/ogAdmClient/ComandosPendientes', methods=['POST']) def comandos_pendientes(): logging.info(f'{request.get_json()}') j = request.get_json(force=True) @@ -150,7 +150,7 @@ def comandos_pendientes(): return jsonify(param) -@app.route('/opengnsys/rest/__ogAdmClient/DisponibilidadComandos', methods=['POST']) +@app.route('/opengnsys/rest/ogAdmClient/DisponibilidadComandos', methods=['POST']) def disponibilidad_comandos(): logging.info(f'{request.get_json()}') j = request.get_json(force=True) @@ -167,13 +167,8 @@ def disponibilidad_comandos(): return jsonify({}) -@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 - -@app.route('/opengnsys/rest/__ogAdmClient/', methods=['GET', 'POST']) -def cucu(cucu): +@app.route('/opengnsys/rest/ogAdmClient/', methods=['GET', 'POST']) +def oac_cucu(cucu): #j = request.get_json(force=True) #logging.info(f'{request.get_json()} {j}') #if 'cucu' not in j: @@ -181,6 +176,21 @@ def cucu(cucu): #return jsonify({'cucu': j['cucu']}) abort (404) + + +## agente oglive: modulo CloningEngine + +@app.route('/opengnsys/rest/CloningEngine/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 + +@app.route('/opengnsys/rest/CloningEngine/', methods=['GET', 'POST']) +def ce_cucu(cucu): + abort (404) + + + @app.errorhandler(404) def _page_not_found(e): if type(e.description) is dict: diff --git a/src/cfg/ogagent.cfg b/src/cfg/ogagent.cfg index 96f4da0..f9b012b 100644 --- a/src/cfg/ogagent.cfg +++ b/src/cfg/ogagent.cfg @@ -7,7 +7,7 @@ port=8000 #path=test_modules/server,more_modules/server # Remote OpenGnsys Service -remote=https://192.168.2.10/opengnsys/rest +remote=https://192.168.2.1/opengnsys/rest # Alternate OpenGnsys Service (comment out to enable this option) #altremote=https://10.0.2.2/opengnsys/rest @@ -22,12 +22,16 @@ log=DEBUG # This section will be passes on activation to module [ogAdmClient] #path=test_modules/server,more_modules/server -## this URL will probably be left equal to the other one, but let's see -remote=https://192.168.2.10/opengnsys/rest -log=DEBUG -#servidorAdm=192.168.2.1 -#puerto=2008 +remote=https://192.168.2.1/opengnsys/rest +log=DEBUG +pathinterface=/opt/opengnsys/interfaceAdm +urlMenu=https://192.168.2.1/opengnsys/varios/menubrowser.php +urlMsg=http://localhost/cgi-bin/httpd-log.sh + +[CloningEngine] +remote=https://192.168.2.1/opengnsys/rest +log=DEBUG pathinterface=/opt/opengnsys/interfaceAdm urlMenu=https://192.168.2.1/opengnsys/varios/menubrowser.php urlMsg=http://localhost/cgi-bin/httpd-log.sh diff --git a/src/opengnsys/modules/server/CloningEngine/__init__.py b/src/opengnsys/modules/server/CloningEngine/__init__.py new file mode 100644 index 0000000..bba0923 --- /dev/null +++ b/src/opengnsys/modules/server/CloningEngine/__init__.py @@ -0,0 +1,314 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Copyright (c) 2024 Qindel Formación y Servicios S.L. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of Virtual Cable S.L. nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +""" +@author: Natalia Serrano, nserrano at qindel dot com +""" + +import base64 +import os +import subprocess +from pathlib import Path + +from configparser import NoOptionError +from opengnsys import REST +from opengnsys.log import logger +from opengnsys.workers import ServerWorker + +class CloningEngineWorker (ServerWorker): + name = 'CloningEngine' # Module name + REST = None # REST object + + def onDeactivation (self): + logger.debug ('onDeactivation') + + def process_status (self, path, get_params, post_params, server): + return {self.name: 'in process_status'} ## XXX + + 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; + 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)) + p = subprocess.run (proc, capture_output=True) + if 0 != p.returncode: + cmd_txt = ' '.join (proc) + logger.error (f'command ({cmd_txt}) failed, stderr follows:') + for l in p.stderr.strip().decode ('utf-8').splitlines(): + logger.error (f' {l}') + raise Exception (f'command ({cmd_txt}) failed, see log for details') + return p.stdout.strip().decode ('utf-8') + + def tomaIPlocal (self): + try: + self.IPlocal = self.interfaceAdmin ('getIpAddress') + except Exception as e: + logger.error (e) + logger.error ('No se ha podido recuperar la dirección IP del cliente') + return False + logger.info ('local IP is "{}"'.format (self.IPlocal)) + return True + + def enviaMensajeServidor (self, path, obj={}): + obj['iph'] = self.IPlocal ## Ip del ordenador + obj['ido'] = self.idordenador ## Identificador del ordenador + obj['npc'] = self.nombreordenador ## Nombre del ordenador + obj['idc'] = self.idcentro ## Identificador del centro + obj['ida'] = self.idaula ## Identificador del aula + + res = self.REST.sendMessage ('/'.join (self.name, path), obj) + + if (type (res) is not dict): + #logger.error ('No se ha podido establecer conexión con el Servidor de Administración') ## Error de conexión con el servidor + logger.debug (f'res ({res})') + logger.error ('Error al enviar trama ***send() fallo') + return False + + return res + + 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]) + try: + p.wait (2) ## if the process dies before 2 seconds... + logger.error ('Error al ejecutar la llamada a la interface de administración') + logger.error ('Error en la creación del proceso hijo') + logger.error ('return code "{}"'.format (p.returncode)) + return False + except subprocess.TimeoutExpired: + pass + + return True + + def muestraMenu (self): + self.cargaPaginaWeb() + + def muestraMensaje (self, idx): + self.cargaPaginaWeb (f'{self.urlMsg}?idx={idx}') + + def onActivation (self): + if not os.path.exists ('/scripts/oginit'): + ## no estamos en oglive, este modulo no debe cargarse + ## esta lógica la saco de src/opengnsys/linux/operations.py, donde hay un if similar + raise Exception ('Refusing to load within an operating system') + + self.pathinterface = None + self.IPlocal = None ## Ip del ordenador + self.idordenador = None ## Identificador del ordenador + self.nombreordenador = None ## Nombre del ordenador + self.cache = None + self.idproautoexec = None + self.idcentro = None ## Identificador del centro + self.idaula = None ## Identificador del aula + + try: + url = self.service.config.get (self.name, 'remote') + loglevel = self.service.config.get (self.name, 'log') + self.pathinterface = self.service.config.get (self.name, 'pathinterface') + self.urlMenu = self.service.config.get (self.name, 'urlMenu') + self.urlMsg = self.service.config.get (self.name, 'urlMsg') + except NoOptionError as e: + logger.error ("Configuration error: {}".format (e)) + raise e + logger.setLevel (loglevel) + self.REST = REST (url) + + logger.info ('onActivation ok') + + ## en C, esto envia una trama de respuesta al servidor. Devuelve un boolean + ## en python, simplemente termina de construir la respuesta y la devuelve; no envía nada por la red. El caller la usa en return() para enviar implícitamente la respuesta + 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})') + 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 + + def process_CrearImagen (self, path, get_params, post_params, server): + 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))) + + 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: + self.interfaceAdmin (nfn, [dsk, par, nci, ipr]) + self.muestraMensaje (9) + herror = 0 + except: + 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.debug ('in process_CrearImagenBasica, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server)) + logger.warning ('this method has been removed') + raise Exception ({ '_httpcode': 404, '_msg': 'This method has been removed' }) + + def process_CrearSoftIncremental (self, path, get_params, post_params, server): + logger.debug ('in process_CrearSoftIncremental, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server)) + logger.warning ('this method has been removed') + raise Exception ({ '_httpcode': 404, '_msg': 'This method has been removed' }) + + def process_RestaurarImagen (self, path, get_params, post_params, server): + logger.debug ('in process_RestaurarImagen, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server)) + + for k in ['dsk', 'par', 'idi', 'ipr', 'nci', 'ifs', 'ptc', 'nfn', 'ids']: + if k not in post_params: + logger.error (f'required parameter ({k}) not in POST params') + return {} + + dsk = post_params['dsk'] + par = post_params['par'] + idi = post_params['idi'] + ipr = post_params['ipr'] + nci = post_params['nci'] + ifs = post_params['ifs'] + ptc = post_params['ptc'] ## Protocolo de clonación: Unicast, Multicast, Torrent + nfn = post_params['nfn'] + ids = post_params['ids'] + + self.muestraMensaje (3) + + try: + self.interfaceAdmin (nfn, [dsk, par, nci, ipr, ptc]) + self.muestraMensaje (11) + herror = 0 + except: + logger.warning ('Error al ejecutar el comando') + self.muestraMensaje (12) + herror = 1 + + cfg = self.LeeConfiguracion() + if not cfg: + logger.warning ('No se ha podido recuperar la configuración de las particiones del disco') + + self.muestraMenu() + + cmd = { + 'nfn': 'RESPUESTA_RestaurarImagen', + 'idi': idi, ## Identificador de la imagen + 'dsk': dsk, ## Número de disco + 'par': par, ## Número de partición + 'ifs': ifs, ## Identificador del perfil software + 'cfg': cfg, ## Configuración de discos + } + return self.respuestaEjecucionComando (cmd, herror, ids) + + def process_RestaurarImagenBasica (self, path, get_params, post_params, server): + logger.debug ('in process_RestaurarImagenBasica, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server)) + logger.warning ('this method has been removed') + raise Exception ({ '_httpcode': 404, '_msg': 'This method has been removed' }) + + def process_RestaurarSoftIncremental (self, path, get_params, post_params, server): + logger.warning ('in process_RestaurarSoftIncremental') + logger.debug ('in process_RestaurarSoftIncremental, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server)) + logger.warning ('this method has been removed') + raise Exception ({ '_httpcode': 404, '_msg': 'This method has been removed' }) diff --git a/src/opengnsys/modules/server/ogAdmClient/__init__.py b/src/opengnsys/modules/server/ogAdmClient/__init__.py index 057216b..86e35ee 100644 --- a/src/opengnsys/modules/server/ogAdmClient/__init__.py +++ b/src/opengnsys/modules/server/ogAdmClient/__init__.py @@ -277,7 +277,7 @@ class ogAdmClientWorker (ServerWorker): obj['idc'] = self.idcentro ## Identificador del centro obj['ida'] = self.idaula ## Identificador del aula - res = self.REST.sendMessage (path, obj) + res = self.REST.sendMessage ('/'.join (self.name, path), obj) if (type (res) is not dict): #logger.error ('No se ha podido establecer conexión con el Servidor de Administración') ## Error de conexión con el servidor @@ -421,9 +421,6 @@ 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)) @@ -472,8 +469,6 @@ class ogAdmClientWorker (ServerWorker): try: url = self.service.config.get (self.name, 'remote') loglevel = self.service.config.get (self.name, 'log') - #self.servidorAdm = self.service.config.get (self.name, 'servidorAdm') - #self.puerto = self.service.config.get (self.name, 'puerto') self.pathinterface = self.service.config.get (self.name, 'pathinterface') self.urlMenu = self.service.config.get (self.name, 'urlMenu') self.urlMsg = self.service.config.get (self.name, 'urlMsg') @@ -510,55 +505,6 @@ class ogAdmClientWorker (ServerWorker): self.muestraMenu() self.procesaComandos() - 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})') - 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): logger.warning ('in process_Actualizar') @@ -584,117 +530,6 @@ class ogAdmClientWorker (ServerWorker): def process_IniciarSesion (self, path, get_params, post_params, server): logger.warning ('in process_IniciarSesion') - def process_CrearImagen (self, path, get_params, post_params, server): - 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))) - - 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: - 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.debug ('in process_CrearImagenBasica, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server)) - logger.warning ('this method has been removed') - raise Exception ({ '_httpcode': 404, '_msg': 'This method has been removed' }) - - def process_CrearSoftIncremental (self, path, get_params, post_params, server): - logger.debug ('in process_CrearSoftIncremental, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server)) - logger.warning ('this method has been removed') - raise Exception ({ '_httpcode': 404, '_msg': 'This method has been removed' }) - - def process_RestaurarImagen (self, path, get_params, post_params, server): - logger.debug ('in process_RestaurarImagen, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server)) - - for k in ['dsk', 'par', 'idi', 'ipr', 'nci', 'ifs', 'ptc', 'nfn', 'ids']: ## XXX "ids" es realmente obligatorio? - if k not in post_params: - logger.error (f'required parameter ({k}) not in POST params') - return {} - - dsk = post_params['dsk'] - par = post_params['par'] - idi = post_params['idi'] - ipr = post_params['ipr'] - nci = post_params['nci'] - ifs = post_params['ifs'] - ptc = post_params['ptc'] ## Protocolo de clonación: Unicast, Multicast, Torrent - nfn = post_params['nfn'] - ids = post_params['ids'] - - self.muestraMensaje (3) - - try: - output = self.interfaceAdmin (nfn, [dsk, par, nci, ipr, ptc]) - self.muestraMensaje (11) - herror = 0 - except: - logger.warning ('Error al ejecutar el comando') - self.muestraMensaje (12) - herror = 1 - - cfg = self.LeeConfiguracion() - if not cfg: - logger.warning ('No se ha podido recuperar la configuración de las particiones del disco') - - self.muestraMenu() - - cmd = { - 'nfn': 'RESPUESTA_RestaurarImagen', - 'idi': idi, ## Identificador de la imagen - 'dsk': dsk, ## Número de disco - 'par': par, ## Número de partición - 'ifs': ifs, ## Identificador del perfil software - 'cfg': cfg, ## Configuración de discos - } - return self.respuestaEjecucionComando (cmd, herror, ids) - - def process_RestaurarImagenBasica (self, path, get_params, post_params, server): - logger.debug ('in process_RestaurarImagenBasica, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server)) - logger.warning ('this method has been removed') - raise Exception ({ '_httpcode': 404, '_msg': 'This method has been removed' }) - - def process_RestaurarSoftIncremental (self, path, get_params, post_params, server): - logger.warning ('in process_RestaurarSoftIncremental') - logger.debug ('in process_RestaurarSoftIncremental, path "{}" get_params "{}" post_params "{}" server "{}"'.format (path, get_params, post_params, server)) - logger.warning ('this method has been removed') - raise Exception ({ '_httpcode': 404, '_msg': 'This method has been removed' }) - def process_Configurar (self, path, get_params, post_params, server): logger.warning ('in process_Configurar')