Source code for networkapi.filterequiptype.models

# -*- coding: utf-8 -*-
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import logging

from django.core.exceptions import ObjectDoesNotExist
from django.db import models

from networkapi.filter.models import Filter
from networkapi.filter.models import FilterError
from networkapi.models.BaseModel import BaseModel


[docs]class FilterEquipTypeDuplicateError(FilterError): """Returns exception for FilterEquipType search by filter and equiptype.""" def __init__(self, cause, message=None): FilterError.__init__(self, cause, message)
[docs]class CantDissociateError(FilterError): """Returns exception when a equip type cant be dissociated.""" def __init__(self, cause, message=None): FilterError.__init__(self, cause, message)
[docs]class FilterEquipType(BaseModel): id = models.AutoField(primary_key=True, db_column='id') filter = models.ForeignKey(Filter, db_column='id_filter') equiptype = models.ForeignKey( 'equipamento.TipoEquipamento', db_column='id_equiptype') log = logging.getLogger('FilterEquipType') class Meta(BaseModel.Meta): db_table = u'filter_equiptype_xref' managed = True unique_together = ('filter', 'equiptype')
[docs] def validate(self): """Validates if EquipType is already associated with Filter @raise FilterEquipTypeDuplicateError: if EquipType is already associated with Filter """ try: FilterEquipType.objects.get( filter=self.filter, equiptype=self.equiptype) raise FilterEquipTypeDuplicateError( None, u'EquipType already registered for the Filter.') except ObjectDoesNotExist: pass
[docs] def delete(self): from networkapi.ambiente.models import Ambiente from networkapi.ip.models import NetworkIPv4, NetworkIPv6, IpEquipamento, Ipv6Equipament from networkapi.vlan.models import Vlan from django.db.models import Count # Get environments using this filter envs_using_this_filter = [ env.id for env in Ambiente.objects.filter(filter=self.filter.id)] if len(envs_using_this_filter) > 0: # Test if there's filter case 1 and 2, two networks with same ip # range or equipment with two ips in networks with same ip range # Get filters using this equip type and not this filter filters_using_eq_tp = [fet.filter.id for fet in FilterEquipType.objects.filter( equiptype=self.equiptype.id).exclude(filter=self.filter.id)] # Get environments using other filters envs_using_filters = [ env.id for env in Ambiente.objects.filter(filter__in=filters_using_eq_tp)] # Get all networks from environments using this filter, grouped by # ip range this_filter_nets = NetworkIPv4.objects.filter(vlan__ambiente__in=envs_using_this_filter).values( 'oct1', 'oct2', 'oct3', 'oct4', 'block').annotate(count=Count('id')) for net in this_filter_nets: if net['count'] > 1: self.log.error( u'Cannot dissociate filter and equip type because there are two networks with same ip range using filters') raise CantDissociateError( {'equiptype': self.equiptype.tipo_equipamento, 'filter_name': self.filter.name}, u'Cannot dissociate filter and equip type') # Get all networks from environments using other filters, grouped # by ip range other_filter_nets = NetworkIPv4.objects.filter(vlan__ambiente__in=envs_using_filters).values( 'oct1', 'oct2', 'oct3', 'oct4', 'block').annotate(count=Count('id')) for net in this_filter_nets: if net in other_filter_nets: self.log.error( u'Cannot dissociate filter and equip type because there are two networks with same ip range using filters') raise CantDissociateError( {'equiptype': self.equiptype.tipo_equipamento, 'filter_name': self.filter.name}, u'Cannot dissociate filter and equip type') # Get all networks from environments using this filter, grouped by # ip range this_filter_nets = NetworkIPv6.objects.filter(vlan__ambiente__in=envs_using_this_filter).values( 'block1', 'block2', 'block3', 'block4', 'block5', 'block6', 'block7', 'block8', 'block').annotate(count=Count('id')) for net in this_filter_nets: if net['count'] > 1: self.log.error( u'Cannot dissociate filter and equip type because there are two networks with same ip range using filters') raise CantDissociateError( {'equiptype': self.equiptype.tipo_equipamento, 'filter_name': self.filter.name}, u'Cannot dissociate filter and equip type') # Get all networks from environments using other filters, grouped # by ip range other_filter_nets = NetworkIPv6.objects.filter(vlan__ambiente__in=envs_using_filters).values( 'block1', 'block2', 'block3', 'block4', 'block5', 'block6', 'block7', 'block8', 'block').annotate(count=Count('id')) for net in this_filter_nets: if net in other_filter_nets: self.log.error( u'Cannot dissociate filter and equip type because there are two networks with same ip range using filters') raise CantDissociateError( {'equiptype': self.equiptype.tipo_equipamento, 'filter_name': self.filter.name}, u'Cannot dissociate filter and equip type') # End of filter test case 1 and 2 # Filter test case 3 vlans_in_environments = Vlan.objects.filter( ambiente__in=envs_using_this_filter + envs_using_filters).values('num_vlan').annotate(count=Count('id')) for vlan_group in vlans_in_environments: # Two or more vlans with same number if vlan_group['count'] > 1: # Get vlans with same number vlans_same_number = [vlan.id for vlan in Vlan.objects.filter( ambiente__in=envs_using_this_filter + envs_using_filters, num_vlan=vlan_group['num_vlan'])] # Equips for each vlan equips_in_diff_vlans = dict() # All equips from these vlans final_list = list() total_len = 0 for vlan_ in vlans_same_number: # Create entry in dict if vlan_ not in equips_in_diff_vlans: equips_in_diff_vlans[vlan_] = list() # Get all equips in networks of vlan for ipeq in IpEquipamento.objects.filter(ip__networkipv4__vlan=vlan_): equips_in_diff_vlans[vlan_].append( ipeq.equipamento.id) final_list.append(ipeq.equipamento.id) # Get all equips in networks v6 of vlan for ipv6eq in Ipv6Equipament.objects.filter(ip__networkipv6__vlan=vlan_): equips_in_diff_vlans[vlan_].append( ipv6eq.equipamento.id) final_list.append(ipv6eq.equipamento.id) total_len = total_len + \ len(equips_in_diff_vlans[vlan_]) # If any equip is duplicated if len(list(set(final_list))) != total_len: # Get equipments in more than one vlan equips = [ eqp for eqp in final_list if final_list.count(eqp) > 1] # Test if these equips are in environments using this # filter if len(IpEquipamento.objects.filter(ip__networkipv4__vlan__ambiente__in=envs_using_this_filter, equipamento__in=equips)) > 0 or \ len(Ipv6Equipament.objects.filter(ip__networkipv6__vlan__ambiente__in=envs_using_this_filter, equipamento__in=equips)) > 0: self.log.error( u'Cannot dissociate filter and equip type because there are two vlans with same equipment') raise CantDissociateError( {'equiptype': self.equiptype.tipo_equipamento, 'filter_name': self.filter.name}, u'Cannot dissociate filter and equip type') # End of filter test case 3 super(FilterEquipType, self).delete()