Source code for networkapi.api_network.facade.v3.networkv6

# -*- coding: utf-8 -*-
import logging

from django.core.exceptions import FieldError
from django.core.exceptions import ObjectDoesNotExist

from networkapi.api_deploy.facade import deploy_config_in_equipment
from networkapi.api_equipment import exceptions as exceptions_eqpt
from networkapi.api_equipment import facade as facade_eqpt
from networkapi.api_network import exceptions
from networkapi.api_network.facade.v3 import utils
from networkapi.api_rest.exceptions import NetworkAPIException
from networkapi.api_rest.exceptions import ObjectDoesNotExistException
from networkapi.api_rest.exceptions import ValidationAPIException
from networkapi.distributedlock import \
    LOCK_EQUIPMENT_DEPLOY_CONFIG_NETWORK_SCRIPT
from networkapi.distributedlock import LOCK_NETWORK_IPV6
from networkapi.distributedlock import LOCK_VLAN
from networkapi.infrastructure.datatable import build_query_to_datatable_v3
from networkapi.ip import models as ip_models
from networkapi.util.geral import create_lock_with_blocking
from networkapi.util.geral import destroy_lock

log = logging.getLogger(__name__)

TEMPLATE_NETWORKv6_ACTIVATE = 'ipv6_activate_network_configuration'
TEMPLATE_NETWORKv6_DEACTIVATE = 'ipv6_deactivate_network_configuration'


[docs]def get_networkipv6_by_id(network_id): """Get NetworkIPv6.""" try: network = ip_models.NetworkIPv6.get_by_pk(network_id) except ObjectDoesNotExistException, e: raise ObjectDoesNotExistException(e.detail) except Exception, e: raise NetworkAPIException(str(e)) return network
[docs]def get_networkipv6_by_ids(network_ids): """Get Many NetworkIPv6.""" net_ids = list() for network_id in network_ids: try: net = get_networkipv6_by_id(network_id) except ObjectDoesNotExistException, e: raise ObjectDoesNotExistException(e.detail) except Exception, e: raise NetworkAPIException(str(e)) else: net_ids.append(net.id) networks = ip_models.NetworkIPv6.objects.filter(id__in=net_ids) return networks
[docs]def create_networkipv6(networkv6, user, force=False): """Creates a NetworkIPv6.""" try: netv6_obj = ip_models.NetworkIPv6() netv6_obj.create_v3(networkv6, force=force) except ip_models.NetworkIPv6ErrorV3, e: raise ValidationAPIException(e.message) except exceptions.InvalidInputException, e: raise ValidationAPIException(e.detail) except ValidationAPIException, e: raise ValidationAPIException(e.detail) except Exception, e: raise NetworkAPIException(str(e)) else: return netv6_obj
[docs]def update_networkipv6(networkv6, user, force=False): """Updates a NetworkIPv6.""" try: netv6_obj = get_networkipv6_by_id(networkv6.get('id')) netv6_obj.update_v3(networkv6, force=force) except ObjectDoesNotExistException, e: raise ObjectDoesNotExistException(e.detail) except ip_models.NetworkIPv6ErrorV3, e: raise ValidationAPIException(e.message) except exceptions.InvalidInputException, e: raise ValidationAPIException(e.detail) except ValidationAPIException, e: raise ValidationAPIException(e.detail) except Exception, e: raise NetworkAPIException(str(e)) else: return netv6_obj
[docs]def delete_networkipv6(network_ids, user, force=False): """Deletes a list of NetworkIPv6.""" for network_id in network_ids: try: netv6_obj = get_networkipv6_by_id(network_id) netv6_obj.delete_v3(force=force) except ObjectDoesNotExistException, e: raise ObjectDoesNotExistException(e.detail) except ip_models.NetworkIPv6ErrorV3, e: raise ValidationAPIException(e.message) except ValidationAPIException, e: raise ValidationAPIException(e.detail) except Exception, e: raise NetworkAPIException(str(e))
[docs]def undeploy_networkipv6(network_id, user): """Loads template for removing Network IPv6 equipment configuration, creates file and apply config. Args: NetworkIPv6 object Equipamento objects list Returns: List with status of equipments output """ try: netv6_obj = get_networkipv6_by_id(network_id) routers = netv6_obj.vlan.ambiente.routers if not routers: raise exceptions.NoEnvironmentRoutersFoundException() if facade_eqpt.all_equipments_are_in_maintenance(routers): raise exceptions_eqpt.AllEquipmentsAreInMaintenanceException() if user: if not facade_eqpt.all_equipments_can_update_config(routers, user): raise exceptions_eqpt.UserDoesNotHavePermInAllEqptException( 'User does not have permission to update conf in eqpt. ' 'Verify the permissions of user group with equipment group' '. Network:{}'.format(netv6_obj.id)) except ObjectDoesNotExistException, e: raise ObjectDoesNotExistException(e.detail) except exceptions.NoEnvironmentRoutersFoundException, e: raise ValidationAPIException(e.detail) except exceptions_eqpt.AllEquipmentsAreInMaintenanceException, e: raise ValidationAPIException(e.detail) except exceptions_eqpt.UserDoesNotHavePermInAllEqptException, e: raise ValidationAPIException(e.detail) except exceptions.NetworkAlreadyActive, e: raise ValidationAPIException(e.detail) except Exception, e: raise NetworkAPIException(str(e)) else: # lock network id to prevent multiple requests to same id locks_name = list() locks_name.append(LOCK_NETWORK_IPV6 % netv6_obj.id) locks_name.append(LOCK_VLAN % netv6_obj.vlan.id) for equipment in routers: lock_name = LOCK_EQUIPMENT_DEPLOY_CONFIG_NETWORK_SCRIPT % \ (equipment.id) locks_name.append(lock_name) locks_list = create_lock_with_blocking(locks_name) try: if netv6_obj.active == 0: return 'Network already not active. Nothing to do.' # load dict with all equipment attributes dict_ips = get_dict_v6_to_use_in_configuration_deploy( user, netv6_obj, routers) status_deploy = dict() # TODO implement threads for equipment in routers: # generate config file file_to_deploy = utils.generate_config_file( dict_ips, equipment, TEMPLATE_NETWORKv6_DEACTIVATE) # deploy config file in equipments status_deploy[equipment.id] = \ deploy_config_in_equipment(file_to_deploy, equipment) netv6_obj.deactivate_v3() if netv6_obj.vlan.ativada == 1: # if there are no other networks active in vlan, remove int # vlan if not utils.has_active_network_in_vlan(netv6_obj.vlan): # remove int vlan for equipment in routers: if equipment.maintenance is not True: status_deploy[ equipment.id] += utils.remove_svi( equipment, netv6_obj.vlan.num_vlan) netv6_obj.vlan.deactivate_v3(locks_name) return status_deploy except ip_models.NetworkIPv6ErrorV3, e: raise ValidationAPIException(e.message) except ObjectDoesNotExistException, e: raise ObjectDoesNotExistException(e.detail) except exceptions_eqpt.AllEquipmentsAreInMaintenanceException, e: raise ValidationAPIException(e.detail) except exceptions.IncorrectRedundantGatewayRegistryException, e: raise ValidationAPIException(e.detail) except exceptions.NetworkAlreadyActive, e: raise ValidationAPIException(e.detail) except ValidationAPIException, e: raise ValidationAPIException(e.detail) except Exception, e: raise NetworkAPIException(str(e)) finally: destroy_lock(locks_list)
[docs]def deploy_networkipv6(network_id, user): """Loads template for creating Network IPv6 equipment configuration, creates file and apply config. Args: NetworkIPv6 object Equipamento objects list Returns: List with status of equipments output """ try: netv6_obj = get_networkipv6_by_id(network_id) routers = netv6_obj.vlan.ambiente.routers if not routers: raise exceptions.NoEnvironmentRoutersFoundException() if facade_eqpt.all_equipments_are_in_maintenance(routers): raise exceptions_eqpt.AllEquipmentsAreInMaintenanceException() if user: if not facade_eqpt.all_equipments_can_update_config(routers, user): raise exceptions_eqpt.UserDoesNotHavePermInAllEqptException( 'User does not have permission to update conf in eqpt. ' 'Verify the permissions of user group with equipment group' '. Network:{}'.format(netv6_obj.id)) except ObjectDoesNotExistException, e: raise ObjectDoesNotExistException(e.detail) except exceptions.NoEnvironmentRoutersFoundException, e: raise ValidationAPIException(e.detail) except exceptions_eqpt.AllEquipmentsAreInMaintenanceException, e: raise ValidationAPIException(e.detail) except exceptions_eqpt.UserDoesNotHavePermInAllEqptException, e: raise ValidationAPIException(e.detail) except exceptions.NetworkAlreadyActive, e: raise ValidationAPIException(e.detail) except Exception, e: raise NetworkAPIException(str(e)) else: # lock network id to prevent multiple requests to same id locks_name = list() locks_name.append(LOCK_NETWORK_IPV6 % netv6_obj.id) locks_name.append(LOCK_VLAN % netv6_obj.vlan.id) for equipment in routers: lock_name = LOCK_EQUIPMENT_DEPLOY_CONFIG_NETWORK_SCRIPT % \ (equipment.id) locks_name.append(lock_name) locks_list = create_lock_with_blocking(locks_name) try: if netv6_obj.active == 1: raise exceptions.NetworkAlreadyActive() # load dict with all equipment attributes dict_ips = get_dict_v6_to_use_in_configuration_deploy( user, netv6_obj, routers) status_deploy = dict() # TODO implement threads for equipment in routers: # generate config file file_to_deploy = utils.generate_config_file( dict_ips, equipment, TEMPLATE_NETWORKv6_ACTIVATE) status_deploy[equipment.id] = \ deploy_config_in_equipment(file_to_deploy, equipment) netv6_obj.activate_v3() # transaction.commit() if netv6_obj.vlan.ativada == 0: netv6_obj.vlan.activate_v3(locks_name) return status_deploy except ip_models.NetworkIPv6ErrorV3, e: raise ValidationAPIException(e.message) except ObjectDoesNotExistException, e: raise ObjectDoesNotExistException(e.detail) except exceptions_eqpt.AllEquipmentsAreInMaintenanceException, e: raise ValidationAPIException(e.detail) except exceptions.IncorrectRedundantGatewayRegistryException, e: raise ValidationAPIException(e.detail) except exceptions.NetworkAlreadyActive, e: raise ValidationAPIException(e.detail) except ValidationAPIException, e: raise ValidationAPIException(e.detail) except Exception, e: raise NetworkAPIException(str(e)) finally: destroy_lock(locks_list)
[docs]def get_dict_v6_to_use_in_configuration_deploy(user, networkipv6, equipment_list): """Generate dictionary with vlan an IP information to be used to generate template dict for equipment configuration Args: networkipv4 NetworkIPv4 object equipment_list: Equipamento objects list Returns: 2-dimension dictionary with equipments information for template rendering """ try: gateway_ip = ip_models.Ipv6.get_by_blocks_and_net( '{0:0{1}x}'.format(int(networkipv6.block1, 16), 4), '{0:0{1}x}'.format(int(networkipv6.block2, 16), 4), '{0:0{1}x}'.format(int(networkipv6.block3, 16), 4), '{0:0{1}x}'.format(int(networkipv6.block4, 16), 4), '{0:0{1}x}'.format(int(networkipv6.block5, 16), 4), '{0:0{1}x}'.format(int(networkipv6.block6, 16), 4), '{0:0{1}x}'.format(int(networkipv6.block7, 16), 4), '{0:0{1}x}'.format(int(networkipv6.block8, 16) + 1, 4), networkipv6) except ip_models.IpNotFoundError: log.error('Equipment IPs not correctly registered.' 'Router equipments should have first IP of ' 'network allocated for them.') raise exceptions.IncorrectRedundantGatewayRegistryException() # Default Vrf of environment default_vrf = networkipv6.vlan.ambiente.default_vrf for equipment in equipment_list: # Verify if equipments have Ip of gateway try: gateway_ip.ipv6equipament_set.get(equipamento=equipment) except ObjectDoesNotExist: log.error('Equipment IPs not correctly registered.' 'Router equipments should have first IP ' 'of network allocated for them. Equipment: %s' % equipment) raise exceptions.IncorrectRedundantGatewayRegistryException() # Get internal name of vrf to set in equipment # Can be empty, a default value of environment or a # value by vlan + equipment try: vrf_eqpt = equipment.vrfvlanequipment_set.filter( vlan=networkipv6.vlan ).uniqueResult() # Customized vrf vrf = vrf_eqpt.vrf except ObjectDoesNotExist: # Default vrf vrf = default_vrf finally: try: # Customized internal name of vrf for this equipment vrf_eqpt = equipment.vrfequipment_set.filter( vrf=vrf ).uniqueResult() vrf_name = vrf_eqpt.internal_name except ObjectDoesNotExist: vrf_name = vrf.internal_name dict_ips = dict() if vrf_name: dict_ips['vrf'] = vrf_name # DHCPRelay list dhcprelay_list = networkipv6.dhcprelay if dhcprelay_list: dict_ips['dhcprelay_list'] = list() for dhcprelay in dhcprelay_list: ipv6 = dhcprelay.ipv6.ip_formated dict_ips['dhcprelay_list'].append(ipv6) dict_ips['gateway'] = gateway_ip.ip_formated dict_ips['ip_version'] = 'IPV6' dict_ips['equipments'] = dict() dict_ips['vlan_num'] = networkipv6.vlan.num_vlan dict_ips['vlan_name'] = networkipv6.vlan.nome dict_ips['cidr_block'] = networkipv6.block dict_ips['mask'] = networkipv6.mask_formated dict_ips['wildmask'] = 'Not used' has_active = utils.has_active_network_in_vlan(networkipv6.vlan) dict_ips['first_network'] = has_active is False # Check IPs for routers when there are multiple gateways if len(equipment_list) > 1: dict_ips['gateway_redundancy'] = True equip_number = 0 for equipment in equipment_list: # Verify if equipment have more ips ip_equip = equipment.ipv6equipament_set.filter( ip__networkipv6=networkipv6 ).exclude(ip=gateway_ip).select_related('ip') if not ip_equip: log.error('Equipment IPs not correctly registered. ' 'In case of multiple gateways, they should ' 'have an IP other than the gateway registered.' 'Equipment: %s' % equipment.id) raise exceptions.IncorrectNetworkRouterRegistryException() ip = ip_equip[0].ip dict_ips[equipment] = dict() dict_ips[equipment]['ip'] = ip.ip_formated dict_ips[equipment]['prio'] = 100 + equip_number equip_number += 1 else: dict_ips['gateway_redundancy'] = False dict_ips[equipment_list[0]] = dict() dict_ips[equipment_list[0]]['ip'] = dict_ips['gateway'] dict_ips[equipment_list[0]]['prio'] = 100 return dict_ips