def handle_post(self, request, user, *args, **kwargs):
        '''Handles GET requests get an IP4 available for vip_request by evip_id.

        URL: ip/availableip6/vip/id_evip/
        '''

        self.log.info('Get an IP4 available for vip_request')

        try:
            # User permission
            if not has_perm(user, AdminPermission.IPS, AdminPermission.WRITE_OPERATION):
                self.log.error(
                    u'User does not have permission to perform the operation.')
                return self.not_authorized()

            # Load XML data
            xml_map, attrs_map = loads(request.raw_post_data)

            # XML data format
            networkapi_map = xml_map.get('networkapi')

            ip_map = networkapi_map.get('ip_map')

            # Get XML data
            id_evip = ip_map.get('id_evip')
            name = ip_map.get('name')

            if not is_valid_int_greater_zero_param(id_evip):
                self.log.error(
                    u'Parameter id_evip is invalid. Value: %s.', id_evip)
                raise InvalidValueError(None, 'id_evip', id_evip)

            # Business Rules
            evip = EnvironmentVip.get_by_pk(id_evip)

            ipv4 = Ip()

            len_network = len(evip.networkipv4_set.all())
            raise_not_found_balanceamento = False

            if (len_network <= 0):
                raise NetworkNotInEvip(
                    None, 'Não há rede no ambiente vip fornecido')

            cont_network = 0
            cont_balanceador_not_found = 0

            for net in evip.networkipv4_set.all():

                balanceador_found_flag = False
                cont_network = cont_network + 1
                list_ips_equips = list()

                try:
                    ip_available = ipv4.get_available_ip(net.id)

                    ip_new = Ip()
                    ip_available = ip_available.exploded
                    ip_available = ip_available.split(".")
                    ip_new.oct1 = ip_available[0]
                    ip_new.oct2 = ip_available[1]
                    ip_new.oct3 = ip_available[2]
                    ip_new.oct4 = ip_available[3]
                    ip_new.descricao = name

                    for env_equipment in net.vlan.ambiente.equipamentoambiente_set.all():
                        equipment = env_equipment.equipamento
                        if equipment.tipo_equipamento == TipoEquipamento.get_tipo_balanceador():

                            if equipment.id not in list_ips_equips:

                                list_ips_equips.append(equipment.id)

                                if ip_new.id is None:
                                    ip_new.save_ipv4(equipment.id, user, net)
                                else:
                                    new_ip_equip = IpEquipamento()
                                    new_ip_equip.ip = ip_new
                                    new_ip_equip.equipamento = equipment
                                    new_ip_equip.save(user)

                                balanceador_found_flag = True

                    if not balanceador_found_flag:
                        cont_balanceador_not_found = cont_balanceador_not_found + \
                            1
                    else:
                        break

                    if cont_balanceador_not_found == len_network:
                        raise_not_found_balanceamento = True
                        raise IpNotAvailableError(None, "Não há ipv4 disponivel para as redes associdas com o Ambiente Vip: %s - %s - %s, pois não existe equipamentos do Tipo Balanceador nessas redes." % (
                            evip.finalidade_txt, evip.cliente_txt, evip.ambiente_p44_txt))

                except (IpNotAvailableError, IpRangeAlreadyAssociation), e:
                    cont_balanceador_not_found = cont_balanceador_not_found + 1
                    if raise_not_found_balanceamento:
                        raise IpNotAvailableError(None, e.message)
                    elif len_network == cont_network:
                        raise IpNotAvailableError(None, "Não há ipv4 disponivel para as redes associdas com o Ambiente Vip: %s - %s - %s" % (
                            evip.finalidade_txt, evip.cliente_txt, evip.ambiente_p44_txt))

            return self.response(dumps_networkapi({"ip": model_to_dict(ip_new)}))
    def handle_post(self, request, user, *args, **kwargs):
        '''Handles POST requests to associate and IP to an equipment.

        URL: ipv4/assoc/
        '''

        self.log.info('Associate Ip to an Equipment')

        try:
            # Load XML data
            xml_map, attrs_map = loads(request.raw_post_data)

            # XML data format
            networkapi_map = xml_map.get('networkapi')
            if networkapi_map is None:
                msg = u'There is no value to the networkapi tag of XML request.'
                self.log.error(msg)
                return self.response_error(3, msg)

            ip_map = networkapi_map.get('ip_map')
            if ip_map is None:
                msg = u'There is no value to the ip tag of XML request.'
                self.log.error(msg)
                return self.response_error(3, msg)

            # Get XML data
            ip_id = ip_map.get('id_ip')
            equip_id = ip_map.get('id_equip')
            network_ipv4_id = ip_map.get('id_net')

            # Valid ip_id
            if not is_valid_int_greater_zero_param(ip_id):
                self.log.error(
                    u'Parameter ip_id is invalid. Value: %s.', ip_id)
                raise InvalidValueError(None, 'ip_id', ip_id)

            # Valid equip_id
            if not is_valid_int_greater_zero_param(equip_id):
                self.log.error(
                    u'Parameter equip_id is invalid. Value: %s.', equip_id)
                raise InvalidValueError(None, 'equip_id', equip_id)

            # Valid network_ipv4_id
            if not is_valid_int_greater_zero_param(network_ipv4_id):
                self.log.error(
                    u'Parameter network_ipv4_id is invalid. Value: %s.', network_ipv4_id)
                raise InvalidValueError(
                    None, 'network_ipv4_id', network_ipv4_id)

            # User permission
            if not has_perm(user,
                            AdminPermission.IPS,
                            AdminPermission.WRITE_OPERATION,
                            None,
                            equip_id,
                            AdminPermission.EQUIP_WRITE_OPERATION):
                raise UserNotAuthorizedError(
                    None, u'User does not have permission to perform the operation.')

            # Business Rules

            # Get net
            net = NetworkIPv4.get_by_pk(network_ipv4_id)

            with distributedlock(LOCK_NETWORK_IPV4 % network_ipv4_id):

                # Get ip
                ip = Ip.get_by_pk(ip_id)
                # Get equipment
                equip = Equipamento.get_by_pk(equip_id)

                listaVlansDoEquip = []

                for ipequip in equip.ipequipamento_set.all():
                    vlan = ipequip.ip.networkipv4.vlan
                    if vlan not in listaVlansDoEquip:
                        listaVlansDoEquip.append(vlan)

                for ipequip in equip.ipv6equipament_set.all():
                    vlan = ipequip.ip.networkipv6.vlan
                    if vlan not in listaVlansDoEquip:
                        listaVlansDoEquip.append(vlan)

                vlan_atual = net.vlan
                vlan_aux = None
                ambiente_aux = None

                for vlan in listaVlansDoEquip:
                    if vlan.num_vlan == vlan_atual.num_vlan:
                        if vlan.id != vlan_atual.id:

                            # Filter case 3 - Vlans with same number cannot
                            # share equipments ##

                            flag_vlan_error = False
                            # Filter testing
                            if vlan.ambiente.filter is None or vlan_atual.ambiente.filter is None:
                                flag_vlan_error = True
                            else:
                                # Test both environment's filters
                                tp_equip_list_one = list()
                                for fet in FilterEquipType.objects.filter(filter=vlan_atual.ambiente.filter.id):
                                    tp_equip_list_one.append(fet.equiptype)

                                tp_equip_list_two = list()
                                for fet in FilterEquipType.objects.filter(filter=vlan.ambiente.filter.id):
                                    tp_equip_list_two.append(fet.equiptype)

                                #Equipment type should be in both filters
                                if equip.tipo_equipamento not in tp_equip_list_one or equip.tipo_equipamento not in tp_equip_list_two:
                                    flag_vlan_error = True

                                    #Out of band network is never trunked, it is only in mgmt interface
                                    # allow it - not a good thing to to, but is very specific
                                    if vlan.ambiente.divisao_dc.nome == 'OOB-CM' or vlan_atual.ambiente.divisao_dc.nome == 'OOB-CM':
                                        flag_vlan_error = False
                                        

                            ## Filter case 3 - end ##

                            if flag_vlan_error:
                                ambiente_aux = vlan.ambiente
                                vlan_aux = vlan
                                nome_ambiente = "%s - %s - %s" % (
                                    vlan.ambiente.divisao_dc.nome, vlan.ambiente.ambiente_logico.nome, vlan.ambiente.grupo_l3.nome)
                                raise VlanNumberNotAvailableError(None,
                                                                  '''O ip informado não pode ser cadastrado, pois o equipamento %s, faz parte do ambiente %s (id %s), 
                                                                    que possui a Vlan de id %s, que também possui o número %s, e não é permitido que vlans que compartilhem o mesmo ambiente 
                                                                    por meio de equipamentos, possuam o mesmo número, edite o número de uma das Vlans ou adicione um filtro no ambiente para efetuar o cadastro desse IP no Equipamento Informado.
                                                                    ''' % (equip.nome, nome_ambiente, ambiente_aux.id, vlan_aux.id, vlan_atual.num_vlan))

                # Persist
                try:

                    try:
                        ipEquip = IpEquipamento()
                        ipEquip.get_by_ip_equipment(ip.id, equip_id)

                        # Ip %s.%s.%s.%s already has association with
                        # Equipament %s.' % (self.oct1, self.oct2, self.oct3,
                        # self.oct4,equipment_id)
                        raise IpEquipmentAlreadyAssociation(None, u'Ip %s.%s.%s.%s already has association with Equipament %s.' % (
                            ip.oct1, ip.oct2, ip.oct3, ip.oct4, equip_id))
                    except IpEquipmentNotFoundError, e:
                        pass

                    equipment = Equipamento().get_by_pk(equip_id)
                    ip_equipment = IpEquipamento()
                    ip_equipment.ip = ip

                    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=equip_id)

                    for ip_test in [ip_equip.ip for ip_equip in ip_equips]:
                        if ip_test.networkipv4.oct1 == ip.networkipv4.oct1 and \
                                ip_test.networkipv4.oct2 == ip.networkipv4.oct2 and \
                                ip_test.networkipv4.oct3 == ip.networkipv4.oct3 and \
                                ip_test.networkipv4.oct4 == ip.networkipv4.oct4 and \
                                ip_test.networkipv4.block == ip.networkipv4.block and \
                                ip_test.networkipv4 != ip.networkipv4:

                            # Filter testing
                            if ip_test.networkipv4.vlan.ambiente.filter is None or ip.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=ip.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)

                        # Delete vlan's cache
                        destroy_cache_function([net.vlan_id])
                    except EquipamentoAmbienteDuplicatedError, e:
                        # If already exists, OK !
                        pass

                except IpRangeAlreadyAssociation, e:
                    raise IpRangeAlreadyAssociation(None, e.message)
    def handle_post(self, request, user, *args, **kwargs):
        '''Handles GET requests get an IP4 available for vip_request by evip_id.

        URL: ip/availableip6/vip/id_evip/
        '''

        self.log.info('Get an IP4 available for vip_request')

        try:
            # User permission
            if not has_perm(user, AdminPermission.IPS, AdminPermission.WRITE_OPERATION):
                self.log.error(u'User does not have permission to perform the operation.')
                return self.not_authorized()

            # Load XML data
            xml_map, attrs_map = loads(request.raw_post_data)

            # XML data format
            networkapi_map = xml_map.get('networkapi')
            ip_map = networkapi_map.get('ip_map')

            # Get XML data
            id_evip = ip_map.get('id_evip')
            name = ip_map.get('name')

            if not is_valid_int_greater_zero_param(id_evip):
                self.log.error(u'Parameter id_evip is invalid. Value: %s.', id_evip)
                raise InvalidValueError(None, 'id_evip', id_evip)

            # Business Rules
            evip = EnvironmentVip.get_by_pk(id_evip)

            with distributedlock(LOCK_GET_IPV4_AVAILABLE % id_evip):
                ipv4 = Ip()

                len_network = len(evip.networkipv4_set.all())
                raise_not_found_balanceamento = False

                if (len_network <= 0):
                    raise NetworkNotInEvip(None, 'Não há rede no ambiente vip fornecido')

                cont_network = 0
                cont_balanceador_not_found = 0

                for net in evip.networkipv4_set.all():

                    balanceador_found_flag = False
                    cont_network = cont_network + 1
                    list_ips_equips = list()

                    try:
                        ip_available = ipv4.get_available_ip(net.id)
                        ip_new = Ip()
                        ip_available = ip_available.exploded
                        ip_available = ip_available.split(".")
                        ip_new.oct1 = ip_available[0]
                        ip_new.oct2 = ip_available[1]
                        ip_new.oct3 = ip_available[2]
                        ip_new.oct4 = ip_available[3]
                        ip_new.descricao = name

                        for env_equipment in net.vlan.ambiente.equipamentoambiente_set.all():
                            equipment = env_equipment.equipamento
                            if equipment.tipo_equipamento == TipoEquipamento.get_tipo_balanceador():

                                if equipment.id not in list_ips_equips:

                                    list_ips_equips.append(equipment.id)

                                    if ip_new.id is None:
                                        ip_new.save_ipv4(equipment.id, user, net)
                                    else:
                                        new_ip_equip = IpEquipamento()
                                        new_ip_equip.ip = ip_new
                                        new_ip_equip.equipamento = equipment
                                        new_ip_equip.save()

                                    balanceador_found_flag = True

                        if not balanceador_found_flag:
                            cont_balanceador_not_found = cont_balanceador_not_found + 1
                        else:
                            break

                        if cont_balanceador_not_found == len_network:
                            raise_not_found_balanceamento = True
                            raise IpNotAvailableError(None, "Não há ipv4 disponivel para as redes associdas com o Ambiente "
                                                            "Vip: %s - %s - %s, pois não existe equipamentos do Tipo "
                                                            "Balanceador nessas redes."
                                                      % (evip.finalidade_txt, evip.cliente_txt, evip.ambiente_p44_txt))

                    except (IpNotAvailableError, IpRangeAlreadyAssociation), e:
                        cont_balanceador_not_found = cont_balanceador_not_found + 1
                        if raise_not_found_balanceamento:
                            raise IpNotAvailableError(None, e.message)
                        elif len_network == cont_network:
                            raise IpNotAvailableError(None, "Não há ipv4 disponivel para as redes associdas com o Ambiente "
                                                            "Vip: %s - %s - %s"
                                                      % (evip.finalidade_txt, evip.cliente_txt, evip.ambiente_p44_txt))

                transaction.commit()

                return self.response(dumps_networkapi({"ip": model_to_dict(ip_new)}))

        except NetworkNotInEvip, e:
            return self.response_error(321, 'ipv4')