Metadata-Version: 2.4
Name: firewall_operations_roan
Version: 0.1.3
Summary: Herramienta para validacion y diagnostico de firewalls Fortinet y Juniper
Author: Angel Rogelio Argonza Roblero
License: MIT
Keywords: firewall,fortinet,juniper,netmiko,network-automation
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: System :: Logging
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: netmiko>=4.7.0
Requires-Dist: PyMySQL>=1.2.0
Requires-Dist: secure-credentials-roan>=0.1.0
Requires-Dist: w-log-roan>=0.1.0
Dynamic: license-file

# Firewall Operations Roan

Herramienta en Python para la validación, diagnóstico y monitoreo de firewalls **Fortinet** (FortiGate) y **Juniper** (JunOS) mediante conexiones SSH automatizadas (Netmiko). Está pensada para operaciones de red que necesitan verificar de forma programática el estado de conectividad, interfaces, túneles VPN, MPLS y versión de sistema operativo de los dispositivos gestionados.

## Índice

- [Características](#características)
- [Arquitectura del proyecto](#arquitectura-del-proyecto)
- [Requisitos previos](#requisitos-previos)
- [Instalación](#instalación)
- [Configuración](#configuración)
- [Uso básico](#uso-básico)
- [Excepciones](#excepciones)
- [Logging](#logging)
- [Pruebas](#pruebas)
- [Licencia](#licencia)

## Características

- **Autodetección de dispositivo**: identifica automáticamente si el equipo es Juniper o Fortinet antes de conectarse.
- **Conexión gestionada como context manager**: `DeviceManager` abre y cierra la sesión SSH de forma segura usando `with`.
- **Checks de diagnóstico**: verificación de conexión, versión de sistema operativo, interfaces, comando `stitch` y `diagnose`.
- **Consulta de estado**: obtención de uptime del equipo, estado de túneles VPN y estado de MPLS.
- **Credenciales cifradas**: las credenciales de acceso a los firewalls y a la base de datos nunca se guardan en texto plano; se cifran en disco mediante el paquete `secure-credentials-roan`.
- **Selección de credenciales por país**: las credenciales a usar (LAM o México) se determinan automáticamente según el país asociado a la IP del dispositivo, consultado en base de datos.
- **Logging estructurado**: cada módulo registra su actividad en archivos de log independientes mediante `w-log-roan`.
- **Comandos por tipo de dispositivo**: diccionario central (`COMMAND_DICT`) que traduce cada operación al comando específico de Juniper o Fortinet.

## Arquitectura del proyecto

```
firewall_operations_roan/
├── src/firewall_operations/
│   ├── __init__.py                  # Punto de entrada del paquete (exports públicos)
│   ├── application/
│   │   ├── check_firewall.py        # Checks: conexión, so_info, interfaz, stitch, diagnose
│   │   ├── get_status.py            # Estado: uptime, túneles, MPLS, log de stitch
│   │   ├── run_sp_sel.py            # Stored procedures: credenciales y catálogo de sucursales
│   │   └── Exceptions.py            # Excepciones propias del dominio
│   ├── config/
│   │   ├── firewall.py              # DeviceManager: conexión SSH vía Netmiko (Fortinet/Juniper)
│   │   ├── database.py              # Conexión a MySQL (PyMySQL)
│   │   └── commands.py              # Diccionario de comandos por tipo de dispositivo
│   ├── secure/
│   │   └── secure.py                # Cifrado/descifrado de credenciales en disco
│   └── utils/
│       └── utils.py                 # Utilidades (desencriptado de blobs de BD)
├── tests/                           # Pruebas (excluidas del control de versiones)
├── pyproject.toml                   # Metadatos y dependencias del paquete
├── requirements313.txt              # Dependencias fijadas para Python 3.13
└── LICENSE
```

### Flujo general

1. `DeviceManager(ip)` obtiene el país asociado a la IP (`get_pais_from_ip`) y las credenciales correspondientes (LAM o MX) desde base de datos, vía `run_sp_sel.py`.
2. Al entrar al `with`, se hace autodetección de puerto/tipo de dispositivo (`get_device_type`) y se abre la sesión SSH con Netmiko (`ConnectHandler`).
3. Sobre la conexión (`conn`) y el tipo de dispositivo (`device`) se ejecutan los checks (`check_firewall.py`) o las consultas de estado (`get_status.py`), que traducen la operación al comando correcto usando `COMMAND_DICT`.
4. Al salir del bloque `with`, la conexión SSH se cierra automáticamente.

## Requisitos previos

- Python **3.10 o superior** (probado con Python 3.13).
- Acceso de red a los firewalls a gestionar (puerto 22 para Juniper, puerto 20424 para Fortinet).
- Acceso a una base de datos MySQL con los stored procedures esperados (`sp_selfwlam`, `sp_selfwMX`, `sp_sel_pais_suc`, `obtener_lista_fw`) en el esquema `automcae`.
- Los paquetes internos `secure-credentials-roan` y `w-log-roan` (dependencias del proyecto, se instalan automáticamente).

## Instalación

```bash
pip install firewall-operations-roan
pip install --index-url https://{username}:{password}@gitea.example.com/api/packages/{owner}/pypi/simple --no-deps {package_name}
```

O bien, para desarrollo local dentro del repositorio:

```bash
git clone <url-del-repositorio>
cd firewall_operations_roan
python -m venv venv
venv\Scripts\activate          # En Windows
pip install -e .
```

Si se requiere instalar el set de dependencias fijadas para Python 3.13:

```bash
pip install -r requirements313.txt
```

## Configuración

### Credenciales de base de datos y de firewall

Las credenciales **no se escriben en el código**. Se colocan una sola vez en un archivo de texto plano que la herramienta cifra y elimina automáticamente:

1. Crear la carpeta `secure_data/` en la raíz del proyecto (si no existe).
2. Colocar dentro un archivo `access.txt` con el siguiente formato:

   ```
   host=<host_bd>
   user=<usuario_bd>
   password=<password_bd>
   database=<nombre_bd>
   port=<puerto_bd>
   ```

3. Al primer uso, `secure.py` cifra automáticamente este archivo generando `credentials.enc` y `secret.key` dentro de `secure_data/`, y elimina el `access.txt` original. Las siguientes ejecuciones descifran las credenciales en memoria bajo demanda.

También puede ejecutarse manualmente el cifrado:

```bash
python -m firewall_operations.secure.secure
```

> **Importante:** `secure_data/` está excluido en `.gitignore`; nunca debe subirse al control de versiones.

### Logging

Por defecto, todos los módulos escriben sus logs en `C:\logs\<módulo>\`. Este directorio (`BASE_DIR`) está definido en cada archivo (`check_firewall.py`, `get_status.py`, `firewall.py`, `secure.py`) y puede modificarse ahí si se requiere otra ruta.

## Uso básico

```python
from firewall_operations import DeviceManager, check_so_info, get_uptime_fw
from firewall_operations.application.Exceptions import UnknownActionError

ip = "10.0.0.1"

# Instanciando la conexión (autodetecta Fortinet/Juniper y credenciales por país)
manager = DeviceManager(ip)

with manager as conn:
    device = manager.device_type

    # Prueba de comando "version"
    try:
        check_so_info(conn, device)
        print("Comando de versión ejecutado correctamente")
    except UnknownActionError as ue:
        print(f"El comando no está permitido en este dispositivo: {ue}")

    # Consultar el uptime del equipo
    uptime = get_uptime_fw(conn, device)
    print(uptime)
```

### Verificar solo la conectividad

```python
from firewall_operations import check_conn

if check_conn("10.0.0.1"):
    print("Conexión exitosa")
else:
    print("No se pudo establecer conexión")
```

### Consultar estado de túneles VPN y MPLS

```python
from firewall_operations import DeviceManager, get_status_tunnels, get_status_mpls

with DeviceManager("10.0.0.1") as conn:
    device = "generic"  # o "juniper_junos", según el dispositivo detectado

    tunnels = get_status_tunnels(conn, device)
    mpls = get_status_mpls(conn, device)

    print(tunnels)
    print(mpls)
```

## Excepciones

El proyecto define excepciones propias en `firewall_operations.application.Exceptions` para distinguir el origen del error:

| Excepción | Causa |
|---|---|
| `ConnectionError` | Falla de conexión al dispositivo |
| `AuthenticationError` | Credenciales inválidas |
| `TimeoutException` | El dispositivo no respondió a tiempo |
| `SSHExceptionRaise` | Error en la capa de comunicación SSH |
| `UnknownActionError` | El comando enviado no está permitido/reconocido por el dispositivo ("Unknown action") |
| `ShowVersionError` | Error específico al ejecutar el comando de versión |
| `StitchComandVersion` | Error específico al ejecutar el comando `stitch` |
| `DiagnoseError` | Error específico al ejecutar el comando `diagnose` |
| `CredentialsNotFoundError` | No se encontraron credenciales cifradas ni `access.txt` para generarlas |

## Pruebas

El directorio `tests/` contiene las pruebas del proyecto (`tests_db.py`, `tests_firewall.py`, `test_get_firewall_status.py`, `test_get_status_fw.py`, `test_run_sp.py`). Este directorio está excluido de `.gitignore` y no se distribuye junto con el paquete.

## Licencia

Este proyecto se distribuye bajo licencia **MIT**. Ver el archivo [LICENSE](LICENSE) para más detalles.

## Autor

Angel Rogelio Argonza Roblero
