# -*- 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 _mysql_exceptions import OperationalError
from django.core.exceptions import ObjectDoesNotExist
from django.db import models
from django.db import transaction
from django.db.models import get_model
from rest_framework import status
from networkapi.ambiente.models import ConfigEnvironmentInvalidError
from networkapi.ambiente.models import IP_VERSION
from networkapi.api_network.exceptions import InvalidInputException
from networkapi.api_network.exceptions import NetworkConflictException
from networkapi.api_rest.exceptions import ObjectDoesNotExistException
from networkapi.api_vip_request import syncs
from networkapi.distributedlock import distributedlock
from networkapi.distributedlock import LOCK_ENVIRONMENT
from networkapi.distributedlock import LOCK_ENVIRONMENT_ALLOCATES
from networkapi.distributedlock import LOCK_IP_EQUIPMENT
from networkapi.distributedlock import LOCK_IP_EQUIPMENT_ONE
from networkapi.distributedlock import LOCK_VINTERFACE
from networkapi.distributedlock import LOCK_IPV4
from networkapi.distributedlock import LOCK_IPV6
from networkapi.distributedlock import LOCK_IPV6_EQUIPMENT
from networkapi.distributedlock import LOCK_IPV6_EQUIPMENT_ONE
from networkapi.distributedlock import LOCK_NETWORK_IPV4
from networkapi.distributedlock import LOCK_NETWORK_IPV6
from networkapi.distributedlock import LOCK_VIP
from networkapi.equipamento.models import EquipamentoAmbienteDuplicatedError
from networkapi.equipamento.models import EquipamentoAmbienteNotFoundError
from networkapi.equipamento.models import EquipamentoError
from networkapi.exception import InvalidValueError
from networkapi.exception import NetworkActiveError
from networkapi.infrastructure.ipaddr import AddressValueError
from networkapi.infrastructure.ipaddr import IPNetwork
from networkapi.infrastructure.ipaddr import IPv4Address
from networkapi.infrastructure.ipaddr import IPv4Network
from networkapi.infrastructure.ipaddr import IPv6Address
from networkapi.infrastructure.ipaddr import IPv6Network
from networkapi.models.BaseModel import BaseModel
from networkapi.queue_tools import queue_keys
from networkapi.queue_tools.rabbitmq import QueueManager
from networkapi.util import mount_ipv4_string
from networkapi.util import mount_ipv6_string
from networkapi.util import network
from networkapi.util.decorators import cached_property
from networkapi.util.geral import create_lock_with_blocking
from networkapi.util.geral import destroy_lock
from networkapi.util.geral import get_app
log = logging.getLogger(__name__)
[docs]class NetworkIPv4Error(Exception):
"""Generic exception for everything related to NetworkIPv4."""
def __init__(self, cause, message=None):
self.cause = cause
self.message = message
def __str__(self):
msg = u'Caused by: %s, Message: %s' % (self.cause, self.message)
return msg.encode('utf-8', 'replace')
[docs]class NetworkIPv4ErrorV3(Exception):
"""Generic exception for everything related to NetworkIPv4."""
def __init__(self, message):
self.message = message
def __str__(self):
return str(self.message)
[docs]class NetworkIPv6ErrorV3(Exception):
"""Generic exception for everything related to NetworkIPv6."""
def __init__(self, message):
self.message = message
def __str__(self):
return str(self.message)
[docs]class NetworkIPv6Error(Exception):
"""Generic exception for everything related to NetworkIPv6."""
def __init__(self, cause, message=None):
self.cause = cause
self.message = message
def __str__(self):
msg = u'Caused by: %s, Message: %s' % (self.cause, self.message)
return msg.encode('utf-8', 'replace')
[docs]class NetworkIPvXError(Exception):
"""Generic exception for everything related to both NetworkIPv4 and NetworkIPv6."""
def __init__(self, cause, message=None):
self.cause = cause
self.message = message
def __str__(self):
msg = u'Caused by: %s, Message: %s' % (self.cause, self.message)
return msg.encode('utf-8', 'replace')
[docs]class NetworkIPRangeEnvError(NetworkIPvXError):
"""Exception for two environments with same ip range when trying to add new network."""
def __init__(self, cause, message=None):
self.cause = cause
self.message = message
def __str__(self):
msg = u'Caused by: %s, Message: %s' % (self.cause, self.message)
return msg.encode('utf-8', 'replace')
[docs]class IpErrorV3(Exception):
"""Representa um erro ocorrido durante acesso à tabelas relacionadas com IP."""
def __init__(self, message):
self.message = message
def __str__(self):
return str(self.message)
[docs]class IpError(Exception):
"""Representa um erro ocorrido durante acesso à tabelas relacionadas com IP."""
def __init__(self, cause, message=None):
self.cause = cause
self.message = message
def __str__(self):
msg = u'Causa: %s, Mensagem: %s' % (self.cause, self.message)
return msg.encode('utf-8', 'replace')
[docs]class NetworkIPv4NotFoundError(NetworkIPv4Error):
"""Exception to search by primary key."""
status_code = status.HTTP_404_NOT_FOUND
def __init__(self, cause, message=None):
NetworkIPv4Error.__init__(self, cause, message)
[docs]class NetworkIPv6NotFoundError(NetworkIPv6Error):
"""Exception to search by primary key."""
def __init__(self, cause, message=None):
NetworkIPv6Error.__init__(self, cause, message)
[docs]class NetworkIPvXNotFoundError(NetworkIPvXError):
"""Exception to search by primary key."""
def __init__(self, cause, message=None):
NetworkIPvXError.__init__(self, cause, message)
[docs]class NetworkIPv4AddressNotAvailableError(NetworkIPv4Error):
"""Exception to unavailable address to create a new NetworkIPv4."""
def __init__(self, cause, message=None):
NetworkIPv4Error.__init__(self, cause, message)
[docs]class NetworkIPv6AddressNotAvailableError(NetworkIPv6Error):
"""Exception to unavailable address to create a new NetworkIPv6."""
def __init__(self, cause, message=None):
NetworkIPv6Error.__init__(self, cause, message)
[docs]class NetworkIpAddressNotAvailableError(NetworkIPvXError):
"""Exception to unavailable address."""
def __init__(self, cause, message=None):
NetworkIPvXError.__init__(self, cause, message)
[docs]class IpNotFoundError(IpError):
"""Retorna exceção para pesquisa de IP por chave primária."""
def __init__(self, cause, message=None):
IpError.__init__(self, cause, message)
[docs]class IpEquipmentNotFoundError(IpError):
"""Retorna exceção para pesquisa de IP-Equipamento por chave primária/ip e equipamento."""
def __init__(self, cause, message=None):
IpError.__init__(self, cause, message)
[docs]class IpEquipamentoDuplicatedError(IpError):
"""Retorna exceção para pesquisa de IP-Equipamento duplicado."""
def __init__(self, cause, message=None):
IpError.__init__(self, cause, message)
[docs]class IpNotAvailableError(IpError):
"""Retorna exceção porque não existe um IP disponível para a VLAN."""
def __init__(self, cause, message=None):
IpError.__init__(self, cause, message)
[docs]class IpEquipmentAlreadyAssociation(IpError):
"""Retorna exceção caso um Ip já esteja associado a um determinado equipamento."""
def __init__(self, cause, message=None):
IpError.__init__(self, cause, message)
[docs]class IpNotFoundByEquipAndVipError(IpError):
"""Retorna exceção caso um Ip já esteja associado a um determinado equipamento."""
def __init__(self, cause, message=None):
IpError.__init__(self, cause, message)
[docs]class IpCantBeRemovedFromVip(IpError):
"""Retorna exceção caso um Ip não possa ser excluído por estar em uso por uma requisição VIP."""
def __init__(self, cause, message=None):
IpError.__init__(self, cause, message)
[docs]class NetworkNotInEvip(IpError):
"""Retorna exceção caso não haja uma rede Ipv4 ou Ipv6 para o Ambiente Vip."""
def __init__(self, cause, message=None):
IpError.__init__(self, cause, message)
[docs]class IpRangeAlreadyAssociation(IpError):
"""Returns exception for equipment already having ip with same ip range in another network."""
def __init__(self, cause, message=None):
IpError.__init__(self, cause, message)
[docs]class IpEquipCantDissociateFromVip(IpError):
"""Returns exception when trying to dissociate ip and equipment, but equipment is the last balancer for Vip Request"""
def __init__(self, cause, message=None):
IpError.__init__(self, cause, message)
[docs]class IpCantRemoveFromServerPool(IpError):
"""Returns exception when trying to dissociate ip and equipment, but equipment is the last balancer for Vip Request"""
def __init__(self, cause, message=None):
IpError.__init__(self, cause, message)
[docs]class NetworkIPv4(BaseModel):
id = models.AutoField(
primary_key=True
)
oct1 = models.IntegerField(
db_column='rede_oct1'
)
oct2 = models.IntegerField(
db_column='rede_oct2'
)
oct3 = models.IntegerField(
db_column='rede_oct3'
)
oct4 = models.IntegerField(
db_column='rede_oct4'
)
block = models.IntegerField(
db_column='bloco'
)
mask_oct1 = models.IntegerField(
db_column='masc_oct1'
)
mask_oct2 = models.IntegerField(
db_column='masc_oct2'
)
mask_oct3 = models.IntegerField(
db_column='masc_oct3'
)
mask_oct4 = models.IntegerField(
db_column='masc_oct4'
)
broadcast = models.CharField(
max_length=15,
blank=False
)
vlan = models.ForeignKey(
'vlan.Vlan',
db_column='id_vlan'
)
network_type = models.ForeignKey(
'vlan.TipoRede',
null=True,
db_column='id_tipo_rede'
)
ambient_vip = models.ForeignKey(
'ambiente.EnvironmentVip',
null=True,
db_column='id_ambientevip'
)
cluster_unit = models.CharField(
max_length=45,
null=True,
db_column='cluster_unit'
)
active = models.BooleanField()
log = logging.getLogger('NetworkIPv4')
class Meta(BaseModel.Meta):
db_table = u'redeipv4'
managed = True
def __str__(self):
return self.networkv4
def _get_networkv4(self):
"""Returns formated ip."""
return '{}/{}'.format(self.formated_octs, self.block)
networkv4 = property(_get_networkv4)
def _get_formated_octs(self):
"""Returns formated octs."""
return '{}.{}.{}.{}'.format(self.oct1, self.oct2, self.oct3, self.oct4)
formated_octs = property(_get_formated_octs)
def _get_mask_formated(self):
"""Returns formated mask."""
return '{}.{}.{}.{}'.format(self.mask_oct1, self.mask_oct2,
self.mask_oct3, self.mask_oct4)
mask_formated = property(_get_mask_formated)
def _get_wildcard(self):
return '%d.%d.%d.%d' % (255 - self.mask_oct1, 255 - self.mask_oct2,
255 - self.mask_oct3, 255 - self.mask_oct4)
wildcard = property(_get_wildcard)
def _get_dhcprelay(self):
dhcprelay = self.dhcprelayipv4_set.all()
return dhcprelay
dhcprelay = property(_get_dhcprelay)
[docs] @classmethod
def get_by_pk(cls, id):
"""Get NetworkIPv4 by id.
@return: NetworkIPv4.
@raise NetworkIPv4NotFoundError: NetworkIPv4 is not registered.
@raise NetworkIPv4Error: Failed to search for the NetworkIPv4.
@raise OperationalError: Lock wait timeout exceeded.
"""
try:
return NetworkIPv4.objects.filter(id=id).uniqueResult()
except ObjectDoesNotExist, e:
raise ObjectDoesNotExistException(
u'There is no NetworkIPv4 with pk = %s.' % id)
except OperationalError, e:
cls.log.error(u'Lock wait timeout exceeded.')
raise OperationalError(
e, u'Lock wait timeout exceeded; try restarting transaction')
except Exception, e:
cls.log.error(u'Failure to search the NetworkIPv4.')
raise NetworkIPv4Error(e, u'Failure to search the NetworkIPv4.')
[docs] def activate(self, authenticated_user):
try:
self.active = 1
self.save()
net_slz = get_app('api_network', 'serializers.v3')
serializer = net_slz.NetworkIPv4V3Serializer(
self,
include=('vlan__details__environment__basic',))
data_to_queue = serializer.data
data_to_queue.update({
'description': queue_keys.NETWORKv4_ACTIVATE
})
# Send to Queue
queue_manager = QueueManager(broker_vhost='tasks',
queue_name='tasks.aclapi',
exchange_name='tasks.aclapi',
routing_key='tasks.aclapi')
queue_manager.append({
'action': queue_keys.NETWORKv4_ACTIVATE,
'kind': queue_keys.NETWORKv4_KEY,
'data': data_to_queue
})
queue_manager.send()
except Exception, e:
self.log.error(u'Error activating NetworkIPv4.')
raise NetworkIPv4Error(e, u'Error activating NetworkIPv4.')
[docs] def deactivate(self, authenticated_user, commit=False):
"""
Update status column to 'active = 0'
@param authenticated_user: User authenticate
@raise NetworkIPv4Error: Error disabling a NetworkIPv4.
"""
from networkapi.api_network.serializers.v1 import NetworkIPv4Serializer
try:
self.active = 0
# Send to Queue
queue_manager = QueueManager(broker_vhost='tasks',
queue_name='tasks.aclapi',
exchange_name='tasks.aclapi',
routing_key='tasks.aclapi')
serializer = NetworkIPv4Serializer(self)
data_to_queue = serializer.data
data_to_queue.update({
'description': queue_keys.NETWORKv4_DEACTIVATE})
queue_manager.append({
'action': queue_keys.NETWORKv4_DEACTIVATE,
'kind': queue_keys.NETWORKv4_KEY,
'data': data_to_queue})
queue_manager.send()
self.save(authenticated_user, commit=commit)
except Exception, e:
self.log.error(u'Error disabling NetworkIPv4.')
raise NetworkIPv4Error(e, u'Error disabling NetworkIPv4.')
[docs] def edit_network_ipv4(self, authenticated_user, id_net_type, id_env_vip, cluster_unit):
try:
self.network_type = id_net_type
self.ambient_vip = id_env_vip
self.cluster_unit = cluster_unit
self.save()
except Exception, e:
self.log.error(u'Error on update NetworkIPv4.')
raise NetworkIPv4Error(e, u'Error on update NetworkIPv4.')
[docs] def add_network_ipv4(self, user, id_vlan, network_type, evip, prefix=None):
"""Allocate and Insert new NetworkIPv4 in database
@return: Vlan map
@raise VlanNotFoundError: Vlan is not registered.
@raise VlanError: Failed to search for the Vlan
@raise ConfigEnvironmentInvalidError: Invalid Environment Configuration or not registered
@raise NetworkIPv4Error: Error persisting a NetworkIPv4.
@raise NetworkIPv4AddressNotAvailableError: Unavailable address to create a NetworkIPv4.
@raise Invalid: Unavailable address to create a NetworkIPv4.
@raise InvalidValueError: Network type does not exist.
"""
configenvironment = get_model('ambiente', 'ConfigEnvironment')
vlan_model = get_model('vlan', 'Vlan')
self.vlan = vlan_model().get_by_pk(id_vlan)
network_found = None
stop = False
internal_network_type = None
type_ipv4 = IP_VERSION.IPv4[0]
try:
# Find all configs type v4 in environment
configs = configenvironment.get_by_environment(
self.vlan.ambiente.id).filter(ip_config__type=IP_VERSION.IPv4[0])
# If not found, an exception is thrown
if len(configs) == 0:
raise ConfigEnvironmentInvalidError(
None, u'Invalid Configuration')
# Needs to lock IPv4 listing when there are any allocation in progress
# If not, it will allocate two networks with same range
with distributedlock(LOCK_ENVIRONMENT % self.vlan.ambiente.id):
# Find all networks ralated to environment
nets = NetworkIPv4.objects.filter(
vlan__ambiente__id=self.vlan.ambiente.id)
# Cast to API class
networksv4 = set([(IPv4Network(
'%d.%d.%d.%d/%d' % (net_ip.oct1, net_ip.oct2, net_ip.oct3, net_ip.oct4, net_ip.block))) for net_ip in nets])
# For each configuration founded in environment
for config in configs:
# If already get a network stop this
if stop:
break
# Need to be IPv4
if config.ip_config.type == IP_VERSION.IPv4[0]:
net4 = IPv4Network(config.ip_config.subnet)
if prefix is not None:
new_prefix = int(prefix)
else:
new_prefix = int(config.ip_config.new_prefix)
self.log.info(
u'Prefix that will be used: %s' % new_prefix)
# For each subnet generated with configs
for subnet in net4.iter_subnets(new_prefix=new_prefix):
net_found = True
for netv4 in networksv4:
if subnet in netv4:
net_found = False
# Checks if the network generated is UNUSED
if net_found:
# Checks if it is subnet/supernet of any
# existing network
in_range = network_in_range(
self.vlan, subnet, type_ipv4)
if not in_range:
continue
# If not this will be USED
network_found = subnet
if network_type:
internal_network_type = network_type
elif config.ip_config.network_type is not None:
internal_network_type = config.ip_config.network_type
else:
self.log.error(
u'Parameter tipo_rede is invalid. Value: %s', network_type)
raise InvalidValueError(
None, 'network_type', network_type)
# Stop generation logic
stop = True
break
# If not IPv4
else:
# Throw an exception
raise ConfigEnvironmentInvalidError(
None, u'Invalid Configuration')
# Checks if found any available network
if network_found is None:
# If not found, an exception is thrown
raise NetworkIPv4AddressNotAvailableError(
None, u'Unavailable address to create a NetworkIPv4.')
# Set octs by network generated
self.oct1, self.oct2, self.oct3, self.oct4 = str(
network_found.network).split('.')
# Set block by network generated
self.block = network_found.prefixlen
# Set mask by network generated
self.mask_oct1, self.mask_oct2, self.mask_oct3, self.mask_oct4 = str(
network_found.netmask).split('.')
# Set broadcast by network generated
self.broadcast = network_found.broadcast
try:
self.network_type = internal_network_type
self.ambient_vip = evip
self.save()
transaction.commit()
except Exception, e:
self.log.error(u'Error persisting a NetworkIPv4.')
raise NetworkIPv4Error(
e, u'Error persisting a NetworkIPv4.')
except (ValueError, TypeError, AddressValueError), e:
raise ConfigEnvironmentInvalidError(e, u'Invalid Configuration')
# Return vlan map
vlan_map = dict()
vlan_map['id'] = self.vlan.id
vlan_map['nome'] = self.vlan.nome
vlan_map['num_vlan'] = self.vlan.num_vlan
vlan_map['id_tipo_rede'] = self.network_type.id
vlan_map['id_ambiente'] = self.vlan.ambiente.id
vlan_map['rede_oct1'] = self.oct1
vlan_map['rede_oct2'] = self.oct2
vlan_map['rede_oct3'] = self.oct3
vlan_map['rede_oct4'] = self.oct4
vlan_map['bloco'] = self.block
vlan_map['mascara_oct1'] = self.mask_oct1
vlan_map['mascara_oct2'] = self.mask_oct2
vlan_map['mascara_oct3'] = self.mask_oct3
vlan_map['mascara_oct4'] = self.mask_oct4
vlan_map['broadcast'] = self.broadcast
vlan_map['descricao'] = self.vlan.descricao
vlan_map['acl_file_name'] = self.vlan.acl_file_name
vlan_map['acl_valida'] = self.vlan.acl_valida
vlan_map['acl_file_name_v6'] = self.vlan.acl_file_name_v6
vlan_map['acl_valida_v6'] = self.vlan.acl_valida_v6
vlan_map['ativada'] = self.vlan.ativada
vlan_map['id_network'] = self.id
map = dict()
map['vlan'] = vlan_map
return map
[docs] def delete(self):
try:
for ip in self.ip_set.all():
ip.delete()
super(NetworkIPv4, self).delete()
except IpCantBeRemovedFromVip, e:
# Network id and ReqVip id
net_name = str(self.oct1) + '.' + str(self.oct2) + '.' + \
str(self.oct3) + '.' + str(self.oct4) + '/' + str(self.block)
cause = {'Net': net_name, 'ReqVip': e.cause}
raise IpCantBeRemovedFromVip(
cause, 'Esta Rede possui um Vip apontando para ela, e não pode ser excluída')
##################
# Methods for V3 #
##################
[docs] def create_v3(self, networkv4, locks_used=[], force=False):
"""Create new networkIPv4."""
vlan_model = get_app('vlan')
envvip_model = get_app('ambiente')
try:
self.oct1 = networkv4.get('oct1')
self.oct2 = networkv4.get('oct2')
self.oct3 = networkv4.get('oct3')
self.oct4 = networkv4.get('oct4')
self.block = networkv4.get('prefix')
self.mask_oct1 = networkv4.get('mask_oct1')
self.mask_oct2 = networkv4.get('mask_oct2')
self.mask_oct3 = networkv4.get('mask_oct3')
self.mask_oct4 = networkv4.get('mask_oct4')
self.cluster_unit = networkv4.get('cluster_unit')
if force:
self.active = networkv4.get('active', False)
# Vlan
self.vlan = vlan_model.Vlan().get_by_pk(networkv4.get('vlan'))
# Network Type
if networkv4.get('network_type'):
self.network_type = vlan_model.TipoRede()\
.get_by_pk(networkv4.get('network_type'))
# Environment vip
if networkv4.get('environmentvip'):
self.ambient_vip = envvip_model.EnvironmentVip().get_by_pk(
networkv4.get('environmentvip'))
# Get environments related
envs = self.vlan.get_environment_related(use_vrf=True)\
.values_list('id', flat=True)
except vlan_model.VlanNotFoundError, e:
self.log.error(e.message)
raise InvalidInputException(e.message)
except vlan_model.NetworkTypeNotFoundError, e:
self.log.error(e.message)
raise InvalidInputException(e.message)
except envvip_model.EnvironmentVipNotFoundError, e:
self.log.error(e.message)
raise InvalidInputException(e.message)
except NetworkIPv4ErrorV3, e:
self.log.error(e.message)
raise NetworkIPv4ErrorV3(e.message)
except Exception, e:
self.log.error(e)
raise NetworkIPv4ErrorV3(e)
else:
# Create locks for environment
locks_name = list()
for env in envs:
lock_name = LOCK_ENVIRONMENT_ALLOCATES % env
if lock_name not in locks_used:
locks_name.append(lock_name)
locks_list = create_lock_with_blocking(locks_name)
try:
if self.oct1 is None and self.oct2 is None and \
self.oct3 is None and self.oct4 is None:
# Allocate network for vlan with prefix(optional)
try:
self.allocate_network_v3(networkv4.get('vlan'),
networkv4.get('prefix'))
except NetworkIPv4AddressNotAvailableError, e:
self.log.error(e.message)
raise NetworkIPv4ErrorV3(e.message)
elif self.block is not None and self.oct1 is not None and \
self.oct2 is not None and self.oct3 is not None and \
self.oct4 is not None:
# Was send prefix and octs
# IP address manually configured
ip = IPNetwork('%s/%s' % (self.formated_octs, self.block))
self.broadcast = ip.broadcast.compressed
mask = ip.netmask.exploded.split('.')
self.mask_oct1 = mask[0]
self.mask_oct2 = mask[1]
self.mask_oct3 = mask[2]
self.mask_oct4 = mask[3]
envs = self.vlan.get_environment_related(use_vrf=True)
net_ip = [IPNetwork(self.networkv4)]
try:
network.validate_network(envs, net_ip, IP_VERSION.IPv4[0])
except NetworkConflictException, e:
self.log.error(e.detail)
raise NetworkIPv4ErrorV3(e.detail)
else:
# Was not send correctly
raise NetworkIPv4ErrorV3(
'There is need to send block ou mask.')
try:
self.validate_v3()
except vlan_model.VlanErrorV3, e:
self.log.error(e.message)
raise NetworkIPv4ErrorV3(e.message)
self.save()
if self.block < 31:
# Creates Ips for routers of environment
eqpt_model = get_model('equipamento', 'EquipamentoAmbiente')
eqpts = eqpt_model.get_routers_by_environment(self.vlan.ambiente)\
.values_list('equipamento', flat=True)
if eqpts:
ip = Ip.get_first_available_ip(self.id)
gateway_ip = str(ip).split('.')
ip_map = {
'oct1': gateway_ip[0],
'oct2': gateway_ip[1],
'oct3': gateway_ip[2],
'oct4': gateway_ip[3],
'networkipv4': self.id,
'equipments': [{
'id': eqpt
} for eqpt in eqpts]
}
locks = locks_name + locks_used
ip_inst = Ip()
ip_inst.create_v3(ip_map, locks_used=locks)
if len(eqpts) > 1 and self.block < 30:
for eqpt in eqpts:
ip = Ip.get_first_available_ip(
self.id, topdown=True)
router_ip = str(ip).split('.')
ip_map = {
'oct1': router_ip[0],
'oct2': router_ip[1],
'oct3': router_ip[2],
'oct4': router_ip[3],
'networkipv4': self.id,
'equipments': [{
'id': eqpt
}]
}
locks = locks_name + locks_used
ip_inst = Ip()
ip_inst.create_v3(ip_map, locks_used=locks)
except NetworkIPv4ErrorV3, e:
self.log.error(e.message)
raise NetworkIPv4ErrorV3(e.message)
except Exception, e:
self.log.exception(e)
raise NetworkIPv4ErrorV3(e)
finally:
destroy_lock(locks_list)
[docs] def update_v3(self, networkv4, locks_used=[], force=False):
"""Update networkIPv4."""
vlan_model = get_app('vlan')
envvip_model = get_app('ambiente')
try:
self.cluster_unit = networkv4.get('cluster_unit')
self.network_type = vlan_model.TipoRede()\
.get_by_pk(networkv4.get('network_type'))
if force:
self.active = networkv4.get('active', False)
# has environmentvip
if networkv4.get('environmentvip'):
self.ambient_vip = envvip_model.EnvironmentVip()\
.get_by_pk(networkv4.get('environmentvip'))
else:
self.ambient_vip = None
except vlan_model.NetworkTypeNotFoundError, e:
self.log.error(e.message)
raise InvalidInputException(e.message)
except envvip_model.EnvironmentVipNotFoundError, e:
self.log.error(e.message)
raise InvalidInputException(e.message)
except NetworkIPv4ErrorV3, e:
self.log.error(e.message)
raise NetworkIPv4ErrorV3(e.message)
except Exception, e:
self.log.error(e)
raise NetworkIPv4ErrorV3(e)
else:
# Create locks for environment
locks_name = list()
lock_name = LOCK_NETWORK_IPV4 % self.id
if lock_name not in locks_used:
locks_name.append(lock_name)
locks_list = create_lock_with_blocking(locks_name)
try:
self.validate_v3()
self.save()
except vlan_model.VlanErrorV3, e:
self.log.error(e.message)
raise NetworkIPv4ErrorV3(e.message)
except NetworkIPv4ErrorV3, e:
self.log.error(e.message)
raise NetworkIPv4ErrorV3(e.message)
except Exception, e:
self.log.error(e)
raise NetworkIPv4ErrorV3(e)
finally:
destroy_lock(locks_list)
[docs] def delete_v3(self, locks_used=[], force=False):
"""Method V3 to remove NetworkIPv4.
Before removing the NetworkIPv4 removes all your Ipv4
"""
# Get environments related
envs = self.vlan.get_environment_related(use_vrf=True)\
.values_list('id', flat=True)
locks_name = list()
# Prepares lock for object current network
lock_name = LOCK_NETWORK_IPV4 % self.id
if lock_name not in locks_used:
locks_name.append(lock_name)
# Prepares lock for environment related
for env in envs:
lock_name = LOCK_ENVIRONMENT_ALLOCATES % env
if lock_name not in locks_used:
locks_name.append(lock_name)
# Create locks for environment and vlan
locks_list = create_lock_with_blocking(locks_name)
try:
if self.active and not force:
msg = 'Can\'t remove network {} because it is active. ' \
'Try to set it inactive before removing it.'.format(
str(self))
raise NetworkActiveError(None, msg)
for ip in self.ip_set.all():
ip.delete_v3()
super(NetworkIPv4, self).delete()
except IpCantBeRemovedFromVip, e:
msg = 'This network has a VIP pointing to it, and can not '\
'be deleted. Network: {}, Vip Request: {}'.format(
str(self), e.cause)
self.log.error(msg)
raise NetworkIPv4ErrorV3(msg)
except NetworkActiveError, e:
self.log.error(e.message)
raise NetworkIPv4ErrorV3(e.message)
except NetworkIPv4ErrorV3, e:
self.log.error(e.message)
raise NetworkIPv4ErrorV3(e.message)
except Exception, e:
self.log.error(e)
raise NetworkIPv4ErrorV3(e)
finally:
destroy_lock(locks_list)
[docs] def validate_v3(self):
"""Validate networkIPv4."""
if not self.network_type:
raise NetworkIPv4ErrorV3('Network type can not null')
# validate if network if allow in environment
configs = self.vlan.ambiente.configs.all()
self.vlan.allow_networks_environment(configs, [self], [])
[docs] def activate_v3(self):
"""
Send activate notication of network v4 for queue of ACL
configuration system.
Update status column to 'active = 1'.
@raise NetworkIPv4Error: Error activating a NetworkIPv4.
"""
try:
self.active = 1
self.save()
net_slz = get_app('api_network', 'serializers.v3')
serializer = net_slz.NetworkIPv4V3Serializer(
self,
include=('vlan__details__environment__basic',))
data_to_queue = serializer.data
data_to_queue.update({
'description': queue_keys.NETWORKv4_ACTIVATE
})
# Send to Queue
queue_manager = QueueManager(broker_vhost='tasks',
queue_name='tasks.aclapi',
exchange_name='tasks.aclapi',
routing_key='tasks.aclapi')
queue_manager.append({
'action': queue_keys.NETWORKv4_ACTIVATE,
'kind': queue_keys.NETWORKv4_KEY,
'data': data_to_queue
})
queue_manager.send()
except Exception, e:
self.log.error(u'Error activating NetworkIPv4.')
raise NetworkIPv4Error(e, u'Error activating NetworkIPv4.')
[docs] def deactivate_v3(self):
"""
Send deactivate notication of network v4 for queue of ACL
configuration system.
Update status column to 'active = 0'.
@raise NetworkIPv4Error: Error disabling a NetworkIPv4.
"""
try:
net_slz = get_app('api_network', 'serializers.v3')
self.active = 0
serializer = net_slz.NetworkIPv4V3Serializer(
self,
include=('vlan__details__environment__basic',))
data_to_queue = serializer.data
data_to_queue.update({
'description': queue_keys.NETWORKv4_DEACTIVATE
})
# Send to Queue
queue_manager = QueueManager(broker_vhost='tasks',
queue_name='tasks.aclapi',
exchange_name='tasks.aclapi',
routing_key='tasks.aclapi')
queue_manager.append({
'action': queue_keys.NETWORKv4_DEACTIVATE,
'kind': queue_keys.NETWORKv4_KEY,
'data': data_to_queue
})
queue_manager.send()
self.save()
except Exception, e:
self.log.error(u'Error disabling NetworkIPv4.')
raise NetworkIPv4Error(e, u'Error disabling NetworkIPv4.')
[docs] def allocate_network_v3(self, id_vlan, prefix=None):
"""
Allocate new NetworkIPv4.
@raise VlanNotFoundError: Vlan is not registered.
@raise VlanError: Failed to search for the Vlan
@raise ConfigEnvironmentInvalidError: Invalid Environment
Configuration or not
registered
@raise NetworkIPv4Error: Error persisting a NetworkIPv4.
@raise NetworkIPv4AddressNotAvailableError: Unavailable address to
create a NetworkIPv4.
@raise Invalid: Unavailable address to create a NetworkIPv4.
@raise InvalidValueError: Network type does not exist.
"""
vlan_model = get_model('vlan', 'Vlan')
self.vlan = vlan_model().get_by_pk(id_vlan)
nets_envs, netv6 = network.get_networks_related(
vrfs=self.vlan.get_vrf(),
eqpts=self.vlan.get_eqpt(),
has_netv6=False
)
nets_envs = [IPNetwork(net.networkv4) for net in nets_envs]
network_found = None
try:
configs = self.vlan.ambiente.configs.filter(
ip_config__type=IP_VERSION.IPv4[0])
# For each configuration founded in environment
for config in configs:
net4 = IPNetwork(config.ip_config.subnet)
if prefix is not None:
new_prefix = int(prefix)
else:
new_prefix = int(config.ip_config.new_prefix)
self.log.info(
u'Prefix that will be used: %s' % new_prefix)
free_nets = network.get_free_space_network([net4], nets_envs)
for free_net in free_nets:
try:
subnets = free_net.iter_subnets(new_prefix=new_prefix)
subnet = subnets.next()
except Exception:
pass
else:
# Set octs by network generated
self.oct1, self.oct2, self.oct3, self.oct4 = str(
subnet.network).split('.')
# Set block by network generated
self.block = subnet.prefixlen
self.broadcast = subnet.broadcast.compressed
mask = subnet.netmask.exploded.split('.')
self.mask_oct1 = mask[0]
self.mask_oct2 = mask[1]
self.mask_oct3 = mask[2]
self.mask_oct4 = mask[3]
if not self.network_type:
self.network_type = config.ip_config.network_type
return
# Checks if found any available network
if network_found is None:
self.log.error(u'Unavailable address to create a NetworkIPv4.')
# If not found, an exception is thrown
raise NetworkIPv4AddressNotAvailableError(
None, u'Unavailable address to create a NetworkIPv4.')
except (ValueError, TypeError, AddressValueError), e:
self.log.error(u'Invalid Configuration')
raise ConfigEnvironmentInvalidError(e, u'Invalid Configuration')
[docs]class Ip(BaseModel):
id = models.AutoField(
primary_key=True,
db_column='id_ip'
)
oct4 = models.IntegerField()
oct3 = models.IntegerField()
oct2 = models.IntegerField()
oct1 = models.IntegerField()
descricao = models.CharField(
max_length=100,
blank=True,
null=True
)
networkipv4 = models.ForeignKey(
'ip.NetworkIPv4',
db_column='id_redeipv4'
)
log = logging.getLogger('Ip')
class Meta(BaseModel.Meta):
db_table = u'ips'
managed = True
unique_together = ('oct1', 'oct2', 'oct3', 'oct4', 'networkipv4')
def __str__(self):
return self.ip_formated
def _get_formated_ip(self):
"""Returns formated ip."""
return '%s.%s.%s.%s' % (self.oct1, self.oct2, self.oct3, self.oct4)
ip_formated = property(_get_formated_ip)
def _get_equipments(self):
"""Returns equipments list."""
ipeqs = self.ipequipamento_set.all().select_related('equipamento')
eqpts = [ipeq.equipamento for ipeq in ipeqs]
return eqpts
equipments = property(_get_equipments)
def _get_ipv4_equipment(self):
return self.ipequipamento_set.all()
ipv4_equipment = \
property(_get_ipv4_equipment)
def _get_vips(self):
"""Returns vips list."""
vips = self.viprequest_set.all()
return vips
vips = property(_get_vips)
def _get_server_pool_members(self):
"""Returns pool members list."""
server_pool_members = self.serverpoolmember_set.all()
return server_pool_members
server_pool_members = property(_get_server_pool_members)
[docs] @classmethod
def list_by_network(cls, id_network):
"""Get IP LIST by id_network.
@return: IP List.
@raise IpNotFoundError: IP is not registered.
@raise IpError: Failed to search for the IP.
@raise OperationalError: Lock wait timeout exceeded.
"""
try:
return Ip.objects.filter(networkipv4=id_network)
except ObjectDoesNotExist, e:
raise IpNotFoundError(
e, u'There is no IP with network_id = %s.' % id)
except OperationalError, e:
cls.log.error(u'Lock wait timeout exceeded.')
raise OperationalError(
e, u'Lock wait timeout exceeded; try restarting transaction')
except Exception, e:
cls.log.error(u'Failure to search the IP.')
raise IpError(e, u'Failure to search the IP')
[docs] @classmethod
def list_by_environment_and_equipment(cls, id_ambiente, id_equipment):
"""Get IP LIST by id_network.
@return: IP List.
@raise IpNotFoundError: IP is not registered.
@raise IpError: Failed to search for the IP.
@raise OperationalError: Lock wait timeout exceeded.
"""
try:
return Ip.objects.filter(
networkipv4__vlan__ambiente__id=id_ambiente,
ipequipamento__equipamento__id=id_equipment)
except ObjectDoesNotExist, e:
raise IpNotFoundError(
e, u'There is no IP with network_id = %s.' % id)
except OperationalError, e:
cls.log.error(u'Lock wait timeout exceeded.')
raise OperationalError(
e, u'Lock wait timeout exceeded; try restarting transaction')
except Exception, e:
cls.log.error(u'Failure to search the IP.')
raise IpError(e, u'Failure to search the IP')
[docs] @classmethod
def get_by_pk(cls, id):
"""Get IP by id.
@return: IP.
@raise IpNotFoundError: IP is not registered.
@raise IpError: Failed to search for the IP.
@raise OperationalError: Lock wait timeout exceeded.
"""
try:
return Ip.objects.filter(id=id).uniqueResult()
except ObjectDoesNotExist, e:
raise IpNotFoundError(e, u'There is no IP with pk = %s.' % id)
except OperationalError, e:
cls.log.error(u'Lock wait timeout exceeded.')
raise OperationalError(
e, u'Lock wait timeout exceeded; try restarting transaction')
except Exception, e:
cls.log.error(u'Failure to search the IP.')
raise IpError(e, u'Failure to search the IP')
[docs] def delete_ip4(self, user, id_ip):
try:
ip = self.get_by_pk(id_ip)
ip.delete()
except IpNotFoundError, e:
raise IpNotFoundError(None, e)
except Exception, e:
self.log.error(u'Failure to delete the IP.')
raise IpError(e, u'Failure to delete the IP')
[docs] @classmethod
def get_available_ip(cls, id_network):
"""Get a available Ipv4 for networkIPv4
@return: Available Ipv4
@raise IpNotAvailableError: NetworkIPv4 does not has available Ipv4
"""
configuration = get_model('config', 'Configuration')
networkipv4 = NetworkIPv4().get_by_pk(id_network)
# Cast to API
net4 = IPv4Network(networkipv4.networkv4)
# Find all ips ralated to network
ips = Ip.objects.filter(networkipv4__id=networkipv4.id)
# Cast all to API class
ipsv4 = set([IPv4Address(ip.ip_formated) for ip in ips])
# Get configuration
conf = configuration.get()
selected_ip = None
# For each ip generated
i = 0
for ip in net4.iterhosts():
# Do not use some range of IPs (config)
i = i + 1
if i >= conf.IPv4_MIN and i < (net4.numhosts - conf.IPv4_MAX):
# If IP generated was not used
if ip not in ipsv4:
# Use it
selected_ip = ip
# Stop generation
return selected_ip
if selected_ip is None:
raise IpNotAvailableError(
None, u'No IP available to NETWORK %s.' % networkipv4.id)
[docs] @classmethod
def get_first_available_ip(cls, id_network, topdown=False):
"""Get a first available Ipv4 for networkIPv4
@return: Available Ipv4
@raise IpNotAvailableError: NetworkIPv4 does not has available Ipv4
"""
networkipv4 = NetworkIPv4().get_by_pk(id_network)
# Cast to API
net4 = IPv4Network(networkipv4.networkv4)
# Find all ips ralated to network
ips = Ip.objects.filter(networkipv4__id=networkipv4.id)
# Cast all to API class
ipsv4 = set([IPv4Address(ip.ip_formated) for ip in ips])
selected_ip = None
if topdown:
method = net4.iterhostsTopDown
else:
method = net4.iterhosts
# For each ip generated
for ip in method():
# If IP generated was not used
if ip not in ipsv4:
# Use it
selected_ip = ip
# Stop generation
return selected_ip
if selected_ip is None:
raise IpNotAvailableError(
None, u'No IP available to NETWORK %s.' % networkipv4.id)
[docs] def edit_ipv4(self, user):
try:
# Cast to API
net4 = IPv4Network('%d.%d.%d.%d/%d' % (self.networkipv4.oct1, self.networkipv4.oct2,
self.networkipv4.oct3, self.networkipv4.oct4, self.networkipv4.block))
# Find all ips ralated to network
ips = Ip.objects.filter(networkipv4__id=self.networkipv4.id)
ip4_object = IPv4Address(
'%s.%s.%s.%s' % (self.oct1, self.oct2, self.oct3, self.oct4))
# Cast all to API class
ipsv4 = set(
[IPv4Address('%d.%d.%d.%d' % (ip.oct1, ip.oct2, ip.oct3, ip.oct4)) for ip in ips])
flag = True
if ip4_object not in ipsv4:
flag = False
if ip4_object in net4:
# Get configuration
# conf = Configuration.get()
first_ip_network = int(net4.network)
bcast_ip_network = int(net4.broadcast)
ipv4_network = int(ip4_object)
if ipv4_network >= (first_ip_network) and ipv4_network < (bcast_ip_network):
flag = True
else:
ip4_aux = self.get_by_octs_and_net(
self.oct1, self.oct2, self.oct3, self.oct4, self.networkipv4.id)
if self.id != ip4_aux.id:
raise IpNotAvailableError(None, u'Ip %s.%s.%s.%s already on use by network %s.' % (
self.oct1, self.oct2, self.oct3, self.oct4, self.networkipv4.id))
if flag:
self.save()
else:
raise IpNotAvailableError(None, u'Ip %s.%s.%s.%s not available for network %s.' % (
self.oct1, self.oct2, self.oct3, self.oct4, self.networkipv4.id))
except IpEquipmentAlreadyAssociation, e:
self.log.error(e)
raise IpEquipmentAlreadyAssociation(None, e)
except AddressValueError:
raise InvalidValueError(
None, 'ip', u'%s.%s.%s.%s' % (self.oct1, self.oct2, self.oct3, self.oct4))
except IpNotAvailableError, e:
raise IpNotAvailableError(None, u'Ip %s.%s.%s.%s not available for network %s.' % (
self.oct1, self.oct2, self.oct3, self.oct4, self.networkipv4.id))
except IpError, e:
self.log.error(
u'Error adding new IP or relationship ip-equipment.')
raise IpError(
e, u'Error adding new IP or relationship ip-equipment.')
[docs] def save_ipv4(self, equipment_id, user, net):
equipamentoambiente = get_model('equipamento', 'EquipamentoAmbiente')
equipamento = get_model('equipamento', 'Equipamento')
filterequiptype = get_model('filterequiptype', 'FilterEquipType')
try:
already_ip = False
# Cast to API
net4 = IPv4Network(
'%d.%d.%d.%d/%d' % (net.oct1, net.oct2, net.oct3, net.oct4, net.block))
# Find all ips ralated to network
ips = Ip.objects.filter(networkipv4__id=net.id)
ip4_object = IPv4Address(
'%s.%s.%s.%s' % (self.oct1, self.oct2, self.oct3, self.oct4))
# Cast all to API class
ipsv4 = set(
[IPv4Address('%d.%d.%d.%d' % (ip.oct1, ip.oct2, ip.oct3, ip.oct4)) for ip in ips])
flag = False
if ip4_object not in ipsv4:
if ip4_object in net4:
# Get configuration
# conf = Configuration.get()
first_ip_network = int(net4.network)
bcast_ip_network = int(net4.broadcast)
ipv4_network = int(ip4_object)
if ipv4_network >= (first_ip_network) and ipv4_network < (bcast_ip_network):
flag = True
else:
ip_aux = self.get_by_octs_and_net(
self.oct1, self.oct2, self.oct3, self.oct4, net.id)
try:
IpEquipamento.get_by_ip(ip_aux.id)
raise IpEquipmentAlreadyAssociation(None, u'Ip %s.%s.%s.%s already has association with an Equipament. Try using the association screen for this Ip.' % (
self.oct1, self.oct2, self.oct3, self.oct4))
except IpEquipmentNotFoundError, e:
flag = True
already_ip = True
if flag:
equipment = equipamento().get_by_pk(equipment_id)
ip_equipment = IpEquipamento()
if not already_ip:
self.networkipv4_id = net.id
self.save()
ip_equipment.ip = self
else:
ip_equipment.ip = ip_aux
if self.descricao is not None and len(self.descricao) > 0:
ip_aux.descricao = self.descricao
ip_aux.save()
ip_equipment.equipamento = equipment
# # Filter case 2 - Adding new IpEquip for a equip that already have ip in other network with the same range ##
# Get all IpEquipamento related to this equipment
ip_equips = IpEquipamento.objects.filter(
equipamento=equipment_id)
for ip_test in [ip_equip.ip for ip_equip in ip_equips]:
if ip_test.networkipv4.oct1 == self.networkipv4.oct1 and \
ip_test.networkipv4.oct2 == self.networkipv4.oct2 and \
ip_test.networkipv4.oct3 == self.networkipv4.oct3 and \
ip_test.networkipv4.oct4 == self.networkipv4.oct4 and \
ip_test.networkipv4.block == self.networkipv4.block and \
ip_test.networkipv4 != self.networkipv4:
# Filter testing
if ip_test.networkipv4.vlan.ambiente.filter is None or self.networkipv4.vlan.ambiente.filter is None:
raise IpRangeAlreadyAssociation(
None, u'Equipment is already associated with another ip with the same ip range.')
else:
# Test both environment's filters
tp_equip_list_one = list()
for fet in filterequiptype.objects.filter(filter=self.networkipv4.vlan.ambiente.filter.id):
tp_equip_list_one.append(fet.equiptype)
tp_equip_list_two = list()
for fet in filterequiptype.objects.filter(filter=ip_test.networkipv4.vlan.ambiente.filter.id):
tp_equip_list_two.append(fet.equiptype)
if equipment.tipo_equipamento not in tp_equip_list_one or equipment.tipo_equipamento not in tp_equip_list_two:
raise IpRangeAlreadyAssociation(
None, u'Equipment is already associated with another ip with the same ip range.')
# # Filter case 2 - end ##
ip_equipment.save()
# Makes Environment Equipment association
try:
equipment_environment = equipamentoambiente()
equipment_environment.equipamento = equipment
equipment_environment.ambiente = net.vlan.ambiente
equipment_environment.create(user)
except EquipamentoAmbienteDuplicatedError, e:
# If already exists, OK !
pass
else:
raise IpNotAvailableError(None, u'Ip %s.%s.%s.%s not available for network %s.' % (
self.oct1, self.oct2, self.oct3, self.oct4, net.id))
except IpRangeAlreadyAssociation, e:
raise IpRangeAlreadyAssociation(None, e.message)
except IpEquipmentAlreadyAssociation, e:
raise IpEquipmentAlreadyAssociation(None, e.message)
except AddressValueError:
raise InvalidValueError(
None, 'ip', u'%s.%s.%s.%s' % (self.oct1, self.oct2, self.oct3, self.oct4))
except IpNotAvailableError, e:
raise IpNotAvailableError(None, u'Ip %s.%s.%s.%s not available for network %s.' % (
self.oct1, self.oct2, self.oct3, self.oct4, net.id))
except (IpError, EquipamentoError), e:
self.log.error(
u'Error adding new IP or relationship ip-equipment.')
raise IpError(
e, u'Error adding new IP or relationship ip-equipment.')
[docs] def create(self, authenticated_user, equipment_id, id, new):
"""Persist an IPv4 and associate it to an equipment.
If equipment was not related with VLAN environment, this makes the relationship
@return: Nothing
@raise NetworkIPv6NotFoundError: NetworkIPv6 does not exist.
@raise NetworkIPv6Error: Error finding NetworkIPv6.
@raise EquipamentoNotFoundError: Equipment does not exist.
@raise EquipamentoError: Error finding Equipment.
@raise IpNotAvailableError: No IP available to VLAN.
@raise IpError: Error persisting in database.
"""
equipamentoambiente = get_model('equipamento', 'EquipamentoAmbiente')
equipamento = get_model('equipamento', 'Equipamento')
configuration = get_model('config', 'Configuration')
vlan_model = get_model('vlan', 'Vlan')
if new is False:
# Search vlan by id
vlan = vlan_model().get_by_pk(id)
# Get first networkipv4 related to vlan
try:
self.networkipv4 = vlan.networkipv4_set.order_by('id')[0]
except IndexError, e:
self.log.error(
u'Error finding the first networkipv4 from vlan.')
raise NetworkIPv4NotFoundError(
e, u'Error finding the first networkipv4 from vlan.')
else:
self.networkipv4 = NetworkIPv4().get_by_pk(id)
# Cast to API
net4 = IPv4Network('%d.%d.%d.%d/%d' % (self.networkipv4.oct1, self.networkipv4.oct2,
self.networkipv4.oct3, self.networkipv4.oct4,
self.networkipv4.block))
# Find all ips ralated to network
ips = Ip.objects.filter(networkipv4__id=self.networkipv4.id)
# Cast all to API class
ipsv4 = set(
[(IPv4Address('%d.%d.%d.%d' % (ip.oct1, ip.oct2, ip.oct3, ip.oct4))) for ip in ips])
# Get configuration
conf = configuration.get()
selected_ip = None
# For each ip generated
i = 0
for ip in net4.iterhosts():
# Do not use some range of IPs (config)
i = i + 1
if i >= conf.IPv4_MIN and i < (net4.numhosts - conf.IPv4_MAX):
# If IP generated was not used
if ip not in ipsv4:
# Use it
selected_ip = ip
# Stop generation
break
if selected_ip is None:
raise IpNotAvailableError(
None, u'No IP available to VLAN %s.' % self.networkipv4.vlan.num_vlan)
self.oct1, self.oct2, self.oct3, self.oct4 = str(
selected_ip).split('.')
equipment = equipamento().get_by_pk(equipment_id)
try:
self.save()
ip_equipment = IpEquipamento()
ip_equipment.ip = self
ip_equipment.equipamento = equipment
ip_equipment.save(authenticated_user)
try:
equipment_environment = equipamentoambiente()\
.get_by_equipment_environment(
equipment_id,
self.networkipv4.vlan.ambiente_id
)
except EquipamentoAmbienteNotFoundError:
equipment_environment = equipamentoambiente()
equipment_environment.equipamento = equipment
equipment_environment.ambiente = self.networkipv4.vlan.ambiente
equipment_environment.save(authenticated_user)
except Exception, e:
self.log.error(
u'Error adding new IP or relationship ip-equipment.')
raise IpError(
e, u'Error adding new IP or relationship ip-equipment.')
[docs] def get_by_octs_equipment(self, oct1, oct2, oct3, oct4, equip_id):
"""Get IP by octs and equip_id.
@return: IP.
@raise IpNotFoundError: IP is not registered.
@raise IpError: Failed to search for the IP.
"""
try:
return Ip.objects.get(oct1=oct1, oct2=oct2, oct3=oct3, oct4=oct4, ipequipamento__equipamento__id=equip_id)
except ObjectDoesNotExist, e:
raise IpNotFoundError(e, u'There is no IP %s.%s.%s.%s of the equipament %s.' % (
oct1, oct2, oct3, oct4, equip_id))
except Exception, e:
self.log.error(u'Failure to search the IP.')
raise IpError(e, u'Failure to search the IP.')
[docs] @classmethod
def get_by_octs_and_net(cls, oct1, oct2, oct3, oct4, id_network):
"""Get IP by octs and net.
@return: IP.
@raise IpNotFoundError: IP is not registered.
@raise IpError: Failed to search for the IP.
"""
try:
return Ip.objects.get(oct1=oct1, oct2=oct2, oct3=oct3, oct4=oct4, networkipv4=id_network)
except ObjectDoesNotExist, e:
raise IpNotFoundError(
e, u'There is no IP = %s.%s.%s.%s.' % (oct1, oct2, oct3, oct4))
except Exception, e:
cls.log.error(u'Failure to search the IP.')
raise IpError(e, u'Failure to search the IP.')
[docs] @classmethod
def get_by_octs_and_environment_vip(cls, oct1, oct2, oct3, oct4, id_evip, valid=True):
"""Get IP by octs and environment vip.
@return: IP.
@raise IpNotFoundByEquipAndVipError: IP is not related with equipament.
@raise IpNotFoundError: IP is not registered.
@raise IpError: Failed to search for the IP.
"""
environmentvip = get_model('ambiente', 'EnvironmentVip')
ambiente_model = get_model('ambiente', 'Ambiente')
try:
ips = Ip.objects.filter(oct1=oct1, oct2=oct2, oct3=oct3, oct4=oct4)
if ips.count() == 0:
raise IpNotFoundError(None)
if valid is True:
return Ip.objects.get(oct1=oct1, oct2=oct2, oct3=oct3, oct4=oct4,
networkipv4__ambient_vip__id=id_evip)
else:
for ip in ips:
if ip.networkipv4.ambient_vip:
if ip.networkipv4.ambient_vip.id == id_evip:
return ip
else:
environments = ambiente_model.objects.filter(
vlan__networkipv4__ambient_vip__id=id_evip)
for env in environments:
if ip.networkipv4.vlan.ambiente.divisao_dc.id == env.divisao_dc.id \
and ip.networkipv4.vlan.ambiente.ambiente_logico.id == env.ambiente_logico.id:
return ip
raise ObjectDoesNotExist()
except ObjectDoesNotExist, e:
evip = environmentvip.get_by_pk(id_evip)
msg = u'Ipv4 não está relacionado ao Ambiente Vip: %s.' % evip.show_environment_vip()
cls.log.error(msg)
raise IpNotFoundByEquipAndVipError(e, msg)
except IpNotFoundError, e:
msg = u'Ipv4 "%s.%s.%s.%s" não exite.' % (oct1, oct2, oct3, oct4)
cls.log.error(msg)
raise IpNotFoundError(e, msg)
except Exception, e:
cls.log.error(u'Failure to search the IP.')
raise IpError(e, u'Failure to search the IP.')
[docs] @classmethod
def get_by_octs_and_environment(cls, oct1, oct2, oct3, oct4, id_environment):
"""Get IP by octs and environment.
@return: IP.
@raise IpNotFoundError: IP is not registered.
@raise IpError: Failed to search for the IP.
"""
try:
return Ip.objects.get(oct1=oct1, oct2=oct2, oct3=oct3, oct4=oct4, networkipv4__vlan__ambiente__id=id_environment)
except ObjectDoesNotExist, e:
raise IpNotFoundError(e, u'There is no IP %s.%s.%s.%s of the environment %s.' % (
oct1, oct2, oct3, oct4, id_environment))
except Exception, e:
cls.log.error(u'Failure to search the IP.')
raise IpError(e, u'Failure to search the IP.')
[docs] @classmethod
def get_by_octs(cls, oct1, oct2, oct3, oct4):
"""Get IP by octs.
@return: IP.
@raise IpNotFoundError: IP is not registered.
@raise IpError: Failed to search for the IP.
"""
try:
ips = Ip.objects.filter(oct1=oct1, oct2=oct2, oct3=oct3, oct4=oct4)
if len(ips) == 0:
raise ObjectDoesNotExist()
return ips
except ObjectDoesNotExist, e:
raise IpNotFoundError(
e, u'There is no IP = %s.%s.%s.%s.' % (oct1, oct2, oct3, oct4))
except Exception, e:
cls.log.error(u'Failure to search the IP.')
raise IpError(e, u'Failure to search the IP.')
[docs] def delete(self):
"""Sobrescreve o método do Django para remover um IP.
Antes de remover o IP remove todas as suas requisições de VIP e os relacionamentos com equipamentos.
"""
try:
for r in self.requisicaovips_set.all():
r_alter = False
# Assures VIP request is not being changed - issue #48
with distributedlock(LOCK_VIP % r.id):
# updates query after lock for object
r = self.requisicaovips_set.get(id=r.id)
id_vip = r.id
if r.vip_criado:
raise IpCantBeRemovedFromVip(
r.id, 'Ipv4 não pode ser removido, porque está em uso por Requisição Vip %s' % (r.id))
else:
if r.ipv6 is not None:
r.ip = None
r.validado = 0
r.save()
r_alter = True
# SYNC_VIP
syncs.old_to_new(r)
if not r_alter:
r.delete()
# SYNC_VIP
syncs.delete_new(id_vip)
for ie in self.ipequipamento_set.all():
# Codigo removido, pois não devemos remover o ambiente do equipamento mesmo que não tenha IP
# para o ambiente solicidado pelo Henrique
# ambienteequip = EquipamentoAmbiente()
# ambienteequip = ambienteequip.get_by_equipment_environment(
# ie.equipamento.id, self.networkipv4.vlan.ambiente_id)
#
# ips = Ip.list_by_environment_and_equipment(
# ambienteequip.ambiente_id, ie.equipamento.id)
# ips6 = Ipv6.list_by_environment_and_equipment(
# ambienteequip.ambiente_id, ie.equipamento.id)
#
# if len(ips) <= 1 and len(ips6) <= 0:
#
# ambienteequip.delete()
ie.delete()
ip_slz = get_app('api_ip', module_label='serializers')
serializer = ip_slz.Ipv4V3Serializer(self)
data_to_queue = serializer.data
# Deletes Obj IP
super(Ip, self).delete()
# Sends to Queue
queue_manager = QueueManager(broker_vhost='tasks',
queue_name='tasks.aclapi',
exchange_name='tasks.aclapi',
routing_key='tasks.aclapi')
data_to_queue.update({'description': queue_keys.IPv4_REMOVE})
queue_manager.append({
'action': queue_keys.IPv4_REMOVE,
'kind': queue_keys.IPv4_KEY,
'data': data_to_queue
})
except EquipamentoAmbienteNotFoundError, e:
raise EquipamentoAmbienteNotFoundError(None, e.message)
except IpCantBeRemovedFromVip, e:
raise IpCantBeRemovedFromVip(e.cause, e.message)
except IpEquipmentNotFoundError, e:
raise IpEquipmentNotFoundError(None, e.message)
##################
# Methods for V3 #
##################
[docs] def create_v3(self, ip_map, locks_used=[]):
"""Method V3 to create Ip."""
models = get_app('equipamento', 'models')
try:
self.networkipv4 = NetworkIPv4()\
.get_by_pk(ip_map.get('networkipv4'))
self.oct1 = ip_map.get('oct1')
self.oct2 = ip_map.get('oct2')
self.oct3 = ip_map.get('oct3')
self.oct4 = ip_map.get('oct4')
self.descricao = ip_map.get('description')
# Get environments related
envs = self.networkipv4.vlan\
.get_environment_related(use_vrf=True)\
.values_list('id', flat=True)
# Get objects of equipments
eqpts = models.Equipamento.objects.filter(
id__in=[eqpt.get('id')
for eqpt in ip_map.get('equipments', [])])
except Exception, e:
raise IpErrorV3(e)
else:
locks_name = list()
# Prepare locks for environment
for env in envs:
lock_name = LOCK_ENVIRONMENT_ALLOCATES % env
if lock_name not in locks_used:
locks_name.append(lock_name)
for eqpt_obj in eqpts:
# Prepare locks for ips-equipments
lock_name = LOCK_IP_EQUIPMENT_ONE % eqpt_obj.id
if lock_name not in locks_used:
locks_name.append(lock_name)
# Prepare locks for environments related with equipaments
for env in eqpt_obj.environments:
lock_name = LOCK_ENVIRONMENT_ALLOCATES % env.ambiente_id
if lock_name not in locks_used:
locks_name.append(lock_name)
# Create Locks
locks_name = list(set(locks_name))
locks_list = create_lock_with_blocking(locks_name)
try:
if self.oct1 is None and self.oct2 is None and \
self.oct3 is None and self.oct4 is None:
self.allocate_v3()
else:
net4 = IPv4Network(self.networkipv4.networkv4)
# Find all ips ralated to network
ips = Ip.objects.filter(networkipv4=self.networkipv4)
ip4_object = IPv4Address(self.ip_formated)
# Cast all to API class
ipsv4 = set([IPv4Address(ip.ip_formated) for ip in ips])
flag = False
if ip4_object not in ipsv4:
if ip4_object in net4:
first_ip_network = int(net4.network)
bcast_ip_network = int(net4.broadcast)
ipv4_network = int(ip4_object)
# First and last ip are reserved in network
if ipv4_network >= (first_ip_network) and \
ipv4_network < (bcast_ip_network):
flag = True
if flag is False:
raise IpNotAvailableError(
None,
u'Ip %s not available for network %s.' %
(self.ip_formated, self.networkipv4.id))
self.validate_v3(eqpts)
self.save()
# Creates relationship between ip and equipment #
for eqpt in ip_map.get('equipments', []):
ip_equipment = IpEquipamento()
ip_equipment.create_v3({
'ip': self.id,
'equipment': eqpt.get('id')
})
except IpErrorV3, e:
self.log.error(e.message)
raise IpErrorV3(e.message)
except IpNotAvailableError, e:
self.log.error(e.message)
raise IpErrorV3(e.message)
except Exception, e:
msg = u'Error save new IP.: %s' % e
self.log.exception(msg)
raise IpErrorV3(msg)
finally:
# Destroy locks
destroy_lock(locks_list)
[docs] def update_v3(self, ip_map, locks_used=[]):
"""Method V3 to update Ip."""
models = get_app('equipamento', 'models')
try:
self.descricao = ip_map.get('description')
# Get environments related
envs = self.networkipv4.vlan.get_environment_related(use_vrf=True)\
.values_list('id', flat=True)
# Get objects of equipments
eqpts = models.Equipamento.objects.filter(id__in=[
eqpt.get('id') for eqpt in ip_map.get('equipments', [])]
)
except Exception, e:
raise IpErrorV3(e)
else:
locks_name = list()
# Prepare lock for ip
lock_name = LOCK_IPV4 % self.id
if lock_name not in locks_used:
locks_name.append(lock_name)
# Prepare locks for environment
for env in envs:
lock_name = LOCK_ENVIRONMENT_ALLOCATES % env
if lock_name not in locks_used:
locks_name.append(lock_name)
for eqpt_obj in eqpts:
# Prepare locks for ips-equipments
lock_name = LOCK_IP_EQUIPMENT % (self.id, eqpt_obj.id)
if lock_name not in locks_used:
locks_name.append(lock_name)
# Prepare locks for environments related with equipaments
for env in eqpt_obj.environments:
lock_name = LOCK_ENVIRONMENT_ALLOCATES % env.ambiente_id
if lock_name not in locks_used:
locks_name.append(lock_name)
# Create Locks
locks_name = list(set(locks_name))
locks_list = create_lock_with_blocking(locks_name)
try:
self.validate_v3(eqpts)
self.save()
# Get current associates
current = self.ipequipamento_set\
.filter(equipamento__in=eqpts)\
.values_list('equipamento', flat=True)
# Creates new associate
for eqpt in eqpts:
if eqpt.id not in current:
ip_equipment = IpEquipamento()
ip_equipment.create_v3({
'ip': self.id,
'equipment': eqpt.id
})
# Removes old associates
for ip_eqpt in self.ipequipamento_set\
.exclude(equipamento__in=eqpts):
ip_eqpt.delete_v3(bypass_ip=True)
except IpErrorV3, e:
self.log.error(e.message)
raise IpErrorV3(e.message)
except Exception, e:
msg = u'Error edit IP.: %s' % e
self.log.error(msg)
raise IpErrorV3(msg)
finally:
# Destroy locks
destroy_lock(locks_list)
[docs] def delete_v3(self, locks_used=[]):
"""
Method V3 to remove Ip.
Before removing the IP removes all your requests
VIP and relationships with equipment.
@raise IpCantBeRemovedFromVip: Ip is associated with created
Vip Request.
"""
locks_name = list()
# Prepare lock for ip
lock_name = LOCK_IPV4 % self.id
if lock_name not in locks_used:
locks_name.append(lock_name)
# Create Locks
locks_name = list(set(locks_name))
locks_list = create_lock_with_blocking(locks_name)
try:
for vip in self.viprequest_set.all():
id_vip = vip.id
with distributedlock(LOCK_VIP % id_vip):
if vip.created:
raise IpCantBeRemovedFromVip(
str(vip),
'IPv4 can not be removed because it is '
'in use by Vip Request: {}'.format(str(vip)))
# Deletes only VIP, Related Ipv6 with VIP is not removed
vip.delete_v3(bypass_ipv4=True, bypass_ipv6=True)
# Deletes Related Equipment
for ip_eqpt in self.ipequipamento_set.all():
ip_eqpt.delete_v3(bypass_ip=True)
# Serializes obj
ip_slz = get_app('api_ip', module_label='serializers')
serializer = ip_slz.Ipv4V3Serializer(self)
data_to_queue = serializer.data
# Deletes Obj IP
super(Ip, self).delete()
# Sends to Queue
queue_manager = QueueManager(broker_vhost='tasks',
queue_name='tasks.aclapi',
exchange_name='tasks.aclapi',
routing_key='tasks.aclapi')
data_to_queue.update({'description': queue_keys.IPv4_REMOVE})
queue_manager.append({
'action': queue_keys.IPv4_REMOVE,
'kind': queue_keys.IPv4_KEY,
'data': data_to_queue
})
queue_manager.send()
except IpCantBeRemovedFromVip, e:
raise IpCantBeRemovedFromVip(e.cause, e.message)
except Exception, e:
msg = u'Error delete IP.: %s' % e
self.log.error(msg)
raise IpErrorV3(msg)
finally:
# Destroy locks
destroy_lock(locks_list)
[docs] def validate_v3(self, equipments):
"""Validate Ip."""
env_ip = self.networkipv4.vlan.ambiente
network.validate_conflict_join_envs(env_ip, equipments)
[docs] def allocate_v3(self):
"""Persist an IPv4 and associate it to an equipment.
If equipment was not related with VLAN environment, this makes the relationship
@return: Nothing
@raise NetworkIPv4NotFoundError: NetworkIPv4 does not exist.
@raise NetworkIPv4Error: Error finding NetworkIPv4.
@raise EquipamentoNotFoundError: Equipment does not exist.
@raise EquipamentoError: Error finding Equipment.
@raise IpNotAvailableError: No IP available to VLAN.
@raise IpError: Error persisting in database.
"""
configuration = get_model('config', 'Configuration')
# Cast to API
net4 = IPNetwork(self.networkipv4.networkv4)
# Find all ips ralated to network
ips = self.networkipv4.ip_set.all()
# Cast all to API class
ipsv4 = set([IPv4Address(ip.ip_formated) for ip in ips])
# Get configuration
conf = configuration.get()
selected_ip = None
# For each ip generated
i = 0
for ip in net4.iterhosts():
# Do not use some range of IPs (config)
# IPv4_MIN = Firsts
# IPv4_MAX = Number minimum of Ip reserveds
# First IP and 2 last I
i = i + 1
if i >= conf.IPv4_MIN and i < (net4.numhosts - conf.IPv4_MAX):
# If IP generated was not used
if ip not in ipsv4:
# Use it
selected_ip = ip
# Stop generation
break
if selected_ip is None:
raise IpNotAvailableError(None, u'No IP available to VLAN %s.' %
self.networkipv4.vlan.num_vlan)
self.oct1, self.oct2, self.oct3, self.oct4 = str(
selected_ip).split('.')
[docs]class IpEquipamento(BaseModel):
id = models.AutoField(
primary_key=True,
db_column='id_ips_dos_equipamentos'
)
ip = models.ForeignKey(
'ip.Ip',
db_column='id_ip'
)
equipamento = models.ForeignKey(
'equipamento.Equipamento',
db_column='id_equip'
)
log = logging.getLogger('IpEquipamento')
class Meta(BaseModel.Meta):
db_table = u'ips_dos_equipamentos'
managed = True
unique_together = ('ip', 'equipamento')
[docs] @classmethod
def get_by_ip(cls, ip_id):
"""Get IP by id_ip
@return: IP.
@raise IpEquipmentNotFoundError: IP is not registered.
@raise IpError: Failed to search for the IP.
"""
try:
return IpEquipamento.objects.filter(ip__id=ip_id).uniqueResult()
except ObjectDoesNotExist, e:
raise IpEquipmentNotFoundError(
e, u'There is no IP-Equipament by IP = %s.')
except Exception, e:
cls.log.error(u'Failure to search the Ip-Equipament.')
raise IpError(e, u'Failure to search the Ip-Equipament.')
[docs] @classmethod
def list_by_ip(cls, ip_id):
"""Get IP by id_ip
@return: IP.
@raise IpEquipmentNotFoundError: IP is not registered.
@raise IpError: Failed to search for the IP.
"""
try:
return IpEquipamento.objects.filter(ip__id=ip_id)
except ObjectDoesNotExist, e:
raise IpEquipmentNotFoundError(
e, u'There is no IP-Equipament by IP = %s.')
except Exception, e:
cls.log.error(u'Failure to search the Ip-Equipament.')
raise IpError(e, u'Failure to search the Ip-Equipament.')
[docs] @classmethod
def list_by_equip(cls, equip_id):
"""Get IP by id_ip
@return: IPEquipment.
@raise IpEquipmentNotFoundError: IP is not registered.
@raise IpError: Failed to search for the IP.
"""
try:
return IpEquipamento.objects.filter(equipamento__id=equip_id)
except ObjectDoesNotExist, e:
raise IpEquipmentNotFoundError(
e, u'There is no IP-Equipament by Equip = %s.')
except Exception, e:
cls.log.error(u'Failure to search the Ip-Equipament.')
raise IpError(e, u'Failure to search the Ip-Equipament.')
[docs] @classmethod
def get_by_ip_equipment(cls, ip_id, equip_id):
"""Get IP by id and equip_id.
@return: IP.
@raise IpEquipmentNotFoundError: IP is not registered.
@raise IpError: Failed to search for the IP.
"""
try:
return IpEquipamento.objects.get(ip__id=ip_id, equipamento__id=equip_id)
except ObjectDoesNotExist, e:
raise IpEquipmentNotFoundError(
e, u'There is no IP-Equipament by IP = %s. and Equipament = %s.' % (ip_id, equip_id))
except Exception, e:
cls.log.error(u'Failure to search the Ip-Equipament.')
raise IpError(e, u'Failure to search the Ip-Equipament.')
def __validate_ip(self):
try:
IpEquipamento.objects.get(ip=self.ip, equipamento=self.equipamento)
raise IpEquipamentoDuplicatedError(
None, u'IP já cadastrado para o equipamento.')
except ObjectDoesNotExist:
pass
[docs] def create(self, authenticated_user, ip_id, equipment_id):
"""Insere um relacionamento entre IP e Equipamento.
@return: Nothing.
@raise IpError: Falha ao inserir.
@raise EquipamentoNotFoundError: Equipamento não cadastrado.
@raise IpNotFoundError: Ip não cadastrado.
@raise IpEquipamentoDuplicatedError: IP já cadastrado para o equipamento.
@raise EquipamentoError: Falha ao pesquisar o equipamento.
"""
equipamentoambiente = get_model('equipamento', 'EquipamentoAmbiente')
equipamento = get_model('equipamento', 'Equipamento')
self.equipamento = equipamento().get_by_pk(equipment_id)
self.ip = Ip().get_by_pk(ip_id)
# Valida o ip
self.__validate_ip()
try:
if self.equipamento not in [ea.equipamento for ea in self.ip.networkipv4.vlan.ambiente.equipamentoambiente_set.all().select_related('equipamento')]:
ea = equipamentoambiente(
ambiente=self.ip.networkipv4.vlan.ambiente, equipamento=self.equipamento)
ea.save(authenticated_user)
self.save()
except Exception, e:
self.log.error(u'Falha ao inserir um ip_equipamento.')
raise IpError(e, u'Falha ao inserir um ip_equipamento.')
[docs] def delete(self):
"""Override Django's method to remove Ip and Equipment relationship.
If Ip from this Ip-Equipment is associated with created Vip Request, and the Equipment
is the last balancer associated, the IpEquipment association cannot be removed.
If Ip has no relationship with other Equipments, then Ip is also removed.
"""
tipoequipamento = get_model('equipamento', 'TipoEquipamento')
for r in self.ip.requisicaovips_set.all():
if self.equipamento.tipo_equipamento == tipoequipamento.get_tipo_balanceador():
# Get all equipments (except the one being removed) related to ip
# to find another balancer
other_equips = self.ip.ipequipamento_set.exclude(
equipamento=self.equipamento.id)
another_balancer = False
for ipequip in other_equips:
if ipequip.equipamento.tipo_equipamento == tipoequipamento.get_tipo_balanceador():
another_balancer = True
break
if not another_balancer:
if r.vip_criado:
raise IpEquipCantDissociateFromVip({'vip_id': r.id, 'ip': mount_ipv4_string(
self.ip), 'equip_name': self.equipamento.nome}, 'Ipv4 não pode ser disassociado do equipamento %s porque é o último balanceador da Requisição Vip %s.' % (self.equipamento.nome, r.id))
else:
# Remove ip from vip or remove vip
id_vip = r.id
if r.ipv6 is not None:
r.ip = None
r.validado = 0
r.save()
# SYNC_VIP
syncs.old_to_new(r)
else:
r.delete()
# SYNC_VIP
syncs.delete_new(id_vip)
if self.ip.serverpoolmember_set.count() > 0:
server_pool_identifiers = set()
for svm in self.ip.serverpoolmember_set.all():
item = '{}:{}'.format(svm.server_pool.id,
svm.server_pool.identifier)
server_pool_identifiers.add(item)
server_pool_identifiers = list(server_pool_identifiers)
server_pool_identifiers = ', '.join(
str(server_pool) for server_pool in server_pool_identifiers)
raise IpCantRemoveFromServerPool(
{
'ip': mount_ipv4_string(self.ip),
'equip_name': self.equipamento.nome,
'server_pool_identifiers': server_pool_identifiers
},
'Ipv4 não pode ser disassociado do equipamento %s porque ele '
'está sendo utilizando nos Server Pools (id:identifier) %s' %
(self.equipamento.nome, server_pool_identifiers))
super(IpEquipamento, self).delete()
# If IP is not related to any other equipments, its removed
if self.ip.ipequipamento_set.count() == 0:
self.ip.delete()
[docs] def remove(self, authenticated_user, ip_id, equip_id):
"""Search and remove relationship between IP and equipment.
@return: Nothing
@raise IpEquipmentNotFoundError: There's no relationship between Ip and Equipment.
@raise IpCantBeRemovedFromVip: Ip is associated with created Vip Request.
@raise IpEquipCantDissociateFromVip: Equipment is the last balanced in a created Vip Request pointing to ip.
@raise IpError: Failed to remove the relationship.
"""
ip_equipamento = self.get_by_ip_equipment(ip_id, equip_id)
try:
ip_equipamento.delete()
except (IpCantBeRemovedFromVip, IpEquipCantDissociateFromVip), e:
raise e
except Exception, e:
self.log.error(u'Falha ao remover um ip_equipamento.')
raise IpError(e, u'Falha ao remover um ip_equipamento.')
##################
# Methods for V3 #
##################
[docs] def create_v3(self, ip_equipment):
"""Inserts a relationship between IP e Equipment.
@return: Nothing.
@raise IpError: Failure to insert.
@raise EquipamentoNotFoundError: Equipment do not registered.
@raise IpNotFoundError: Ip do not registered.
@raise IpEquipamentoDuplicatedError: IP already registered for the equipment.
@raise EquipamentoError: Failure to search equipment.
"""
equipamentoambiente = get_model('equipamento', 'EquipamentoAmbiente')
equipamento = get_model('equipamento', 'Equipamento')
self.equipamento = equipamento().get_by_pk(ip_equipment.get('equipment'))
self.ip = Ip().get_by_pk(ip_equipment.get('ip'))
# Validate the ip
self.__validate_ip()
try:
try:
equipment_environment = equipamentoambiente()
equipment_environment.create_v3({
'equipment': self.equipamento_id,
'environment': self.ip.networkipv4.vlan.ambiente_id
})
except EquipamentoAmbienteDuplicatedError, e:
# If already exists, OK !
pass
self.save()
except Exception, e:
self.log.error(u'Failure to insert an ip_equipamento.')
raise IpError(e, u'Failure to insert an ip_equipamento.')
[docs] def delete_v3(self, bypass_ip=False):
"""
Method V3 to remove Ip and Equipment relationship.
If Ip from this Ip-Equipment is associated with created Vip Request,
and the Equipment is the last balancer associated, the IpEquipment
association cannot be removed.
If Ip has no relationship with other Equipments, then Ip is also
removed.
@raise IpCantRemoveFromServerPool: Ip is associated with associated
Pool Member.
@raise IpEquipCantDissociateFromVip: Equipment is the last balanced
in a created Vip Request
pointing to ip.
"""
tipoequipamento = get_model('equipamento', 'TipoEquipamento')
type_eqpt = tipoequipamento.get_tipo_balanceador()
if self.equipamento.tipo_equipamento == type_eqpt:
for vip in self.ip.viprequest_set.all():
# Filter equipments to find another balancer
another_balancer = self.ip.ipequipamento_set.exclude(
equipamento=self.equipamento.id
).filter(equipamento__tipo_equipamento=type_eqpt)
id_vip = vip.id
if not another_balancer:
with distributedlock(LOCK_VIP % id_vip):
if vip.created:
raise IpEquipCantDissociateFromVip(
{
'vip_id': id_vip,
'ip': self.ip.ip_formated,
'equip_name': self.equipamento.nome
},
'IPv4 can not be dissociated from the '
'equipment %s because it is the last '
'balancer of Vip Request %s.'
% (self.equipamento.nome, id_vip)
)
else:
# Remove ip from vip
if vip.ipv6 is not None:
vip.ipv4 = None
id_vip.save()
# SYNC_VIP
syncs.new_to_old(vip)
# Remove vip
else:
vip.delete_v3(bypass_ipv4=True,
bypass_ipv6=True)
if self.ip.serverpoolmember_set.count() > 0:
items = ['{}:{}'.format(
svm.server_pool.id,
svm.server_pool.identifier
) for svm in self.ip.serverpoolmember_set.all()]
items = ', '.join(items)
raise IpCantRemoveFromServerPool(
{
'ip': self.ip.ip_formated,
'equip_name': self.equipamento.nome,
'server_pool_identifiers': items
},
'IPv4 can not be dissociated from the equipment% s because it'
'is being using in the Server Pools (id: identifier)%s' %
(self.equipamento.nome, items)
)
super(IpEquipamento, self).delete()
# If IP is not related to any other equipments, its removed
if self.ip.ipequipamento_set.count() == 0 and not bypass_ip:
self.ip.delete_v3()
[docs]class NetworkIPv6(BaseModel):
id = models.AutoField(
primary_key=True
)
vlan = models.ForeignKey(
'vlan.Vlan',
db_column='id_vlan'
)
network_type = models.ForeignKey(
'vlan.TipoRede',
null=True,
db_column='id_tipo_rede'
)
ambient_vip = models.ForeignKey(
'ambiente.EnvironmentVip',
null=True,
db_column='id_ambientevip'
)
block = models.IntegerField(
db_column='bloco'
)
block1 = models.CharField(
max_length=4,
db_column='bloco1'
)
block2 = models.CharField(
max_length=4,
db_column='bloco2'
)
block3 = models.CharField(
max_length=4,
db_column='bloco3'
)
block4 = models.CharField(
max_length=4,
db_column='bloco4'
)
block5 = models.CharField(
max_length=4,
db_column='bloco5'
)
block6 = models.CharField(
max_length=4,
db_column='bloco6'
)
block7 = models.CharField(
max_length=4,
db_column='bloco7'
)
block8 = models.CharField(
max_length=4,
db_column='bloco8'
)
mask1 = models.CharField(
max_length=4,
db_column='mask_bloco1'
)
mask2 = models.CharField(
max_length=4,
db_column='mask_bloco2'
)
mask3 = models.CharField(
max_length=4,
db_column='mask_bloco3'
)
mask4 = models.CharField(
max_length=4,
db_column='mask_bloco4'
)
mask5 = models.CharField(
max_length=4,
db_column='mask_bloco5'
)
mask6 = models.CharField(
max_length=4,
db_column='mask_bloco6'
)
mask7 = models.CharField(
max_length=4,
db_column='mask_bloco7'
)
mask8 = models.CharField(
max_length=4,
db_column='mask_bloco8'
)
cluster_unit = models.CharField(
max_length=45,
null=True,
db_column='cluster_unit'
)
active = models.BooleanField()
log = logging.getLogger('NetworkIPv6')
class Meta(BaseModel.Meta):
db_table = u'redeipv6'
managed = True
def __str__(self):
return self.networkv6
def _get_formated_network(self):
"""Returns formated ip."""
return '{}/{}'.format(self.formated_octs, self.block)
networkv6 = property(_get_formated_network)
def _get_formated_mask(self):
"""Returns formated mask."""
return '{}:{}:{}:{}:{}:{}:{}:{}'.format(
self.mask1, self.mask2, self.mask3, self.mask4,
self.mask5, self.mask6, self.mask7, self.mask8)
mask_formated = property(_get_formated_mask)
def _get_formated_octs(self):
"""Returns formated octs."""
return '{}:{}:{}:{}:{}:{}:{}:{}'.format(
self.block1, self.block2, self.block3, self.block4,
self.block5, self.block6, self.block7, self.block8)
formated_octs = property(_get_formated_octs)
@cached_property
def dhcprelay(self):
dhcprelay = self.dhcprelayipv6_set.all()
return dhcprelay
[docs] @classmethod
def get_by_pk(cls, id):
"""Get NetworkIPv6 by id.
@return: NetworkIPv6.
@raise NetworkIPv6NotFoundError: NetworkIPv6 is not registered.
@raise NetworkIPv6Error: Failed to search for the NetworkIPv6.
@raise OperationalError: Lock wait timeout exceeded.
"""
try:
return NetworkIPv6.objects.filter(id=id).uniqueResult()
except ObjectDoesNotExist, e:
raise ObjectDoesNotExistException(
u'There is no NetworkIPv6 with pk = %s.' % id)
except OperationalError, e:
cls.log.error(u'Lock wait timeout exceeded.')
raise OperationalError(
e, u'Lock wait timeout exceeded; try restarting transaction')
except Exception, e:
cls.log.error(u'Error finding NetworkIPv6.')
raise NetworkIPv6Error(e, u'Error finding NetworkIPv6.')
[docs] def activate(self, authenticated_user):
try:
self.active = 1
self.save()
net_slz = get_app('api_network', 'serializers.v3')
serializer = net_slz.NetworkIPv6V3Serializer(
self,
include=('vlan__details__environment__basic',))
data_to_queue = serializer.data
data_to_queue.update({
'description': queue_keys.NETWORKv6_ACTIVATE
})
# Send to Queue
queue_manager = QueueManager(broker_vhost='tasks',
queue_name='tasks.aclapi',
exchange_name='tasks.aclapi',
routing_key='tasks.aclapi')
queue_manager.append({
'action': queue_keys.NETWORKv6_ACTIVATE,
'kind': queue_keys.NETWORKv6_KEY,
'data': data_to_queue
})
queue_manager.send()
except Exception, e:
self.log.error(u'Error activating NetworkIPv6.')
raise NetworkIPv4Error(e, u'Error activating NetworkIPv6.')
[docs] def deactivate(self, authenticated_user, commit=False):
"""
Update status column to 'active = 0'
@param authenticated_user: User authenticate
@raise NetworkIPv6Error: Error disabling NetworkIPv6.
"""
try:
self.active = 0
self.save(authenticated_user, commit=commit)
net_slz = get_app('api_network', 'serializers.v3')
serializer = net_slz.NetworkIPv6V3Serializer(
self,
include=('vlan__details__environment__basic',))
data_to_queue = serializer.data
data_to_queue.update({
'description': queue_keys.NETWORKv6_DEACTIVATE
})
# Send to Queue
queue_manager = QueueManager(broker_vhost='tasks',
queue_name='tasks.aclapi',
exchange_name='tasks.aclapi',
routing_key='tasks.aclapi')
queue_manager.append({
'action': queue_keys.NETWORKv6_DEACTIVATE,
'kind': queue_keys.NETWORKv6_KEY,
'data': data_to_queue
})
queue_manager.send()
except Exception, e:
self.log.error(u'Error disabling NetworkIPv6.')
raise NetworkIPv6Error(e, u'Error disabling NetworkIPv6.')
[docs] def edit_network_ipv6(self, authenticated_user, id_net_type, id_env_vip, cluster_unit):
try:
self.network_type = id_net_type
self.ambient_vip = id_env_vip
self.cluster_unit = cluster_unit
self.save()
except Exception, e:
self.log.error(u'Error on update NetworkIPv6.')
raise NetworkIPv4Error(e, u'Error on update NetworkIPv6.')
[docs] def add_network_ipv6(self, user, id_vlan, network_type, evip, prefix=None):
"""
Insert new NetworkIPv6 in database
@return: Vlan map
@raise VlanNotFoundError: Vlan is not registered.
@raise VlanError: Failed to search for the Vlan
@raise ConfigEnvironmentInvalidError: Invalid Environment Configuration or not registered
@raise NetworkIPv6Error: Error persisting a NetworkIPv6.
@raise NetworkIPv6AddressNotAvailableError: Unavailable address to create a NetworkIPv6.
@raise InvalidValueError: Network type does not exist.
"""
configenvironment = get_model('ambiente', 'ConfigEnvironment')
vlan_model = get_model('vlan', 'Vlan')
self.vlan = vlan_model().get_by_pk(id_vlan)
network_found = None
stop = False
internal_network_type = None
type_ipv6 = IP_VERSION.IPv6[0]
try:
# Find all configs type v6 in environment
configs = configenvironment.get_by_environment(
self.vlan.ambiente.id).filter(ip_config__type=IP_VERSION.IPv6[0])
# If not found, an exception is thrown
if len(configs) == 0:
raise ConfigEnvironmentInvalidError(
None, u'Invalid Configuration')
# Find all networks ralated to environment
nets = NetworkIPv6.objects.filter(
vlan__ambiente__id=self.vlan.ambiente.id)
# Cast to API class
networksv6 = set([(IPv6Network(
'%s:%s:%s:%s:%s:%s:%s:%s/%s' %
(net_ip.block1, net_ip.block2, net_ip.block3,
net_ip.block4, net_ip.block5, net_ip.block6,
net_ip.block7, net_ip.block8, net_ip.block))) for net_ip in nets])
# For each configuration founded in environment
for config in configs:
# If already get a network stop this
if stop:
break
# Need to be IPv6
if config.ip_config.type == IP_VERSION.IPv6[0]:
net6 = IPv6Network(config.ip_config.subnet)
if prefix is not None:
new_prefix = int(prefix)
else:
new_prefix = int(config.ip_config.new_prefix)
self.log.info(u'Prefix that will be used: %s' % new_prefix)
# For each subnet generated with configs
for subnet in net6.iter_subnets(new_prefix=new_prefix):
# Checks if the network generated is UNUSED
if subnet not in networksv6:
in_range = network_in_range(
self.vlan, subnet, type_ipv6)
if not in_range:
continue
# If not this will be USED
network_found = subnet
if network_type:
internal_network_type = network_type
elif config.ip_config.network_type is not None:
internal_network_type = config.ip_config.network_type
else:
self.log.error(
u'Parameter tipo_rede is invalid. Value: %s', network_type)
raise InvalidValueError(
None, 'network_type', network_type)
# Stop generation logic
stop = True
break
# If not be IPv6
else:
# Throw an exception
raise ConfigEnvironmentInvalidError(
None, u'Invalid Configuration')
except (ValueError, TypeError, AddressValueError), e:
raise ConfigEnvironmentInvalidError(e, u'Invalid Configuration')
# Checks if found any available network
if network_found is None:
# If not found, an exception is thrown
raise NetworkIPv6AddressNotAvailableError(
None, u'Unavailable address to create a NetworkIPv6.')
# Set block by network generated
self.block1, self.block2, self.block3, self.block4, self.block5, self.block6, self.block7, self.block8 = str(
network_found.network.exploded).split(':')
# Set block by network generated
self.block = network_found.prefixlen
# Set mask by network generated
self.mask1, self.mask2, self.mask3, self.mask4, self.mask5, self.mask6, self.mask7, self.mask8 = str(
network_found.netmask.exploded).split(':')
try:
# Set Network Type
self.network_type = internal_network_type
# Set Environment VIP
self.ambient_vip = evip
self.save()
except Exception, e:
self.log.error(u'Error persisting a NetworkIPv6.')
raise NetworkIPv6Error(e, u'Error persisting a NetworkIPv6.')
# Return vlan map
vlan_map = dict()
vlan_map['id'] = self.vlan.id
vlan_map['nome'] = self.vlan.nome
vlan_map['num_vlan'] = self.vlan.num_vlan
vlan_map['id_tipo_rede'] = self.network_type.id
vlan_map['id_ambiente'] = self.vlan.ambiente.id
vlan_map['bloco1'] = self.block1
vlan_map['bloco2'] = self.block2
vlan_map['bloco3'] = self.block3
vlan_map['bloco4'] = self.block4
vlan_map['bloco5'] = self.block5
vlan_map['bloco6'] = self.block6
vlan_map['bloco7'] = self.block7
vlan_map['bloco8'] = self.block8
vlan_map['bloco'] = self.block
vlan_map['mask_bloco1'] = self.mask1
vlan_map['mask_bloco2'] = self.mask2
vlan_map['mask_bloco3'] = self.mask3
vlan_map['mask_bloco4'] = self.mask4
vlan_map['mask_bloco5'] = self.mask5
vlan_map['mask_bloco6'] = self.mask6
vlan_map['mask_bloco7'] = self.mask7
vlan_map['mask_bloco8'] = self.mask8
vlan_map['descricao'] = self.vlan.descricao
vlan_map['acl_file_name'] = self.vlan.acl_file_name
vlan_map['acl_valida'] = self.vlan.acl_valida
vlan_map['acl_file_name_v6'] = self.vlan.acl_file_name_v6
vlan_map['acl_valida_v6'] = self.vlan.acl_valida_v6
vlan_map['ativada'] = self.vlan.ativada
vlan_map['id_network'] = self.id
map = dict()
map['vlan'] = vlan_map
return map
[docs] def delete(self):
try:
for ip in self.ipv6_set.all():
ip.delete()
super(NetworkIPv6, self).delete()
except IpCantBeRemovedFromVip, e:
# Network id and ReqVip id
net_name = str(self.block1) + ':' + str(self.block2) + \
':' + str(self.block3) + ':' + str(self.block4) + ':'
net_name = net_name + str(self.block5) + ':' + str(self.block6) + ':' + str(
self.block7) + ':' + str(self.block8) + '/' + str(self.block)
cause = {'Net': net_name, 'ReqVip': e.cause}
raise IpCantBeRemovedFromVip(
cause, 'Esta Rede possui um Vip apontando para ela, e não pode ser excluída')
##################
# Methods for V3 #
##################
[docs] def create_v3(self, networkv6, locks_used=[], force=False):
"""Create new networkIPv6."""
vlan_model = get_app('vlan')
envvip_model = get_app('ambiente')
try:
self.block1 = networkv6.get('block1')
self.block2 = networkv6.get('block2')
self.block3 = networkv6.get('block3')
self.block4 = networkv6.get('block4')
self.block5 = networkv6.get('block5')
self.block6 = networkv6.get('block6')
self.block7 = networkv6.get('block7')
self.block8 = networkv6.get('block8')
self.block = networkv6.get('prefix')
self.mask1 = networkv6.get('mask1')
self.mask2 = networkv6.get('mask2')
self.mask3 = networkv6.get('mask3')
self.mask4 = networkv6.get('mask4')
self.mask5 = networkv6.get('mask5')
self.mask6 = networkv6.get('mask6')
self.mask7 = networkv6.get('mask7')
self.mask8 = networkv6.get('mask8')
self.cluster_unit = networkv6.get('cluster_unit')
if force:
self.active = networkv6.get('active', False)
# Vlan
self.vlan = vlan_model.Vlan().get_by_pk(networkv6.get('vlan'))
# Type of Network
if networkv6.get('network_type'):
self.network_type = vlan_model.TipoRede()\
.get_by_pk(networkv6.get('network_type'))
# has environmentvip
if networkv6.get('environmentvip'):
self.ambient_vip = envvip_model.EnvironmentVip()\
.get_by_pk(networkv6.get('environmentvip'))
# Get environments related
envs = self.vlan.get_environment_related(use_vrf=True)\
.values_list('id', flat=True)
except vlan_model.VlanNotFoundError, e:
self.log.error(e.message)
raise InvalidInputException(e.message)
except vlan_model.NetworkTypeNotFoundError, e:
self.log.error(e.message)
raise InvalidInputException(e.message)
except envvip_model.EnvironmentVipNotFoundError, e:
self.log.error(e.message)
raise InvalidInputException(e.message)
except NetworkIPv6ErrorV3, e:
self.log.error(e.message)
raise NetworkIPv6ErrorV3(e.message)
except Exception, e:
self.log.error(e)
raise NetworkIPv6ErrorV3(e)
else:
locks_name = list()
for env in envs:
lock_name = LOCK_ENVIRONMENT_ALLOCATES % env
if lock_name not in locks_used:
locks_name.append(lock_name)
locks_list = create_lock_with_blocking(locks_name)
try:
# Allocate network for vlan with prefix(optional)
if not self.block1 and not self.block2 and not self.block3 and \
not self.block4 and not self.block5 and \
not self.block6 and not self.block7 and not self.block8:
try:
self.allocate_network_v3(networkv6.get('vlan'),
networkv6.get('prefix'))
except NetworkIPv6AddressNotAvailableError, e:
self.log.error(e.message)
raise NetworkIPv6ErrorV3(e.message)
# Was send prefix and octs
elif self.block and self.block1 and self.block2 and self.block3 \
and self.block4 and self.block5 and self.block6 and \
self.block7 and self.block8:
ip = IPNetwork('%s/%s' % (self.formated_octs, self.block))
mask = ip.netmask.exploded.split(':')
self.mask1 = mask[0]
self.mask2 = mask[1]
self.mask3 = mask[2]
self.mask4 = mask[3]
self.mask5 = mask[4]
self.mask6 = mask[5]
self.mask7 = mask[6]
self.mask8 = mask[7]
envs = self.vlan.get_environment_related()
net_ip = [IPNetwork(self.networkv6)]
try:
network.validate_network(envs, net_ip, IP_VERSION.IPv6[0])
except NetworkConflictException, e:
self.log.error(e.detail)
raise NetworkIPv6ErrorV3(e.detail)
try:
self.validate_v3()
except vlan_model.VlanErrorV3, e:
self.log.error(e.message)
raise NetworkIPv6ErrorV3(e.message)
else:
# Was not send correctly
self.log.error('There is need to send block ou mask.')
raise NetworkIPv6ErrorV3(
'There is need to send block ou mask.')
self.save()
if self.block < 127:
# Creates Ips for routers of environment
eqpt_model = get_model('equipamento', 'EquipamentoAmbiente')
eqpts = eqpt_model.get_routers_by_environment(self.vlan.ambiente)\
.values_list('equipamento', flat=True)
if eqpts:
ip = Ipv6.get_first_available_ip6(self.id)
gateway_ip = str(ip).split(':')
ip_map = {
'block1': gateway_ip[0],
'block2': gateway_ip[1],
'block3': gateway_ip[2],
'block4': gateway_ip[3],
'block5': gateway_ip[4],
'block6': gateway_ip[5],
'block7': gateway_ip[6],
'block8': gateway_ip[7],
'networkipv6': self.id,
'equipments': [{
'id': eqpt
} for eqpt in eqpts]
}
locks = locks_name + locks_used
ip_inst = Ipv6()
ip_inst.create_v3(ip_map, locks_used=locks)
if len(eqpts) > 1 and self.block < 126:
for eqpt in eqpts:
ip = Ipv6.get_first_available_ip6(self.id, True)
router_ip = str(ip).split(':')
ip_map = {
'block1': router_ip[0],
'block2': router_ip[1],
'block3': router_ip[2],
'block4': router_ip[3],
'block5': router_ip[4],
'block6': router_ip[5],
'block7': router_ip[6],
'block8': router_ip[7],
'networkipv6': self.id,
'equipments': [{
'id': eqpt
}]
}
locks = locks_name + locks_used
ip_inst = Ipv6()
ip_inst.create_v3(ip_map, locks_used=locks)
except NetworkIPv6ErrorV3, e:
self.log.error(e.message)
raise NetworkIPv6ErrorV3(e.message)
except Exception, e:
self.log.error(e)
raise NetworkIPv6ErrorV3(e)
finally:
destroy_lock(locks_list)
[docs] def update_v3(self, networkv6, locks_used=[], force=False):
"""
Update networkIPv6.
"""
vlan_model = get_app('vlan')
envvip_model = get_app('ambiente')
try:
self.cluster_unit = networkv6.get('cluster_unit')
self.network_type = vlan_model.TipoRede() \
.get_by_pk(networkv6.get('network_type'))
if force:
self.active = networkv6.get('active', False)
# has environmentvip
if networkv6.get('environmentvip'):
self.ambient_vip = envvip_model.EnvironmentVip() \
.get_by_pk(networkv6.get('environmentvip'))
else:
self.ambient_vip = None
except vlan_model.NetworkTypeNotFoundError, e:
self.log.error(e.message)
raise InvalidInputException(e.message)
except envvip_model.EnvironmentVipNotFoundError, e:
self.log.error(e.message)
raise InvalidInputException(e.message)
except NetworkIPv6ErrorV3, e:
self.log.error(e.message)
raise NetworkIPv6ErrorV3(e.message)
except Exception, e:
self.log.error(e)
raise NetworkIPv6ErrorV3(e)
else:
# Create locks for environment
locks_name = list()
lock_name = LOCK_NETWORK_IPV6 % self.id
if locks_name not in locks_used:
locks_name.append(lock_name)
locks_list = create_lock_with_blocking(locks_name)
try:
self.validate_v3()
self.save()
except vlan_model.VlanErrorV3, e:
self.log.error(e.message)
raise NetworkIPv6ErrorV3(e.message)
except NetworkIPv6ErrorV3, e:
self.log.error(e)
raise NetworkIPv6ErrorV3(e)
except Exception, e:
self.log.error(e)
raise NetworkIPv6ErrorV3(e)
finally:
destroy_lock(locks_list)
[docs] def delete_v3(self, locks_used=[], force=False):
"""Method V3 to remove networkIPv6.
Before removing the networkIPv6 removes all your Ipv4.
"""
# Get environments related
envs = self.vlan.get_environment_related(use_vrf=True)\
.values_list('id', flat=True)
locks_name = list()
# Prepares lock for object current network
lock_name = LOCK_NETWORK_IPV6 % self.id
if lock_name not in locks_used:
locks_name.append(lock_name)
# Prepares lock for environment related
for env in envs:
lock_name = LOCK_ENVIRONMENT_ALLOCATES % env
if lock_name not in locks_used:
locks_name.append(lock_name)
# Create locks for environment and vlan
locks_list = create_lock_with_blocking(locks_name)
try:
if self.active and not force:
msg = 'Can\'t remove network {} because it is active. ' \
'Try to set it inactive before removing it.'.format(
str(self))
raise NetworkActiveError(None, msg)
for ip in self.ipv6_set.all():
ip.delete_v3()
super(NetworkIPv6, self).delete()
except IpCantBeRemovedFromVip, e:
msg = 'This network has a VIP pointing to it, and can not '\
'be deleted. Network: {}, Vip Request: {}'.format(
str(self), e.cause)
self.log.error(msg)
raise NetworkIPv6ErrorV3(msg)
except NetworkActiveError, e:
self.log.error(e.message)
raise NetworkIPv6ErrorV3(e.message)
except NetworkIPv6ErrorV3, e:
self.log.error(e.message)
raise NetworkIPv6ErrorV3(e.message)
except Exception, e:
self.log.error(e)
raise NetworkIPv6ErrorV3(e)
finally:
destroy_lock(locks_list)
[docs] def validate_v3(self):
"""
Validate NetworkIPv6.
"""
if not self.network_type:
raise NetworkIPv6ErrorV3('Network type can not null')
# validate if network if allow in environment
configs = self.vlan.ambiente.configs.all()
self.vlan.allow_networks_environment(configs, [], [self])
[docs] def activate_v3(self):
"""
Send activate info of network v6 for queue of ACL configuration
system.
Update status column to 'active = 1'.
@raise NetworkIPv6Error: Error activating a NetworkIPv6.
"""
try:
self.active = 1
self.save()
net_slz = get_app('api_network', 'serializers.v3')
serializer = net_slz.NetworkIPv6V3Serializer(
self,
include=('vlan__details__environment__basic',))
data_to_queue = serializer.data
data_to_queue.update({
'description': queue_keys.NETWORKv6_ACTIVATE
})
# Send to Queue
queue_manager = QueueManager(broker_vhost='tasks',
queue_name='tasks.aclapi',
exchange_name='tasks.aclapi',
routing_key='tasks.aclapi')
queue_manager.append({
'action': queue_keys.NETWORKv6_ACTIVATE,
'kind': queue_keys.NETWORKv6_KEY,
'data': data_to_queue
})
queue_manager.send()
except Exception, e:
self.log.error(u'Error activating NetworkIPv6.')
raise NetworkIPv6ErrorV3(e, u'Error activating NetworkIPv6.')
[docs] def deactivate_v3(self):
"""
Send deactivate info of network v6 for queue of ACL configuration
system.
Update status column to 'active = 0'.
@raise NetworkIPv6Error: Error disabling a NetworkIPv6.
"""
try:
net_slz = get_app('api_network', 'serializers.v3')
self.active = 0
serializer = net_slz.NetworkIPv6V3Serializer(
self,
include=('vlan__details__environment__basic',))
data_to_queue = serializer.data
data_to_queue.update({
'description': queue_keys.NETWORKv6_DEACTIVATE
})
# Send to Queue
queue_manager = QueueManager(broker_vhost='tasks',
queue_name='tasks.aclapi',
exchange_name='tasks.aclapi',
routing_key='tasks.aclapi')
queue_manager.append({
'action': queue_keys.NETWORKv6_DEACTIVATE,
'kind': queue_keys.NETWORKv6_KEY,
'data': data_to_queue
})
queue_manager.send()
self.save()
except Exception, e:
self.log.error(u'Error disabling NetworkIPv6.')
raise NetworkIPv6ErrorV3(e, u'Error disabling NetworkIPv6.')
[docs] def allocate_network_v3(self, id_vlan, prefix=None):
"""Allocate new NetworkIPv6
@raise VlanNotFoundError: Vlan is not registered.
@raise VlanError: Failed to search for the Vlan
@raise ConfigEnvironmentInvalidError: Invalid Environment
Configuration or not
registered
@raise NetworkIPv6Error: Error persisting a NetworkIPv6.
@raise NetworkIPv6AddressNotAvailableError: Unavailable address to
create a NetworkIPv6.
@raise Invalid: Unavailable address to create a NetworkIPv6.
@raise InvalidValueError: Network type does not exist.
"""
vlan_model = get_model('vlan', 'Vlan')
self.vlan = vlan_model().get_by_pk(id_vlan)
netv4, nets_envs = network.get_networks_related(
vrfs=self.vlan.get_vrf(),
eqpts=self.vlan.get_eqpt(),
has_netv4=False
)
nets_envs = [IPNetwork(net.networkv6) for net in nets_envs]
network_found = None
try:
configs = self.vlan.ambiente.configs.filter(
ip_config__type=IP_VERSION.IPv6[0])
# For each configuration founded in environment
for config in configs:
net6 = IPNetwork(config.ip_config.subnet)
if prefix is not None:
new_prefix = int(prefix)
else:
new_prefix = int(config.ip_config.new_prefix)
self.log.info(
u'Prefix that will be used: %s' % new_prefix)
free_nets = network.get_free_space_network([net6], nets_envs)
for free_net in free_nets:
try:
subnets = free_net.iter_subnets(new_prefix=new_prefix)
subnet = subnets.next()
except Exception:
pass
else:
# Set octs by network generated
self.block1, self.block2, self.block3, self.block4,\
self.block5, self.block6, self.block7, \
self.block8 = str(
subnet.network.exploded
).split(':')
# Set block by network generated
self.block = subnet.prefixlen
mask = subnet.netmask.exploded.split(':')
self.mask1 = mask[0]
self.mask2 = mask[1]
self.mask3 = mask[2]
self.mask4 = mask[3]
self.mask5 = mask[4]
self.mask6 = mask[5]
self.mask7 = mask[6]
self.mask8 = mask[7]
if not self.network_type:
self.network_type = config.ip_config.network_type
return
# Checks if found any available network
if network_found is None:
# If not found, an exception is thrown
raise NetworkIPv6AddressNotAvailableError(
None, u'Unavailable address to create a NetworkIPv6.')
except (ValueError, TypeError, AddressValueError), e:
raise ConfigEnvironmentInvalidError(e, u'Invalid Configuration')
[docs]class Ipv6(BaseModel):
id = models.AutoField(
primary_key=True,
db_column='id_ipv6'
)
description = models.CharField(
max_length=100,
blank=True,
null=True,
db_column='descricao'
)
networkipv6 = models.ForeignKey(
'ip.NetworkIPv6',
db_column='id_redeipv6'
)
block1 = models.CharField(
max_length=4,
db_column='bloco1'
)
block2 = models.CharField(
max_length=4,
db_column='bloco2'
)
block3 = models.CharField(
max_length=4,
db_column='bloco3'
)
block4 = models.CharField(
max_length=4,
db_column='bloco4'
)
block5 = models.CharField(
max_length=4,
db_column='bloco5'
)
block6 = models.CharField(
max_length=4,
db_column='bloco6'
)
block7 = models.CharField(
max_length=4,
db_column='bloco7'
)
block8 = models.CharField(
max_length=4,
db_column='bloco8'
)
log = logging.getLogger('Ipv6')
class Meta(BaseModel.Meta):
db_table = u'ipsv6'
managed = True
unique_together = ('block1', 'block2', 'block3', 'block4',
'block5', 'block6', 'block7', 'block8',
'networkipv6')
def __str__(self):
return self.ip_formated
def _get_formated_ip(self):
"""Returns formated ip."""
return '%s:%s:%s:%s:%s:%s:%s:%s' % (
self.block1, self.block2, self.block3, self.block4,
self.block5, self.block6, self.block7, self.block8)
ip_formated = property(_get_formated_ip)
def _get_equipments(self):
"""Returns equipments list."""
ipeqs = self.ipv6equipament_set.all().select_related('equipamento')
eqpts = [ipeq.equipamento for ipeq in ipeqs]
return eqpts
equipments = property(_get_equipments)
def _get_ipv6_equipment(self):
return self.ipv6equipament_set.all()
ipv6_equipment = \
property(_get_ipv6_equipment)
def _get_vips(self):
"""Returns vips list."""
vips = self.viprequest_set.all()
return vips
vips = property(_get_vips)
def _get_server_pool_members(self):
"""Returns pool members list."""
server_pool_members = self.serverpoolmember_set.all()
return server_pool_members
server_pool_members = property(_get_server_pool_members)
[docs] @classmethod
def get_by_pk(cls, id):
"""Get IPv6 by id.
@return: IPv6.
@raise IpNotFoundError: IPv6 is not registered.
@raise IpError: Failed to search for the IPv6.
@raise OperationalError: Lock wait timeout exceeded.
"""
try:
return Ipv6.objects.filter(id=id).uniqueResult()
except ObjectDoesNotExist, e:
raise IpNotFoundError(e, u'Dont there is a IP by pk = %s.' % id)
except OperationalError, e:
cls.log.error(u'Lock wait timeout exceeded.')
raise OperationalError(
e, u'Lock wait timeout exceeded; try restarting transaction')
except Exception, e:
cls.log.error(u'Failure to search the IP.')
raise IpError(e, u'Failure to search the IP.')
[docs] def get_by_blocks_equipment(self, block1, block2, block3, block4, block5, block6, block7, block8, equip_id):
"""Get IPv6 by blocks and equip_id.
@return: IPv6.
@raise IpNotFoundError: IP is not registered.
@raise IpError: Failed to search for the IP.
"""
try:
return Ipv6.objects.get(
block1=block1, block2=block2, block3=block3, block4=block4,
block5=block5, block6=block6, block7=block7, block8=block8,
ipv6equipament__equipamento__id=equip_id)
except ObjectDoesNotExist, e:
raise IpNotFoundError(e, u'There is no IP %s:%s:%s:%s:%s:%s:%s:%s of the equipament %s.' % (
block1, block2, block3, block4, block5, block6, block7, block8, equip_id))
except Exception, e:
self.log.error(u'Failure to search the IP.')
raise IpError(e, u'Failure to search the IP.')
[docs] @classmethod
def list_by_network(cls, id_network):
"""Get IP6 LIST by id_network.
@return: IP6 List.
@raise IpNotFoundError: IP6 is not registered.
@raise IpError: Failed to search for the IP6.
@raise OperationalError: Lock wait timeout exceeded.
"""
try:
return Ipv6.objects.filter(networkipv6=id_network)
except ObjectDoesNotExist, e:
raise IpNotFoundError(
e, u'Dont there is a IP by network_id = %s.' % id)
except OperationalError, e:
cls.log.error(u'Lock wait timeout exceeded.')
raise OperationalError(
e, u'Lock wait timeout exceeded; try restarting transaction')
except Exception, e:
cls.log.error(u'Failure to search the IP.')
raise IpError(e, u'Failure to search the IP')
[docs] @classmethod
def list_by_environment_and_equipment(cls, id_ambiente, id_equipment):
"""Get IP LIST by id_network.
@return: IP List.
@raise IpNotFoundError: IP is not registered.
@raise IpError: Failed to search for the IP.
@raise OperationalError: Lock wait timeout exceeded.
"""
try:
return Ipv6.objects.filter(
networkipv6__vlan__ambiente__id=id_ambiente,
ipv6equipament__equipamento__id=id_equipment)
except ObjectDoesNotExist, e:
raise IpNotFoundError(
e, u'Dont there is a IP by network_id = %s.' % id)
except OperationalError, e:
cls.log.error(u'Lock wait timeout exceeded.')
raise OperationalError(
e, u'Lock wait timeout exceeded; try restarting transaction')
except Exception, e:
cls.log.error(u'Failure to search the IP.')
raise IpError(e, u'Failure to search the IP')
[docs] @classmethod
def get_available_ip6(cls, id_network):
"""Get a available ip6 for network6
@return: Available IP6
@raise IpNotAvailableError: NetworkIPv6 does not has available Ip6
"""
configuration = get_model('config', 'Configuration')
cls.networkipv6 = NetworkIPv6.get_by_pk(id_network)
# Cast to API
net6 = IPv6Network('%s:%s:%s:%s:%s:%s:%s:%s/%s' % (
cls.networkipv6.block1, cls.networkipv6.block2, cls.networkipv6.block3,
cls.networkipv6.block4, cls.networkipv6.block5, cls.networkipv6.block6,
cls.networkipv6.block7, cls.networkipv6.block8, cls.networkipv6.block))
# Find all ipv6s ralated to network
ips = Ipv6.objects.filter(networkipv6__id=cls.networkipv6.id)
# Cast all to API class
ipsv6 = set([(IPv6Address('%s:%s:%s:%s:%s:%s:%s:%s' % (
ip.block1, ip.block2, ip.block3, ip.block4, ip.block5, ip.block6, ip.block7, ip.block8))) for ip in ips])
# Get configuration
conf = configuration.get()
selected_ip = None
# For each ip generated
# For each ip generated
i = 0
for ip in net6.iterhosts():
# Do not use some range of IPs (config)
i = i + 1
if i >= conf.IPv6_MIN and i < (net6.numhosts - conf.IPv6_MAX):
# If IP generated was not used
if ip not in ipsv6:
# Use it
selected_ip = ip
return selected_ip.exploded
# Stop generation
break
if selected_ip is None:
raise IpNotAvailableError(
None, u'No IP6 available to NETWORK %s.' % cls.networkipv6.id)
[docs] @classmethod
def get_first_available_ip6(cls, id_network, topdown=False):
"""Get a first available ip6 for network6
@return: Available IP6
@raise IpNotAvailableError: NetworkIPv6 does not has available Ip6
"""
cls.networkipv6 = NetworkIPv6.get_by_pk(id_network)
# Cast to API
net6 = IPv6Network('%s:%s:%s:%s:%s:%s:%s:%s/%s' % (
cls.networkipv6.block1, cls.networkipv6.block2, cls.networkipv6.block3,
cls.networkipv6.block4, cls.networkipv6.block5, cls.networkipv6.block6,
cls.networkipv6.block7, cls.networkipv6.block8, cls.networkipv6.block))
# Find all ipv6s ralated to network
ips = Ipv6.objects.filter(networkipv6__id=cls.networkipv6.id)
for ip in ips:
cls.log.info('ip %s' % ip.block8)
# Cast all to API class
ipsv6 = set([(IPv6Address('%s:%s:%s:%s:%s:%s:%s:%s' % (
ip.block1, ip.block2, ip.block3, ip.block4, ip.block5, ip.block6, ip.block7, ip.block8)
)) for ip in ips])
selected_ip = None
if topdown:
method = net6.iterhostsTopDown
else:
method = net6.iterhosts
# For each ip generated
for ip in method():
# If IP generated was not used
if ip not in ipsv6:
# Use it
selected_ip = ip
return selected_ip.exploded
# Stop generation
break
if selected_ip is None:
raise IpNotAvailableError(
None, u'No IP6 available to NETWORK %s.' % cls.networkipv6.id)
[docs] def delete_ip6(self, user, id_ip):
try:
ip = self.get_by_pk(id_ip)
ip.delete()
except IpNotFoundError, e:
raise IpNotFoundError(None, e)
except Exception, e:
self.log.error(u'Failure to delete the IP.')
raise IpError(e, u'Failure to delete the IP')
[docs] def edit_ipv6(self, user):
configuration = get_model('config', 'Configuration')
try:
# Cast to API
net6 = IPv6Network('%s:%s:%s:%s:%s:%s:%s:%s/%s' %
(self.networkipv6.block1, self.networkipv6.block2, self.networkipv6.block3,
self.networkipv6.block4, self.networkipv6.block5, self.networkipv6.block6,
self.networkipv6.block7, self.networkipv6.block8, self.networkipv6.block))
# Find all ipv6s ralated to network
ips = Ipv6.objects.filter(networkipv6__id=self.networkipv6.id)
ip6_object = IPv6Address('%s:%s:%s:%s:%s:%s:%s:%s' % (
self.block1, self.block2, self.block3, self.block4, self.block5, self.block6, self.block7, self.block8))
# Cast all to API class
ipsv6 = set([IPv6Address('%s:%s:%s:%s:%s:%s:%s:%s' % (
ip.block1, ip.block2, ip.block3, ip.block4, ip.block5, ip.block6, ip.block7, ip.block8)) for ip in ips])
# Get configuration
conf = configuration.get()
flag = True
aux_ip6 = ip6_object.exploded
aux_ip6 = aux_ip6.split(':')
self.block1 = aux_ip6[0]
self.block2 = aux_ip6[1]
self.block3 = aux_ip6[2]
self.block4 = aux_ip6[3]
self.block5 = aux_ip6[4]
self.block6 = aux_ip6[5]
self.block7 = aux_ip6[6]
self.block8 = aux_ip6[7]
if ip6_object not in ipsv6:
flag = False
if ip6_object in net6:
# Get configuration
conf = configuration.get()
first_ip_network = int(net6.network)
bcast_ip_network = int(net6.broadcast)
ipv6_network = int(ip6_object)
if ipv6_network >= (first_ip_network + conf.IPv6_MIN) and ipv6_network < (bcast_ip_network - conf.IPv6_MAX):
flag = True
else:
ip6_aux = self.get_by_blocks_and_net(
self.block1, self.block2, self.block3, self.block4, self.block5, self.block6, self.block7, self.block8, self.networkipv6.id)
if self.id != ip6_aux.id:
raise IpNotAvailableError(None, u'Ipv6 %s:%s:%s:%s:%s:%s:%s:%s already on use by network %s.' % (
self.block1, self.block2, self.block3, self.block4, self.block5,
self.block6, self.block7, self.block8, self.networkipv6.id))
if flag:
self.save()
else:
raise IpNotAvailableError(None, u'Ipv6 %s:%s:%s:%s:%s:%s:%s:%s not available for network %s.' % (
self.block1, self.block2, self.block3, self.block4, self.block5,
self.block6, self.block7, self.block8, self.networkipv6.id))
except IpEquipmentAlreadyAssociation, e:
self.log.error(e)
raise IpEquipmentAlreadyAssociation(None, e)
except AddressValueError:
raise InvalidValueError(None, 'ip6', u'%s:%s:%s:%s:%s:%s:%s:%s' % (
self.block1, self.block2, self.block3, self.block4, self.block5, self.block6, self.block7, self.block8))
except IpNotAvailableError, e:
raise IpNotAvailableError(None, e.message)
except IpError, e:
self.log.error(
u'Error adding new IPv6 or relationship ip-equipment.')
raise IpError(
e, u'Error adding new IPv6 or relationship ip-equipment.')
[docs] def save_ipv6(self, equipment_id, user, net):
equipamentoambiente = get_model('equipamento', 'EquipamentoAmbiente')
equipamento = get_model('equipamento', 'Equipamento')
filterequiptype = get_model('filterequiptype', 'FilterEquipType')
try:
already_ip = False
# Cast to API
net6 = IPv6Network('%s:%s:%s:%s:%s:%s:%s:%s/%s' % (net.block1, net.block2, net.block3, net.block4,
net.block5, net.block6, net.block7, net.block8, net.block))
# Find all ipv6s ralated to network
ips = Ipv6.objects.filter(networkipv6__id=net.id)
ip6_object = IPv6Address('%s:%s:%s:%s:%s:%s:%s:%s' % (
self.block1, self.block2, self.block3, self.block4, self.block5, self.block6, self.block7, self.block8))
# Cast all to API class
ipsv6 = set([IPv6Address('%s:%s:%s:%s:%s:%s:%s:%s' % (
ip.block1, ip.block2, ip.block3, ip.block4, ip.block5, ip.block6, ip.block7, ip.block8)) for ip in ips])
# Get configuration
# conf = Configuration.get()
flag = False
aux_ip6 = ip6_object.exploded
aux_ip6 = aux_ip6.split(':')
self.block1 = aux_ip6[0]
self.block2 = aux_ip6[1]
self.block3 = aux_ip6[2]
self.block4 = aux_ip6[3]
self.block5 = aux_ip6[4]
self.block6 = aux_ip6[5]
self.block7 = aux_ip6[6]
self.block8 = aux_ip6[7]
# ip6_object = ip6_object.exploded
if ip6_object not in ipsv6:
if ip6_object in net6:
# Get configuration
# conf = Configuration.get()
first_ip_network = int(net6.network)
bcast_ip_network = int(net6.broadcast)
ipv6_network = int(ip6_object)
if ipv6_network >= (first_ip_network) and ipv6_network < (bcast_ip_network):
flag = True
else:
ip_aux = self.get_by_blocks_and_net(
self.block1, self.block2, self.block3, self.block4, self.block5, self.block6, self.block7, self.block8, net.id)
try:
Ipv6Equipament.get_by_ip6(ip_aux.id)
raise IpEquipmentAlreadyAssociation(None, u'Ipv6 %s:%s:%s:%s:%s:%s:%s:%s already has association with an Equipament. Try using the association screen for this Ip.' % (
self.block1, self.block2, self.block3, self.block4, self.block5, self.block6, self.block7, self.block8))
except IpEquipmentNotFoundError, e:
flag = True
already_ip = True
if flag:
equipment = equipamento().get_by_pk(equipment_id)
ip6_equipment = Ipv6Equipament()
if not already_ip:
self.networkipv6_id = net.id
self.save()
ip6_equipment.ip = self
else:
ip6_equipment.ip = ip_aux
if self.description is not None and len(self.description) > 0:
ip_aux.description = self.description
ip_aux.save()
ip6_equipment.equipamento = equipment
# # Filter case 2 - Adding new IpEquip for a equip that already have ip in other network with the same range ##
# Get all IpEquipamento related to this equipment
ip_equips = Ipv6Equipament.objects.filter(
equipamento=equipment_id)
for ip_test in [ip_equip.ip for ip_equip in ip_equips]:
if ip_test.networkipv6.block1 == self.networkipv6.block1 and \
ip_test.networkipv6.block2 == self.networkipv6.block2 and \
ip_test.networkipv6.block3 == self.networkipv6.block3 and \
ip_test.networkipv6.block4 == self.networkipv6.block4 and \
ip_test.networkipv6.block5 == self.networkipv6.block5 and \
ip_test.networkipv6.block6 == self.networkipv6.block6 and \
ip_test.networkipv6.block7 == self.networkipv6.block7 and \
ip_test.networkipv6.block8 == self.networkipv6.block8 and \
ip_test.networkipv6.block == self.networkipv6.block and \
ip_test.networkipv6 != self.networkipv6:
# Filter testing
if ip_test.networkipv6.vlan.ambiente.filter is None or self.networkipv6.vlan.ambiente.filter is None:
raise IpRangeAlreadyAssociation(
None, u'Equipment is already associated with another ip with the same ip range.')
else:
# Test both environment's filters
tp_equip_list_one = list()
for fet in filterequiptype.objects.filter(filter=self.networkipv6.vlan.ambiente.filter.id):
tp_equip_list_one.append(fet.equiptype)
tp_equip_list_two = list()
for fet in filterequiptype.objects.filter(filter=ip_test.networkipv6.vlan.ambiente.filter.id):
tp_equip_list_two.append(fet.equiptype)
if equipment.tipo_equipamento not in tp_equip_list_one or equipment.tipo_equipamento not in tp_equip_list_two:
raise IpRangeAlreadyAssociation(
None, u'Equipment is already associated with another ip with the same ip range.')
# # Filter case 2 - end ##
ip6_equipment.save()
# Makes Environment Equipment association
try:
equipment_environment = equipamentoambiente()
equipment_environment.equipamento = equipment
equipment_environment.ambiente = net.vlan.ambiente
equipment_environment.create(user)
except EquipamentoAmbienteDuplicatedError, e:
# If already exists, OK !
pass
else:
raise IpNotAvailableError(None, u'Ipv6 %s:%s:%s:%s:%s:%s:%s:%s not available for network %s.' % (
self.block1, self.block2, self.block3, self.block4, self.block5, self.block6, self.block7, self.block8, net.id))
except IpRangeAlreadyAssociation, e:
raise IpRangeAlreadyAssociation(None, e.message)
except IpEquipmentAlreadyAssociation, e:
raise IpEquipmentAlreadyAssociation(None, e.message)
except AddressValueError:
raise InvalidValueError(None, 'ip6', u'%s:%s:%s:%s:%s:%s:%s:%s' % (
self.block1, self.block2, self.block3, self.block4, self.block5, self.block6, self.block7, self.block8))
except IpNotAvailableError, e:
raise IpNotAvailableError(None, u'Ipv6 %s:%s:%s:%s:%s:%s:%s:%s not available for network %s.' % (
self.block1, self.block2, self.block3, self.block4, self.block5, self.block6, self.block7, self.block8, net.id))
except IpError, e:
self.log.error(
u'Error adding new IPv6 or relationship ip-equipment.')
raise IpError(
e, u'Error adding new IPv6 or relationship ip-equipment.')
[docs] def create(self, authenticated_user, equipment_id, id):
"""Persist an IPv6 and associate it to an equipment.
If equipment was not related with VLAN environment, this makes the relationship
@return: Nothing
@raise NetworkIPv6NotFoundError: NetworkIPv6 does not exist.
@raise NetworkIPv6Error: Error finding NetworkIPv6.
@raise EquipamentoNotFoundError: Equipment does not exist.
@raise EquipamentoError: Error finding Equipment.
@raise IpNotAvailableError: No IP available to VLAN.
@raise IpError: Error persisting in database.
"""
configuration = get_model('config', 'Configuration')
equipamento = get_model('equipamento', 'Equipamento')
equipamentoambiente = get_model('equipamento', 'EquipamentoAmbiente')
self.networkipv6 = NetworkIPv6().get_by_pk(id)
# Cast to API
net6 = IPv6Network('%s:%s:%s:%s:%s:%s:%s:%s/%s' % (
self.networkipv6.block1, self.networkipv6.block2, self.networkipv6.block3, self.networkipv6.block4,
self.networkipv6.block5, self.networkipv6.block6, self.networkipv6.block7, self.networkipv6.block8, self.networkipv6.block))
# Find all ipv6s ralated to network
ips = Ipv6.objects.filter(networkipv6__id=self.networkipv6.id)
# Cast all to API class
ipsv6 = set([(IPv6Address('%s:%s:%s:%s:%s:%s:%s:%s' % (
ip.block1, ip.block2, ip.block3, ip.block4, ip.block5, ip.block6, ip.block7, ip.block8))) for ip in ips])
# Get configuration
conf = configuration.get()
selected_ip = None
# For each ip generated
i = 0
for ip in net6.iterhosts():
# Do not use some range of IPs (config)
i = i + 1
if i >= conf.IPv6_MIN and i < (net6.numhosts - conf.IPv6_MAX):
# If IP generated was not used
if ip not in ipsv6:
# Use it
selected_ip = ip
# Stop generation
break
if selected_ip is None:
raise IpNotAvailableError(
None, u'No IPv6 available to VLAN %s.' % self.networkipv6.vlan.num_vlan)
self.block1, self.block2, self.block3, self.block4, self.block5, self.block6, self.block7, self.block8 = str(
selected_ip.exploded).split(':')
equipment = equipamento().get_by_pk(equipment_id)
try:
self.save()
ipv6_equipment = Ipv6Equipament()
ipv6_equipment.ip = self
ipv6_equipment.equipamento = equipment
ipv6_equipment.save(authenticated_user)
try:
equipment_environment = equipamentoambiente().get_by_equipment_environment(
equipment_id, self.networkipv6.vlan.ambiente_id)
except EquipamentoAmbienteNotFoundError:
equipment_environment = equipamentoambiente()
equipment_environment.equipamento = equipment
equipment_environment.ambiente = self.networkipv6.vlan.ambiente
equipment_environment.save(authenticated_user)
except Exception, e:
self.log.error(
u'Error adding new IPv6 or relationship ip-equipment.')
raise IpError(
e, u'Error adding new IPv6 or relationship ip-equipment.')
[docs] @classmethod
def get_by_blocks_and_net(cls, block1, block2, block3, block4, block5, block6, block7, block8, id_network):
"""Get Ipv6 by blocks and network.
@return: Ipv6.
@raise IpNotFoundError: Ipv6 is not registered.
@raise IpError: Failed to search for the Ipv6.
"""
try:
return Ipv6.objects.get(
block1=block1, block2=block2, block3=block3, block4=block4, block5=block5,
block6=block6, block7=block7, block8=block8, networkipv6=id_network)
except ObjectDoesNotExist, e:
raise IpNotFoundError(e, u'Dont there is a Ipv6 %s:%s:%s:%s:%s:%s:%s:%s ' % (
block1, block2, block3, block4, block5, block6, block7, block8))
except Exception, e:
cls.log.error(u'Failure to search the Ipv6.')
raise IpError(e, u'Failure to search the Ipv6.')
[docs] @classmethod
def get_by_blocks(cls, block1, block2, block3, block4, block5, block6, block7, block8):
"""Get Ipv6's by blocks.
@return: Ipv6's.
@raise IpNotFoundError: Ipv6 is not registered.
@raise IpError: Failed to search for the Ipv6.
"""
try:
ips = Ipv6.objects.filter(block1=block1, block2=block2, block3=block3,
block4=block4, block5=block5, block6=block6, block7=block7, block8=block8)
if len(ips) == 0:
raise ObjectDoesNotExist()
return ips
except ObjectDoesNotExist, e:
raise IpNotFoundError(e, u'Dont there is a Ipv6 %s:%s:%s:%s:%s:%s:%s:%s ' % (
block1, block2, block3, block4, block5, block6, block7, block8))
except Exception, e:
cls.log.error(u'Failure to search the Ipv6.')
raise IpError(e, u'Failure to search the Ipv6.')
[docs] @classmethod
def get_by_octs_and_environment_vip(cls, block1, block2, block3, block4, block5,
block6, block7, block8, id_evip, valid=True):
"""
Get Ipv6 by blocks and environment vip.
@return: Ipv6.
@raise IpNotFoundError: Ipv6 is not registered.
@raise IpError: Failed to search for the Ipv6.
"""
environmentvip = get_model('ambiente', 'EnvironmentVip')
ambiente_model = get_model('ambiente', 'Ambiente')
try:
ips = Ipv6.objects.filter(
block1=block1, block2=block2, block3=block3,
block4=block4, block5=block5, block6=block6, block7=block7, block8=block8)
if ips.count() == 0:
raise IpNotFoundError(None)
if valid is True:
return Ipv6.objects.get(
block1=block1, block2=block2, block3=block3, block4=block4, block5=block5,
block6=block6, block7=block7, block8=block8, networkipv6__ambient_vip__id=id_evip)
else:
for ip in ips:
if ip.networkipv6.ambient_vip:
if ip.networkipv6.ambient_vip.id == id_evip:
return ip
else:
environments = ambiente_model.objects.filter(
vlan__networkipv6__ambient_vip__id=id_evip)
for env in environments:
if ip.networkipv6.vlan.ambiente.divisao_dc.id == env.divisao_dc.id \
and ip.networkipv6.vlan.ambiente.ambiente_logico.id == env.ambiente_logico.id:
return ip
raise ObjectDoesNotExist()
except ObjectDoesNotExist, e:
evip = environmentvip.get_by_pk(id_evip)
msg = u'Ipv6 não está relacionado ao Ambiente Vip: %s.' % evip.show_environment_vip()
cls.log.error(msg)
raise IpNotFoundByEquipAndVipError(e, msg)
except IpNotFoundError, e:
msg = u'Ipv6 "%s.%s.%s.%s.%s.%s.%s.%s" não existe.' % (
block1, block2, block3, block4, block5, block6, block7, block8)
cls.log.error(msg)
raise IpNotFoundError(e, msg)
except Exception, e:
cls.log.error(u'Failure to search the Ipv6.')
raise IpError(e, u'Failure to search the Ipv6.')
[docs] @classmethod
def get_by_octs_and_environment(cls, block1, block2, block3, block4, block5,
block6, block7, block8, id_environment):
"""Get Ipv6 by blocks and environment.
@return: Ipv6.
@raise IpNotFoundError: Ipv6 is not registered.
@raise IpError: Failed to search for the Ipv6.
"""
try:
return Ipv6.objects.get(
block1=block1, block2=block2, block3=block3, block4=block4, block5=block5,
block6=block6, block7=block7, block8=block8, networkipv6__vlan__ambiente__id=id_environment)
except ObjectDoesNotExist, e:
raise IpNotFoundError(e, u'Dont there is a IPv6 %s:%s:%s:%s:%s:%s:%s:%s of the environment %s.' % (
block1, block2, block3, block4, block5, block6, block7, block8, id_environment))
except Exception, e:
cls.log.error(u'Failure to search the Ipv6.')
raise IpError(e, u'Failure to search the Ipv6.')
[docs] def delete(self):
"""Sobrescreve o método do Django para remover um IP.
Antes de remover o IP remove todas as suas requisições de VIP e os relacionamentos com equipamentos.
"""
try:
# Delete all Request Vip associeted
for r in self.requisicaovips_set.all():
r_alter = False
id_vip = r.id
if r.vip_criado:
raise IpCantBeRemovedFromVip(
r.id, 'Ipv6 não pode ser removido, porque está em uso por Requisição Vip %s' % (r.id))
else:
if r.ip is not None:
r.ipv6 = None
r.validado = 0
r.save()
r_alter = True
# SYNC_VIP
syncs.old_to_new(r)
if not r_alter:
r.delete()
# SYNC_VIP
syncs.delete_new(id_vip)
# Delete all EquipmentIp and EnviromentEquip associated
for ie in self.ipv6equipament_set.all():
# Codigo removido, pois não devemos remover o ambiente do equipamento mesmo que não tenha IP
# para o ambiente solicidado pelo Henrique
# ambienteequip = EquipamentoAmbiente()
# ambienteequip = ambienteequip.get_by_equipment_environment(
# ie.equipamento.id, self.networkipv6.vlan.ambiente_id)
#
# ips = Ip.list_by_environment_and_equipment(
# ambienteequip.ambiente_id, ie.equipamento.id)
# ips6 = Ipv6.list_by_environment_and_equipment(
# ambienteequip.ambiente_id, ie.equipamento.id)
#
# if len(ips) <= 0 and len(ips6) <= 1:
#
# ambienteequip.delete()
ie.delete()
# Serializes obj
ip_slz = get_app('api_ip', module_label='serializers')
serializer = ip_slz.Ipv6V3Serializer(self)
data_to_queue = serializer.data
# Deletes Obj IP
super(Ipv6, self).delete()
# Sends to Queue
queue_manager = QueueManager(broker_vhost='tasks',
queue_name='tasks.aclapi',
exchange_name='tasks.aclapi',
routing_key='tasks.aclapi')
data_to_queue.update({'description': queue_keys.IPv6_REMOVE})
queue_manager.append({
'action': queue_keys.IPv6_REMOVE,
'kind': queue_keys.IPv6_KEY,
'data': data_to_queue
})
queue_manager.send()
except EquipamentoAmbienteNotFoundError, e:
raise EquipamentoAmbienteNotFoundError(None, e.message)
except IpCantBeRemovedFromVip, e:
raise IpCantBeRemovedFromVip(e.cause, e.message)
except IpEquipmentNotFoundError, e:
raise IpEquipmentNotFoundError(None, e.message)
##################
# Methods for V3 #
##################
[docs] def create_v3(self, ip_map, locks_used=[]):
"""Method V3 to create Ipv6."""
models = get_app('equipamento', 'models')
try:
self.networkipv6_id = NetworkIPv6()\
.get_by_pk(ip_map.get('networkipv6')).id
self.block1 = ip_map.get('block1')
self.block2 = ip_map.get('block2')
self.block3 = ip_map.get('block3')
self.block4 = ip_map.get('block4')
self.block5 = ip_map.get('block5')
self.block6 = ip_map.get('block6')
self.block7 = ip_map.get('block7')
self.block8 = ip_map.get('block8')
self.descricao = ip_map.get('description')
# Get environments related
envs = self.networkipv6.vlan\
.get_environment_related(use_vrf=True)\
.values_list('id', flat=True)
# Get objects of equipments
eqpts = models.Equipamento.objects.filter(
id__in=[eqpt.get('id')
for eqpt in ip_map.get('equipments', [])])
except Exception, e:
raise IpErrorV3(e)
else:
locks_name = list()
# Prepare locks for environment
for env in envs:
lock_name = LOCK_ENVIRONMENT_ALLOCATES % env
if lock_name not in locks_used:
locks_name.append(lock_name)
for eqpt_obj in eqpts:
# Prepare locks for ips-equipments
lock_name = LOCK_IPV6_EQUIPMENT_ONE % eqpt_obj.id
if lock_name not in locks_used:
locks_name.append(lock_name)
# Prepare locks for environments related with equipaments
for env in eqpt_obj.environments:
lock_name = LOCK_ENVIRONMENT_ALLOCATES % env.ambiente_id
if lock_name not in locks_used:
locks_name.append(lock_name)
# Create Locks
locks_name = list(set(locks_name))
locks_list = create_lock_with_blocking(locks_name)
try:
if self.block1 is None and self.block2 is None and \
self.block3 is None and self.block4 is None and \
self.block5 is None and self.block6 is None and \
self.block7 is None and self.block8 is None:
self.allocate_v3()
else:
net6 = IPv6Network(self.networkipv6.networkv6)
# Find all ips ralated to network
ips = Ipv6.objects.filter(networkipv6=self.networkipv6)
ip6_object = IPv6Address(self.ip_formated)
# Cast all to API class
ipsv6 = set([IPv6Address(ip.ip_formated) for ip in ips])
flag = False
if ip6_object not in ipsv6:
if ip6_object in net6:
first_ip_network = int(net6.network)
bcast_ip_network = int(net6.broadcast)
ipv6_network = int(ip6_object)
# First and last ip are reserved in network
if ipv6_network >= (first_ip_network) and \
ipv6_network < (bcast_ip_network):
flag = True
if flag is False:
raise IpNotAvailableError(
None,
u'Ip %s not available for network %s.' %
(self.ip_formated, self.networkipv6.id))
self.validate_v3(eqpts)
self.save()
# Creates relationship between ip and equipment
for eqpt in ip_map.get('equipments', []):
ip_equipment = Ipv6Equipament()
ip_equipment.create_v3({
'ip': self.id,
'equipment': eqpt.get('id')
})
except IpErrorV3, e:
self.log.error(e.message)
raise IpErrorV3(e.message)
except IpNotAvailableError, e:
self.log.error(e.message)
raise IpErrorV3(e.message)
except Exception, e:
msg = u'Error save new IPV6.: %s' % e
self.log.exception(msg)
raise IpErrorV3(msg)
finally:
# Destroy locks
destroy_lock(locks_list)
[docs] def update_v3(self, ip_map, locks_used=[]):
"""Method V3 to update Ipv6."""
models = get_app('equipamento', 'models')
try:
self.descricao = ip_map.get('description')
# Get environments related
envs = self.networkipv6.vlan.get_environment_related(use_vrf=True)\
.values_list('id', flat=True)
# Get objects of equipments
eqpts = models.Equipamento.objects.filter(id__in=[
eqpt.get('id') for eqpt in ip_map.get('equipments', [])]
)
except Exception, e:
raise IpErrorV3(e)
else:
locks_name = list()
# Prepare lock for ipv6
lock_name = LOCK_IPV6 % self.id
if lock_name not in locks_used:
locks_name.append(lock_name)
# Prepare locks for environment
for env in envs:
lock_name = LOCK_ENVIRONMENT_ALLOCATES % env
if lock_name not in locks_used:
locks_name.append(lock_name)
for eqpt_obj in eqpts:
# Prepare locks for ips-equipments
lock_name = LOCK_IPV6_EQUIPMENT % (self.id, eqpt_obj.id)
if lock_name not in locks_used:
locks_name.append(lock_name)
# Prepare locks for environments related with equipaments
for env in eqpt_obj.environments:
lock_name = LOCK_ENVIRONMENT_ALLOCATES % env.ambiente_id
if lock_name not in locks_used:
locks_name.append(lock_name)
# Create Locks
locks_name = list(set(locks_name))
locks_list = create_lock_with_blocking(locks_name)
try:
self.validate_v3(eqpts)
self.save()
# Get current associates
current = self.ipv6equipament_set\
.filter(equipamento__in=eqpts)\
.values_list('equipamento', flat=True)
# Creates new associate
for eqpt in eqpts:
if eqpt.id not in current:
ip_equipment = Ipv6Equipament()
ip_equipment.create_v3({
'ip': self.id,
'equipment': eqpt.id
})
# Removes old associates
for ip_eqpt in self.ipv6equipament_set\
.exclude(equipamento__in=eqpts):
ip_eqpt.delete_v3(bypass_ip=True)
except IpErrorV3, e:
self.log.error(e.message)
raise IpErrorV3(e.message)
except Exception, e:
msg = u'Error edit IP.: %s' % e
self.log.error(msg)
raise IpErrorV3(msg)
finally:
# Destroy locks
destroy_lock(locks_list)
[docs] def delete_v3(self, locks_used=[]):
"""
Method V3 to remove Ipv6.
Before removing the IP removes all your requests
VIP and relationships with equipment.
@raise IpCantBeRemovedFromVip: Ipv6 is associated with created
Vip Request.
"""
locks_name = list()
# Prepare lock for ipv6
lock_name = LOCK_IPV6 % self.id
if lock_name not in locks_used:
locks_name.append(lock_name)
# Create Locks
locks_name = list(set(locks_name))
locks_list = create_lock_with_blocking(locks_name)
try:
for vip in self.viprequest_set.all():
id_vip = vip.id
with distributedlock(LOCK_VIP % id_vip):
if vip.created:
raise IpCantBeRemovedFromVip(
id_vip,
'IPv6 can not be removed because it is '
'in use by Vip Request %s' % (id_vip))
# Deletes only VIP, Related Ipv6 with VIP is not removed
vip.delete_v3(bypass_ipv4=True, bypass_ipv6=True)
# Deletes Related Equipment
for ip_eqpt in self.ipv6equipament_set.all():
ip_eqpt.delete_v3(bypass_ip=True)
# Serializes obj
ip_slz = get_app('api_ip', module_label='serializers')
serializer = ip_slz.Ipv6V3Serializer(self)
data_to_queue = serializer.data
# Deletes Obj IP
super(Ipv6, self).delete()
# Sends to Queue
queue_manager = QueueManager(broker_vhost='tasks',
queue_name='tasks.aclapi',
exchange_name='tasks.aclapi',
routing_key='tasks.aclapi')
data_to_queue.update({'description': queue_keys.IPv6_REMOVE})
queue_manager.append({
'action': queue_keys.IPv6_REMOVE,
'kind': queue_keys.IPv6_KEY,
'data': data_to_queue
})
queue_manager.send()
except IpCantBeRemovedFromVip, e:
raise IpCantBeRemovedFromVip(e.cause, e.message)
except Exception, e:
msg = u'Error edit IP.: %s' % e
self.log.error(msg)
raise IpErrorV3(msg)
finally:
# Destroy locks
destroy_lock(locks_list)
[docs] def validate_v3(self, equipments):
"""Validate Ip."""
env_ip = self.networkipv6.vlan.ambiente
network.validate_conflict_join_envs(env_ip, equipments)
[docs] def allocate_v3(self):
"""Persist an IPv6 and associate it to an equipment.
If equipment was not related with VLAN environment, this makes the relationship
@return: Nothing
@raise NetworkIPv6NotFoundError: NetworkIPv6 does not exist.
@raise NetworkIPv6Error: Error finding NetworkIPv6.
@raise EquipamentoNotFoundError: Equipment does not exist.
@raise EquipamentoError: Error finding Equipment.
@raise IpNotAvailableError: No IP available to VLAN.
@raise IpError: Error persisting in database.
"""
configuration = get_model('config', 'Configuration')
# Cast to API
net6 = IPNetwork(self.networkipv6.networkv6)
# Find all ips ralated to network
ips = self.networkipv6.ipv6_set.all()
# Cast all to API class
ipsv6 = set([IPv6Address(ip.ip_formated) for ip in ips])
# Get configuration
conf = configuration.get()
selected_ip = None
# For each ip generated
i = 0
for ip in net6.iterhosts():
# Do not use some range of IPs (config)
# IPv6_MIN = Firsts
# IPv6_MAX = Number minimum of Ip reserveds
# First IP and 2 last I
i = i + 1
if i >= conf.IPv6_MIN and i < (net6.numhosts - conf.IPv6_MAX):
# If IP generated was not used
if ip not in ipsv6:
# Use it
selected_ip = ip
# Stop generation
break
if selected_ip is None:
raise IpNotAvailableError(None, u'No IP available to VLAN %s.' %
self.networkipv6.vlan.num_vlan)
self.block1, self.block2, self.block3, self.block4, self.block5, \
self.block6, self.block7, self.block8 = str(
selected_ip.exploded).split(':')
[docs]class Ipv6Equipament(BaseModel):
id = models.AutoField(
primary_key=True,
db_column='id_ipsv6_dos_equipamentos'
)
ip = models.ForeignKey(
'ip.Ipv6',
db_column='id_ipv6'
)
equipamento = models.ForeignKey(
'equipamento.Equipamento',
db_column='id_equip'
)
log = logging.getLogger('Ipv6Equipament')
class Meta(BaseModel.Meta):
db_table = u'ipsv6_dos_equipamentos'
managed = True
unique_together = ('ip', 'equipamento')
[docs] @classmethod
def list_by_equip(cls, equip_id):
"""Get IP6 by id_ip
@return: IPEquipment.
@raise IpEquipmentNotFoundError: IP6 is not registered.
@raise IpError: Failed to search for the IP.
"""
try:
return Ipv6Equipament.objects.filter(equipamento__id=equip_id)
except ObjectDoesNotExist, e:
raise IpEquipmentNotFoundError(
e, u'Dont there is a IP-Equipament by Equip = %s.')
except Exception, e:
cls.log.error(u'Failure to search the Ip-Equipament.')
raise IpError(e, u'Failure to search the Ip-Equipament.')
[docs] @classmethod
def get_by_ip6(cls, ip6_id):
"""Get IP6 by id_ip6
@return: IP6.
@raise IpEquipmentNotFoundError: IP6 is not registered.
@raise IpError: Failed to search for the I6P.
"""
try:
return Ipv6Equipament.objects.filter(ip__id=ip6_id).uniqueResult()
except ObjectDoesNotExist, e:
raise IpEquipmentNotFoundError(
e, u'Dont there is a IP-Equipament by IP = %s.')
except Exception, e:
cls.log.error(u'Failure to search the Ip-Equipament.')
raise IpError(e, u'Failure to search the Ip-Equipament.')
[docs] @classmethod
def list_by_ip6(cls, ip6_id):
"""Get IP6 by id_ip6
@return: IP6.
@raise IpEquipmentNotFoundError: IP6 is not registered.
@raise IpError: Failed to search for the I6P.
"""
try:
return Ipv6Equipament.objects.filter(ip__id=ip6_id)
except ObjectDoesNotExist, e:
raise IpEquipmentNotFoundError(
e, u'Dont there is a IP-Equipament by IP = %s.')
except Exception, e:
cls.log.error(u'Failure to search the Ip-Equipament.')
raise IpError(e, u'Failure to search the Ip-Equipament.')
[docs] @classmethod
def get_by_ip_equipment(cls, ip_id, equip_id):
"""Get Ipv6Equipament by ip_id and equip_id.
@return: Ipv6Equipament.
@raise IpEquipmentNotFoundError: Ipv6Equipament is not registered.
@raise IpError: Failed to search for the Ipv6Equipament.
@raise OperationalError: Lock wait timeout exceeded.
"""
try:
return Ipv6Equipament.objects.filter(ip__id=ip_id, equipamento__id=equip_id).uniqueResult()
except ObjectDoesNotExist, e:
raise IpEquipmentNotFoundError(
e, u'Dont there is a Ipv6Equipament by ip_id = %s and equip_id = %s' % (ip_id, equip_id))
except OperationalError, e:
cls.log.error(u'Lock wait timeout exceeded.')
raise OperationalError(
e, u'Lock wait timeout exceeded; try restarting transaction')
except Exception, e:
cls.log.error(u'Failure to search the Ipv6Equipament.')
raise IpError(e, u'Failure to search the Ipv6Equipament.')
[docs] def validate_ip(self):
"""Validates whether IPv6 is already associated with equipment
@raise IpEquipamentoDuplicatedError: if IPv6 is already associated with equipment
"""
try:
Ipv6Equipament.objects.get(
ip=self.ip, equipamento=self.equipamento)
raise IpEquipamentoDuplicatedError(
None, u'IP already registered for the equipment. '
'Ip: %s, Equipment: %s' %
(str(self.ip), str(self.equipamento)))
except ObjectDoesNotExist:
pass
[docs] def create(self, authenticated_user, ip_id, equipment_id):
"""Insere um relacionamento entre IP e Equipamento.
@return: Nothing.
@raise IpError: Falha ao inserir.
@raise EquipamentoNotFoundError: Equipamento não cadastrado.
@raise IpNotFoundError: Ip não cadastrado.
@raise IpEquipamentoDuplicatedError: IP já cadastrado para o equipamento.
@raise EquipamentoError: Falha ao pesquisar o equipamento.
"""
equipamento = get_model('equipamento', 'Equipamento')
equipamentoambiente = get_model('equipamento', 'EquipamentoAmbiente')
self.equipamento = equipamento().get_by_pk(equipment_id)
self.ip = Ipv6().get_by_pk(ip_id)
# Valida o ip
self.validate_ip()
try:
if self.equipamento not in [ea.equipamento for ea in self.ip.networkipv6.vlan.ambiente.equipamentoambiente_set.all()]:
ea = equipamentoambiente(
ambiente=self.ip.networkipv6.vlan.ambiente, equipamento=self.equipamento)
ea.save(authenticated_user)
self.save()
except Exception, e:
self.log.error(u'Falha ao inserir um ip_equipamento.')
raise IpError(e, u'Falha ao inserir um ip_equipamento.')
[docs] def remove(self, authenticated_user, ip_id, equip_id):
"""Research and removes the relationship between IP and equipment.
@return: Nothing
@raise IpEquipmentNotFoundError: Dont is no relationship between the IP and Equipment.
@raise IpError: Failure to remove the relationship.
"""
ip_equipamento = self.get_by_ip_equipment(ip_id, equip_id)
try:
ip_equipamento.delete()
except (IpCantBeRemovedFromVip, IpEquipCantDissociateFromVip), e:
raise e
except Exception, e:
self.log.error(u'Failure to remove the Ipv6Equipament.')
raise IpError(e, u'Failure to remove the Ipv6Equipament.')
[docs] def delete(self):
"""Override Django's method to remove Ipv6 and Equipment relationship.
If Ip from this Ip-Equipment is associated with created Vip Request, and the Equipment
is the last balancer associated, the IpEquipment association cannot be removed.
If Ip has no relationship with other Equipments, then Ip is also removed.
"""
tipoequipamento = get_model('equipamento', 'TipoEquipamento')
for r in self.ip.requisicaovips_set.all():
if self.equipamento.tipo_equipamento == tipoequipamento.get_tipo_balanceador():
# Get all equipments (except the one being removed) related to ip
# to find another balancer
other_equips = self.ip.ipv6equipament_set.exclude(
equipamento=self.equipamento.id)
another_balancer = False
for ipequip in other_equips:
if ipequip.equipamento.tipo_equipamento == tipoequipamento.get_tipo_balanceador():
another_balancer = True
break
if not another_balancer:
if r.vip_criado:
raise IpEquipCantDissociateFromVip(
{
'vip_id': r.id,
'ip': mount_ipv6_string(self.ip),
'equip_name': self.equipamento.nome
}, 'Ipv6 não pode ser disassociado do equipamento %s '
'porque é o último balanceador da Requisição Vip %s.' %
(self.equipamento.nome, r.id))
else:
# Remove ip from vip or remove vip
id_vip = r.id
if r.ip is not None:
r.ipv6 = None
r.validado = 0
r.save()
# SYNC_VIP
syncs.old_to_new(r)
else:
r.delete()
# SYNC_VIP
syncs.delete_new(id_vip)
if self.ip.serverpoolmember_set.count() > 0:
server_pool_identifiers = set()
for svm in self.ip.serverpoolmember_set.all():
item = '{}:{}'.format(svm.server_pool.id,
svm.server_pool.identifier)
server_pool_identifiers.add(item)
server_pool_identifiers = list(server_pool_identifiers)
server_pool_identifiers = ', '.join(
str(server_pool) for server_pool in server_pool_identifiers)
raise IpCantRemoveFromServerPool(
{
'ip': mount_ipv6_string(self.ip),
'equip_name': self.equipamento.nome,
'server_pool_identifiers': server_pool_identifiers
},
'Ipv6 não pode ser disassociado do equipamento %s '
'porque ele está sendo utilizando nos Server Pools '
'(id:identifier) %s' % (
self.equipamento.nome, server_pool_identifiers)
)
super(Ipv6Equipament, self).delete()
# If ip has no other equipment, than he will be removed to
if self.ip.ipv6equipament_set.count() == 0:
self.ip.delete()
##################
# Methods for V3 #
##################
[docs] def create_v3(self, ip_equipment):
"""Inserts a relationship between IP e Equipment.
@return: Nothing.
@raise IpError: Failure to insert.
@raise EquipamentoNotFoundError: Equipment do not registered.
@raise IpNotFoundError: Ip do not registered.
@raise IpEquipamentoDuplicatedError: IP already registered for the equipment.
@raise EquipamentoError: Failure to search equipment.
"""
equipamento = get_model('equipamento', 'Equipamento')
equipamentoambiente = get_model('equipamento', 'EquipamentoAmbiente')
self.equipamento = equipamento().get_by_pk(ip_equipment.get('equipment'))
self.ip = Ipv6().get_by_pk(ip_equipment.get('ip'))
# Validate the ip
self.validate_ip()
try:
# All equipments related with environment of IP
eqpts = self.ip.networkipv6.vlan.ambiente\
.equipamentoambiente_set.all()\
.values_list('equipamento', flat=True)
if ip_equipment.get('equipment') not in eqpts:
ea = equipamentoambiente(
ambiente=self.ip.networkipv6.vlan.ambiente,
equipamento=self.equipamento
)
ea.save()
self.save()
except Exception, e:
self.log.error(u'Failure to insert an ip_equipamento.')
raise IpError(e, u'Failure to insert an ip_equipamento.')
[docs] def delete_v3(self, bypass_ip=False):
"""
Method V3 to remove Ipv6 and Equipment relationship.
If Ipv6 from this Ipv6-Equipment is associated with created Vip
Request and the Equipment is the last balancer associated,
the IpEquipment association cannot be removed.
If Ipv6 has no relationship with other Equipments, then Ipv6 is
also removed.
@raise IpCantRemoveFromServerPool: Ip is associated with associated
Pool Member.
@raise IpEquipCantDissociateFromVip: Equipment is the last balanced
in a created Vip Request
pointing to ip.
"""
tipoequipamento = get_model('equipamento', 'TipoEquipamento')
type_eqpt = tipoequipamento.get_tipo_balanceador()
if self.equipamento.tipo_equipamento == type_eqpt:
for vip in self.ip.viprequest_set.all():
# Filter equipments to find another balancer
another_balancer = self.ip.ipv6equipament_set.exclude(
equipamento=self.equipamento.id
).filter(equipamento__tipo_equipamento=type_eqpt)
id_vip = vip.id
if not another_balancer:
with distributedlock(LOCK_VIP % id_vip):
if vip.created:
raise IpEquipCantDissociateFromVip(
{
'vip_id': id_vip,
'ip': self.ip.ip_formated,
'equip_name': self.equipamento.nome
},
'Ipv6 can not be dissociated from the '
'equipment %s because it is the last '
'balancer of Vip Request %s.'
% (self.equipamento.nome, id_vip)
)
else:
# Remove ipv6 from vip
if vip.ipv4 is not None:
vip.ipv6 = None
id_vip.save()
# SYNC_VIP
syncs.new_to_old(vip)
# Remove vip
else:
vip.delete_v3(bypass_ipv4=True,
bypass_ipv6=True)
if self.ip.serverpoolmember_set.count() > 0:
items = ['{}:{}'.format(
svm.server_pool.id,
svm.server_pool.identifier
) for svm in self.ip.serverpoolmember_set.all()]
items = ', '.join(items)
raise IpCantRemoveFromServerPool(
{
'ip': self.ip.ip_formated,
'equip_name': self.equipamento.nome,
'server_pool_identifiers': items
},
'IPv6 can not be dissociated from the equipment% s because it'
'is being using in the Server Pools (id: identifier)%s' %
(self.equipamento.nome, items)
)
super(Ipv6Equipament, self).delete()
# If ip has no other equipment, than he will be removed to
if self.ip.ipv6equipament_set.count() == 0 and not bypass_ip:
self.ip.delete_v3()
[docs]def network_in_range(vlan, network, version):
# Get all vlans environments from equipments of the current
# environment
tipoequipamento = get_model('equipamento', 'TipoEquipamento')
equips = list()
envs = list()
envs_aux = list()
ids_all = list()
ambiente = vlan.ambiente
filter = ambiente.filter
equipment_types = tipoequipamento.objects.filter(
filterequiptype__filter=filter)
# Get all equipments from the environment being tested
# that are not supposed to be filtered
# (not the same type of the equipment type of a filter of the environment)
for env in ambiente.equipamentoambiente_set.all().exclude(
equipamento__tipo_equipamento__in=equipment_types
).select_related('equipamento'):
equips.append(env.equipamento)
# Get all environment that the equipments above are included
for equip in equips:
for env in equip.equipamentoambiente_set.all().select_related('ambiente'):
if env.ambiente_id not in envs_aux:
envs.append(env.ambiente)
envs_aux.append(env.ambiente_id)
# Check in all vlans from all environments above
# if there is a network that is sub or super network of the current
# network being tested
for env in envs:
for vlan in env.vlan_set.all().prefetch_related(
'networkipv4_set'
).prefetch_related('networkipv6_set'):
ids_all.append(vlan.id)
is_subnet = verify_subnet(vlan, network, version)
if is_subnet:
return False
return True
[docs]def verify_subnet(vlan, network, version):
from networkapi.infrastructure.ipaddr import IPNetwork
if version == IP_VERSION.IPv4[0]:
vlan_net = vlan.networkipv4_set.all()
else:
vlan_net = vlan.networkipv6_set.all()
# One vlan may have many networks, iterate over it
for net in vlan_net:
if version == IP_VERSION.IPv4[0]:
ip = '%s.%s.%s.%s/%s' % (net.oct1,
net.oct2, net.oct3, net.oct4, net.block)
else:
ip = '%s:%s:%s:%s:%s:%s:%s:%s/%d' % (
net.block1, net.block2, net.block3, net.block4,
net.block5, net.block6, net.block7, net.block8, net.block)
ip_net = IPNetwork(ip)
# If some network, inside this vlan, is subnet of network search param
if ip_net in network or network in ip_net:
# This vlan must be in vlans founded, don't need to continue
# checking
return True
# If don't found any subnet return False
return False