bemade-addons/unifi_integration/models/unifi_vlan.py
2025-03-27 15:34:13 -04:00

232 lines
7.2 KiB
Python

# -*- coding: utf-8 -*-
import json
import logging
from odoo import models, fields, api, _
from .unifi_common import UnifiCommonMixin
from odoo.exceptions import ValidationError
_logger = logging.getLogger(__name__)
class UnifiVLAN(models.Model, UnifiCommonMixin):
"""Modèle pour gérer les VLANs UniFi
Ce modèle représente les VLANs configurés dans les sites UniFi.
Il permet de stocker et gérer les informations des VLANs depuis les API Controller et Site Manager.
"""
_name = 'unifi.vlan'
_description = 'UniFi VLAN'
_order = 'vlan_id'
# Champs d'identification
name = fields.Char(
string='Nom',
required=True,
help='Nom du VLAN'
)
vlan_id = fields.Integer(
string='ID VLAN',
required=True,
help='Identifiant numérique du VLAN'
)
# Champs techniques
enabled = fields.Boolean(
string='Activé',
default=True,
help='Indique si le VLAN est activé'
)
purpose = fields.Selection(
selection=[
('corporate', 'Corporate'),
('guest', 'Guest'),
('iot', 'IoT'),
('management', 'Management'),
('voip', 'VoIP'),
('other', 'Autre')
],
string='Usage',
default='corporate',
help='Usage prévu pour ce VLAN'
)
# Champs réseau
subnet = fields.Char(
string='Sous-réseau',
help='Sous-réseau au format CIDR (ex: 192.168.1.0/24)'
)
network_id = fields.Many2one(
comodel_name='unifi.network',
string='Réseau associé',
help='Réseau associé à ce VLAN'
)
# Champs de relation
site_id = fields.Many2one(
comodel_name='unifi.site',
string='Site',
required=True,
ondelete='cascade',
help='Site UniFi auquel ce VLAN appartient'
)
# Champs de synchronisation
vlan_api_id = fields.Char(
string='ID API',
help='Identifiant unique du VLAN dans l\'API UniFi'
)
last_sync = fields.Datetime(
string='Dernière synchronisation',
help='Date et heure de la dernière synchronisation avec l\'API'
)
created_at = fields.Datetime(
string='Créé le',
help='Date et heure de création du VLAN dans UniFi'
)
updated_at = fields.Datetime(
string='Mis à jour le',
help='Date et heure de la dernière mise à jour du VLAN dans UniFi'
)
# Données brutes
raw_data = fields.Text(
string='Données brutes',
help='Données brutes JSON du VLAN depuis l\'API'
)
raw_data_json = fields.Text(
string='Données brutes (JSON)',
compute='_compute_raw_data_json',
help='Données brutes du VLAN au format JSON formaté'
)
@api.depends('raw_data')
def _compute_raw_data_json(self):
for record in self:
record.raw_data_json = self.format_raw_data_json(record.raw_data)
_sql_constraints = [
('vlan_id_site_uniq', 'unique(vlan_id, site_id)', 'L\'ID VLAN doit être unique par site!')
]
@api.model_create_multi
def create(self, vals_list):
"""Surcharge de la méthode create pour ajouter des validations
Args:
vals_list (list): Liste des valeurs pour créer les enregistrements
Returns:
unifi.vlan: Les enregistrements créés
"""
return super(UnifiVLAN, self).create(vals_list)
def write(self, vals):
"""Surcharge de la méthode write pour ajouter des validations
Args:
vals (dict): Valeurs à écrire
Returns:
bool: Résultat de l'opération d'écriture
"""
return super(UnifiVLAN, self).write(vals)
@api.model
def create_or_update_from_api(self, site, vlan_data):
"""Crée ou met à jour un VLAN à partir des données de l'API
Cette méthode analyse les données de l'API et crée ou met à jour
l'enregistrement VLAN correspondant.
Args:
site (unifi.site): L'enregistrement du site
vlan_data (dict): Les données du VLAN depuis l'API
Returns:
unifi.vlan: L'enregistrement VLAN créé ou mis à jour
"""
# Extraire l'ID API du VLAN
vlan_api_id = vlan_data.get('_id') or vlan_data.get('id')
if not vlan_api_id:
_logger.warning("Données de VLAN sans ID API: %s", json.dumps(vlan_data))
return False
# Rechercher un VLAN existant avec cet ID API
existing_vlan = self.search([
('vlan_api_id', '=', vlan_api_id),
('site_id', '=', site.id)
], limit=1)
# Extraire les valeurs communes
vlan_id = vlan_data.get('vlan_id') or vlan_data.get('id')
if not vlan_id and isinstance(vlan_id, int):
_logger.warning("Données de VLAN sans ID numérique: %s", json.dumps(vlan_data))
return False
# Préparer les valeurs pour la création ou mise à jour
vals = {
'vlan_api_id': vlan_api_id,
'vlan_id': vlan_id,
'name': vlan_data.get('name') or f"VLAN {vlan_id}",
'purpose': vlan_data.get('purpose', 'corporate'),
'enabled': vlan_data.get('enabled', True),
'site_id': site.id,
'raw_data': json.dumps(vlan_data),
'last_sync': fields.Datetime.now()
}
# Ajouter les champs spécifiques s'ils existent
if 'subnet' in vlan_data:
vals['subnet'] = vlan_data['subnet']
# Dates de création et mise à jour
if 'created_at' in vlan_data:
vals['created_at'] = fields.Datetime.from_string(vlan_data['created_at'])
if 'updated_at' in vlan_data:
vals['updated_at'] = fields.Datetime.from_string(vlan_data['updated_at'])
if existing_vlan:
# Mettre à jour le VLAN existant
existing_vlan.write(vals)
return existing_vlan
else:
# Créer un nouveau VLAN
return self.create(vals)
@api.model
def sync_vlans_from_api(self, site):
"""Synchronise les VLANs depuis l'API UniFi
Cette méthode récupère tous les VLANs depuis l'API et les crée ou met à jour
dans la base de données.
Args:
site (unifi.site): L'enregistrement du site
Returns:
list: Liste des VLANs synchronisés
"""
# Récupérer les données des VLANs depuis l'API
vlan_data_list = site.get_vlan_data()
if not vlan_data_list:
_logger.warning("Aucune donnée de VLAN récupérée pour le site %s", site.name)
return False
synced_vlans = []
# Créer ou mettre à jour chaque VLAN
for vlan_data in vlan_data_list:
vlan = self.create_or_update_from_api(site, vlan_data)
if vlan:
synced_vlans.append(vlan)
return synced_vlans