123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412 |
- # -*- coding: utf-8 -*-
- '''
- Gestor de nodos para LaOtraRed La Paz - El Alto
- Copyright (C) 2017 Rodrigo Garcia
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
- published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- '''
- import datetime, time
- from collections import deque
- from flask import render_template, jsonify, abort, Markup, escape, request #, make_response
- from flask import Blueprint
- from flask import flash, g, session
- from flask import redirect, send_from_directory, safe_join, send_file
- from flask import url_for
- from werkzeug import secure_filename
- from werkzeug import secure_filename
- from jinja2 import Environment, PackageLoader
- from gestor.main import app
- from gestor import configs
- from database.database import init_db, db_session
- from database.database import engine
- from sqlalchemy.exc import IntegrityError
- from .models import Nodo, Ubicacion
- from gestor import utils
- from gestor import utils_red
- from gestor import utils_firmware
- gestor = Blueprint("gestor", __name__, url_prefix='')
- @gestor.before_request
- def before_request():
- g.nodo = None
- if 'nodo_id' in session:
- g.nodo = Nodo.query.get(session['nodo_id'])
- print ("sesion: "+str(g.nodo))
- g.estado_construccion = 'No'
- @gestor.route('/')
- def hello_world():
- return render_template("index.html", p_actual="inicio", \
- nodo=session.get('nodo_id', None))
- #return "DATABASE = "+str(configs.DATABASE_NAME)+"\n"+\
- #"DB: "+str(engine)
- @gestor.route('/agregar', methods=['GET'])
- def get_agregar_nodos(errors=None):
- contexto = {}
- contexto['modelos_posibles'] = utils.listas_routers()
- if errors:
- return render_template("agregar_nodo.html", p_actual="agregar",\
- contexto=contexto, errors=errors,
- nodo=session.get('nodo_id', None))
- return render_template("agregar_nodo.html", p_actual="agregar",\
- contexto=contexto,\
- nodo=session.get('nodo_id', None))
- @gestor.route('/nuevo', methods=['POST'])
- def post_agregar_nodos():
- if request.method == "POST":
- errors = utils.comprobar_postAgregarNodo(request, errores_detalle=True)
-
- # comprobando nuevo nodo en la base de datos
- #nodo_similar = utils.comprobar_responsableNodo(request)
- nodo_similar = utils.comprobar_nodoSimilar(request)
- #if nodo_similar is not None:
- if nodo_similar != False:
- errors['nodo_similar'] = u"Un nodo tiene registrado el email <"+\
- str(request.form['email'].lower())+\
- "> y el nombre, apellido son distintos a "+\
- " los que has introducido."
- errors['id_nodo_similar'] = str(nodo_similar)
-
- if len(errors) > 0:
- contexto = {}
- contexto['modelos_posibles'] = utils.listas_routers()
- contexto['errors'] = errors
- print ("Errores en formulario: "+str(errors))
- return (get_agregar_nodos(errors=errors))
- return render_template("agregar_nodo.html", p_actual="agregar",\
- contexto=contexto, errors=errors, \
- nodo=session.get('nodo_id', None) )
-
- # insertando en la base de datos
- db_session.rollback()
-
- compartir_ubicacion = request.form.get("compartir_ubicacion")
- # creando nodo con ubicacion dummy
- if compartir_ubicacion == "SI":
- id_ubicacion_dummy = utils.crear_ubicacionDummy(is_public=True)
- elif compartir_ubicacion == "NO":
- id_ubicacion_dummy = utils.crear_ubicacionDummy(is_public=False)
- # obteniendo bloques de red
- cidr_publica = utils_red.get_cidrIpV4(request.form['ips_publicas'])
- cidr_privada = utils_red.get_cidrIpV4(request.form['ips_privadas'])
- bloque_ipv4_publico = utils_red.\
- siguiente_bloqueIpv4Disponible(cidr_publica)
- bloque_ipv4_privado = utils_red.\
- siguiente_bloqueIpv4Disponible(cidr_privada, publico=False)
- bloque_ipv6 = utils_red.siguiente_bloqueIpv6Disponible()
-
- clave_edicion = utils.hash_claveEdicion(request.form['clave'])
-
- nombre_nodo = request.form.get('nombre_nodo', bloque_ipv4_publico)
- fecha_actual = datetime.datetime.now().\
- strftime("%Y-%m-%d %H:%M:%S")
- # creacion de nuevo registro
- nodo = Nodo(ubicacion_id = id_ubicacion_dummy,\
- nombre = nombre_nodo,\
- descripcion = request.form['descripcion'],\
- clave_edicion = clave_edicion,\
-
- bloque_ipv4 = bloque_ipv4_publico+"/"+str(cidr_publica) , \
- ipv4_network_addr = bloque_ipv4_publico, \
- ipv4_cidr = cidr_publica,\
- bloque_ipv4_privado = bloque_ipv4_privado, \
- ipv4_cidr_privado = cidr_privada, \
- bloque_ipv6 = bloque_ipv6,\
- ipv6_network_addr = bloque_ipv6.split("/")[0],\
- ipv6_cidr = 128,\
- url_descarga=utils.get_randomToken(), \
-
- nombres_responsable = request.form['nombres'],\
- apellidos_responsable = request.form['apellidos'],\
- email = request.form['email'],\
- fecha_creacion = fecha_actual
- )
- try:
- db_session.add(nodo)
- db_session.commit()
- except IntegrityError:
- print ('"IntegrityError" con "Nodo" detectado')
- return u"Error Interno, datos duplicados en la base de datos"
- # generacion de firmware
- #TODO: Antes de comenzar a genera la imagen de firmware,
- # mostrar en la pagina actual una notificacion (javascript) de que
- # se esta procesando la peticion y que se redijira automaticamente
- # cuando el proceso termine y tambien se enviara una notificacion
- # por email con el directorio para descarga del firmware.
- # marcando variable que indica estado de construccion
- g.estado_construccion = 'construyendo'
-
- r = utils_firmware.\
- crear_imagenFirmware(request.form['modelos'],\
- bloque_ipv4_publico,
- cidr_publica
- )
-
- if r == "Error":
- return render_template("generando_firmware.html", error = "1", \
- nombre_nodo=nombre_nodo,\
- email=request.form['email'],\
- bloque_ipv4=bloque_ipv4_publico+"/"+str(cidr_publica),\
- modelo_enrutador=request.form["modelos"],\
-
- nombres_responsable = request.form['nombres'],\
- apellidos_responsable = request.form['apellidos'],\
- #TODO: quitar lo siguiente
- resultado = r,\
- ##
- nodo=session.get('nodo_id', None),\
- p_actual="nodos"
- )
- else:
- #TODO: enviar email indicando que el proceso ha terminado
- #...
- # enviar senyal ajax indicando que el proceso ha terminado
- #...
- g.estado_construccion = 'terminado'
- time.sleep(10)
-
- return render_template("generando_firmware.html",
- nombre_nodo=nombre_nodo,\
- email=request.form['email'],\
- bloque_ipv4=bloque_ipv4_publico+"/"+str(cidr_publica),\
- modelo_enrutador=request.form["modelos"],\
-
- nombres_responsable = request.form['nombres'],\
- apellidos_responsable = request.form['apellidos'],\
- url_descarga = nodo.url_descarga,\
- #TODO: quitar lo siguiente
- resultado = r, \
- ##
- nodo=session.get('nodo_id', None)
- )
-
- return "no autorizado"
-
- @gestor.route('/nodos', methods=['GET'])
- def lista_nodos():
- lista_activos = deque([])
- lista_proyectados = deque([])
- lista = []
- for nodo in db_session.query(Nodo).order_by(Nodo.id).all():
- dict = {}
- dict['id'] = nodo.id
- dict['nombre'] = nodo.nombre
- dict['bloque_ipv4'] = nodo.bloque_ipv4
- dict['bloque_ipv6'] = nodo.bloque_ipv6
- dict['descripcion'] = nodo.descripcion
- dict['ubicacion_id'] = nodo.ubicacion_id
- dict['tupla_ubicacion'] = utils.obtener_ubicacionResumida(nodo.ubicacion_id)
- if nodo.is_active == True:
- lista_activos.append(dict)
- else:
- lista_proyectados.append(dict)
-
- for row in db_session.query(Nodo).all():
- lista.append(str(row))
- for row in db_session.query(Ubicacion).all():
- lista.append(str(row))
- flash("Obteniendo lista", 'warning')
- return render_template("nodos.html", p_actual="nodos",\
- rows=lista, \
- lista_proyectados=lista_proyectados,\
- lista_activos=lista_activos,
- num_activos=utils.num_nodosActivos(),\
- num_proyectados=utils.num_nodosProyectados(), \
- nodo=session.get('nodo_id', None))
- @gestor.route('/nodos/<nodo_id>', methods=['GET'])
- def info_nodo(nodo_id):
- if not nodo_id.isdigit():
- return render_template("404.html"), 404
- nodo = db_session.query(Nodo).\
- filter(Nodo.id == int(nodo_id)).first()
- if nodo is None:
- return render_template("404.html"), 404
-
- ubicacion = utils.obtener_ubicacionDetallada(nodo.ubicacion_id)
- return render_template("nodo.html",\
- nombre = nodo.nombre, \
- bloque_ipv4 = nodo.bloque_ipv4, \
- ipv4_network_addr = nodo.ipv4_network_addr,\
- ipv4_cidr = nodo.ipv4_cidr,\
- bloque_ipv6 = nodo.bloque_ipv6,\
- ipv6_network_addr = nodo.ipv6_network_addr, \
- is_active = nodo.is_active,\
- is_confirmed = nodo.is_confirmed, \
- url_descarga = nodo.url_descarga,\
- fecha_creacion = nodo.fecha_creacion, \
- descripcion = nodo.descripcion, \
- nombres = nodo.nombres_responsable, \
- apellidos = nodo.apellidos_responsable, \
- email = nodo.email, \
- telf = nodo.telf,
- ubicacion = ubicacion, \
- nodo=session.get('nodo_id', None)
- )
- @gestor.route('/descargas/<url>', methods = ['GET'])
- def descargas_firmware(url):
- # probando que exista un nodo con la url asociada
- nodo = db_session.query(Nodo).\
- filter(Nodo.url_descarga == url).first()
- if nodo is None:
- return render_template("404.html") , 404
- if not g.nodo:
- # password de edicion
- return render_template("descarga.html",\
- nodo=session.get('nodo_id', None),\
- nodo_id=nodo.id,\
- nombre=nodo.nombre,\
- url=url)
- else:
- # comprobando que la sesion iniciada sea correspondiente a este nodo
- if g.nodo.url_descarga != url:
- return render_template("descarga.html",\
- incorrecto=True,\
- nodo=None,\
- nodo_id=nodo.id,\
- nombre=nodo.nombre,\
- url=url)
-
- # retornar template con los archivos para descargar
- carpetas = utils_firmware.carpetas_descargaFirmware(nodo.bloque_ipv4)
- return render_template("descarga.html",\
- nodo=session['nodo_id'],\
- nodo_id=nodo.id,\
- nombre=nodo.nombre,\
- url=url,
- carpetas=carpetas)
-
- return "Falta implementar"
- @gestor.route('/descargas/<url>/<carpeta>', methods=['GET'])
- def descargas_firmwareCarpetas(url, carpeta=None):
- nodo = db_session.query(Nodo).\
- filter(Nodo.url_descarga == url).first()
- if nodo is None:
- return render_template("404.html") , 404
- if not g.nodo:
- # password de edicion
- return render_template("descarga.html",\
- nodo=session.get('nodo_id', None),\
- nodo_id=nodo.id,\
- nombre=nodo.nombre,\
- url=url)
- else:
- # comprobando que la sesion iniciada sea correspondiente a este nodo
- if g.nodo.url_descarga != url:
- return render_template("descarga.html",\
- incorrecto=True,\
- nodo=None,\
- nodo_id=nodo.id,\
- nombre=nodo.nombre,\
- url=url)
- l = utils_firmware.listar_carpetaFirmware(carpeta=carpeta)
- dirs = l[0]
- archs = l[1]
- return render_template("descarga.html",\
- nodo=session['nodo_id'],\
- nodo_id=nodo.id,\
- nombre=nodo.nombre,\
- url=url,\
- carpeta=carpeta,\
- directorios=dirs,\
- archivos=archs)
- @gestor.route('/descargas/<url>/login', methods=['POST'])
- def login_descargas_firmware(url):
- nodo = db_session.query(Nodo).\
- filter(Nodo.url_descarga == url).first()
- if nodo is None:
- return render_template("404.html") , 404
-
- if g.nodo and session['nodo_id'] == nodo.id:
- print ("ruta:"+url_for('gestor.descargas_firmware', url=url))
- return redirect(url_for('gestor.descargas_firmware', url=url))
- else:
- # comprobando clave de edicion
- if utils.hash_claveEdicion(request.form['password']) == \
- nodo.clave_edicion:
- print ("--- Descarga de firmware ---")
- print ("nodo:"+str(nodo))
- print ("clave de edicion correcta :)")
- print ("ruta:"+url_for('gestor.descargas_firmware',url=url))
- print ("----------------------------")
- session['nodo_id'] = nodo.id
- return redirect(url_for("gestor.descargas_firmware",url=url))
- else:
- print ("--- Descarga de firmware ---")
- print ("nodo:"+str(nodo))
- print ("clave de edicion INCORRECTA")
- print ("ruta:"+url_for('gestor.descargas_firmware',url=url))
- print ("----------------------------")
- return redirect(url_for("gestor.descargas_firmware",url=url))
- @gestor.route('/logout', methods=['GET'])
- def logout_descargas_firmware():
- session.pop('nodo_id', None)
- return redirect(url_for('gestor.hello_world'))
- # respuestas con json
- @gestor.route('/nuevo/_construccion')
- def estado_construccion():
- print
- print ("AJAX construccion")
- print
- return jsonify(estado=g.estado_construccion)
- @gestor.route('/_cons')
- def prueba_json():
- a = 123+321
- return jsonify(r=a)
- # errores
- @gestor.errorhandler(404)
- def page_not_found(error):
- return render_template( "404.html" ), 404
|