Skip to content

Commit

Permalink
Merge pull request #448 from globocom/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
renan-lopes-rodrigues authored Oct 30, 2024
2 parents fcfb3ba + e444d6c commit 9ecaa3c
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 0 deletions.
35 changes: 35 additions & 0 deletions networkapi/api_interface/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
from networkapi.util.decorators import prepare_search
from networkapi.util.json_validate import json_validate
from networkapi.util.json_validate import raise_json_validate
from networkapi.util.interface_validate import InterfaceOverrideValidator
from networkapi.util.geral import create_lock
from networkapi.util.geral import destroy_lock
from networkapi.util.geral import render_to_json
Expand Down Expand Up @@ -327,6 +328,10 @@ class InterfaceV3View(CustomAPIView):
def get(self, request, *args, **kwargs):
"""URL: api/v3/interface/"""

log.info('InterfaceV3View GET')
log.info('kwargs: %s', kwargs)
log.info('search: %s', self.search)

if not kwargs.get('obj_ids'):
obj_model = facade.get_interface_by_search(self.search)
interfaces = obj_model['query_set']
Expand Down Expand Up @@ -354,6 +359,8 @@ def get(self, request, *args, **kwargs):
only_main_property=only_main_property
)

log.info('get interfaces response: %s', data)

return Response(data, status=status.HTTP_200_OK)

@logs_method_apiview
Expand All @@ -369,8 +376,36 @@ def post(self, request, *args, **kwargs):
response = list()

interfaces = request.DATA
log.info('InterfaceV3View POST')
log.info('interfaces: %s', interfaces)
log.info('kwargs: %s', kwargs)
json_validate(SPECS.get('interface_post')).validate(interfaces)

user_interface_str_list = []
equipmemnt_interface_str_list = []
for interface in interfaces.get('interfaces'):

# User interface input, ex.:
# ex.: eth1, eth1/1, 1, Gi1/5, FF:FF:FF:FF:FF:F, int1, mgmt0, ethernet1/12, ..
interface_input = interface['interface']
user_interface_str_list.append(interface_input)

# Equipments from input interface
equipment_id = interface['equipment']
obj_model = facade.get_interface_by_search(
{'extends_search': [], 'start_record': 0, 'custom_search': equipment_id, 'end_record': 1000, 'asorting_cols': ['id'], 'searchable_columns': ['equipamento__id']}
)
equipment_list = obj_model['query_set']
log.debug("equipment_list %s", equipment_list)
for equipment_interface in equipment_list:
equipmemnt_interface_str_list.append(equipment_interface.interface)

# Validate interface overrinding
InterfaceOverrideValidator().check_overriding(
source_interface_str_list=user_interface_str_list,
target_interface_str_list=equipmemnt_interface_str_list
)

for i in interfaces.get('interfaces'):
try:
interface = facade.create_interface(i)
Expand Down
87 changes: 87 additions & 0 deletions networkapi/util/interface_validate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
"""
Interface validator module
"""
import re
import logging
from networkapi.api_rest.exceptions import NetworkAPIException

log = logging.getLogger(__name__)


class InterfaceOverrideValidator:
"""
Class responsible to interfaces (or ports) valitions.
"""

def check_overriding(self, source_interface_str_list, target_interface_str_list):
"""
Public method to check if source interface overides target interfaces.
Allowed interfaces sample:
source_interface_str_list = ['eth1/1', 'eth3/2']
target_interface_str_list = ['eth2', 'eth3/1']
Prohibited interfaces sample:
source_interface_str_list = ['eth1/1', 'eth3/2']
target_interface_str_list = ['eth1', 'eth1/1', 'eth3']
:param source_interface_str_list str list: String array of interfaces, ex.: ['eth1', 'eth2', 'eth2/1']
:param target_interface_str_list str list: String array of interfaces, ex.: ['eth2/1/3', 'eth2/1/2/1']
:return first prohibited interface as False, otherwise, allowed interface as True:
"""

try:

log.info('check_overriding START')
log.info('source_interface_str_list: %s', source_interface_str_list)
log.info('target_interface_str_list: %s', target_interface_str_list)

# Validate
for source_interface_str in source_interface_str_list:
for target_interface_str in target_interface_str_list:

log.info("Validating '%s' with '%s'", source_interface_str, source_interface_str)
source_interface_array = [int(num) for num in re.findall(r'\d+', source_interface_str)]
target_interface_array = [int(num) for num in re.findall(r'\d+', target_interface_str)]
response = self._is_overriding(
source_list=source_interface_array,
target_list=target_interface_array)
if not response:
raise NetworkAPIException("A interface requisitada '{}' sobrepoe a interface '{}' do equipamento".format(
source_interface_str, target_interface_str
)
)

except Exception as ex:
raise NetworkAPIException(str(ex))

def _is_overriding(self, source_list, target_list, lvl=0):
"""
Private method check if source interface overides target interfaces.
The interfaces are represented by array, ex. [1,1] is 'eth1/1'.
:param source interfaces: Represented array of interfaces, ex.: [1,1] [1,2,1] [2]
:param source interfaces: Represented array of interfaces, ex.: [1] [1,2,3] [4]
:param recursive level control.
:return first prohibited interface as False, otherwise, allowed interface as True:
"""

try:
# Identical
if source_list == target_list:
log.info('*** PROHIBITED ***')
return False
elif not source_list or not target_list:
log.info('**** PROHIBITED ****')
return False
elif source_list and target_list and source_list[0] == target_list[0]:
return self._is_overriding(
source_list=source_list[1:],
target_list=target_list[1:],
lvl=lvl+1
)
else:
log.info('**** ALLOWED ****')
return True
except Exception as ex:
raise NetworkAPIException(str(ex))

0 comments on commit 9ecaa3c

Please sign in to comment.