232 lines
7.2 KiB
Python
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
|