From fbbf4116c3c1687a6ec19c51f4e035426b221b3a Mon Sep 17 00:00:00 2001 From: renan-lopes-rodrigues <143722907+renan-lopes-rodrigues@users.noreply.github.com> Date: Tue, 24 Oct 2023 18:13:21 -0300 Subject: [PATCH 01/89] unit test --- fast_start_test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fast_start_test.sh b/fast_start_test.sh index e29151f8..27c348eb 100755 --- a/fast_start_test.sh +++ b/fast_start_test.sh @@ -1,5 +1,5 @@ #!/bin/sh -source venv/bin/activate +source /venv/bin/activate pip install --no-cache --upgrade pip pip install -r requirements_test.txt From 7f9302ebfcdb15ce921f845cfd20738961b8a5db Mon Sep 17 00:00:00 2001 From: renan-lopes-rodrigues <143722907+renan-lopes-rodrigues@users.noreply.github.com> Date: Wed, 25 Oct 2023 11:02:33 -0300 Subject: [PATCH 02/89] test for network v6 --- fast_start_test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fast_start_test.sh b/fast_start_test.sh index 27c348eb..55a22289 100755 --- a/fast_start_test.sh +++ b/fast_start_test.sh @@ -100,7 +100,7 @@ echo "=============== Tests for Network v6 =================" python manage.py test networkapi/api_network.tests.v3.unit.networkipv6.async.test_delete.py python manage.py test networkapi/api_network.tests.v3.unit.networkipv6.async.test_post.py python manage.py test networkapi/api_network.tests.v3.unit.networkipv6.async.test_put.py -python manage.py test networkapi/api_network.tests.v3.sanity.allocate.test_network_v4.py +python manage.py test networkapi/api_network.tests.v3.sanity.allocate.test_network_v6.py python manage.py test networkapi/api_network.tests.v3.sanity.networkipv6.sync.test_delete.py python manage.py test networkapi/api_network.tests.v3.sanity.networkipv6.sync.test_get.py python manage.py test networkapi/api_network.tests.v3.sanity.networkipv6.sync.test_post.py From 274e38c1630dc25d2726093cb69efb2aced6b321 Mon Sep 17 00:00:00 2001 From: "deivison.marteleto" Date: Tue, 26 Mar 2024 12:49:54 -0300 Subject: [PATCH 03/89] ajustar deploy local --- docker-compose.yml | 9 +++++---- scripts/docker/docker-start-netapi.sh | 4 ++-- scripts/docker/netapi.env | 8 ++++---- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index c52a6d4b..684108dd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,10 +5,11 @@ services: container_name: netapi_db image: mysql:5.7 platform: linux/x86_64 + command: --default-authentication-plugin=mysql_native_password ports: - - "3306:3306" + - "33306:3306" environment: - MYSQL_ALLOW_EMPTY_PASSWORD: 1 + MYSQL_ROOT_PASSWORD: 'put your password here' volumes: - netapi_db_vol:/var/lib/mysql networks: @@ -55,11 +56,11 @@ services: - queue:netapi_queue - cache:netapi_cache depends_on: - - queue + - queue netapi: container_name: netapi_app - image: globocom:latest + image: networkapi:latest build: context: . dockerfile: ./scripts/docker/Dockerfile diff --git a/scripts/docker/docker-start-netapi.sh b/scripts/docker/docker-start-netapi.sh index 3cc12301..ed37b82c 100755 --- a/scripts/docker/docker-start-netapi.sh +++ b/scripts/docker/docker-start-netapi.sh @@ -53,7 +53,7 @@ fi echo "Creating networkapi database" -mysql -u root -h ${NETWORKAPI_DATABASE_HOST} -e 'CREATE DATABASE IF NOT EXISTS networkapi;' +mysql -u root -h ${NETWORKAPI_DATABASE_HOST} -p${NETWORKAPI_DATABASE_PASSWORD} -e 'CREATE DATABASE IF NOT EXISTS networkapi;' # Running database migrations if exists @@ -61,7 +61,7 @@ cd /netapi/dbmigrate; db-migrate --show-sql echo "Loading base Network API data into database" -mysql -u root -h ${NETWORKAPI_DATABASE_HOST} networkapi < /netapi/dev/load_example_environment.sql +mysql -u root -h ${NETWORKAPI_DATABASE_HOST} -p${NETWORKAPI_DATABASE_PASSWORD} networkapi < /netapi/dev/load_example_environment.sql # Discovering SDN controller diff --git a/scripts/docker/netapi.env b/scripts/docker/netapi.env index 9b984950..4442b6f6 100644 --- a/scripts/docker/netapi.env +++ b/scripts/docker/netapi.env @@ -1,10 +1,10 @@ -NETWORKAPI_DATABASE_NAME=networkapi +NETWORKAPI_DATABASE_NAME='networkapi' -NETWORKAPI_DATABASE_USER=root +NETWORKAPI_DATABASE_USER='root' -NETWORKAPI_DATABASE_PASSWORD= +NETWORKAPI_DATABASE_PASSWORD='put your password here' -NETWORKAPI_DATABASE_HOST=netapi_db +NETWORKAPI_DATABASE_HOST='netapi_db' NETWORKAPI_DATABASE_PORT=3306 From cb724412213bc5e0ed4b02b019000c05c34fdf96 Mon Sep 17 00:00:00 2001 From: "deivison.marteleto" Date: Tue, 26 Mar 2024 13:49:19 -0300 Subject: [PATCH 04/89] ajustar deploy local --- Makefile | 11 ++++++++--- docker-compose.yml | 13 +++++++++---- scripts/docker/Dockerfile | 2 +- scripts/docker/netapi.env | 2 +- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 6ae448e2..aa3b9518 100644 --- a/Makefile +++ b/Makefile @@ -120,11 +120,16 @@ publish: clean # Containers based target rules # -start: docker-compose-sdn.yml docker-compose.yml +start_recreate: docker-compose-sdn.yml docker-compose.yml docker-compose up --force-recreate --remove-orphans -d docker-compose --file $< up --force-recreate -d +start: docker-compose-sdn.yml docker-compose.yml + docker-compose up -d + docker-compose --file $< up -d + + stop: docker-compose-sdn.yml docker-compose.yml @docker-compose down --remove-orphans @@ -172,8 +177,8 @@ endif build_img: scripts/docker/Dockerfile - docker build -t networkapi:latest --file scripts/docker/Dockerfile . - docker build -t networkapi:$(NETAPI_IMAGE_VERSION) --file scripts/docker/Dockerfile . + docker build --platform=linux/x86_64 -t networkapi:latest --file scripts/docker/Dockerfile . + docker build --platform=linux/x86_64 -t networkapi:$(NETAPI_IMAGE_VERSION) --file scripts/docker/Dockerfile . push_img: scripts/docker/push_image.sh diff --git a/docker-compose.yml b/docker-compose.yml index 684108dd..c79824d0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,11 +9,17 @@ services: ports: - "33306:3306" environment: - MYSQL_ROOT_PASSWORD: 'put your password here' + MYSQL_ROOT_PASSWORD: 'put_your_password_here' volumes: - netapi_db_vol:/var/lib/mysql networks: - netapi_net + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1",-p$$MYSQL_ROOT_PASSWORD ,"--silent"] + interval: 5s + timeout: 3s + retries: 2 + start_period: 15s queue: container_name: netapi_queue @@ -80,9 +86,8 @@ services: networks: - netapi_net depends_on: - - db - - queue - - cache + db: + condition: service_healthy links: - db:netapi_db external_links: diff --git a/scripts/docker/Dockerfile b/scripts/docker/Dockerfile index 5a98a61e..4bbf628e 100644 --- a/scripts/docker/Dockerfile +++ b/scripts/docker/Dockerfile @@ -1,7 +1,7 @@ # # Base stage # -FROM alpine:3.7 as base +FROM alpine:3.7 as base RUN apk update diff --git a/scripts/docker/netapi.env b/scripts/docker/netapi.env index 4442b6f6..2f79e793 100644 --- a/scripts/docker/netapi.env +++ b/scripts/docker/netapi.env @@ -2,7 +2,7 @@ NETWORKAPI_DATABASE_NAME='networkapi' NETWORKAPI_DATABASE_USER='root' -NETWORKAPI_DATABASE_PASSWORD='put your password here' +NETWORKAPI_DATABASE_PASSWORD='put_your_password_here' NETWORKAPI_DATABASE_HOST='netapi_db' From 86d17576fbcc86a73f7a3121f7e93b99e35d448d Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Fri, 24 May 2024 17:48:21 -0300 Subject: [PATCH 05/89] bugfix --- networkapi/middlewares.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/networkapi/middlewares.py b/networkapi/middlewares.py index 4f5f1aef..3339a4fe 100644 --- a/networkapi/middlewares.py +++ b/networkapi/middlewares.py @@ -65,12 +65,18 @@ def process_request(self, request): AuditRequest.new_request(request.get_full_path(), request.user, ip, identity, context) else: - user_auth_tuple = BasicAuthentication().authenticate(request) + try: + user_auth_tuple = BasicAuthentication().authenticate(request) + except Exception as ex: + user_auth_tuple = None if user_auth_tuple is not None: user, token = user_auth_tuple else: # keeps compatibility with old authentication method - user = RestResource.authenticate_user(request) + try: + user = RestResource.authenticate_user(request) + except Exception as ex: + user = None if user is not None: ip = self._get_ip(request) From 89305678cc51da16b5c4bb9bd7a220a69d7d992f Mon Sep 17 00:00:00 2001 From: marcusgc Date: Tue, 11 Jun 2024 16:55:31 -0300 Subject: [PATCH 06/89] update docker image to globocom/networkapi --- docker-compose.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index c79824d0..34fc80c7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -44,7 +44,7 @@ services: celery: container_name: netapi_celery - image: networkapi:latest + image: globocom/networkapi:latest build: context: . dockerfile: ./scripts/docker/Dockerfile @@ -66,7 +66,7 @@ services: netapi: container_name: netapi_app - image: networkapi:latest + image: globocom/networkapi:latest build: context: . dockerfile: ./scripts/docker/Dockerfile @@ -100,4 +100,4 @@ volumes: netapi_db_vol: networks: - netapi_net: \ No newline at end of file + netapi_net: From 12f673a388daee8047936b14f607a0ec09b43a86 Mon Sep 17 00:00:00 2001 From: marcusgc Date: Tue, 11 Jun 2024 20:51:51 -0300 Subject: [PATCH 07/89] fix alocacao de ambientes spine x leaf para fabric --- networkapi/api_rack/rackenvironments.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/networkapi/api_rack/rackenvironments.py b/networkapi/api_rack/rackenvironments.py index a3a932e5..a5a2fe4f 100644 --- a/networkapi/api_rack/rackenvironments.py +++ b/networkapi/api_rack/rackenvironments.py @@ -89,11 +89,15 @@ def spines_environment_save(self): id_amb_log = amb_log_dict.id pass config = list() + subnet_index = (spn*int(self.rack.dcroom.racks))+int(self.rack.numero) for sub in config_subnet: config_spn = { - 'subnet': str(sub.get("cidr")[spn]), + 'subnet': str(sub.get("cidr")[subnet_index]), + 'network': str(sub.get("cidr")[subnet_index]), 'new_prefix': str(31) if str(sub.get("type"))[-1] is "4" else str(127), + 'subnet_mask': str(31) if str(sub.get("type"))[-1] is "4" else str(127), 'type': str(sub.get("type")), + 'ip_version': str(sub.get("type")), 'network_type': sub.get("network_type") } config.append(config_spn) @@ -105,16 +109,19 @@ def spines_environment_save(self): 'ipv4_template': env.ipv4_template, 'ipv6_template': env.ipv6_template, 'link': env.link, - 'min_num_vlan_2': env.min_num_vlan_2, - 'max_num_vlan_2': env.max_num_vlan_2, - 'min_num_vlan_1': env.min_num_vlan_1, - 'max_num_vlan_1': env.max_num_vlan_1, + 'min_num_vlan_2': env.min_num_vlan_1+subnet_index, + 'max_num_vlan_2': env.min_num_vlan_1+subnet_index, + 'min_num_vlan_1': env.min_num_vlan_1+subnet_index, + 'max_num_vlan_1': env.min_num_vlan_1+subnet_index, 'vrf': env.vrf, 'father_environment': env.id, 'default_vrf': env.default_vrf.id, 'configs': config, 'fabric_id': self.rack.dcroom.id } + #TODO SAVE ENVS OBJ + amb_new = models_env.Ambiente() + amb_new.create_v3(obj) return environment_spn_lf_list From d5418b2d0612281a039bf1b705e3c2aa1d5a8411 Mon Sep 17 00:00:00 2001 From: marcusgc Date: Wed, 12 Jun 2024 10:47:44 -0300 Subject: [PATCH 08/89] fix alocacao de ambientes leaf x leaf --- networkapi/api_rack/rackenvironments.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/networkapi/api_rack/rackenvironments.py b/networkapi/api_rack/rackenvironments.py index a5a2fe4f..1b188fc2 100644 --- a/networkapi/api_rack/rackenvironments.py +++ b/networkapi/api_rack/rackenvironments.py @@ -119,10 +119,8 @@ def spines_environment_save(self): 'configs': config, 'fabric_id': self.rack.dcroom.id } - #TODO SAVE ENVS OBJ - amb_new = models_env.Ambiente() - amb_new.create_v3(obj) - + environment = facade_env.create_environment(obj) + return environment_spn_lf_list def spines_environment_read(self): @@ -185,7 +183,7 @@ def leaf_leaf_vlans_save(self): log.debug("_create_lflf_vlans") env_lf = models_env.Ambiente.objects.filter(dcroom=int(self.rack.dcroom.id), - grupo_l3__nome=str(self.rack.dcroom.name), + grupo_l3__nome=str(self.rack.name), ambiente_logico__nome="LEAF-LEAF") log.debug("Leaf-leaf environments: " + str(env_lf)) From 2430bc35d8e7cd24b2cf07aba5f1e1d9b7487c6d Mon Sep 17 00:00:00 2001 From: marcusgc Date: Tue, 18 Jun 2024 16:32:20 -0300 Subject: [PATCH 09/89] fix typo for rack name identifier --- networkapi/api_rack/rackenvironments.py | 2 +- networkapi/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/networkapi/api_rack/rackenvironments.py b/networkapi/api_rack/rackenvironments.py index 1b188fc2..945f8032 100644 --- a/networkapi/api_rack/rackenvironments.py +++ b/networkapi/api_rack/rackenvironments.py @@ -183,7 +183,7 @@ def leaf_leaf_vlans_save(self): log.debug("_create_lflf_vlans") env_lf = models_env.Ambiente.objects.filter(dcroom=int(self.rack.dcroom.id), - grupo_l3__nome=str(self.rack.name), + grupo_l3__nome=str(self.rack.nome), ambiente_logico__nome="LEAF-LEAF") log.debug("Leaf-leaf environments: " + str(env_lf)) diff --git a/networkapi/settings.py b/networkapi/settings.py index 9e30d677..fbd44242 100644 --- a/networkapi/settings.py +++ b/networkapi/settings.py @@ -71,7 +71,7 @@ def local_files(path): NETWORKAPI_DATABASE_PORT = os.getenv('NETWORKAPI_DATABASE_PORT', '3306') NETWORKAPI_DATABASE_OPTIONS = os.getenv( 'NETWORKAPI_DATABASE_OPTIONS', - '{"init_command": "SET storage_engine=INNODB"}') + '{"init_command": "SET default_storage_engine=INNODB"}') # Configurações de banco de dados DATABASES = { From 788f669e1230f126368e4dee113aaf2a812f5bad Mon Sep 17 00:00:00 2001 From: marcusgc Date: Wed, 19 Jun 2024 16:13:44 -0300 Subject: [PATCH 10/89] fix operator type --- networkapi/ambiente/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/networkapi/ambiente/models.py b/networkapi/ambiente/models.py index 568a38a7..e9e01335 100644 --- a/networkapi/ambiente/models.py +++ b/networkapi/ambiente/models.py @@ -2000,7 +2000,7 @@ def nextAvailableCIDR(self, subnets, network, network_mask=None): elif int(network_mask) == last_subnet.prefixlen: subnet = last_subnet.next() else: - subnet = NETADDR(str(last_subnet.next().ip) + "/" + network_mask) + subnet = NETADDR(str(last_subnet.next().ip) + "/" + str(network_mask)) if not subnet.ip == subnet.network: subnet = subnet.next() From ce7453ef8835dfbe0cead44fe81046ef82a6fb40 Mon Sep 17 00:00:00 2001 From: marcusgc Date: Thu, 20 Jun 2024 10:51:28 -0300 Subject: [PATCH 11/89] fix operator type --- networkapi/ambiente/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/networkapi/ambiente/models.py b/networkapi/ambiente/models.py index e9e01335..c072dc56 100644 --- a/networkapi/ambiente/models.py +++ b/networkapi/ambiente/models.py @@ -1976,7 +1976,7 @@ def searchNextAvailableCIDR(self, subnets, network_mask=None): for idx in range(len(subnets)-1): step = int(subnets[idx+1].network_first_ip) - int(subnets[idx].network_last_ip) - 1 if step >= 2 ** (32-int(network_mask)): - subnet = NETADDR(str(NETADDR(subnets[idx].network).next().ip) + "/" + network_mask) + subnet = NETADDR(str(NETADDR(subnets[idx].network).next().ip) + "/" + str(network_mask)) if subnet.ip == subnet.network and \ not ipaddr.IPNetwork(subnet).overlaps(ipaddr.IPNetwork(subnets[idx+1].network)): return str(subnet) From 417e56a38d2e3e33a1e9ef66effbe4d902ed2238 Mon Sep 17 00:00:00 2001 From: marcusgc Date: Mon, 24 Jun 2024 11:12:49 -0300 Subject: [PATCH 12/89] Change error message text --- networkapi/api_neighbor/v4/exceptions.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/networkapi/api_neighbor/v4/exceptions.py b/networkapi/api_neighbor/v4/exceptions.py index df02f2a0..e06bee66 100644 --- a/networkapi/api_neighbor/v4/exceptions.py +++ b/networkapi/api_neighbor/v4/exceptions.py @@ -132,18 +132,18 @@ class LocalIpAndPeerGroupAtDifferentEnvironmentsException(APIException): status_code = status.HTTP_400_BAD_REQUEST def __init__(self, neighbor): - self.detail = u'LocalIp id = {} and PeerGroup id = {} belongs to ' \ - u'different Environments'. \ - format(neighbor.local_ip, neighbor.peer_group) + self.detail = u'Not allowed to configure BGP neighbor using this Peer Group. ' \ + u'PeerGroup id = {} is not mapped to the environment of LocalIp id = {}' \ + format(neighbor.peer_group, neighbor.local_ip) class NeighborDuplicatedException(APIException): status_code = status.HTTP_400_BAD_REQUEST def __init__(self, neighbor): - self.detail = u'It already exists Neighbor with LocalAsn id = {}, ' \ + self.detail = u'Duplicated neighbor. A Neighbor with LocalAsn id = {}, ' \ u'LocalIp id = {}, RemoteAsn id = {} and ' \ - u'RemoteIp id = {}'.\ + u'RemoteIp id = {} already exists'.\ format(neighbor.local_asn, neighbor.local_ip, neighbor.remote_asn, neighbor.remote_ip) From 296779b715aa504b40b472bbc8af2e3b369c06ec Mon Sep 17 00:00:00 2001 From: marcusgc Date: Tue, 25 Jun 2024 14:34:17 -0300 Subject: [PATCH 13/89] fix allocation of intra-rack Leaf x Leaf vlans - change order to allocate vlans after allocating environments --- networkapi/api_rack/facade.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/networkapi/api_rack/facade.py b/networkapi/api_rack/facade.py index 083e2242..c3c7799c 100644 --- a/networkapi/api_rack/facade.py +++ b/networkapi/api_rack/facade.py @@ -970,8 +970,8 @@ def allocate_env_vlan(user, rack_id): rack_env.spine_leaf_vlans_save() # leaf x leaf - rack_env.leaf_leaf_vlans_save() rack_env.leaf_leaf_envs_save() + rack_env.leaf_leaf_vlans_save() # producao/cloud rack_env.prod_environment_save() From 0c6a4c1c79ddaab634a1c2e64ff2fae07072cf40 Mon Sep 17 00:00:00 2001 From: Deivison Marteleto <42618693+deivisonmarteleto@users.noreply.github.com> Date: Thu, 27 Jun 2024 10:32:20 -0300 Subject: [PATCH 14/89] Update exceptions.py fix: add '.' before formart --- networkapi/api_neighbor/v4/exceptions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/networkapi/api_neighbor/v4/exceptions.py b/networkapi/api_neighbor/v4/exceptions.py index e06bee66..4f3b334f 100644 --- a/networkapi/api_neighbor/v4/exceptions.py +++ b/networkapi/api_neighbor/v4/exceptions.py @@ -133,7 +133,7 @@ class LocalIpAndPeerGroupAtDifferentEnvironmentsException(APIException): def __init__(self, neighbor): self.detail = u'Not allowed to configure BGP neighbor using this Peer Group. ' \ - u'PeerGroup id = {} is not mapped to the environment of LocalIp id = {}' \ + u'PeerGroup id = {} is not mapped to the environment of LocalIp id = {}'. \ format(neighbor.peer_group, neighbor.local_ip) From 79d1ab42f7cb25b7a16db5ba484c606dc117d3ad Mon Sep 17 00:00:00 2001 From: Deivison Marteleto <42618693+deivisonmarteleto@users.noreply.github.com> Date: Thu, 27 Jun 2024 12:46:26 -0300 Subject: [PATCH 15/89] Update exceptions.py --- networkapi/api_neighbor/v4/exceptions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/networkapi/api_neighbor/v4/exceptions.py b/networkapi/api_neighbor/v4/exceptions.py index 4f3b334f..187f1d3f 100644 --- a/networkapi/api_neighbor/v4/exceptions.py +++ b/networkapi/api_neighbor/v4/exceptions.py @@ -133,7 +133,7 @@ class LocalIpAndPeerGroupAtDifferentEnvironmentsException(APIException): def __init__(self, neighbor): self.detail = u'Not allowed to configure BGP neighbor using this Peer Group. ' \ - u'PeerGroup id = {} is not mapped to the environment of LocalIp id = {}'. \ + u'PeerGroup id = {} is not mapped to the environment of LocalIp id = {}'.\ format(neighbor.peer_group, neighbor.local_ip) From 38d50b8470317081d73345a13ec2ab28b94cb691 Mon Sep 17 00:00:00 2001 From: marcusgc Date: Tue, 9 Jul 2024 17:12:36 -0300 Subject: [PATCH 16/89] troca codigo para gerar spines de acordo com quantidade --- networkapi/api_rack/provision.py | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/networkapi/api_rack/provision.py b/networkapi/api_rack/provision.py index 8dbcdf9b..d92399fe 100644 --- a/networkapi/api_rack/provision.py +++ b/networkapi/api_rack/provision.py @@ -282,28 +282,17 @@ def spine_provision(self, rack, equips): id_vlt = [envconfig.get("VLT").get("id_vlt_lf1"), envconfig.get("VLT").get("id_vlt_lf2")] priority_vlt = [envconfig.get("VLT").get("priority_vlt_lf1"), envconfig.get("VLT").get("priority_vlt_lf2")] - IPSPINEipv4[numero_rack].append(CIDRBEipv4[0][0]) - IPSPINEipv4[numero_rack].append(CIDRBEipv4[1][0]) - IPSPINEipv4[numero_rack].append(CIDRBEipv4[2][0]) - IPSPINEipv4[numero_rack].append(CIDRBEipv4[3][0]) - # - IPLEAFipv4[numero_rack].append(CIDRBEipv4[0][1]) - IPLEAFipv4[numero_rack].append(CIDRBEipv4[1][1]) - IPLEAFipv4[numero_rack].append(CIDRBEipv4[2][1]) - IPLEAFipv4[numero_rack].append(CIDRBEipv4[3][1]) + for i in range(len(CIDRBEipv4)): + IPSPINEipv4[numero_rack].append(CIDRBEipv4[i][0]) + IPLEAFipv4[numero_rack].append(CIDRBEipv4[i][1]) + + IPSPINEipv6[numero_rack].append(CIDRBEipv6[i][0]) + IPLEAFipv6[numero_rack].append(CIDRBEipv6[i][1]) + # IPSIBGPipv4[numero_rack].append(IBGPToRLxLipv4[0]) IPSIBGPipv4[numero_rack].append(IBGPToRLxLipv4[1]) # - IPSPINEipv6[numero_rack].append(CIDRBEipv6[0][0]) - IPSPINEipv6[numero_rack].append(CIDRBEipv6[1][0]) - IPSPINEipv6[numero_rack].append(CIDRBEipv6[2][0]) - IPSPINEipv6[numero_rack].append(CIDRBEipv6[3][0]) - # - IPLEAFipv6[numero_rack].append(CIDRBEipv6[0][1]) - IPLEAFipv6[numero_rack].append(CIDRBEipv6[1][1]) - IPLEAFipv6[numero_rack].append(CIDRBEipv6[2][1]) - IPLEAFipv6[numero_rack].append(CIDRBEipv6[3][1]) # IPSIBGPipv6[numero_rack].append(IBGPToRLxLipv6[0]) IPSIBGPipv6[numero_rack].append(IBGPToRLxLipv6[1]) @@ -322,6 +311,10 @@ def spine_provision(self, rack, equips): log.debug("as") log.debug(BASE_AS_LFS) log.debug(numero_rack) + log.debug(numero_rack) + log.debug("zip equips_sorted") + log.debug(zip(equips_sorted[:2], [0, 2], [0, 1])) + ASLEAF[numero_rack].append(BASE_AS_LFS + numero_rack) for equip, spn, j in zip(equips_sorted[:2], [0, 2], [0, 1]): From 5d2966a298c34e161e49c786551f0686e1e857e8 Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Mon, 15 Jul 2024 15:38:46 -0300 Subject: [PATCH 17/89] created migration to change relation from equipment_list_config_bgp x route_map to equipment_list_config_bgp x list_config_bgp --- .../20240715173246_fix_fk_list_config_bgp.migration | 9 +++++++++ networkapi/api_list_config_bgp/models.py | 2 +- scripts/docker/netapi.env | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 dbmigrate/migrations/20240715173246_fix_fk_list_config_bgp.migration diff --git a/dbmigrate/migrations/20240715173246_fix_fk_list_config_bgp.migration b/dbmigrate/migrations/20240715173246_fix_fk_list_config_bgp.migration new file mode 100644 index 00000000..1411c24f --- /dev/null +++ b/dbmigrate/migrations/20240715173246_fix_fk_list_config_bgp.migration @@ -0,0 +1,9 @@ +#-*- coding:utf-8 -*- +SQL_UP = u""" +ALTER TABLE equipment_list_config_bgp DROP FOREIGN KEY fk_equipment_list_config_bgp_2; +ALTER TABLE equipment_list_config_bgp ADD CONSTRAINT `fk_equipment_list_config_bgp_2` FOREIGN KEY (`id_list_config_bgp`) REFERENCES `list_config_bgp` (`id`) +""" + +SQL_DOWN = u""" + +""" diff --git a/networkapi/api_list_config_bgp/models.py b/networkapi/api_list_config_bgp/models.py index 45f95650..50bafab6 100644 --- a/networkapi/api_list_config_bgp/models.py +++ b/networkapi/api_list_config_bgp/models.py @@ -156,7 +156,7 @@ class EquipmentListConfig(BaseModel): ) list_config_bgp = models.ForeignKey( 'api_list_config_bgp.ListConfigBGP', - db_column='id_list_config_bgp' + db_column='id' ) class Meta(BaseModel.Meta): diff --git a/scripts/docker/netapi.env b/scripts/docker/netapi.env index 2f79e793..1db49da5 100644 --- a/scripts/docker/netapi.env +++ b/scripts/docker/netapi.env @@ -2,7 +2,7 @@ NETWORKAPI_DATABASE_NAME='networkapi' NETWORKAPI_DATABASE_USER='root' -NETWORKAPI_DATABASE_PASSWORD='put_your_password_here' +NETWORKAPI_DATABASE_PASSWORD='' NETWORKAPI_DATABASE_HOST='netapi_db' From 0343bd85f018be9d738edf7c37e5e82c936ca10f Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Mon, 15 Jul 2024 15:46:53 -0300 Subject: [PATCH 18/89] Migrations documentation --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 64273687..7caa9686 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,10 @@ It was not created to be and inventory database, so it does not have CMDB functi ## Run Unit Tests To run the unit tests just run `make build_img && make start && make test_ci` this instruction will run all the unit tests specified in the `networkapi/tests/__init__.py` file. +## Create and run migrations +To create a new migration, just run into app container `cd dbmigrate; db-migrate --new=`. This step will create a enpty migration file, you must write the SQL statement. +To run a migration, just run into app container `cd dbmigrate; db-migrate`. This command will execute all migrations files not executed until now. + ## How to contribute Check this out at [Contributing](https://github.com/globocom/GloboNetworkAPI/blob/master/CONTRIBUTING.md) file. From ebd0491f6ede3ff2f23d4e4373decf8afacc7131 Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Mon, 15 Jul 2024 15:48:47 -0300 Subject: [PATCH 19/89] revert .env --- scripts/docker/netapi.env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/docker/netapi.env b/scripts/docker/netapi.env index 1db49da5..2f79e793 100644 --- a/scripts/docker/netapi.env +++ b/scripts/docker/netapi.env @@ -2,7 +2,7 @@ NETWORKAPI_DATABASE_NAME='networkapi' NETWORKAPI_DATABASE_USER='root' -NETWORKAPI_DATABASE_PASSWORD='' +NETWORKAPI_DATABASE_PASSWORD='put_your_password_here' NETWORKAPI_DATABASE_HOST='netapi_db' From 6f85fb03574eb1211f8ea1c037c754fac2d348c9 Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Mon, 15 Jul 2024 15:57:09 -0300 Subject: [PATCH 20/89] downgrade --- .../migrations/20240715173246_fix_fk_list_config_bgp.migration | 3 ++- scripts/docker/netapi.env | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/dbmigrate/migrations/20240715173246_fix_fk_list_config_bgp.migration b/dbmigrate/migrations/20240715173246_fix_fk_list_config_bgp.migration index 1411c24f..e147642b 100644 --- a/dbmigrate/migrations/20240715173246_fix_fk_list_config_bgp.migration +++ b/dbmigrate/migrations/20240715173246_fix_fk_list_config_bgp.migration @@ -5,5 +5,6 @@ ALTER TABLE equipment_list_config_bgp ADD CONSTRAINT `fk_equipment_list_config_b """ SQL_DOWN = u""" - +ALTER TABLE equipment_list_config_bgp DROP FOREIGN KEY fk_equipment_list_config_bgp_2; +ALTER TABLE equipment_list_config_bgp ADD CONSTRAINT `fk_equipment_list_config_bgp_2` FOREIGN KEY (`id_list_config_bgp`) REFERENCES `route_map` (`id`) """ diff --git a/scripts/docker/netapi.env b/scripts/docker/netapi.env index 2f79e793..1db49da5 100644 --- a/scripts/docker/netapi.env +++ b/scripts/docker/netapi.env @@ -2,7 +2,7 @@ NETWORKAPI_DATABASE_NAME='networkapi' NETWORKAPI_DATABASE_USER='root' -NETWORKAPI_DATABASE_PASSWORD='put_your_password_here' +NETWORKAPI_DATABASE_PASSWORD='' NETWORKAPI_DATABASE_HOST='netapi_db' From fe6af87055ec9b65e2b2fea7c79873727efd47b9 Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Mon, 15 Jul 2024 15:58:34 -0300 Subject: [PATCH 21/89] revert .env --- scripts/docker/netapi.env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/docker/netapi.env b/scripts/docker/netapi.env index 1db49da5..2f79e793 100644 --- a/scripts/docker/netapi.env +++ b/scripts/docker/netapi.env @@ -2,7 +2,7 @@ NETWORKAPI_DATABASE_NAME='networkapi' NETWORKAPI_DATABASE_USER='root' -NETWORKAPI_DATABASE_PASSWORD='' +NETWORKAPI_DATABASE_PASSWORD='put_your_password_here' NETWORKAPI_DATABASE_HOST='netapi_db' From f80f795e8c4a36ba07c6b0fd2d52bfc5fcafe4b4 Mon Sep 17 00:00:00 2001 From: marcusgc Date: Thu, 18 Jul 2024 14:20:20 -0300 Subject: [PATCH 22/89] workaround bug bugged db table. do not create prefix-list for bgp route-maps in switches --- networkapi/api_neighbor/models.py | 12 +++++---- networkapi/api_rack/rackenvironments.py | 28 +++++++++++++++++---- networkapi/plugins/Dell/FTOS/BGP/Cli.py | 4 +-- networkapi/plugins/Juniper/JUNOS/BGP/Cli.py | 12 ++++----- 4 files changed, 38 insertions(+), 18 deletions(-) diff --git a/networkapi/api_neighbor/models.py b/networkapi/api_neighbor/models.py index cf85a476..5a8c6b21 100644 --- a/networkapi/api_neighbor/models.py +++ b/networkapi/api_neighbor/models.py @@ -271,10 +271,12 @@ def deploy(self): list_config_bgp=entry.list_config_bgp ) if not eqpt_list_config: - EquipmentListConfig().create_v4({ - 'equipment': equipment.id, - 'list_config_bgp': entry.list_config_bgp.id - }) + self.log.debug('equipment id %s' % equipment.id) + self.log.debug('id_list_config_bgp %s' % entry.list_config_bgp.id) + # EquipmentListConfig().create_v4({ + # 'equipment': equipment.id, + # 'list_config_bgp': entry.list_config_bgp.id + # }) def undeploy(self): """Undeploy NeighborV4.""" @@ -611,7 +613,7 @@ def deploy(self): 'route_map': route_map_out.id }) - entries = route_map_out.route_map_entries | route_map_in.route_map_entries + entries = route_map_out.route_map_entries | route_map_in.:619: for entry in entries: eqpt_list_config = EquipmentListConfig.objects.filter( equipment=equipment, diff --git a/networkapi/api_rack/rackenvironments.py b/networkapi/api_rack/rackenvironments.py index 945f8032..ee6b709a 100644 --- a/networkapi/api_rack/rackenvironments.py +++ b/networkapi/api_rack/rackenvironments.py @@ -56,12 +56,14 @@ def spines_environment_save(self): environment_spn_lf_list = list() spines = int(self.rack.dcroom.spines) fabric = self.rack.dcroom.name + rackname = self.rack.nome + grupoL3name = fabric+"_"+racknome try: - id_grupo_l3 = models_env.GrupoL3().get_by_name(fabric).id + id_grupo_l3 = models_env.GrupoL3().get_by_name(grupoL3name).id except: grupo_l3_dict = models_env.GrupoL3() - grupo_l3_dict.nome = fabric + grupo_l3_dict.nome = grupoL3name grupo_l3_dict.save() id_grupo_l3 = grupo_l3_dict.id pass @@ -483,13 +485,29 @@ def manage_vlan_save(self): def rack_environment_remove(self): log.info("_remove_envs") - envs = models_env.Ambiente.objects.filter(dcroom=int(self.rack.dcroom.id), + envs_racks = models_env.Ambiente.objects.filter(dcroom=int(self.rack.dcroom.id), grupo_l3__nome=str(self.rack.nome)) - for env in envs: + log.debug("PROD RACK environments to be removed: %s. Total: %s" % (str(envs_racks), len(envs_racks))) + + for env in envs_racks: + env.delete_v3() + + log.debug("PROD RACK environments removed.") + + envs_spines = models_env.Ambiente.objects.filter(dcroom=int(rack.dcroom.id), + grupo_l3__nome=str(rack.dcroom.name), + ambiente_logico__nome__in=["SPINE01LEAF", + "SPINE02LEAF", + "SPINE03LEAF", + "SPINE04LEAF"]) + + log.debug("PROD SPINELEAF environments to be removed: %s. Total: %s" % (str(envs_spines), len(envs_spines))) + + for env in envs_spines: env.delete_v3() - log.debug("PROD environments: %s. Total: %s" % (str(envs), len(envs))) + log.debug("PROD SPINELEAF environments removed.") def rack_vlans_remove(self): log.info("remove_vlans") diff --git a/networkapi/plugins/Dell/FTOS/BGP/Cli.py b/networkapi/plugins/Dell/FTOS/BGP/Cli.py index 811f2aba..1028b77a 100644 --- a/networkapi/plugins/Dell/FTOS/BGP/Cli.py +++ b/networkapi/plugins/Dell/FTOS/BGP/Cli.py @@ -76,8 +76,8 @@ def _deploy_pre_req(self, neighbor): for rm_entry in rms: list_config_bgp = rm_entry.list_config_bgp - if not list_config_bgp.equipments.filter(id=self.equipment.id): - self.deploy_list_config_bgp(list_config_bgp) + # if not list_config_bgp.equipments.filter(id=self.equipment.id): + # self.deploy_list_config_bgp(list_config_bgp) if not route_map_in.equipments.filter(id=self.equipment.id): self.deploy_route_map(neighbor.peer_group.route_map_in) diff --git a/networkapi/plugins/Juniper/JUNOS/BGP/Cli.py b/networkapi/plugins/Juniper/JUNOS/BGP/Cli.py index b99ca517..7a35e7d4 100644 --- a/networkapi/plugins/Juniper/JUNOS/BGP/Cli.py +++ b/networkapi/plugins/Juniper/JUNOS/BGP/Cli.py @@ -65,14 +65,14 @@ def _deploy_pre_req(self, neighbor): route_map_out.route_map_entries for rm_entry in rms: list_config_bgp = rm_entry.list_config_bgp - if not list_config_bgp.equipments.filter(id=self.equipment.id): - self.deploy_list_config_bgp(list_config_bgp) + # if not list_config_bgp.equipments.filter(id=self.equipment.id): + # self.deploy_list_config_bgp(list_config_bgp) - if not route_map_in.equipments.filter(id=self.equipment.id): - self.deploy_route_map(neighbor.peer_group.route_map_in) + # if not route_map_in.equipments.filter(id=self.equipment.id): + # self.deploy_route_map(neighbor.peer_group.route_map_in) - if not route_map_out.equipments.filter(id=self.equipment.id): - self.deploy_route_map(neighbor.peer_group.route_map_out) + # if not route_map_out.equipments.filter(id=self.equipment.id): + # self.deploy_route_map(neighbor.peer_group.route_map_out) def _undeploy_pre_req(self, neighbor, ip_version): log.info("_undeploy_pre_req") From 8fd248d167852d390a0600059443da328200acff Mon Sep 17 00:00:00 2001 From: marcusgc Date: Thu, 18 Jul 2024 14:37:55 -0300 Subject: [PATCH 23/89] fix mistypo --- networkapi/api_neighbor/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/networkapi/api_neighbor/models.py b/networkapi/api_neighbor/models.py index 5a8c6b21..036775ca 100644 --- a/networkapi/api_neighbor/models.py +++ b/networkapi/api_neighbor/models.py @@ -613,7 +613,7 @@ def deploy(self): 'route_map': route_map_out.id }) - entries = route_map_out.route_map_entries | route_map_in.:619: + entries = route_map_out.route_map_entries | route_map_in.route_map_entries for entry in entries: eqpt_list_config = EquipmentListConfig.objects.filter( equipment=equipment, From 5357135af30826817f5ec1beb7e4efa63f4b037b Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Mon, 22 Jul 2024 10:59:13 -0300 Subject: [PATCH 24/89] added reck_num variable to add rack template --- networkapi/api_rack/autoprovision.py | 1 + 1 file changed, 1 insertion(+) diff --git a/networkapi/api_rack/autoprovision.py b/networkapi/api_rack/autoprovision.py index 61648ccf..56dc63d4 100644 --- a/networkapi/api_rack/autoprovision.py +++ b/networkapi/api_rack/autoprovision.py @@ -511,6 +511,7 @@ def autoprovision_splf(rack, equips): variablestochangespine1["ASLEAF"] = str(ASLEAF[numero_rack][0]) variablestochangespine1["IPNEIGHLEAFIPV4"] = str(IPLEAFipv4[numero_rack][spine_num-1]) variablestochangespine1["IPNEIGHLEAFIPV6"] = str(IPLEAFipv6[numero_rack][spine_num-1]) + variablestochangespine1["RACK_NUM"] = str(numero_rack) if spine_num in [1, 3]: variablestochangeleaf1["SP1_HOSTNAME"] = i.get("nome") variablestochangeleaf1["INTERFACE_SP1"] = i.get("interface") From 83ecc1706dd9a5731b34dba6d9a9d94c3a2b90a5 Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Tue, 23 Jul 2024 09:33:44 -0300 Subject: [PATCH 25/89] fixed model --- networkapi/api_list_config_bgp/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/networkapi/api_list_config_bgp/models.py b/networkapi/api_list_config_bgp/models.py index 50bafab6..45f95650 100644 --- a/networkapi/api_list_config_bgp/models.py +++ b/networkapi/api_list_config_bgp/models.py @@ -156,7 +156,7 @@ class EquipmentListConfig(BaseModel): ) list_config_bgp = models.ForeignKey( 'api_list_config_bgp.ListConfigBGP', - db_column='id' + db_column='id_list_config_bgp' ) class Meta(BaseModel.Meta): From d2f6fdf55948a86e12550d1fafbe6ae420a2b6d4 Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Tue, 23 Jul 2024 09:42:51 -0300 Subject: [PATCH 26/89] fixed rack algorithm --- networkapi/rack/resource/GeraConfig.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/networkapi/rack/resource/GeraConfig.py b/networkapi/rack/resource/GeraConfig.py index efb456c0..74aa6b94 100644 --- a/networkapi/rack/resource/GeraConfig.py +++ b/networkapi/rack/resource/GeraConfig.py @@ -958,6 +958,7 @@ def autoprovision_splf(rack,FILEINLF1, FILEINLF2,FILEINSP1, FILEINSP2, FILEINSP3 variablestochangespine1['INTERFACE'] = INTERFACE_SP1 variablestochangespine1['LEAFNAME'] = HOSTNAME_LF1 variablestochangespine1['INT_LF_UPLINK'] = int_lf1_sp1 + variablestochangespine1['RACK_NUM'] = str(rack) # # variablestochangespine2['IPSPINEIPV4'] = str(IPSPINEipv4[rack][1]) @@ -973,6 +974,8 @@ def autoprovision_splf(rack,FILEINLF1, FILEINLF2,FILEINSP1, FILEINSP2, FILEINSP3 variablestochangespine2['INTERFACE'] = INTERFACE_SP2 variablestochangespine2['LEAFNAME'] = HOSTNAME_LF1 variablestochangespine2['INT_LF_UPLINK'] = int_lf1_sp2 + variablestochangespine2['RACK_NUM'] = str(rack) + # # variablestochangespine3['IPSPINEIPV4'] = str(IPSPINEipv4[rack][2]) @@ -988,6 +991,8 @@ def autoprovision_splf(rack,FILEINLF1, FILEINLF2,FILEINSP1, FILEINSP2, FILEINSP3 variablestochangespine3['INTERFACE'] = INTERFACE_SP3 variablestochangespine3['LEAFNAME'] = HOSTNAME_LF2 variablestochangespine3['INT_LF_UPLINK'] = int_lf2_sp3 + variablestochangespine3['RACK_NUM'] = str(rack) + # # variablestochangespine4['IPSPINEIPV4'] = str(IPSPINEipv4[rack][3]) @@ -1003,6 +1008,8 @@ def autoprovision_splf(rack,FILEINLF1, FILEINLF2,FILEINSP1, FILEINSP2, FILEINSP3 variablestochangespine4['INTERFACE'] = INTERFACE_SP4 variablestochangespine4['LEAFNAME'] = HOSTNAME_LF2 variablestochangespine4['INT_LF_UPLINK'] = int_lf2_sp4 + variablestochangespine4['RACK_NUM'] = str(rack) + # # variablestochangeleaf1['IPLEAFSP1IPV4'] = str(IPLEAFipv4[rack][0]) From 53e34e5d5a4e3a54b0f4e790447b3038698eecd8 Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Tue, 23 Jul 2024 09:45:28 -0300 Subject: [PATCH 27/89] Revert "fixed rack algorithm" This reverts commit d2f6fdf55948a86e12550d1fafbe6ae420a2b6d4. --- networkapi/rack/resource/GeraConfig.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/networkapi/rack/resource/GeraConfig.py b/networkapi/rack/resource/GeraConfig.py index 74aa6b94..efb456c0 100644 --- a/networkapi/rack/resource/GeraConfig.py +++ b/networkapi/rack/resource/GeraConfig.py @@ -958,7 +958,6 @@ def autoprovision_splf(rack,FILEINLF1, FILEINLF2,FILEINSP1, FILEINSP2, FILEINSP3 variablestochangespine1['INTERFACE'] = INTERFACE_SP1 variablestochangespine1['LEAFNAME'] = HOSTNAME_LF1 variablestochangespine1['INT_LF_UPLINK'] = int_lf1_sp1 - variablestochangespine1['RACK_NUM'] = str(rack) # # variablestochangespine2['IPSPINEIPV4'] = str(IPSPINEipv4[rack][1]) @@ -974,8 +973,6 @@ def autoprovision_splf(rack,FILEINLF1, FILEINLF2,FILEINSP1, FILEINSP2, FILEINSP3 variablestochangespine2['INTERFACE'] = INTERFACE_SP2 variablestochangespine2['LEAFNAME'] = HOSTNAME_LF1 variablestochangespine2['INT_LF_UPLINK'] = int_lf1_sp2 - variablestochangespine2['RACK_NUM'] = str(rack) - # # variablestochangespine3['IPSPINEIPV4'] = str(IPSPINEipv4[rack][2]) @@ -991,8 +988,6 @@ def autoprovision_splf(rack,FILEINLF1, FILEINLF2,FILEINSP1, FILEINSP2, FILEINSP3 variablestochangespine3['INTERFACE'] = INTERFACE_SP3 variablestochangespine3['LEAFNAME'] = HOSTNAME_LF2 variablestochangespine3['INT_LF_UPLINK'] = int_lf2_sp3 - variablestochangespine3['RACK_NUM'] = str(rack) - # # variablestochangespine4['IPSPINEIPV4'] = str(IPSPINEipv4[rack][3]) @@ -1008,8 +1003,6 @@ def autoprovision_splf(rack,FILEINLF1, FILEINLF2,FILEINSP1, FILEINSP2, FILEINSP3 variablestochangespine4['INTERFACE'] = INTERFACE_SP4 variablestochangespine4['LEAFNAME'] = HOSTNAME_LF2 variablestochangespine4['INT_LF_UPLINK'] = int_lf2_sp4 - variablestochangespine4['RACK_NUM'] = str(rack) - # # variablestochangeleaf1['IPLEAFSP1IPV4'] = str(IPLEAFipv4[rack][0]) From 5f3e5f8f1a0e34acc7f4ab54b095f624785011ff Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Tue, 23 Jul 2024 09:47:22 -0300 Subject: [PATCH 28/89] fix algorithm --- networkapi/rack/resource/GeraConfig.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/networkapi/rack/resource/GeraConfig.py b/networkapi/rack/resource/GeraConfig.py index efb456c0..74aa6b94 100644 --- a/networkapi/rack/resource/GeraConfig.py +++ b/networkapi/rack/resource/GeraConfig.py @@ -958,6 +958,7 @@ def autoprovision_splf(rack,FILEINLF1, FILEINLF2,FILEINSP1, FILEINSP2, FILEINSP3 variablestochangespine1['INTERFACE'] = INTERFACE_SP1 variablestochangespine1['LEAFNAME'] = HOSTNAME_LF1 variablestochangespine1['INT_LF_UPLINK'] = int_lf1_sp1 + variablestochangespine1['RACK_NUM'] = str(rack) # # variablestochangespine2['IPSPINEIPV4'] = str(IPSPINEipv4[rack][1]) @@ -973,6 +974,8 @@ def autoprovision_splf(rack,FILEINLF1, FILEINLF2,FILEINSP1, FILEINSP2, FILEINSP3 variablestochangespine2['INTERFACE'] = INTERFACE_SP2 variablestochangespine2['LEAFNAME'] = HOSTNAME_LF1 variablestochangespine2['INT_LF_UPLINK'] = int_lf1_sp2 + variablestochangespine2['RACK_NUM'] = str(rack) + # # variablestochangespine3['IPSPINEIPV4'] = str(IPSPINEipv4[rack][2]) @@ -988,6 +991,8 @@ def autoprovision_splf(rack,FILEINLF1, FILEINLF2,FILEINSP1, FILEINSP2, FILEINSP3 variablestochangespine3['INTERFACE'] = INTERFACE_SP3 variablestochangespine3['LEAFNAME'] = HOSTNAME_LF2 variablestochangespine3['INT_LF_UPLINK'] = int_lf2_sp3 + variablestochangespine3['RACK_NUM'] = str(rack) + # # variablestochangespine4['IPSPINEIPV4'] = str(IPSPINEipv4[rack][3]) @@ -1003,6 +1008,8 @@ def autoprovision_splf(rack,FILEINLF1, FILEINLF2,FILEINSP1, FILEINSP2, FILEINSP3 variablestochangespine4['INTERFACE'] = INTERFACE_SP4 variablestochangespine4['LEAFNAME'] = HOSTNAME_LF2 variablestochangespine4['INT_LF_UPLINK'] = int_lf2_sp4 + variablestochangespine4['RACK_NUM'] = str(rack) + # # variablestochangeleaf1['IPLEAFSP1IPV4'] = str(IPLEAFipv4[rack][0]) From 73fa1769e7bd92b18c4d4c9bf0fb5681230bc766 Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Tue, 23 Jul 2024 15:57:48 -0300 Subject: [PATCH 29/89] added variables to create 2 sessions per spine --- networkapi/rack/resource/GeraConfig.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/networkapi/rack/resource/GeraConfig.py b/networkapi/rack/resource/GeraConfig.py index 74aa6b94..a5053355 100644 --- a/networkapi/rack/resource/GeraConfig.py +++ b/networkapi/rack/resource/GeraConfig.py @@ -952,6 +952,13 @@ def autoprovision_splf(rack,FILEINLF1, FILEINLF2,FILEINSP1, FILEINSP2, FILEINSP3 variablestochangespine1['VLANBORDALEAF'] = str(VLANBORDALEAF[rack][0]) variablestochangespine1['VLANBORDACACHOSLEAF'] = str( VLANBORDACACHOSLEAF[rack][0]) + + ### TO POP Berrini + variablestochangespine1['IPNEIGHLEAFIPV4_2'] = str(IPLEAFipv4[rack][1]) + variablestochangespine1['IPNEIGHLEAFIPV6_2'] = str(IPLEAFipv6[rack][1]) + variablestochangespine1['LEAFNAME_2'] = HOSTNAME_LF2 + + variablestochangespine1['ASLEAF'] = str(ASLEAF[rack][0]) variablestochangespine1['IPNEIGHLEAFIPV4'] = str(IPLEAFipv4[rack][0]) variablestochangespine1['IPNEIGHLEAFIPV6'] = str(IPLEAFipv6[rack][0]) @@ -968,6 +975,14 @@ def autoprovision_splf(rack,FILEINLF1, FILEINLF2,FILEINSP1, FILEINSP2, FILEINSP3 variablestochangespine2['VLANBORDALEAF'] = str(VLANBORDALEAF[rack][1]) variablestochangespine2['VLANBORDACACHOSLEAF'] = str( VLANBORDACACHOSLEAF[rack][1]) + + + ### TO POP Berrini + variablestochangespine1['IPNEIGHLEAFIPV4_2'] = str(IPLEAFipv4[rack][0]) + variablestochangespine1['IPNEIGHLEAFIPV6_2'] = str(IPLEAFipv6[rack][0]) + variablestochangespine1['LEAFNAME_2'] = HOSTNAME_LF2 + + variablestochangespine2['ASLEAF'] = str(ASLEAF[rack][0]) variablestochangespine2['IPNEIGHLEAFIPV4'] = str(IPLEAFipv4[rack][1]) variablestochangespine2['IPNEIGHLEAFIPV6'] = str(IPLEAFipv6[rack][1]) From 9137248025a45a33f60dd31c0b27913bce722948 Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Tue, 23 Jul 2024 17:28:22 -0300 Subject: [PATCH 30/89] fix variables --- networkapi/api_rack/autoprovision.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/networkapi/api_rack/autoprovision.py b/networkapi/api_rack/autoprovision.py index 56dc63d4..02652ab4 100644 --- a/networkapi/api_rack/autoprovision.py +++ b/networkapi/api_rack/autoprovision.py @@ -509,8 +509,15 @@ def autoprovision_splf(rack, equips): variablestochangespine1["VLANBORDACACHOSLEAF"] = str(VLANBORDACACHOSLEAF[numero_rack][spine_num-1]) variablestochangespine1["VLANBORDACACHOSBLEAF"] = str(VLANBORDACACHOSBLEAF[numero_rack][spine_num-1]) variablestochangespine1["ASLEAF"] = str(ASLEAF[numero_rack][0]) + + ### To pop Berrini + variablestochangespine1["IPNEIGHLEAFIPV4_2"] = str(IPLEAFipv4[numero_rack][spine_num]) + variablestochangespine1["IPNEIGHLEAFIPV6_2"] = str(IPLEAFipv6[numero_rack][spine_num]) + + variablestochangespine1["IPNEIGHLEAFIPV4"] = str(IPLEAFipv4[numero_rack][spine_num-1]) variablestochangespine1["IPNEIGHLEAFIPV6"] = str(IPLEAFipv6[numero_rack][spine_num-1]) + variablestochangespine1["RACK_NUM"] = str(numero_rack) if spine_num in [1, 3]: variablestochangeleaf1["SP1_HOSTNAME"] = i.get("nome") From 0666edbf388aa860d850b50a4082cce7cbf8374b Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Tue, 23 Jul 2024 17:40:30 -0300 Subject: [PATCH 31/89] fixed variable --- networkapi/api_rack/autoprovision.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/networkapi/api_rack/autoprovision.py b/networkapi/api_rack/autoprovision.py index 02652ab4..3812706e 100644 --- a/networkapi/api_rack/autoprovision.py +++ b/networkapi/api_rack/autoprovision.py @@ -511,8 +511,8 @@ def autoprovision_splf(rack, equips): variablestochangespine1["ASLEAF"] = str(ASLEAF[numero_rack][0]) ### To pop Berrini - variablestochangespine1["IPNEIGHLEAFIPV4_2"] = str(IPLEAFipv4[numero_rack][spine_num]) - variablestochangespine1["IPNEIGHLEAFIPV6_2"] = str(IPLEAFipv6[numero_rack][spine_num]) + variablestochangespine1["IPNEIGHLEAF2IPV4"] = str(IPLEAFipv4[numero_rack][spine_num]) + variablestochangespine1["IPNEIGHLEAF2IPV6"] = str(IPLEAFipv6[numero_rack][spine_num]) variablestochangespine1["IPNEIGHLEAFIPV4"] = str(IPLEAFipv4[numero_rack][spine_num-1]) From 056a899ed12b5f77de1a71e151168714876363ef Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Tue, 23 Jul 2024 17:53:09 -0300 Subject: [PATCH 32/89] another variable --- networkapi/api_rack/provision.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/networkapi/api_rack/provision.py b/networkapi/api_rack/provision.py index d92399fe..8d5e8c40 100644 --- a/networkapi/api_rack/provision.py +++ b/networkapi/api_rack/provision.py @@ -409,6 +409,11 @@ def spine_provision(self, rack, equips): variablestochangespine1["VLANBORDACACHOSLEAF"] = str(vlanBOCA[spine_num - 1]) variablestochangespine1["VLANBORDACACHOSB"] = str(vlanBOCAB[spine_num - 1]) variablestochangespine1["ASLEAF"] = str(ASLEAF[numero_rack][0]) + + ### TO BERRINI + variablestochangespine1["IPNEIGHLEAF2IPV4"] = str(IPLEAFipv4[numero_rack][spine_num]) + variablestochangespine1["IPNEIGHLEAF2IPV6"] = str(IPLEAFipv6[numero_rack][spine_num]) + variablestochangespine1["IPNEIGHLEAFIPV4"] = str(IPLEAFipv4[numero_rack][spine_num - 1]) variablestochangespine1["IPNEIGHLEAFIPV6"] = str(IPLEAFipv6[numero_rack][spine_num - 1]) From 44556906c6def02af4b08f48126fd59ce2dd3db2 Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Tue, 23 Jul 2024 18:06:55 -0300 Subject: [PATCH 33/89] testing --- networkapi/api_rack/provision.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/networkapi/api_rack/provision.py b/networkapi/api_rack/provision.py index 8d5e8c40..a0ef9b02 100644 --- a/networkapi/api_rack/provision.py +++ b/networkapi/api_rack/provision.py @@ -411,8 +411,12 @@ def spine_provision(self, rack, equips): variablestochangespine1["ASLEAF"] = str(ASLEAF[numero_rack][0]) ### TO BERRINI - variablestochangespine1["IPNEIGHLEAF2IPV4"] = str(IPLEAFipv4[numero_rack][spine_num]) - variablestochangespine1["IPNEIGHLEAF2IPV6"] = str(IPLEAFipv6[numero_rack][spine_num]) + if spine_num == 1: + variablestochangespine1["IPNEIGHLEAF2IPV4"] = str(IPLEAFipv4[numero_rack][spine_num]) + variablestochangespine1["IPNEIGHLEAF2IPV6"] = str(IPLEAFipv6[numero_rack][spine_num]) + elif spine_num == 2: + variablestochangespine1["IPNEIGHLEAF2IPV4"] = str(IPLEAFipv4[numero_rack][spine_num - 2]) + variablestochangespine1["IPNEIGHLEAF2IPV6"] = str(IPLEAFipv6[numero_rack][spine_num - 2]) variablestochangespine1["IPNEIGHLEAFIPV4"] = str(IPLEAFipv4[numero_rack][spine_num - 1]) variablestochangespine1["IPNEIGHLEAFIPV6"] = str(IPLEAFipv6[numero_rack][spine_num - 1]) From 28a6e0b95ab187f28037aeb41ccec647b4193dc2 Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Tue, 23 Jul 2024 18:28:46 -0300 Subject: [PATCH 34/89] two leafs per spine --- networkapi/api_rack/provision.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/networkapi/api_rack/provision.py b/networkapi/api_rack/provision.py index a0ef9b02..40b3a739 100644 --- a/networkapi/api_rack/provision.py +++ b/networkapi/api_rack/provision.py @@ -412,9 +412,23 @@ def spine_provision(self, rack, equips): ### TO BERRINI if spine_num == 1: + variablestochangespine1["VLANBORDA2LEAF"] = str(vlanBO[spine_num]) + variablestochangespine1["VLANBORDA2CACHOSLEAF"] = str(vlanBOCA[spine_num]) + variablestochangespine1["VLANBORDA2CACHOSB"] = str(vlanBOCAB[spine_num]) + variablestochangespine1["VLANFE2LEAF"] = str(vlanFE[spine_num]) + variablestochangespine1["IPSPI2NEIPV6"] = str(IPSPINEipv6[numero_rack][spine_num]) + variablestochangespine1["IPSPI2NEIPV4"] = str(IPSPINEipv4[numero_rack][spine_num]) + variablestochangespine1["VLANBE2LEAF"] = str(vlanBE[spine_num]) variablestochangespine1["IPNEIGHLEAF2IPV4"] = str(IPLEAFipv4[numero_rack][spine_num]) variablestochangespine1["IPNEIGHLEAF2IPV6"] = str(IPLEAFipv6[numero_rack][spine_num]) elif spine_num == 2: + variablestochangespine1["VLANBORDA2LEAF"] = str(vlanBO[spine_num - 2]) + variablestochangespine1["VLANBORDA2CACHOSLEAF"] = str(vlanBOCA[spine_num - 2]) + variablestochangespine1["VLANBORDA2CACHOSB"] = str(vlanBOCAB[spine_num - 2]) + variablestochangespine1["VLANFE2LEAF"] = str(vlanFE[spine_num - 2]) + variablestochangespine1["IPSPI2NEIPV6"] = str(IPSPINEipv6[numero_rack][spine_num - 2]) + variablestochangespine1["IPSPI2NEIPV4"] = str(IPSPINEipv4[numero_rack][spine_num - 2]) + variablestochangespine1["VLANBE2LEAF"] = str(vlanBE[spine_num - 2]) variablestochangespine1["IPNEIGHLEAF2IPV4"] = str(IPLEAFipv4[numero_rack][spine_num - 2]) variablestochangespine1["IPNEIGHLEAF2IPV6"] = str(IPLEAFipv6[numero_rack][spine_num - 2]) From b755e4efc45b2869d4805c44ee0aade90a2ffd22 Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Wed, 24 Jul 2024 10:02:45 -0300 Subject: [PATCH 35/89] logger test --- networkapi/api_rack/provision.py | 1 + 1 file changed, 1 insertion(+) diff --git a/networkapi/api_rack/provision.py b/networkapi/api_rack/provision.py index 40b3a739..f0e78e68 100644 --- a/networkapi/api_rack/provision.py +++ b/networkapi/api_rack/provision.py @@ -316,6 +316,7 @@ def spine_provision(self, rack, equips): log.debug(zip(equips_sorted[:2], [0, 2], [0, 1])) ASLEAF[numero_rack].append(BASE_AS_LFS + numero_rack) + log.debug(IPLEAFipv4) for equip, spn, j in zip(equips_sorted[:2], [0, 2], [0, 1]): variablestochangeleaf1["IPLEAFSP1IPV4"] = str(IPLEAFipv4[numero_rack][spn]) From f347118b30ebec89522093f4d525353e8b79af79 Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Wed, 24 Jul 2024 10:41:21 -0300 Subject: [PATCH 36/89] changed algorithm to get all 4 ips --- networkapi/api_rack/provision.py | 47 ++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/networkapi/api_rack/provision.py b/networkapi/api_rack/provision.py index f0e78e68..ebb228b5 100644 --- a/networkapi/api_rack/provision.py +++ b/networkapi/api_rack/provision.py @@ -316,7 +316,6 @@ def spine_provision(self, rack, equips): log.debug(zip(equips_sorted[:2], [0, 2], [0, 1])) ASLEAF[numero_rack].append(BASE_AS_LFS + numero_rack) - log.debug(IPLEAFipv4) for equip, spn, j in zip(equips_sorted[:2], [0, 2], [0, 1]): variablestochangeleaf1["IPLEAFSP1IPV4"] = str(IPLEAFipv4[numero_rack][spn]) @@ -417,21 +416,51 @@ def spine_provision(self, rack, equips): variablestochangespine1["VLANBORDA2CACHOSLEAF"] = str(vlanBOCA[spine_num]) variablestochangespine1["VLANBORDA2CACHOSB"] = str(vlanBOCAB[spine_num]) variablestochangespine1["VLANFE2LEAF"] = str(vlanFE[spine_num]) - variablestochangespine1["IPSPI2NEIPV6"] = str(IPSPINEipv6[numero_rack][spine_num]) - variablestochangespine1["IPSPI2NEIPV4"] = str(IPSPINEipv4[numero_rack][spine_num]) + + counter = 1 + for ipv6 in IPSPINEipv6[numero_rack]: + variablestochangespine1[f'IPSPINE{counter}IPV6'] = ipv6 + variablestochangespine1[f"IPNEIGHLEAF{counter}IPV6"] = str(IPLEAFipv6[numero_rack][counter -1]) + + counter += 1 + + counter = 1 + for ipv4 in IPSPINEipv4[numero_rack]: + variablestochangespine1[f'IPSPINE{counter}IPV4'] = str(ipv6) + variablestochangespine1[f"IPNEIGHLEAF{counter}IPV4"] = str(IPLEAFipv4[numero_rack][counter -1]) + + counter += 1 + + # variablestochangespine1["IPSPI2NEIPV6"] = str(IPSPINEipv6[numero_rack][spine_num]) + # variablestochangespine1["IPSPI2NEIPV4"] = str(IPSPINEipv4[numero_rack][spine_num]) variablestochangespine1["VLANBE2LEAF"] = str(vlanBE[spine_num]) - variablestochangespine1["IPNEIGHLEAF2IPV4"] = str(IPLEAFipv4[numero_rack][spine_num]) - variablestochangespine1["IPNEIGHLEAF2IPV6"] = str(IPLEAFipv6[numero_rack][spine_num]) + # variablestochangespine1["IPNEIGHLEAF2IPV4"] = str(IPLEAFipv4[numero_rack][spine_num]) + # variablestochangespine1["IPNEIGHLEAF2IPV6"] = str(IPLEAFipv6[numero_rack][spine_num]) elif spine_num == 2: variablestochangespine1["VLANBORDA2LEAF"] = str(vlanBO[spine_num - 2]) variablestochangespine1["VLANBORDA2CACHOSLEAF"] = str(vlanBOCA[spine_num - 2]) variablestochangespine1["VLANBORDA2CACHOSB"] = str(vlanBOCAB[spine_num - 2]) variablestochangespine1["VLANFE2LEAF"] = str(vlanFE[spine_num - 2]) - variablestochangespine1["IPSPI2NEIPV6"] = str(IPSPINEipv6[numero_rack][spine_num - 2]) - variablestochangespine1["IPSPI2NEIPV4"] = str(IPSPINEipv4[numero_rack][spine_num - 2]) + counter = 1 + for ipv6 in IPSPINEipv6[numero_rack]: + variablestochangespine1[f'IPSPINE{counter}IPV6'] = str(ipv6) + variablestochangespine1[f"IPNEIGHLEAF{counter}IPV6"] = str(IPLEAFipv6[numero_rack][counter - 1]) + counter += 1 + + counter = 1 + for ipv4 in IPSPINEipv4[numero_rack]: + variablestochangespine1[f'IPSPINE{counter}IPV4'] = str(ipv6) + variablestochangespine1[f"IPNEIGHLEAF{counter}IPV4"] = str(IPLEAFipv4[numero_rack][counter - 1]) + + + counter += 1 + # variablestochangespine1["IPSPI2NEIPV6"] = str(IPSPINEipv6[numero_rack][spine_num - 2]) + # variablestochangespine1["IPSPI2NEIPV4"] = str(IPSPINEipv4[numero_rack][spine_num - 2]) variablestochangespine1["VLANBE2LEAF"] = str(vlanBE[spine_num - 2]) - variablestochangespine1["IPNEIGHLEAF2IPV4"] = str(IPLEAFipv4[numero_rack][spine_num - 2]) - variablestochangespine1["IPNEIGHLEAF2IPV6"] = str(IPLEAFipv6[numero_rack][spine_num - 2]) + # variablestochangespine1["IPNEIGHLEAF2IPV4"] = str(IPLEAFipv4[numero_rack][spine_num - 2]) + # variablestochangespine1["IPNEIGHLEAF2IPV6"] = str(IPLEAFipv6[numero_rack][spine_num - 2]) + + #### END to Berrini Block ##### variablestochangespine1["IPNEIGHLEAFIPV4"] = str(IPLEAFipv4[numero_rack][spine_num - 1]) variablestochangespine1["IPNEIGHLEAFIPV6"] = str(IPLEAFipv6[numero_rack][spine_num - 1]) From ba9fda48dcf448cbc03078bc0430350edc4f46ad Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Wed, 24 Jul 2024 11:00:48 -0300 Subject: [PATCH 37/89] format fix --- networkapi/api_rack/provision.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/networkapi/api_rack/provision.py b/networkapi/api_rack/provision.py index ebb228b5..e4d6d634 100644 --- a/networkapi/api_rack/provision.py +++ b/networkapi/api_rack/provision.py @@ -419,15 +419,15 @@ def spine_provision(self, rack, equips): counter = 1 for ipv6 in IPSPINEipv6[numero_rack]: - variablestochangespine1[f'IPSPINE{counter}IPV6'] = ipv6 - variablestochangespine1[f"IPNEIGHLEAF{counter}IPV6"] = str(IPLEAFipv6[numero_rack][counter -1]) + variablestochangespine1["IPSPINE{}IPV6".format(counter)] = str(ipv6) + variablestochangespine1["IPNEIGHLEAF{}IPV6".format(counter)] = str(IPLEAFipv6[numero_rack][counter -1]) counter += 1 counter = 1 for ipv4 in IPSPINEipv4[numero_rack]: - variablestochangespine1[f'IPSPINE{counter}IPV4'] = str(ipv6) - variablestochangespine1[f"IPNEIGHLEAF{counter}IPV4"] = str(IPLEAFipv4[numero_rack][counter -1]) + variablestochangespine1["IPSPINE{}IPV4".format(counter)] = str(ipv6) + variablestochangespine1["IPNEIGHLEAF{}IPV4".format(counter)] = str(IPLEAFipv4[numero_rack][counter -1]) counter += 1 @@ -443,14 +443,14 @@ def spine_provision(self, rack, equips): variablestochangespine1["VLANFE2LEAF"] = str(vlanFE[spine_num - 2]) counter = 1 for ipv6 in IPSPINEipv6[numero_rack]: - variablestochangespine1[f'IPSPINE{counter}IPV6'] = str(ipv6) - variablestochangespine1[f"IPNEIGHLEAF{counter}IPV6"] = str(IPLEAFipv6[numero_rack][counter - 1]) + variablestochangespine1["IPSPINE{}IPV6".format(counter)] = str(ipv6) + variablestochangespine1["IPNEIGHLEAF{}IPV6".format(counter)] = str(IPLEAFipv6[numero_rack][counter - 1]) counter += 1 counter = 1 for ipv4 in IPSPINEipv4[numero_rack]: - variablestochangespine1[f'IPSPINE{counter}IPV4'] = str(ipv6) - variablestochangespine1[f"IPNEIGHLEAF{counter}IPV4"] = str(IPLEAFipv4[numero_rack][counter - 1]) + variablestochangespine1["IPSPINE{}IPV4".format(counter)] = str(ipv6) + variablestochangespine1["IPNEIGHLEAF{}IPV4".format(counter)] = str(IPLEAFipv4[numero_rack][counter - 1]) counter += 1 From 16fe748d3f6732d37601bd27306ceef58961b9e8 Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Wed, 24 Jul 2024 12:06:30 -0300 Subject: [PATCH 38/89] testing variales --- networkapi/api_rack/provision.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/networkapi/api_rack/provision.py b/networkapi/api_rack/provision.py index e4d6d634..b859c52a 100644 --- a/networkapi/api_rack/provision.py +++ b/networkapi/api_rack/provision.py @@ -426,7 +426,7 @@ def spine_provision(self, rack, equips): counter = 1 for ipv4 in IPSPINEipv4[numero_rack]: - variablestochangespine1["IPSPINE{}IPV4".format(counter)] = str(ipv6) + variablestochangespine1["IPSPINE{}IPV4".format(counter)] = str(ipv4) variablestochangespine1["IPNEIGHLEAF{}IPV4".format(counter)] = str(IPLEAFipv4[numero_rack][counter -1]) counter += 1 @@ -441,16 +441,18 @@ def spine_provision(self, rack, equips): variablestochangespine1["VLANBORDA2CACHOSLEAF"] = str(vlanBOCA[spine_num - 2]) variablestochangespine1["VLANBORDA2CACHOSB"] = str(vlanBOCAB[spine_num - 2]) variablestochangespine1["VLANFE2LEAF"] = str(vlanFE[spine_num - 2]) - counter = 1 + counter = 0 for ipv6 in IPSPINEipv6[numero_rack]: - variablestochangespine1["IPSPINE{}IPV6".format(counter)] = str(ipv6) - variablestochangespine1["IPNEIGHLEAF{}IPV6".format(counter)] = str(IPLEAFipv6[numero_rack][counter - 1]) + if spine_num + counter < len(IPLEAFipv6[numero_rack]): + variablestochangespine1["IPSPINE{}IPV6".format(counter + 1)] = str(IPSPINEipv6[numero_rack][counter + spine_num]) + variablestochangespine1["IPNEIGHLEAF{}IPV6".format(counter + 1)] = str(IPLEAFipv6[numero_rack][counter + spine_num]) counter += 1 - counter = 1 + counter = 0 for ipv4 in IPSPINEipv4[numero_rack]: - variablestochangespine1["IPSPINE{}IPV4".format(counter)] = str(ipv6) - variablestochangespine1["IPNEIGHLEAF{}IPV4".format(counter)] = str(IPLEAFipv4[numero_rack][counter - 1]) + if spine_num + counter < len(IPLEAFipv4[numero_rack]): + variablestochangespine1["IPSPINE{}IPV4".format(counter + 1)] = str(IPSPINEipv4[numero_rack][counter + spine_num]) + variablestochangespine1["IPNEIGHLEAF{}IPV4".format(counter + 1)] = str(IPLEAFipv4[numero_rack][counter + spine_num]) counter += 1 From 95a8b54ca447b788995a2b35e1434d4760c17405 Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Wed, 24 Jul 2024 12:22:02 -0300 Subject: [PATCH 39/89] logger --- networkapi/api_rack/provision.py | 1 + 1 file changed, 1 insertion(+) diff --git a/networkapi/api_rack/provision.py b/networkapi/api_rack/provision.py index b859c52a..bb1a58d8 100644 --- a/networkapi/api_rack/provision.py +++ b/networkapi/api_rack/provision.py @@ -442,6 +442,7 @@ def spine_provision(self, rack, equips): variablestochangespine1["VLANBORDA2CACHOSB"] = str(vlanBOCAB[spine_num - 2]) variablestochangespine1["VLANFE2LEAF"] = str(vlanFE[spine_num - 2]) counter = 0 + log.debug(IPSPINEipv6[numero_rack]) for ipv6 in IPSPINEipv6[numero_rack]: if spine_num + counter < len(IPLEAFipv6[numero_rack]): variablestochangespine1["IPSPINE{}IPV6".format(counter + 1)] = str(IPSPINEipv6[numero_rack][counter + spine_num]) From 254f7cf96b808a6e6e62db09a3fdaaeb3bea733d Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Wed, 24 Jul 2024 14:55:02 -0300 Subject: [PATCH 40/89] teste --- networkapi/api_rack/provision.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/networkapi/api_rack/provision.py b/networkapi/api_rack/provision.py index bb1a58d8..1090d42f 100644 --- a/networkapi/api_rack/provision.py +++ b/networkapi/api_rack/provision.py @@ -396,6 +396,8 @@ def spine_provision(self, rack, equips): variablestochangeleaf1["LFNEIGH_IP_MGMT"] = i.get("ip_mngt") elif i.get("nome")[:3] == self.spine_prefix: spine_num = int(i.get("nome")[-1]) + log.debug(spn) + log.debug(spine_num) variablestochangespine1["ASSPINE"] = str(BASE_AS_SPN + spine_num - 1) variablestochangespine1["INTERFACE"] = i.get("interface") variablestochangespine1["LEAFNAME"] = equip.get("nome") From 93f0a15da48475f47c0314570fe11387050097ae Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Wed, 24 Jul 2024 16:22:24 -0300 Subject: [PATCH 41/89] changed variables --- networkapi/api_rack/provision.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/networkapi/api_rack/provision.py b/networkapi/api_rack/provision.py index 1090d42f..6c4ed67d 100644 --- a/networkapi/api_rack/provision.py +++ b/networkapi/api_rack/provision.py @@ -335,6 +335,19 @@ def spine_provision(self, rack, equips): variablestochangeleaf1["VLANBORDACACHOSLEAFSP2"] = str(vlanBOCA[spn + 1]) variablestochangeleaf1["VLANBORDACACHOSBLEAFSP1"] = str(vlanBOCAB[spn]) variablestochangeleaf1["VLANBORDACACHOSBLEAFSP2"] = str(vlanBOCAB[spn + 1]) + + ### To pop Berrini + variablestochangeleaf1["BERVLANBELEAFSP1"] = str(vlanBE[0]) + variablestochangeleaf1["BERVLANBELEAFSP2"] = str(vlanBE[1]) + variablestochangeleaf1["BERVLANFELEAFSP1"] = str(vlanFE[0]) + variablestochangeleaf1["BERVLANFELEAFSP2"] = str(vlanFE[1]) + variablestochangeleaf1["BERVLANBORDALEAFSP1"] = str(vlanBO[0]) + variablestochangeleaf1["BERVLANBORDALEAFSP2"] = str(vlanBO[1]) + variablestochangeleaf1["BERVLANBORDACACHOSLEAFSP1"] = str(vlanBOCA[0]) + variablestochangeleaf1["BERVLANBORDACACHOSLEAFSP2"] = str(vlanBOCA[1]) + variablestochangeleaf1["BERVLANBORDACACHOSBLEAFSP1"] = str(vlanBOCAB[0]) + variablestochangeleaf1["BERVLANBORDACACHOSBLEAFSP2"] = str(vlanBOCAB[1]) + log.debug("2") variablestochangeleaf1["ASLEAF"] = str(ASLEAF[numero_rack][0]) From 6b61079daeb19cdc41796b56be02fe1ce1556d9a Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Wed, 24 Jul 2024 16:49:38 -0300 Subject: [PATCH 42/89] fix variables --- networkapi/api_rack/provision.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/networkapi/api_rack/provision.py b/networkapi/api_rack/provision.py index 6c4ed67d..7be6f6f0 100644 --- a/networkapi/api_rack/provision.py +++ b/networkapi/api_rack/provision.py @@ -337,16 +337,16 @@ def spine_provision(self, rack, equips): variablestochangeleaf1["VLANBORDACACHOSBLEAFSP2"] = str(vlanBOCAB[spn + 1]) ### To pop Berrini - variablestochangeleaf1["BERVLANBELEAFSP1"] = str(vlanBE[0]) - variablestochangeleaf1["BERVLANBELEAFSP2"] = str(vlanBE[1]) - variablestochangeleaf1["BERVLANFELEAFSP1"] = str(vlanFE[0]) - variablestochangeleaf1["BERVLANFELEAFSP2"] = str(vlanFE[1]) - variablestochangeleaf1["BERVLANBORDALEAFSP1"] = str(vlanBO[0]) - variablestochangeleaf1["BERVLANBORDALEAFSP2"] = str(vlanBO[1]) - variablestochangeleaf1["BERVLANBORDACACHOSLEAFSP1"] = str(vlanBOCA[0]) - variablestochangeleaf1["BERVLANBORDACACHOSLEAFSP2"] = str(vlanBOCA[1]) - variablestochangeleaf1["BERVLANBORDACACHOSBLEAFSP1"] = str(vlanBOCAB[0]) - variablestochangeleaf1["BERVLANBORDACACHOSBLEAFSP2"] = str(vlanBOCAB[1]) + variablestochangeleaf1["VLANBERBELEAFSP1"] = str(vlanBE[0]) + variablestochangeleaf1["VLANBERBELEAFSP2"] = str(vlanBE[1]) + variablestochangeleaf1["VLANBERFELEAFSP1"] = str(vlanFE[0]) + variablestochangeleaf1["VLANBERFELEAFSP2"] = str(vlanFE[1]) + variablestochangeleaf1["VLANBERBORDALEAFSP1"] = str(vlanBO[0]) + variablestochangeleaf1["VLANBERBORDALEAFSP2"] = str(vlanBO[1]) + variablestochangeleaf1["VLANBERBORDACACHOSLEAFSP1"] = str(vlanBOCA[0]) + variablestochangeleaf1["VLANBERBORDACACHOSLEAFSP2"] = str(vlanBOCA[1]) + variablestochangeleaf1["VLANBERBORDACACHOSBLEAFSP1"] = str(vlanBOCAB[0]) + variablestochangeleaf1["VLANBERBORDACACHOSBLEAFSP2"] = str(vlanBOCAB[1]) log.debug("2") variablestochangeleaf1["ASLEAF"] = str(ASLEAF[numero_rack][0]) From 947d28c5091f2965f4451809c0044f32c1e9fa97 Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Wed, 24 Jul 2024 17:29:31 -0300 Subject: [PATCH 43/89] added variables to desciprion on spine --- networkapi/api_rack/provision.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/networkapi/api_rack/provision.py b/networkapi/api_rack/provision.py index 7be6f6f0..52490bbf 100644 --- a/networkapi/api_rack/provision.py +++ b/networkapi/api_rack/provision.py @@ -478,6 +478,10 @@ def spine_provision(self, rack, equips): # variablestochangespine1["IPNEIGHLEAF2IPV4"] = str(IPLEAFipv4[numero_rack][spine_num - 2]) # variablestochangespine1["IPNEIGHLEAF2IPV6"] = str(IPLEAFipv6[numero_rack][spine_num - 2]) + e_counter = 1 + for e in equips_sorted[:2]: + variablestochangespine1["DESCRIPTION{}INTERFACE".format(e_counter)] = e.get("name") + e_counter += 1 #### END to Berrini Block ##### variablestochangespine1["IPNEIGHLEAFIPV4"] = str(IPLEAFipv4[numero_rack][spine_num - 1]) From 0f51ad3a80311d6f6286c75b207b001d3129f07b Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Wed, 24 Jul 2024 17:47:06 -0300 Subject: [PATCH 44/89] fix --- networkapi/api_rack/provision.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/networkapi/api_rack/provision.py b/networkapi/api_rack/provision.py index 52490bbf..a0690ae1 100644 --- a/networkapi/api_rack/provision.py +++ b/networkapi/api_rack/provision.py @@ -479,8 +479,8 @@ def spine_provision(self, rack, equips): # variablestochangespine1["IPNEIGHLEAF2IPV6"] = str(IPLEAFipv6[numero_rack][spine_num - 2]) e_counter = 1 - for e in equips_sorted[:2]: - variablestochangespine1["DESCRIPTION{}INTERFACE".format(e_counter)] = e.get("name") + for e, s, y in zip(equips_sorted[:2], [0, 2], [0, 1]): + variablestochangespine1["DESCRIPTION{}INTERFACE".format(e_counter)] = e.get("nome") e_counter += 1 #### END to Berrini Block ##### From 2aaece4ac2ef00dc4dd03bc9440ecef7ed6fe99c Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Wed, 24 Jul 2024 17:53:47 -0300 Subject: [PATCH 45/89] fix variable --- networkapi/api_rack/provision.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/networkapi/api_rack/provision.py b/networkapi/api_rack/provision.py index a0690ae1..558e6c7c 100644 --- a/networkapi/api_rack/provision.py +++ b/networkapi/api_rack/provision.py @@ -480,7 +480,7 @@ def spine_provision(self, rack, equips): e_counter = 1 for e, s, y in zip(equips_sorted[:2], [0, 2], [0, 1]): - variablestochangespine1["DESCRIPTION{}INTERFACE".format(e_counter)] = e.get("nome") + variablestochangespine1["DESCRIPTION{}CONNECT".format(e_counter)] = e.get("nome") e_counter += 1 #### END to Berrini Block ##### From 72e268d75b78addc7cefb47d829abc8a9103244f Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Wed, 24 Jul 2024 18:01:54 -0300 Subject: [PATCH 46/89] testing --- networkapi/api_rack/provision.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/networkapi/api_rack/provision.py b/networkapi/api_rack/provision.py index 558e6c7c..11a79636 100644 --- a/networkapi/api_rack/provision.py +++ b/networkapi/api_rack/provision.py @@ -478,10 +478,12 @@ def spine_provision(self, rack, equips): # variablestochangespine1["IPNEIGHLEAF2IPV4"] = str(IPLEAFipv4[numero_rack][spine_num - 2]) # variablestochangespine1["IPNEIGHLEAF2IPV6"] = str(IPLEAFipv6[numero_rack][spine_num - 2]) - e_counter = 1 - for e, s, y in zip(equips_sorted[:2], [0, 2], [0, 1]): - variablestochangespine1["DESCRIPTION{}CONNECT".format(e_counter)] = e.get("nome") - e_counter += 1 + # e_counter = 1 + # for e in equips_sorted[:2]: + # # "DESCRIPTION{}CONNECT" + variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[0].get("nome") + variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[0].get("nome") + # e_counter += 1 #### END to Berrini Block ##### variablestochangespine1["IPNEIGHLEAFIPV4"] = str(IPLEAFipv4[numero_rack][spine_num - 1]) From 362162ab2f21037064132f9422d00b672dab80ee Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Wed, 24 Jul 2024 18:02:34 -0300 Subject: [PATCH 47/89] testing --- networkapi/api_rack/provision.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/networkapi/api_rack/provision.py b/networkapi/api_rack/provision.py index 11a79636..5581b2eb 100644 --- a/networkapi/api_rack/provision.py +++ b/networkapi/api_rack/provision.py @@ -482,7 +482,7 @@ def spine_provision(self, rack, equips): # for e in equips_sorted[:2]: # # "DESCRIPTION{}CONNECT" variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[0].get("nome") - variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[0].get("nome") + variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[1].get("nome") # e_counter += 1 #### END to Berrini Block ##### From 6ce17d60fad116c8601a6fc157067a0ce4d3a945 Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Wed, 24 Jul 2024 18:07:46 -0300 Subject: [PATCH 48/89] testing --- networkapi/api_rack/provision.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/networkapi/api_rack/provision.py b/networkapi/api_rack/provision.py index 5581b2eb..a13d2b89 100644 --- a/networkapi/api_rack/provision.py +++ b/networkapi/api_rack/provision.py @@ -481,8 +481,8 @@ def spine_provision(self, rack, equips): # e_counter = 1 # for e in equips_sorted[:2]: # # "DESCRIPTION{}CONNECT" - variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[0].get("nome") - variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[1].get("nome") + variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[0].get("nome") + variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[1].get("nome") # e_counter += 1 #### END to Berrini Block ##### From e1033585d590c04b484fe0e1648b19230cf70d70 Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Thu, 25 Jul 2024 11:16:10 -0300 Subject: [PATCH 49/89] fixed variables --- networkapi/api_rack/provision.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/networkapi/api_rack/provision.py b/networkapi/api_rack/provision.py index a13d2b89..3c873aec 100644 --- a/networkapi/api_rack/provision.py +++ b/networkapi/api_rack/provision.py @@ -427,6 +427,8 @@ def spine_provision(self, rack, equips): ### TO BERRINI if spine_num == 1: + variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[0].get("nome") + variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[1].get("nome") variablestochangespine1["VLANBORDA2LEAF"] = str(vlanBO[spine_num]) variablestochangespine1["VLANBORDA2CACHOSLEAF"] = str(vlanBOCA[spine_num]) variablestochangespine1["VLANBORDA2CACHOSB"] = str(vlanBOCAB[spine_num]) @@ -452,6 +454,8 @@ def spine_provision(self, rack, equips): # variablestochangespine1["IPNEIGHLEAF2IPV4"] = str(IPLEAFipv4[numero_rack][spine_num]) # variablestochangespine1["IPNEIGHLEAF2IPV6"] = str(IPLEAFipv6[numero_rack][spine_num]) elif spine_num == 2: + variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[1].get("nome") + variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[2].get("nome") variablestochangespine1["VLANBORDA2LEAF"] = str(vlanBO[spine_num - 2]) variablestochangespine1["VLANBORDA2CACHOSLEAF"] = str(vlanBOCA[spine_num - 2]) variablestochangespine1["VLANBORDA2CACHOSB"] = str(vlanBOCAB[spine_num - 2]) @@ -481,8 +485,7 @@ def spine_provision(self, rack, equips): # e_counter = 1 # for e in equips_sorted[:2]: # # "DESCRIPTION{}CONNECT" - variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[0].get("nome") - variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[1].get("nome") + # e_counter += 1 #### END to Berrini Block ##### From 6f42dc8a036f40af5261efc23677b7cfbacba2a8 Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Thu, 25 Jul 2024 11:21:06 -0300 Subject: [PATCH 50/89] fixed --- networkapi/api_rack/provision.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/networkapi/api_rack/provision.py b/networkapi/api_rack/provision.py index 3c873aec..e4b46472 100644 --- a/networkapi/api_rack/provision.py +++ b/networkapi/api_rack/provision.py @@ -455,7 +455,7 @@ def spine_provision(self, rack, equips): # variablestochangespine1["IPNEIGHLEAF2IPV6"] = str(IPLEAFipv6[numero_rack][spine_num]) elif spine_num == 2: variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[1].get("nome") - variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[2].get("nome") + variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[0].get("nome") variablestochangespine1["VLANBORDA2LEAF"] = str(vlanBO[spine_num - 2]) variablestochangespine1["VLANBORDA2CACHOSLEAF"] = str(vlanBOCA[spine_num - 2]) variablestochangespine1["VLANBORDA2CACHOSB"] = str(vlanBOCAB[spine_num - 2]) From dffa1c95db6c583843daa22e1101bff7bc500f85 Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Thu, 25 Jul 2024 12:24:07 -0300 Subject: [PATCH 51/89] fixed --- networkapi/api_rack/provision.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/networkapi/api_rack/provision.py b/networkapi/api_rack/provision.py index e4b46472..2b93bd2c 100644 --- a/networkapi/api_rack/provision.py +++ b/networkapi/api_rack/provision.py @@ -427,8 +427,8 @@ def spine_provision(self, rack, equips): ### TO BERRINI if spine_num == 1: - variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[0].get("nome") - variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[1].get("nome") + # variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[0].get("nome") + # variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[1].get("nome") variablestochangespine1["VLANBORDA2LEAF"] = str(vlanBO[spine_num]) variablestochangespine1["VLANBORDA2CACHOSLEAF"] = str(vlanBOCA[spine_num]) variablestochangespine1["VLANBORDA2CACHOSB"] = str(vlanBOCAB[spine_num]) @@ -454,8 +454,6 @@ def spine_provision(self, rack, equips): # variablestochangespine1["IPNEIGHLEAF2IPV4"] = str(IPLEAFipv4[numero_rack][spine_num]) # variablestochangespine1["IPNEIGHLEAF2IPV6"] = str(IPLEAFipv6[numero_rack][spine_num]) elif spine_num == 2: - variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[1].get("nome") - variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[0].get("nome") variablestochangespine1["VLANBORDA2LEAF"] = str(vlanBO[spine_num - 2]) variablestochangespine1["VLANBORDA2CACHOSLEAF"] = str(vlanBOCA[spine_num - 2]) variablestochangespine1["VLANBORDA2CACHOSB"] = str(vlanBOCAB[spine_num - 2]) @@ -487,6 +485,8 @@ def spine_provision(self, rack, equips): # # "DESCRIPTION{}CONNECT" # e_counter += 1 + variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[1].get("nome") + variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[0].get("nome") #### END to Berrini Block ##### variablestochangespine1["IPNEIGHLEAFIPV4"] = str(IPLEAFipv4[numero_rack][spine_num - 1]) From 7a2cab3eb09e376d941c079885c6048d6a409174 Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Thu, 25 Jul 2024 14:34:53 -0300 Subject: [PATCH 52/89] multiple interfaces --- networkapi/api_rack/provision.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/networkapi/api_rack/provision.py b/networkapi/api_rack/provision.py index 2b93bd2c..ea8854ab 100644 --- a/networkapi/api_rack/provision.py +++ b/networkapi/api_rack/provision.py @@ -403,6 +403,7 @@ def spine_provision(self, rack, equips): variablestochangeleaf1["OWN_IP_MGMT"] = equip.get("ip_mngt") variablestochangeleaf1["LF_HOSTNAME"] = equip.get("nome") log.debug("5") + interface_counter = 1 for i in equip.get("interfaces"): if i.get("nome")[:3] == self.leaf_prefix: variablestochangeleaf1["LFNEIGH_HOSTNAME"] = i.get("nome") @@ -429,6 +430,7 @@ def spine_provision(self, rack, equips): if spine_num == 1: # variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[0].get("nome") # variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[1].get("nome") + variablestochangespine1["VLANBORDA2LEAF"] = str(vlanBO[spine_num]) variablestochangespine1["VLANBORDA2CACHOSLEAF"] = str(vlanBOCA[spine_num]) variablestochangespine1["VLANBORDA2CACHOSB"] = str(vlanBOCAB[spine_num]) @@ -485,6 +487,9 @@ def spine_provision(self, rack, equips): # # "DESCRIPTION{}CONNECT" # e_counter += 1 + variablestochangespine1["SINGLE1{}INT".format(interface_counter)] = i.get("interface") + variablestochangespine1["SINGLE2{}INT".format(interface_counter)] = i.get("interface") + interface_counter += 1 variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[1].get("nome") variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[0].get("nome") #### END to Berrini Block ##### From 6141afc8136bacd0bb1b80ad6044a2bad5fda895 Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Thu, 25 Jul 2024 14:56:18 -0300 Subject: [PATCH 53/89] testing --- networkapi/api_rack/provision.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/networkapi/api_rack/provision.py b/networkapi/api_rack/provision.py index ea8854ab..98f7fa74 100644 --- a/networkapi/api_rack/provision.py +++ b/networkapi/api_rack/provision.py @@ -403,7 +403,6 @@ def spine_provision(self, rack, equips): variablestochangeleaf1["OWN_IP_MGMT"] = equip.get("ip_mngt") variablestochangeleaf1["LF_HOSTNAME"] = equip.get("nome") log.debug("5") - interface_counter = 1 for i in equip.get("interfaces"): if i.get("nome")[:3] == self.leaf_prefix: variablestochangeleaf1["LFNEIGH_HOSTNAME"] = i.get("nome") @@ -487,9 +486,11 @@ def spine_provision(self, rack, equips): # # "DESCRIPTION{}CONNECT" # e_counter += 1 - variablestochangespine1["SINGLE1{}INT".format(interface_counter)] = i.get("interface") - variablestochangespine1["SINGLE2{}INT".format(interface_counter)] = i.get("interface") - interface_counter += 1 + interface_counter = 1 + for iface in equip.get("interfaces"): + variablestochangespine1["SINGLE1{}INT".format(interface_counter)] = iface.get("interface") + variablestochangespine1["SINGLE2{}INT".format(interface_counter)] = iface.get("interface") + interface_counter += 1 variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[1].get("nome") variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[0].get("nome") #### END to Berrini Block ##### From 902cece33b44515c083f32483aabf6d2902b6f71 Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Thu, 25 Jul 2024 15:26:15 -0300 Subject: [PATCH 54/89] fix variable --- networkapi/api_rack/provision.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/networkapi/api_rack/provision.py b/networkapi/api_rack/provision.py index 98f7fa74..711474aa 100644 --- a/networkapi/api_rack/provision.py +++ b/networkapi/api_rack/provision.py @@ -429,6 +429,13 @@ def spine_provision(self, rack, equips): if spine_num == 1: # variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[0].get("nome") # variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[1].get("nome") + for lf in equips_sorted[:2]: + interface_counter = 1 + for iface in lf.get("interfaces"): + if iface.get("nome")[:3] == self.spine_prefix and iface.get("nome")[-1] == 1: + variablestochangespine1["SINGLE1{}INT".format(interface_counter)] = iface.get("interface") + # variablestochangespine1["SINGLE2{}INT".format(interface_counter)] = iface.get("interface") + interface_counter += 1 variablestochangespine1["VLANBORDA2LEAF"] = str(vlanBO[spine_num]) variablestochangespine1["VLANBORDA2CACHOSLEAF"] = str(vlanBOCA[spine_num]) @@ -455,6 +462,13 @@ def spine_provision(self, rack, equips): # variablestochangespine1["IPNEIGHLEAF2IPV4"] = str(IPLEAFipv4[numero_rack][spine_num]) # variablestochangespine1["IPNEIGHLEAF2IPV6"] = str(IPLEAFipv6[numero_rack][spine_num]) elif spine_num == 2: + for lf in equips_sorted[:2]: + interface_counter = 1 + for iface in lf.get("interfaces"): + if iface.get("nome")[:3] == self.spine_prefix and iface.get("nome")[-1] == 2: + variablestochangespine1["SINGLE2{}INT".format(interface_counter)] = iface.get("interface") + # variablestochangespine1["SINGLE2{}INT".format(interface_counter)] = iface.get("interface") + interface_counter += 1 variablestochangespine1["VLANBORDA2LEAF"] = str(vlanBO[spine_num - 2]) variablestochangespine1["VLANBORDA2CACHOSLEAF"] = str(vlanBOCA[spine_num - 2]) variablestochangespine1["VLANBORDA2CACHOSB"] = str(vlanBOCAB[spine_num - 2]) @@ -486,11 +500,7 @@ def spine_provision(self, rack, equips): # # "DESCRIPTION{}CONNECT" # e_counter += 1 - interface_counter = 1 - for iface in equip.get("interfaces"): - variablestochangespine1["SINGLE1{}INT".format(interface_counter)] = iface.get("interface") - variablestochangespine1["SINGLE2{}INT".format(interface_counter)] = iface.get("interface") - interface_counter += 1 + variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[1].get("nome") variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[0].get("nome") #### END to Berrini Block ##### From 31797675268c7d3b5eee563639b9dc7cb232c575 Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Thu, 25 Jul 2024 15:38:55 -0300 Subject: [PATCH 55/89] changed variables local --- networkapi/api_rack/provision.py | 39 ++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/networkapi/api_rack/provision.py b/networkapi/api_rack/provision.py index 711474aa..7a1d661f 100644 --- a/networkapi/api_rack/provision.py +++ b/networkapi/api_rack/provision.py @@ -429,13 +429,13 @@ def spine_provision(self, rack, equips): if spine_num == 1: # variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[0].get("nome") # variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[1].get("nome") - for lf in equips_sorted[:2]: - interface_counter = 1 - for iface in lf.get("interfaces"): - if iface.get("nome")[:3] == self.spine_prefix and iface.get("nome")[-1] == 1: - variablestochangespine1["SINGLE1{}INT".format(interface_counter)] = iface.get("interface") - # variablestochangespine1["SINGLE2{}INT".format(interface_counter)] = iface.get("interface") - interface_counter += 1 + # interface_counter = 1 + # for lf in equips_sorted[:2]: + # for iface in lf.get("interfaces"): + # if iface.get("nome")[:3] == self.spine_prefix and iface.get("nome")[-1] == 1: + # variablestochangespine1["SINGLE1{}INT".format(interface_counter)] = iface.get("interface") + # # variablestochangespine1["SINGLE2{}INT".format(interface_counter)] = iface.get("interface") + # interface_counter += 1 variablestochangespine1["VLANBORDA2LEAF"] = str(vlanBO[spine_num]) variablestochangespine1["VLANBORDA2CACHOSLEAF"] = str(vlanBOCA[spine_num]) @@ -462,13 +462,13 @@ def spine_provision(self, rack, equips): # variablestochangespine1["IPNEIGHLEAF2IPV4"] = str(IPLEAFipv4[numero_rack][spine_num]) # variablestochangespine1["IPNEIGHLEAF2IPV6"] = str(IPLEAFipv6[numero_rack][spine_num]) elif spine_num == 2: - for lf in equips_sorted[:2]: - interface_counter = 1 - for iface in lf.get("interfaces"): - if iface.get("nome")[:3] == self.spine_prefix and iface.get("nome")[-1] == 2: - variablestochangespine1["SINGLE2{}INT".format(interface_counter)] = iface.get("interface") - # variablestochangespine1["SINGLE2{}INT".format(interface_counter)] = iface.get("interface") - interface_counter += 1 + # interface_counter = 1 + # for lf in equips_sorted[:2]: + # for iface in lf.get("interfaces"): + # if iface.get("nome")[:3] == self.spine_prefix and iface.get("nome")[-1] == 2: + # variablestochangespine1["SINGLE2{}INT".format(interface_counter)] = iface.get("interface") + # # variablestochangespine1["SINGLE2{}INT".format(interface_counter)] = iface.get("interface") + # interface_counter += 1 variablestochangespine1["VLANBORDA2LEAF"] = str(vlanBO[spine_num - 2]) variablestochangespine1["VLANBORDA2CACHOSLEAF"] = str(vlanBOCA[spine_num - 2]) variablestochangespine1["VLANBORDA2CACHOSB"] = str(vlanBOCAB[spine_num - 2]) @@ -500,7 +500,16 @@ def spine_provision(self, rack, equips): # # "DESCRIPTION{}CONNECT" # e_counter += 1 - + interface_counter = 1 + for lf in equips_sorted[:2]: + for iface in lf.get("interfaces"): + if iface.get("nome")[:3] == self.spine_prefix and iface.get("nome")[-1] == 2: + variablestochangespine1["SINGLE2{}INT".format(interface_counter)] = iface.get("interface") + # variablestochangespine1["SINGLE2{}INT".format(interface_counter)] = iface.get("interface") + elif iface.get("nome")[:3] == self.spine_prefix and iface.get("nome")[-1] == 1: + variablestochangespine1["SINGLE1{}INT".format(interface_counter)] = iface.get("interface") + # variablestochangespine1["SINGLE2{}INT".format(interface_counter)] = iface.get("interface") + interface_counter += 1 variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[1].get("nome") variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[0].get("nome") #### END to Berrini Block ##### From 8fd4d5b8767d2ab0a46bad13bdd8ad478f3b1ac5 Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Thu, 25 Jul 2024 16:13:17 -0300 Subject: [PATCH 56/89] fix --- networkapi/api_rack/provision.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/networkapi/api_rack/provision.py b/networkapi/api_rack/provision.py index 7a1d661f..d9e1aaa3 100644 --- a/networkapi/api_rack/provision.py +++ b/networkapi/api_rack/provision.py @@ -500,16 +500,24 @@ def spine_provision(self, rack, equips): # # "DESCRIPTION{}CONNECT" # e_counter += 1 - interface_counter = 1 + interface1_counter = 1 + interface2_counter = 1 + for lf in equips_sorted[:2]: for iface in lf.get("interfaces"): - if iface.get("nome")[:3] == self.spine_prefix and iface.get("nome")[-1] == 2: - variablestochangespine1["SINGLE2{}INT".format(interface_counter)] = iface.get("interface") - # variablestochangespine1["SINGLE2{}INT".format(interface_counter)] = iface.get("interface") - elif iface.get("nome")[:3] == self.spine_prefix and iface.get("nome")[-1] == 1: - variablestochangespine1["SINGLE1{}INT".format(interface_counter)] = iface.get("interface") - # variablestochangespine1["SINGLE2{}INT".format(interface_counter)] = iface.get("interface") - interface_counter += 1 + iface_name = iface.get("nome") + if iface_name[:3] == self.spine_prefix and int(iface_name[-1]) == 2: + variablestochangespine1["SINGLE2{}INT".format(interface2_counter)] = iface.get("interface") + variablestochangespine1["INT_LF_2{}UPLINK".format(interface2_counter)] = iface.get("eq_interface") + + interface2_counter += 1 + # variablestochangespine1["SINGLE2{}INT".format(interface_counter)] = iface.get("interface") + + elif iface_name[:3] == self.spine_prefix and int(iface_name[-1]) == 1: + variablestochangespine1["SINGLE1{}INT".format(interface1_counter)] = iface.get("interface") + variablestochangespine1["INT_LF_1{}UPLINK".format(interface1_counter)] = iface.get("eq_interface") + # variablestochangespine1["SINGLE2{}INT".format(interface_counter)] = iface.get("interface") + interface1_counter += 1 variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[1].get("nome") variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[0].get("nome") #### END to Berrini Block ##### From 09ff98ae1f5605c20fc68ef9508fe92e15990787 Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Thu, 25 Jul 2024 16:30:41 -0300 Subject: [PATCH 57/89] fix variable --- networkapi/api_rack/provision.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/networkapi/api_rack/provision.py b/networkapi/api_rack/provision.py index d9e1aaa3..ba879ecf 100644 --- a/networkapi/api_rack/provision.py +++ b/networkapi/api_rack/provision.py @@ -509,6 +509,8 @@ def spine_provision(self, rack, equips): if iface_name[:3] == self.spine_prefix and int(iface_name[-1]) == 2: variablestochangespine1["SINGLE2{}INT".format(interface2_counter)] = iface.get("interface") variablestochangespine1["INT_LF_2{}UPLINK".format(interface2_counter)] = iface.get("eq_interface") + variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[0].get("nome") + variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[1].get("nome") interface2_counter += 1 # variablestochangespine1["SINGLE2{}INT".format(interface_counter)] = iface.get("interface") @@ -518,8 +520,8 @@ def spine_provision(self, rack, equips): variablestochangespine1["INT_LF_1{}UPLINK".format(interface1_counter)] = iface.get("eq_interface") # variablestochangespine1["SINGLE2{}INT".format(interface_counter)] = iface.get("interface") interface1_counter += 1 - variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[1].get("nome") - variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[0].get("nome") + variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[1].get("nome") + variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[0].get("nome") #### END to Berrini Block ##### variablestochangespine1["IPNEIGHLEAFIPV4"] = str(IPLEAFipv4[numero_rack][spine_num - 1]) From 35f16131e9e339ed9dd82682ad2ada85a26da3ce Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Fri, 26 Jul 2024 11:53:32 -0300 Subject: [PATCH 58/89] better variables --- networkapi/api_rack/provision.py | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/networkapi/api_rack/provision.py b/networkapi/api_rack/provision.py index ba879ecf..c0af1bec 100644 --- a/networkapi/api_rack/provision.py +++ b/networkapi/api_rack/provision.py @@ -509,8 +509,10 @@ def spine_provision(self, rack, equips): if iface_name[:3] == self.spine_prefix and int(iface_name[-1]) == 2: variablestochangespine1["SINGLE2{}INT".format(interface2_counter)] = iface.get("interface") variablestochangespine1["INT_LF_2{}UPLINK".format(interface2_counter)] = iface.get("eq_interface") - variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[0].get("nome") - variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[1].get("nome") + # variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[1].get("nome") + variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[0].get("nome") + variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[1].get("nome") + variablestochangespine1["PO2CHANNEL"] = variablestochangespine1["SINGLE21INT".format(interface2_counter)].split('/')[-1].split(':')[0] interface2_counter += 1 # variablestochangespine1["SINGLE2{}INT".format(interface_counter)] = iface.get("interface") @@ -518,10 +520,12 @@ def spine_provision(self, rack, equips): elif iface_name[:3] == self.spine_prefix and int(iface_name[-1]) == 1: variablestochangespine1["SINGLE1{}INT".format(interface1_counter)] = iface.get("interface") variablestochangespine1["INT_LF_1{}UPLINK".format(interface1_counter)] = iface.get("eq_interface") + variablestochangespine1["PO1CHANNEL"] = variablestochangespine1["SINGLE11INT".format(interface2_counter)].split('/')[-1].split(':')[0] + # variablestochangespine1["SINGLE2{}INT".format(interface_counter)] = iface.get("interface") + variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[0].get("nome") + variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[1].get("nome") interface1_counter += 1 - variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[1].get("nome") - variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[0].get("nome") #### END to Berrini Block ##### variablestochangespine1["IPNEIGHLEAFIPV4"] = str(IPLEAFipv4[numero_rack][spine_num - 1]) @@ -538,6 +542,21 @@ def spine_provision(self, rack, equips): fileinspine1 = path_to_guide + i.get("roteiro") fileoutspine1 = path_to_add_config + i.get("nome") + "-ADD-" + rack.nome + ".cfg" + log.debug(i.get("nome"[-1])) + # if self.spine_prefix in fileinspine1 and spine_num in fileinspine1 and spine_num == 1: + if int(i.get("nome")[-1]) == 1: + spn_int_desc1 = variablestochangespine1["DESCRIPTION2CONNECT"] + spn_int_desc2 = variablestochangespine1["DESCRIPTION1CONNECT"] + variablestochangespine1["DESCRIPTION1CONNECT"] = spn_int_desc2 + variablestochangespine1["DESCRIPTION2CONNECT"] = spn_int_desc1 + + # if self.spine_prefix in fileinspine1 and spine_num in fileinspine1 and spine_num == 2: + if int(i.get("nome")[-1]) == 2: + spn_int_desc1 = variablestochangespine1["DESCRIPTION2CONNECT"] + spn_int_desc2 = variablestochangespine1["DESCRIPTION1CONNECT"] + variablestochangespine1["DESCRIPTION2CONNECT"] = spn_int_desc2 + variablestochangespine1["DESCRIPTION1CONNECT"] = spn_int_desc1 + self.replace_file(fileinspine1, fileoutspine1, variablestochangespine1) variablestochangespine1 = dict() From 34d47bf9093ba4c284700dfe1f694823aa90de9d Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Fri, 26 Jul 2024 12:04:24 -0300 Subject: [PATCH 59/89] code cleaning --- networkapi/api_rack/provision.py | 43 +++----------------------------- 1 file changed, 4 insertions(+), 39 deletions(-) diff --git a/networkapi/api_rack/provision.py b/networkapi/api_rack/provision.py index c0af1bec..3092ceba 100644 --- a/networkapi/api_rack/provision.py +++ b/networkapi/api_rack/provision.py @@ -427,16 +427,6 @@ def spine_provision(self, rack, equips): ### TO BERRINI if spine_num == 1: - # variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[0].get("nome") - # variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[1].get("nome") - # interface_counter = 1 - # for lf in equips_sorted[:2]: - # for iface in lf.get("interfaces"): - # if iface.get("nome")[:3] == self.spine_prefix and iface.get("nome")[-1] == 1: - # variablestochangespine1["SINGLE1{}INT".format(interface_counter)] = iface.get("interface") - # # variablestochangespine1["SINGLE2{}INT".format(interface_counter)] = iface.get("interface") - # interface_counter += 1 - variablestochangespine1["VLANBORDA2LEAF"] = str(vlanBO[spine_num]) variablestochangespine1["VLANBORDA2CACHOSLEAF"] = str(vlanBOCA[spine_num]) variablestochangespine1["VLANBORDA2CACHOSB"] = str(vlanBOCAB[spine_num]) @@ -456,25 +446,13 @@ def spine_provision(self, rack, equips): counter += 1 - # variablestochangespine1["IPSPI2NEIPV6"] = str(IPSPINEipv6[numero_rack][spine_num]) - # variablestochangespine1["IPSPI2NEIPV4"] = str(IPSPINEipv4[numero_rack][spine_num]) variablestochangespine1["VLANBE2LEAF"] = str(vlanBE[spine_num]) - # variablestochangespine1["IPNEIGHLEAF2IPV4"] = str(IPLEAFipv4[numero_rack][spine_num]) - # variablestochangespine1["IPNEIGHLEAF2IPV6"] = str(IPLEAFipv6[numero_rack][spine_num]) elif spine_num == 2: - # interface_counter = 1 - # for lf in equips_sorted[:2]: - # for iface in lf.get("interfaces"): - # if iface.get("nome")[:3] == self.spine_prefix and iface.get("nome")[-1] == 2: - # variablestochangespine1["SINGLE2{}INT".format(interface_counter)] = iface.get("interface") - # # variablestochangespine1["SINGLE2{}INT".format(interface_counter)] = iface.get("interface") - # interface_counter += 1 variablestochangespine1["VLANBORDA2LEAF"] = str(vlanBO[spine_num - 2]) variablestochangespine1["VLANBORDA2CACHOSLEAF"] = str(vlanBOCA[spine_num - 2]) variablestochangespine1["VLANBORDA2CACHOSB"] = str(vlanBOCAB[spine_num - 2]) variablestochangespine1["VLANFE2LEAF"] = str(vlanFE[spine_num - 2]) counter = 0 - log.debug(IPSPINEipv6[numero_rack]) for ipv6 in IPSPINEipv6[numero_rack]: if spine_num + counter < len(IPLEAFipv6[numero_rack]): variablestochangespine1["IPSPINE{}IPV6".format(counter + 1)] = str(IPSPINEipv6[numero_rack][counter + spine_num]) @@ -489,17 +467,7 @@ def spine_provision(self, rack, equips): counter += 1 - # variablestochangespine1["IPSPI2NEIPV6"] = str(IPSPINEipv6[numero_rack][spine_num - 2]) - # variablestochangespine1["IPSPI2NEIPV4"] = str(IPSPINEipv4[numero_rack][spine_num - 2]) variablestochangespine1["VLANBE2LEAF"] = str(vlanBE[spine_num - 2]) - # variablestochangespine1["IPNEIGHLEAF2IPV4"] = str(IPLEAFipv4[numero_rack][spine_num - 2]) - # variablestochangespine1["IPNEIGHLEAF2IPV6"] = str(IPLEAFipv6[numero_rack][spine_num - 2]) - - # e_counter = 1 - # for e in equips_sorted[:2]: - # # "DESCRIPTION{}CONNECT" - - # e_counter += 1 interface1_counter = 1 interface2_counter = 1 @@ -509,20 +477,16 @@ def spine_provision(self, rack, equips): if iface_name[:3] == self.spine_prefix and int(iface_name[-1]) == 2: variablestochangespine1["SINGLE2{}INT".format(interface2_counter)] = iface.get("interface") variablestochangespine1["INT_LF_2{}UPLINK".format(interface2_counter)] = iface.get("eq_interface") - # variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[1].get("nome") variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[0].get("nome") variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[1].get("nome") variablestochangespine1["PO2CHANNEL"] = variablestochangespine1["SINGLE21INT".format(interface2_counter)].split('/')[-1].split(':')[0] interface2_counter += 1 - # variablestochangespine1["SINGLE2{}INT".format(interface_counter)] = iface.get("interface") elif iface_name[:3] == self.spine_prefix and int(iface_name[-1]) == 1: variablestochangespine1["SINGLE1{}INT".format(interface1_counter)] = iface.get("interface") variablestochangespine1["INT_LF_1{}UPLINK".format(interface1_counter)] = iface.get("eq_interface") variablestochangespine1["PO1CHANNEL"] = variablestochangespine1["SINGLE11INT".format(interface2_counter)].split('/')[-1].split(':')[0] - - # variablestochangespine1["SINGLE2{}INT".format(interface_counter)] = iface.get("interface") variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[0].get("nome") variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[1].get("nome") interface1_counter += 1 @@ -542,21 +506,22 @@ def spine_provision(self, rack, equips): fileinspine1 = path_to_guide + i.get("roteiro") fileoutspine1 = path_to_add_config + i.get("nome") + "-ADD-" + rack.nome + ".cfg" - log.debug(i.get("nome"[-1])) - # if self.spine_prefix in fileinspine1 and spine_num in fileinspine1 and spine_num == 1: + + ### ANOTHER BERRINI BLOCK if int(i.get("nome")[-1]) == 1: spn_int_desc1 = variablestochangespine1["DESCRIPTION2CONNECT"] spn_int_desc2 = variablestochangespine1["DESCRIPTION1CONNECT"] variablestochangespine1["DESCRIPTION1CONNECT"] = spn_int_desc2 variablestochangespine1["DESCRIPTION2CONNECT"] = spn_int_desc1 - # if self.spine_prefix in fileinspine1 and spine_num in fileinspine1 and spine_num == 2: if int(i.get("nome")[-1]) == 2: spn_int_desc1 = variablestochangespine1["DESCRIPTION2CONNECT"] spn_int_desc2 = variablestochangespine1["DESCRIPTION1CONNECT"] variablestochangespine1["DESCRIPTION2CONNECT"] = spn_int_desc2 variablestochangespine1["DESCRIPTION1CONNECT"] = spn_int_desc1 + #### END BLOCK + self.replace_file(fileinspine1, fileoutspine1, variablestochangespine1) variablestochangespine1 = dict() From fdb2b4fc69ed74f5b29fe533db12df81a9604e69 Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Fri, 26 Jul 2024 12:11:53 -0300 Subject: [PATCH 60/89] added comments --- networkapi/api_rack/provision.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/networkapi/api_rack/provision.py b/networkapi/api_rack/provision.py index 3092ceba..2588aed6 100644 --- a/networkapi/api_rack/provision.py +++ b/networkapi/api_rack/provision.py @@ -426,6 +426,8 @@ def spine_provision(self, rack, equips): variablestochangespine1["ASLEAF"] = str(ASLEAF[numero_rack][0]) ### TO BERRINI + ## To pop Berrini we use new variables, this make the new cross topology and old topology run to. + if spine_num == 1: variablestochangespine1["VLANBORDA2LEAF"] = str(vlanBO[spine_num]) variablestochangespine1["VLANBORDA2CACHOSLEAF"] = str(vlanBOCA[spine_num]) @@ -508,6 +510,8 @@ def spine_provision(self, rack, equips): fileoutspine1 = path_to_add_config + i.get("nome") + "-ADD-" + rack.nome + ".cfg" ### ANOTHER BERRINI BLOCK + ## Here we invert the variables of description, due unique template to diferent spines + ## without this invertion, the description run well on spine 2 but on spine 1 they are inverted if int(i.get("nome")[-1]) == 1: spn_int_desc1 = variablestochangespine1["DESCRIPTION2CONNECT"] spn_int_desc2 = variablestochangespine1["DESCRIPTION1CONNECT"] From bab2badce77675830d3ff191120b67e25ce16d17 Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Mon, 29 Jul 2024 17:48:46 -0300 Subject: [PATCH 61/89] fix leaf variables --- networkapi/api_rack/provision.py | 51 ++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/networkapi/api_rack/provision.py b/networkapi/api_rack/provision.py index 2588aed6..33eaddcc 100644 --- a/networkapi/api_rack/provision.py +++ b/networkapi/api_rack/provision.py @@ -403,6 +403,8 @@ def spine_provision(self, rack, equips): variablestochangeleaf1["OWN_IP_MGMT"] = equip.get("ip_mngt") variablestochangeleaf1["LF_HOSTNAME"] = equip.get("nome") log.debug("5") + lf1_if_counter = 1 + lf2_if_counter = 1 for i in equip.get("interfaces"): if i.get("nome")[:3] == self.leaf_prefix: variablestochangeleaf1["LFNEIGH_HOSTNAME"] = i.get("nome") @@ -481,14 +483,14 @@ def spine_provision(self, rack, equips): variablestochangespine1["INT_LF_2{}UPLINK".format(interface2_counter)] = iface.get("eq_interface") variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[0].get("nome") variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[1].get("nome") - variablestochangespine1["PO2CHANNEL"] = variablestochangespine1["SINGLE21INT".format(interface2_counter)].split('/')[-1].split(':')[0] + variablestochangespine1["PO2CHANNEL"] = variablestochangespine1["SINGLE21INT"].split('/')[-1].split(':')[0] interface2_counter += 1 elif iface_name[:3] == self.spine_prefix and int(iface_name[-1]) == 1: variablestochangespine1["SINGLE1{}INT".format(interface1_counter)] = iface.get("interface") variablestochangespine1["INT_LF_1{}UPLINK".format(interface1_counter)] = iface.get("eq_interface") - variablestochangespine1["PO1CHANNEL"] = variablestochangespine1["SINGLE11INT".format(interface2_counter)].split('/')[-1].split(':')[0] + variablestochangespine1["PO1CHANNEL"] = variablestochangespine1["SINGLE11INT"].split('/')[-1].split(':')[0] variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[0].get("nome") variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[1].get("nome") interface1_counter += 1 @@ -501,6 +503,7 @@ def spine_provision(self, rack, equips): variablestochangeleaf1["SP1_HOSTNAME"] = i.get("nome") variablestochangeleaf1["INTERFACE_SP1"] = i.get("interface") variablestochangeleaf1["ASSPINE1"] = str(BASE_AS_SPN + spine_num - 1) + else: variablestochangeleaf1["SP2_HOSTNAME"] = i.get("nome") variablestochangeleaf1["INTERFACE_SP2"] = i.get("interface") @@ -533,6 +536,50 @@ def spine_provision(self, rack, equips): variablestochangeleaf1["HOSTNAME_OOB"] = i.get("nome") variablestochangeleaf1["INTERFACE_OOB"] = i.get("interface") + interface_name = i.get("nome") + if interface_name[:3] == self.spine_prefix and int(interface_name[-1]) == 1: + variablestochangeleaf1["INTERFACE{}_SP1".format(lf1_if_counter)] = i.get("interface") + lf1_if_counter +=1 + + elif interface_name[:3] == self.spine_prefix and int(interface_name[-1]) == 2: + variablestochangeleaf1["INTERFACE{}_SP2".format(lf2_if_counter)] = i.get("interface") + lf2_if_counter +=1 + + #### ANOTHER BERRINI BLOCK + ## Here we invert the variables of description, due unique template to diferent spines + ## without this invertion, the description run well on spine 2 but on spine 1 they are inverted + if int(equip.get('nome')[-1]) == 2: + ### Here we must have to invert the variables to leaf2, due the new topology + sp1_hostname = variablestochangeleaf1["SP1_HOSTNAME"] + sp2_hostname = variablestochangeleaf1["SP2_HOSTNAME"] + variablestochangeleaf1["SP1_HOSTNAME"] = sp2_hostname + variablestochangeleaf1["SP2_HOSTNAME"] = sp1_hostname + + if1_sp1 = variablestochangeleaf1['INTERFACE1_SP1'] + if2_sp1 = variablestochangeleaf1['INTERFACE2_SP1'] + if3_sp1 = variablestochangeleaf1['INTERFACE3_SP1'] + if4_sp1 = variablestochangeleaf1['INTERFACE4_SP1'] + + if1_sp2 = variablestochangeleaf1['INTERFACE1_SP2'] + if2_sp2 = variablestochangeleaf1['INTERFACE2_SP2'] + if3_sp2 = variablestochangeleaf1['INTERFACE3_SP2'] + if4_sp2 = variablestochangeleaf1['INTERFACE4_SP2'] + + variablestochangeleaf1['INTERFACE1_SP1'] = if1_sp2 + variablestochangeleaf1['INTERFACE2_SP1'] = if2_sp2 + variablestochangeleaf1['INTERFACE3_SP1'] = if3_sp2 + variablestochangeleaf1['INTERFACE4_SP1'] = if4_sp2 + + variablestochangeleaf1['INTERFACE1_SP2'] = if1_sp1 + variablestochangeleaf1['INTERFACE2_SP2'] = if2_sp1 + variablestochangeleaf1['INTERFACE3_SP2'] = if3_sp1 + variablestochangeleaf1['INTERFACE4_SP2'] = if4_sp1 + + variablestochangeleaf1['LFPO1'] = variablestochangeleaf1['INTERFACE1_SP1'].split('/')[-1].split(':')[0] + variablestochangeleaf1['LFPO2'] = variablestochangeleaf1['INTERFACE1_SP2'].split('/')[-1].split(':')[0] + + ### End Berrini Block + variablestochangeleaf1["ID_VLT"] = str(id_vlt[j]) variablestochangeleaf1["PRIORITY_VLT"] = str(priority_vlt[j]) From cc506087fc8bde8e0c156a96925617565f3121e4 Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Wed, 31 Jul 2024 15:09:35 -0300 Subject: [PATCH 62/89] invert variables --- networkapi/api_rack/provision.py | 67 ++++++++++++++++++++++++++------ 1 file changed, 55 insertions(+), 12 deletions(-) diff --git a/networkapi/api_rack/provision.py b/networkapi/api_rack/provision.py index 33eaddcc..ad3d2222 100644 --- a/networkapi/api_rack/provision.py +++ b/networkapi/api_rack/provision.py @@ -436,21 +436,24 @@ def spine_provision(self, rack, equips): variablestochangespine1["VLANBORDA2CACHOSB"] = str(vlanBOCAB[spine_num]) variablestochangespine1["VLANFE2LEAF"] = str(vlanFE[spine_num]) - counter = 1 + counter = 0 for ipv6 in IPSPINEipv6[numero_rack]: - variablestochangespine1["IPSPINE{}IPV6".format(counter)] = str(ipv6) - variablestochangespine1["IPNEIGHLEAF{}IPV6".format(counter)] = str(IPLEAFipv6[numero_rack][counter -1]) + if counter + 1 < len(IPSPINEipv6[numero_rack]): + variablestochangespine1["IPSPINE{}IPV6".format(counter+1)] = str(IPSPINEipv6[numero_rack][counter - 1]) + variablestochangespine1["IPNEIGHLEAF{}IPV6".format(counter+1)] = str(IPLEAFipv6[numero_rack][counter -1]) - counter += 1 + counter += 1 - counter = 1 + counter = 0 for ipv4 in IPSPINEipv4[numero_rack]: - variablestochangespine1["IPSPINE{}IPV4".format(counter)] = str(ipv4) - variablestochangespine1["IPNEIGHLEAF{}IPV4".format(counter)] = str(IPLEAFipv4[numero_rack][counter -1]) + if counter + 1 < len(IPSPINEipv4[numero_rack]): + variablestochangespine1["IPSPINE{}IPV4".format(counter+1)] = str(IPSPINEipv4[numero_rack][counter - 1]) + variablestochangespine1["IPNEIGHLEAF{}IPV4".format(counter+1)] = str(IPLEAFipv4[numero_rack][counter -1]) - counter += 1 + counter += 1 variablestochangespine1["VLANBE2LEAF"] = str(vlanBE[spine_num]) + elif spine_num == 2: variablestochangespine1["VLANBORDA2LEAF"] = str(vlanBO[spine_num - 2]) variablestochangespine1["VLANBORDA2CACHOSLEAF"] = str(vlanBOCA[spine_num - 2]) @@ -459,15 +462,15 @@ def spine_provision(self, rack, equips): counter = 0 for ipv6 in IPSPINEipv6[numero_rack]: if spine_num + counter < len(IPLEAFipv6[numero_rack]): - variablestochangespine1["IPSPINE{}IPV6".format(counter + 1)] = str(IPSPINEipv6[numero_rack][counter + spine_num]) - variablestochangespine1["IPNEIGHLEAF{}IPV6".format(counter + 1)] = str(IPLEAFipv6[numero_rack][counter + spine_num]) + variablestochangespine1["IPSPINE{}IPV6".format(counter + 1)] = str(IPSPINEipv6[numero_rack][counter + 1]) + variablestochangespine1["IPNEIGHLEAF{}IPV6".format(counter + 1)] = str(IPLEAFipv6[numero_rack][counter + 1]) counter += 1 counter = 0 for ipv4 in IPSPINEipv4[numero_rack]: if spine_num + counter < len(IPLEAFipv4[numero_rack]): - variablestochangespine1["IPSPINE{}IPV4".format(counter + 1)] = str(IPSPINEipv4[numero_rack][counter + spine_num]) - variablestochangespine1["IPNEIGHLEAF{}IPV4".format(counter + 1)] = str(IPLEAFipv4[numero_rack][counter + spine_num]) + variablestochangespine1["IPSPINE{}IPV4".format(counter + 1)] = str(IPSPINEipv4[numero_rack][counter + 1]) + variablestochangespine1["IPNEIGHLEAF{}IPV4".format(counter + 1)] = str(IPLEAFipv4[numero_rack][counter + 1]) counter += 1 @@ -527,6 +530,46 @@ def spine_provision(self, rack, equips): variablestochangespine1["DESCRIPTION2CONNECT"] = spn_int_desc2 variablestochangespine1["DESCRIPTION1CONNECT"] = spn_int_desc1 + spn_vlan_bo2 = variablestochangespine1["VLANBORDA2LEAF"] + spn_vlan_bc2 = variablestochangespine1["VLANBORDA2CACHOSLEAF"] + spn_vlan_fe2 = variablestochangespine1["VLANFE2LEAF"] + spn_vlan_be2 = variablestochangespine1["VLANBE2LEAF"] + spn_vlan_be1 = variablestochangespine1["VLANBELEAF"] + spn_vlan_fe1 = variablestochangespine1["VLANFELEAF"] + spn_vlan_bo1 = variablestochangespine1["VLANBORDALEAF"] + spn_vlan_bc1 = variablestochangespine1["VLANBORDACACHOSLEAF"] + + variablestochangespine1["VLANBORDA2LEAF"] = spn_vlan_bo1 + variablestochangespine1["VLANBORDA2CACHOSLEAF"] = spn_vlan_bc1 + variablestochangespine1["VLANFE2LEAF"] = spn_vlan_fe1 + variablestochangespine1["VLANBE2LEAF"] = spn_vlan_be1 + variablestochangespine1["VLANBELEAF"] = spn_vlan_be2 + variablestochangespine1["VLANFELEAF"] = spn_vlan_fe2 + variablestochangespine1["VLANBORDALEAF"] = spn_vlan_bo2 + variablestochangespine1["VLANBORDACACHOSLEAF"] = spn_vlan_bc2 + + ipv4spn1 = variablestochangespine1["IPSPINE1IPV4"] + ipv4spn2 = variablestochangespine1["IPSPINE2IPV4"] + variablestochangespine1["IPSPINE1IPV4"] = ipv4spn2 + variablestochangespine1["IPSPINE2IPV4"] = ipv4spn1 + + ipv6spn1 = variablestochangespine1["IPSPINE1IPV6"] + ipv6spn2 = variablestochangespine1["IPSPINE2IPV6"] + variablestochangespine1["IPSPINE1IPV6"] = ipv6spn2 + variablestochangespine1["IPSPINE2IPV6"] = ipv6spn1 + + ipv4_nei_lf1 = variablestochangespine1["IPNEIGHLEAF1IPV4"] + ipv4_nei_lf2 = variablestochangespine1["IPNEIGHLEAF2IPV4"] + variablestochangespine1["IPNEIGHLEAF1IPV4"] = ipv4_nei_lf2 + variablestochangespine1["IPNEIGHLEAF2IPV4"] = ipv4_nei_lf1 + + ipv6_nei_lf1 = variablestochangespine1["IPNEIGHLEAF1IPV6"] + ipv6_nei_lf2 = variablestochangespine1["IPNEIGHLEAF2IPV6"] + variablestochangespine1["IPNEIGHLEAF1IPV6"] = ipv6_nei_lf2 + variablestochangespine1["IPNEIGHLEAF2IPV6"] = ipv6_nei_lf1 + + + #### END BLOCK self.replace_file(fileinspine1, fileoutspine1, variablestochangespine1) From 96f04d37f03ea4c3dffb8cd5e2039e5c1055fed1 Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Thu, 1 Aug 2024 15:41:05 -0300 Subject: [PATCH 63/89] finished algorithm --- networkapi/api_rack/provision.py | 86 +++++++++++++++++++------------- 1 file changed, 52 insertions(+), 34 deletions(-) diff --git a/networkapi/api_rack/provision.py b/networkapi/api_rack/provision.py index ad3d2222..8c93fd6e 100644 --- a/networkapi/api_rack/provision.py +++ b/networkapi/api_rack/provision.py @@ -337,16 +337,16 @@ def spine_provision(self, rack, equips): variablestochangeleaf1["VLANBORDACACHOSBLEAFSP2"] = str(vlanBOCAB[spn + 1]) ### To pop Berrini - variablestochangeleaf1["VLANBERBELEAFSP1"] = str(vlanBE[0]) - variablestochangeleaf1["VLANBERBELEAFSP2"] = str(vlanBE[1]) - variablestochangeleaf1["VLANBERFELEAFSP1"] = str(vlanFE[0]) - variablestochangeleaf1["VLANBERFELEAFSP2"] = str(vlanFE[1]) - variablestochangeleaf1["VLANBERBORDALEAFSP1"] = str(vlanBO[0]) - variablestochangeleaf1["VLANBERBORDALEAFSP2"] = str(vlanBO[1]) - variablestochangeleaf1["VLANBERBORDACACHOSLEAFSP1"] = str(vlanBOCA[0]) - variablestochangeleaf1["VLANBERBORDACACHOSLEAFSP2"] = str(vlanBOCA[1]) - variablestochangeleaf1["VLANBERBORDACACHOSBLEAFSP1"] = str(vlanBOCAB[0]) - variablestochangeleaf1["VLANBERBORDACACHOSBLEAFSP2"] = str(vlanBOCAB[1]) + variablestochangeleaf1["VLANBERBELEAFSP1"] = str(vlanBE[int(equip.get("nome")[-1]) - 1]) + variablestochangeleaf1["VLANBERBELEAFSP2"] = str(vlanBE[int(equip.get("nome")[-1]) + 1]) + variablestochangeleaf1["VLANBERFELEAFSP1"] = str(vlanFE[int(equip.get("nome")[-1]) - 1]) + variablestochangeleaf1["VLANBERFELEAFSP2"] = str(vlanFE[int(equip.get("nome")[-1]) + 1]) + variablestochangeleaf1["VLANBERBORDALEAFSP1"] = str(vlanBO[int(equip.get("nome")[-1]) - 1]) + variablestochangeleaf1["VLANBERBORDALEAFSP2"] = str(vlanBO[int(equip.get("nome")[-1]) + 1]) + variablestochangeleaf1["VLANBERBORDACACHOSLEAFSP1"] = str(vlanBOCA[int(equip.get("nome")[-1]) - 1]) + variablestochangeleaf1["VLANBERBORDACACHOSLEAFSP2"] = str(vlanBOCA[int(equip.get("nome")[-1]) + 1]) + variablestochangeleaf1["VLANBERBORDACACHOSBLEAFSP1"] = str(vlanBOCAB[int(equip.get("nome")[-1]) - 1]) + variablestochangeleaf1["VLANBERBORDACACHOSBLEAFSP2"] = str(vlanBOCAB[int(equip.get("nome")[-1]) + 1]) log.debug("2") variablestochangeleaf1["ASLEAF"] = str(ASLEAF[numero_rack][0]) @@ -435,6 +435,12 @@ def spine_provision(self, rack, equips): variablestochangespine1["VLANBORDA2CACHOSLEAF"] = str(vlanBOCA[spine_num]) variablestochangespine1["VLANBORDA2CACHOSB"] = str(vlanBOCAB[spine_num]) variablestochangespine1["VLANFE2LEAF"] = str(vlanFE[spine_num]) + variablestochangespine1["VLANBE2LEAF"] = str(vlanBE[spine_num]) + variablestochangespine1["VLANBE1LEAF"] = str(vlanBE[spine_num - 1]) + variablestochangespine1["VLANFE1LEAF"] = str(vlanFE[spine_num - 1]) + variablestochangespine1["VLANBORDA1LEAF"] = str(vlanBO[spine_num - 1]) + variablestochangespine1["VLANBORDA1CACHOSLEAF"] = str(vlanBOCA[spine_num - 1]) + variablestochangespine1["VLANBORDA1CACHOSB"] = str(vlanBOCAB[spine_num - 1]) counter = 0 for ipv6 in IPSPINEipv6[numero_rack]: @@ -452,13 +458,19 @@ def spine_provision(self, rack, equips): counter += 1 - variablestochangespine1["VLANBE2LEAF"] = str(vlanBE[spine_num]) elif spine_num == 2: - variablestochangespine1["VLANBORDA2LEAF"] = str(vlanBO[spine_num - 2]) - variablestochangespine1["VLANBORDA2CACHOSLEAF"] = str(vlanBOCA[spine_num - 2]) - variablestochangespine1["VLANBORDA2CACHOSB"] = str(vlanBOCAB[spine_num - 2]) - variablestochangespine1["VLANFE2LEAF"] = str(vlanFE[spine_num - 2]) + variablestochangespine1["VLANBORDA2LEAF"] = str(vlanBO[spine_num]) + variablestochangespine1["VLANBORDA2CACHOSLEAF"] = str(vlanBOCA[spine_num]) + variablestochangespine1["VLANBORDA2CACHOSB"] = str(vlanBOCAB[spine_num]) + variablestochangespine1["VLANFE2LEAF"] = str(vlanFE[spine_num]) + variablestochangespine1["VLANBE2LEAF"] = str(vlanBE[spine_num]) + variablestochangespine1["VLANBE1LEAF"] = str(vlanBE[spine_num + 1]) + variablestochangespine1["VLANFE1LEAF"] = str(vlanFE[spine_num + 1]) + variablestochangespine1["VLANBORDA1LEAF"] = str(vlanBO[spine_num + 1]) + variablestochangespine1["VLANBORDA1CACHOSLEAF"] = str(vlanBOCA[spine_num + 1]) + variablestochangespine1["VLANBORDA1CACHOSB"] = str(vlanBOCAB[spine_num + 1]) + counter = 0 for ipv6 in IPSPINEipv6[numero_rack]: if spine_num + counter < len(IPLEAFipv6[numero_rack]): @@ -474,7 +486,6 @@ def spine_provision(self, rack, equips): counter += 1 - variablestochangespine1["VLANBE2LEAF"] = str(vlanBE[spine_num - 2]) interface1_counter = 1 interface2_counter = 1 @@ -530,24 +541,6 @@ def spine_provision(self, rack, equips): variablestochangespine1["DESCRIPTION2CONNECT"] = spn_int_desc2 variablestochangespine1["DESCRIPTION1CONNECT"] = spn_int_desc1 - spn_vlan_bo2 = variablestochangespine1["VLANBORDA2LEAF"] - spn_vlan_bc2 = variablestochangespine1["VLANBORDA2CACHOSLEAF"] - spn_vlan_fe2 = variablestochangespine1["VLANFE2LEAF"] - spn_vlan_be2 = variablestochangespine1["VLANBE2LEAF"] - spn_vlan_be1 = variablestochangespine1["VLANBELEAF"] - spn_vlan_fe1 = variablestochangespine1["VLANFELEAF"] - spn_vlan_bo1 = variablestochangespine1["VLANBORDALEAF"] - spn_vlan_bc1 = variablestochangespine1["VLANBORDACACHOSLEAF"] - - variablestochangespine1["VLANBORDA2LEAF"] = spn_vlan_bo1 - variablestochangespine1["VLANBORDA2CACHOSLEAF"] = spn_vlan_bc1 - variablestochangespine1["VLANFE2LEAF"] = spn_vlan_fe1 - variablestochangespine1["VLANBE2LEAF"] = spn_vlan_be1 - variablestochangespine1["VLANBELEAF"] = spn_vlan_be2 - variablestochangespine1["VLANFELEAF"] = spn_vlan_fe2 - variablestochangespine1["VLANBORDALEAF"] = spn_vlan_bo2 - variablestochangespine1["VLANBORDACACHOSLEAF"] = spn_vlan_bc2 - ipv4spn1 = variablestochangespine1["IPSPINE1IPV4"] ipv4spn2 = variablestochangespine1["IPSPINE2IPV4"] variablestochangespine1["IPSPINE1IPV4"] = ipv4spn2 @@ -618,6 +611,31 @@ def spine_provision(self, rack, equips): variablestochangeleaf1['INTERFACE3_SP2'] = if3_sp1 variablestochangeleaf1['INTERFACE4_SP2'] = if4_sp1 + vlan_ber_be1= variablestochangeleaf1["VLANBERBELEAFSP1"] + vlan_ber_be2= variablestochangeleaf1["VLANBERBELEAFSP2"] + vlan_ber_fe1= variablestochangeleaf1["VLANBERFELEAFSP1"] + vlan_ber_fe2= variablestochangeleaf1["VLANBERFELEAFSP2"] + vlan_ber_bo1= variablestochangeleaf1["VLANBERBORDALEAFSP1"] + vlan_ber_bo2= variablestochangeleaf1["VLANBERBORDALEAFSP2"] + vlan_ber_bc1= variablestochangeleaf1["VLANBERBORDACACHOSLEAFSP1"] + vlan_ber_bc2= variablestochangeleaf1["VLANBERBORDACACHOSLEAFSP2"] + vlan_ber_bcb1= variablestochangeleaf1["VLANBERBORDACACHOSBLEAFSP1"] + vlan_ber_bcb2= variablestochangeleaf1["VLANBERBORDACACHOSBLEAFSP2"] + variablestochangeleaf1["VLANBERBELEAFSP1"] = vlan_ber_be2 + variablestochangeleaf1["VLANBERBELEAFSP2"] = vlan_ber_be1 + variablestochangeleaf1["VLANBERFELEAFSP1"] = vlan_ber_fe2 + variablestochangeleaf1["VLANBERFELEAFSP2"] = vlan_ber_fe1 + variablestochangeleaf1["VLANBERBORDALEAFSP1"] = vlan_ber_bo2 + variablestochangeleaf1["VLANBERBORDALEAFSP2"] = vlan_ber_bo1 + variablestochangeleaf1["VLANBERBORDACACHOSLEAFSP1"] = vlan_ber_bc2 + variablestochangeleaf1["VLANBERBORDACACHOSLEAFSP2"] = vlan_ber_bc1 + variablestochangeleaf1["VLANBERBORDACACHOSBLEAFSP1"] = vlan_ber_bcb2 + variablestochangeleaf1["VLANBERBORDACACHOSBLEAFSP2"] = vlan_ber_bcb1 + as_spine1 = variablestochangeleaf1["ASSPINE1"] + as_spine2 = variablestochangeleaf1["ASSPINE2"] + variablestochangeleaf1["ASSPINE1"] = as_spine2 + variablestochangeleaf1["ASSPINE2"] = as_spine1 + variablestochangeleaf1['LFPO1'] = variablestochangeleaf1['INTERFACE1_SP1'].split('/')[-1].split(':')[0] variablestochangeleaf1['LFPO2'] = variablestochangeleaf1['INTERFACE1_SP2'].split('/')[-1].split(':')[0] From 5cc8fc499cfed9190973eb8e203303da2fea5fcb Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Fri, 9 Aug 2024 15:13:12 -0300 Subject: [PATCH 64/89] fixed variable name and query filter to allocate vlans to a new rack --- networkapi/api_rack/rackenvironments.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/networkapi/api_rack/rackenvironments.py b/networkapi/api_rack/rackenvironments.py index ee6b709a..4582993b 100644 --- a/networkapi/api_rack/rackenvironments.py +++ b/networkapi/api_rack/rackenvironments.py @@ -57,7 +57,7 @@ def spines_environment_save(self): spines = int(self.rack.dcroom.spines) fabric = self.rack.dcroom.name rackname = self.rack.nome - grupoL3name = fabric+"_"+racknome + grupoL3name = fabric+"_"+rackname try: id_grupo_l3 = models_env.GrupoL3().get_by_name(grupoL3name).id @@ -122,7 +122,7 @@ def spines_environment_save(self): 'fabric_id': self.rack.dcroom.id } environment = facade_env.create_environment(obj) - + return environment_spn_lf_list def spines_environment_read(self): From 0a337512e806c560cb6aec2c28066bf4f81c0563 Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Fri, 9 Aug 2024 15:31:44 -0300 Subject: [PATCH 65/89] fixed variable name and query filter to allocate vlans to a new rack --- networkapi/api_rack/rackenvironments.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/networkapi/api_rack/rackenvironments.py b/networkapi/api_rack/rackenvironments.py index 4582993b..598352ed 100644 --- a/networkapi/api_rack/rackenvironments.py +++ b/networkapi/api_rack/rackenvironments.py @@ -130,9 +130,12 @@ def spines_environment_read(self): def spine_leaf_vlans_save(self): log.debug("_create_spnlfvlans") + fabric = self.rack.dcroom.name + rackname = self.rack.nome + grupoL3name = fabric+"_"+rackname spn_lf_envs = models_env.Ambiente.objects.filter(dcroom=int(self.rack.dcroom.id), - grupo_l3__nome=str(self.rack.dcroom.name), + grupo_l3__nome=str(grupoL3name), ambiente_logico__nome__in=["SPINE01LEAF", "SPINE02LEAF", "SPINE03LEAF", From ad6ae86615ed87b88f1746cbb87155a45a03b2c7 Mon Sep 17 00:00:00 2001 From: Iuri Malinoski Date: Wed, 11 Sep 2024 13:25:36 -0300 Subject: [PATCH 66/89] Better error message in the exception. --- README.md | 5 ++++- networkapi/api_neighbor/v4/exceptions.py | 8 +++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7caa9686..4b42c71a 100644 --- a/README.md +++ b/README.md @@ -31,8 +31,11 @@ It was not created to be and inventory database, so it does not have CMDB functi ## Documentation [Documentation](http://globonetworkapi.readthedocs.org/) +## Run API +Run `make build_img && make start` and visit `http://localhost:8000/healthcheck` if running locally. + ## Run Unit Tests -To run the unit tests just run `make build_img && make start && make test_ci` this instruction will run all the unit tests specified in the `networkapi/tests/__init__.py` file. +Run `make test_ci`. This command will run all the unit tests specified in the `networkapi/tests/__init__.py` file. ## Create and run migrations To create a new migration, just run into app container `cd dbmigrate; db-migrate --new=`. This step will create a enpty migration file, you must write the SQL statement. diff --git a/networkapi/api_neighbor/v4/exceptions.py b/networkapi/api_neighbor/v4/exceptions.py index 187f1d3f..c2df486e 100644 --- a/networkapi/api_neighbor/v4/exceptions.py +++ b/networkapi/api_neighbor/v4/exceptions.py @@ -123,9 +123,11 @@ class RemoteIpAndRemoteAsnAtDifferentEquipmentsException(APIException): status_code = status.HTTP_400_BAD_REQUEST def __init__(self, neighbor): - self.detail = u'RemoteIp id = {} and RemoteAsn id = {} belongs to ' \ - u'different Equipments'.\ - format(neighbor.remote_ip, neighbor.remote_asn) + # self.detail = u'RemoteIp id = {} and RemoteAsn id = {} belongs to ' \ + # u'different Equipments'.\ + # format(neighbor.remote_ip, neighbor.remote_asn) + self.detail = u'O ASN remoto (id: {}) não está associado a qualquer equipamento do IP (id: {}). '.\ + format(neighbor.remote_asn, neighbor.remote_ip) class LocalIpAndPeerGroupAtDifferentEnvironmentsException(APIException): From 03527edf0a50be4615cfbe5e9374ea343eab3211 Mon Sep 17 00:00:00 2001 From: Iuri Malinoski Date: Thu, 26 Sep 2024 10:23:08 -0300 Subject: [PATCH 67/89] Bug fix for undeploying VIP request without associated equipment; Added additional debug logging. --- networkapi/api_equipment/exceptions.py | 4 ++-- networkapi/api_vip_request/facade/v3.py | 12 ++++++++++-- networkapi/api_vip_request/views/v3.py | 2 ++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/networkapi/api_equipment/exceptions.py b/networkapi/api_equipment/exceptions.py index 47b0eb3f..223806b6 100644 --- a/networkapi/api_equipment/exceptions.py +++ b/networkapi/api_equipment/exceptions.py @@ -7,8 +7,8 @@ class AllEquipmentsAreInMaintenanceException(APIException): status_code = status.HTTP_400_BAD_REQUEST default_detail = 'All equipments to be configured are in maintenance mode.' - def __init__(self, param=default_detail): - self.detail = param + def __init__(self, param=default_detail, equips=None): + self.detail = param if not equips else "{} Equipments: {}".format(param, equips) class EquipmentInvalidValueException(APIException): diff --git a/networkapi/api_vip_request/facade/v3.py b/networkapi/api_vip_request/facade/v3.py index 7d2780e0..5af635b9 100644 --- a/networkapi/api_vip_request/facade/v3.py +++ b/networkapi/api_vip_request/facade/v3.py @@ -156,6 +156,8 @@ def get_vip_request_by_search(search=dict()): def prepare_apply(load_balance, vip, created=True, user=None): + log.debug("Preparing to aplly. load_balance:%s vip:%s, created:%s", load_balance, vip, created) + vip_request = copy.deepcopy(vip) id_vip = str(vip_request.get('id')) @@ -617,6 +619,9 @@ def patch_real_vip_request(vip_requests, user): @commit_on_success def delete_real_vip_request(vip_requests, user, cleanup='0'): + + log.debug("Deleting real VIP request. vip_requests:%s cleanup:%s", vip_requests, cleanup) + load_balance = dict() cleanup = True if cleanup == '1' else False @@ -656,6 +661,8 @@ def delete_real_vip_request(vip_requests, user, cleanup='0'): def _validate_vip_to_apply(vip_request, update=False, user=None): + log.debug("Validating VIP to aplly. vip_request:%s update:%s", vip_request, update) + vip = get_vip_request_by_id(vip_request.get('id')) # validate vip with same ipv4 ou ipv6 @@ -676,11 +683,12 @@ def _validate_vip_to_apply(vip_request, update=False, user=None): raise exceptions.VipRequestAlreadyCreated(vip.id) equips = facade_eqpt.get_eqpt_by_envvip(vip_request['environmentvip']) + log.debug("equips:%s", equips) conf = EnvironmentVip.objects.get(id=vip_request['environmentvip']).conf - if facade_eqpt.all_equipments_are_in_maintenance(equips): - raise exceptions_eqpt.AllEquipmentsAreInMaintenanceException() + if equips and facade_eqpt.all_equipments_are_in_maintenance(equips): + raise exceptions_eqpt.AllEquipmentsAreInMaintenanceException(equips=equips) if user: if not facade_eqpt.all_equipments_can_update_config(equips, user): diff --git a/networkapi/api_vip_request/views/v3.py b/networkapi/api_vip_request/views/v3.py index bb54b114..3536eb2f 100644 --- a/networkapi/api_vip_request/views/v3.py +++ b/networkapi/api_vip_request/views/v3.py @@ -74,6 +74,8 @@ def delete(self, request, *args, **kwargs): """ + log.debug("Undeploying vip request. kwargs: %s", kwargs) + vip_request_ids = kwargs['obj_ids'].split(';') cleanup = request.GET.get('cleanup', '0') From 82ebf39f0d1d1a3160befe53b8fb01ff1a04c9b7 Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Fri, 18 Oct 2024 14:59:00 -0300 Subject: [PATCH 68/89] added channel verification --- networkapi/api_channel/facade.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/networkapi/api_channel/facade.py b/networkapi/api_channel/facade.py index 14fbba26..9aededc9 100644 --- a/networkapi/api_channel/facade.py +++ b/networkapi/api_channel/facade.py @@ -60,6 +60,13 @@ def create(self, data): vlan_nativa = data.get('vlan') envs_vlans = data.get('envs_vlans') + ### Verify if channel number is greater than 0 and smaller or equal to 4096 + if 0 > int(nome) > 4096: + log.error("Channel %s must be between 0 and 4097." % nome) + raise InterfaceError( + "Channel %s must be between 0 and 4097." % nome + ) + api_interface_facade.verificar_vlan_nativa(vlan_nativa) # Checks if Port Channel name already exists on equipment From 75347113a7178933a07ec983e0891ba49423d830 Mon Sep 17 00:00:00 2001 From: Renan Lopes Date: Mon, 21 Oct 2024 14:41:38 -0300 Subject: [PATCH 69/89] better condition --- networkapi/api_channel/facade.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/networkapi/api_channel/facade.py b/networkapi/api_channel/facade.py index 9aededc9..c77621a9 100644 --- a/networkapi/api_channel/facade.py +++ b/networkapi/api_channel/facade.py @@ -61,7 +61,7 @@ def create(self, data): envs_vlans = data.get('envs_vlans') ### Verify if channel number is greater than 0 and smaller or equal to 4096 - if 0 > int(nome) > 4096: + if int(nome) > 4096 or int(nome) <=1 : log.error("Channel %s must be between 0 and 4097." % nome) raise InterfaceError( "Channel %s must be between 0 and 4097." % nome From acf8948c6cd40c0d0d411fcabbe476ea329b8470 Mon Sep 17 00:00:00 2001 From: Iuri Malinoski Date: Thu, 24 Oct 2024 13:03:37 -0300 Subject: [PATCH 70/89] collecting data --- networkapi/api_interface/views.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/networkapi/api_interface/views.py b/networkapi/api_interface/views.py index 7d6d92c4..e200fb64 100644 --- a/networkapi/api_interface/views.py +++ b/networkapi/api_interface/views.py @@ -327,6 +327,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'] @@ -354,6 +358,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 @@ -369,8 +375,29 @@ 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) + for interface in interfaces.get('interfaces'): + + # User interface input,ex.: + # eth1, eth1/1, 1, Gi1/5, FF:FF:FF:FF:FF:F, int1, mgmt0, ethernet1/12, .. + interface_input = interface['interface'] + log.debug('interface_input: %s', interface_input) + + # Equipments from input interface + equipment_id = interface['equipment'] + log.info('equipment_id: %s', equipment_id) + 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.info("equipment_list %s", equipment_list) + for equipment_interface in equipment_list: + log.info('equipment_interface: %s', equipment_interface.interface) + for i in interfaces.get('interfaces'): try: interface = facade.create_interface(i) From 556c5f77bd850ccb3aa171640b09f24154c95f67 Mon Sep 17 00:00:00 2001 From: Iuri Malinoski Date: Thu, 24 Oct 2024 13:55:28 -0300 Subject: [PATCH 71/89] code clean --- networkapi/api_interface/views.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/networkapi/api_interface/views.py b/networkapi/api_interface/views.py index e200fb64..6779e5eb 100644 --- a/networkapi/api_interface/views.py +++ b/networkapi/api_interface/views.py @@ -380,23 +380,24 @@ def post(self, request, *args, **kwargs): log.info('kwargs: %s', kwargs) json_validate(SPECS.get('interface_post')).validate(interfaces) + # Validate input user interface for interface in interfaces.get('interfaces'): - # User interface input,ex.: - # eth1, eth1/1, 1, Gi1/5, FF:FF:FF:FF:FF:F, int1, mgmt0, ethernet1/12, .. + # 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'] log.debug('interface_input: %s', interface_input) # Equipments from input interface equipment_id = interface['equipment'] - log.info('equipment_id: %s', equipment_id) + log.debug('equipment_id: %s', equipment_id) 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.info("equipment_list %s", equipment_list) + log.debug("equipment_list %s", equipment_list) for equipment_interface in equipment_list: - log.info('equipment_interface: %s', equipment_interface.interface) + log.debug('equipment_interface: %s', equipment_interface.interface) for i in interfaces.get('interfaces'): try: From 451b2f9cdd1d02efc74bf7087c88da668322b9e2 Mon Sep 17 00:00:00 2001 From: Iuri Malinoski Date: Wed, 30 Oct 2024 11:23:03 -0300 Subject: [PATCH 72/89] Adding overrides validator to POST interfaces. --- networkapi/api_interface/views.py | 15 +++-- networkapi/util/interface_validate.py | 87 +++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 4 deletions(-) create mode 100644 networkapi/util/interface_validate.py diff --git a/networkapi/api_interface/views.py b/networkapi/api_interface/views.py index 6779e5eb..c7b1408a 100644 --- a/networkapi/api_interface/views.py +++ b/networkapi/api_interface/views.py @@ -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 @@ -380,24 +381,30 @@ def post(self, request, *args, **kwargs): log.info('kwargs: %s', kwargs) json_validate(SPECS.get('interface_post')).validate(interfaces) - # Validate input user interface + 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'] - log.debug('interface_input: %s', interface_input) + user_interface_str_list.append(interface_input) # Equipments from input interface equipment_id = interface['equipment'] - log.debug('equipment_id: %s', equipment_id) 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: - log.debug('equipment_interface: %s', equipment_interface.interface) + 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: diff --git a/networkapi/util/interface_validate.py b/networkapi/util/interface_validate.py new file mode 100644 index 00000000..d045681a --- /dev/null +++ b/networkapi/util/interface_validate.py @@ -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)) From c417553850d40256b8f82cad9203d8df9b4023be Mon Sep 17 00:00:00 2001 From: "renan.lopes" Date: Fri, 31 Jan 2025 18:06:24 -0300 Subject: [PATCH 73/89] first steps --- networkapi/api_deploy/facade.py | 4 +- networkapi/plugins/Netconf/BGP/Cli.py | 132 +++++++++++++++++++ networkapi/plugins/Netconf/BGP/__init__.py | 0 networkapi/plugins/Netconf/__init__.py | 0 networkapi/plugins/Netconf/plugin.py | 146 +++++++++++++++++++++ networkapi/plugins/factory.py | 3 + 6 files changed, 283 insertions(+), 2 deletions(-) create mode 100644 networkapi/plugins/Netconf/BGP/Cli.py create mode 100644 networkapi/plugins/Netconf/BGP/__init__.py create mode 100644 networkapi/plugins/Netconf/__init__.py create mode 100644 networkapi/plugins/Netconf/plugin.py diff --git a/networkapi/api_deploy/facade.py b/networkapi/api_deploy/facade.py index 1c7c3a35..b2e34ddb 100644 --- a/networkapi/api_deploy/facade.py +++ b/networkapi/api_deploy/facade.py @@ -20,7 +20,7 @@ from networkapi.api_equipment.exceptions import AllEquipmentsAreInMaintenanceException from networkapi.api_rest import exceptions as api_exceptions from networkapi.distributedlock import distributedlock -from networkapi.equipamento.models import Equipamento +from networkapi.equipamento.models import Equipamento, EquipamentoAcesso from networkapi.extra_logging import local from networkapi.extra_logging import NO_REQUEST_ID from networkapi.plugins.factory import PluginFactory @@ -41,7 +41,7 @@ log = logging.getLogger(__name__) -def _applyconfig(equipment, filename, equipment_access=None, source_server=None, port=22): +def _applyconfig(equipment: Equipamento, filename, equipment_access: EquipamentoAcesso=None, source_server=None, port=22): """Apply configuration file on equipment Args: diff --git a/networkapi/plugins/Netconf/BGP/Cli.py b/networkapi/plugins/Netconf/BGP/Cli.py new file mode 100644 index 00000000..13500377 --- /dev/null +++ b/networkapi/plugins/Netconf/BGP/Cli.py @@ -0,0 +1,132 @@ +# -*- 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 +import os + +from django.db.models import Q +from django.template import Context +from django.template import Template + +from networkapi.api_deploy import exceptions as deploy_exc +from networkapi.api_equipment.exceptions import \ + AllEquipmentsAreInMaintenanceException +from networkapi.api_neighbor.models import NeighborV4 +from networkapi.api_neighbor.models import NeighborV6 +from networkapi.equipamento import models as eqpt_models +from networkapi.extra_logging import local +from networkapi.extra_logging import NO_REQUEST_ID +from networkapi.infrastructure.ipaddr import IPAddress +from networkapi.settings import BGP_CONFIG_FILES_PATH +from networkapi.settings import BGP_CONFIG_TEMPLATE_PATH +from networkapi.settings import BGP_CONFIG_TOAPPLY_REL_PATH +from networkapi.settings import TFTPBOOT_FILES_PATH +from networkapi.plugins.Juniper.JUNOS.plugin import JUNOS +from networkapi.plugins.Netconf.plugin import GenericNetconf + +log = logging.getLogger(__name__) + +class Generic(GenericNetconf): + + TEMPLATE_NEIGHBOR_V4_ADD = 'neighbor_v4_add' + TEMPLATE_NEIGHBOR_V4_REMOVE = 'neighbor_v4_remove' + TEMPLATE_NEIGHBOR_V6_ADD = 'neighbor_v6_add' + TEMPLATE_NEIGHBOR_V6_REMOVE = 'neighbor_v6_remove' + TEMPLATE_LIST_CONFIG_ADD = 'list_config_add' + TEMPLATE_LIST_CONFIG_REMOVE = 'list_config_remove' + TEMPLATE_ROUTE_MAP_ADD = 'route_map_add' + TEMPLATE_ROUTE_MAP_REMOVE = 'route_map_remove' + + def bgp(self): + return Generic(equipment=self.equipment) + + def _deploy_pre_req(self, neighbor): + log.info("_deploy_pre_req") + + # Concatenate RouteMapEntries Lists + route_map_in = neighbor.peer_group.route_map_in + route_map_out = neighbor.peer_group.route_map_out + + rms = route_map_in.route_map_entries | \ + route_map_out.route_map_entries + + for rm_entry in rms: + list_config_bgp = rm_entry.list_config_bgp + + if not list_config_bgp.equipments.filter(id=self.equipment.id): + self.deploy_list_config_bgp(list_config_bgp) + + @staticmethod + def _get_type_list(type_): + types = { + 'P': { + 'config_list': 'prefix-list', + 'route_map': 'ip address prefix-list' + }, + 'C': { + 'config_list': 'community', + 'route_map': '' + }, + } + return types[type_] + + + def _generate_template_dict_route_map(self, route_map): + """ + Make a dictionary to use in template + """ + + entries = [] + + for entry_obj in route_map.routemapentry_set.all(): + action = 'permit' if entry_obj.action == 'P' else 'deny' + entry = { + 'ACTION': action, + 'ORDER': entry_obj.order, + 'TYPE_MATCH': self._get_type_list( + entry_obj.list_config_bgp.type)['route_map'], + 'LIST': entry_obj.list_config_bgp.name, + 'ACTION_RECONFIG': entry_obj.action_reconfig + } + + entries.append(entry) + + key_dict = { + 'NAME': route_map.name, + 'ENTRIES': entries + } + + return key_dict + + def _operate_equipment(self, types, template_type, config): + # TODO + return + + def deploy_route_map(self, route_map): + """ + Deploy route map + """ + + log.info("Deploy route map") + + config = self._generate_template_dict_route_map(route_map) + + self._operate_equipment( + 'route_map', self.TEMPLATE_ROUTE_MAP_ADD, config + ) + + diff --git a/networkapi/plugins/Netconf/BGP/__init__.py b/networkapi/plugins/Netconf/BGP/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/networkapi/plugins/Netconf/__init__.py b/networkapi/plugins/Netconf/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/networkapi/plugins/Netconf/plugin.py b/networkapi/plugins/Netconf/plugin.py new file mode 100644 index 00000000..a103b7eb --- /dev/null +++ b/networkapi/plugins/Netconf/plugin.py @@ -0,0 +1,146 @@ +from ncclient import manager +from networkapi.plugins import exceptions +from networkapi.equipamento.models import EquipamentoAcesso +from networkapi.plugins.base import BasePlugin +import logging + + +log = logging.getLogger(__name__) + +class GenericNetconf(BasePlugin): + def __try_lock(self): + """ + Try lock to equipment, not necessary in Ncclient + """ + return True + + def connect(self) -> manager.connect: + """ + + Connects to equipment using NCClient to provide Netconf access + + :raises: + IOError: If can't connect to host + Exception: to any other unhandled exceptions + :return: + NCClient connect object + """ + + ### If equipment access was not provided, then search the access ### + if self.equipment_access is None: + try: + self.equipment_access = EquipamentoAcesso.search( + None, self.equipment, 'netconf').uniqueResult() + except Exception: + ### Equipment access not found + log.error('Access type %s not found for equipment %s.' % + ('netconf', self.equipment.nome)) + raise exceptions.InvalidEquipmentAccessException() + ### End block ### + + ### Getting device access data ### + device = self.equipment_access.fqdn + username = self.equipment_access.user + password = self.equipment_access.password + ### End block ### + + ### Runs connection ### + try: + with manager.connect( + host = device, + port = self.connection_port, + username = username, + password = password, + hostkey_verify = False + ) as m: + return m + + ### Exception handler + except IOError, e: + log.error('Could not connect to host %s: %s' % (device, e)) + raise exceptions.ConnectionException(device) + except Exception, e: + log.error('Error connecting to host %s:%s' % (device, e)) + + + def apply_config_to_equipment(self, config, use_vrf=None, tarqet='running'): + + try: + if use_vrf is None: + use_vrf = self.management_vrf + + log.info("Config to apply: '%s'", % config) + + response = self.connect.edit_config(tarqet=tarqet, config=config) + log.info(response) + + return response + + except Exception, e: + log.error('Error on apply config to equipment') + + def ensure_privilege_level(self, privilege_level=None): + """ + Ensure privilege level verifying if the current user is super-user. + + :returns: + Returns True if success, otherwise, raise an exception (it will NOT return a false result) + """ + return True + + def copyScriptFileToConfig(self, filename, use_vrf='', destination=''): + """ + Receives the file path (usually in /mnt/scripts/tftpboot/networkapi/generated_config/interface/) + where contains the command to be executed in the equipment + But in this case, we will not copy a file. We will use the file to read the configuration and apply to + equipment by Netconf + + :param str filename: must contain the full path and file name + :param str use_vrf: not used + :param str destination: not used + + :returns: + Returns a success message, otherwise, raise an exception. That means will NOT return a false result. + """ + + log.info("Trying to load file configuration for host {} ...".format(self.equipment_access.fqdn)) + + # 'filename' was defined in super class, but in plugin junos the 'file_path' will be used instead + file_path = filename + file_path = self.check_configuration_file_exists(file_path) + + try: + command_file = open(file_path, "r") + command = command_file.read() + + # Check if Configuration is not empty and raises exception if not contain + self.check_configuration_has_content(command=command, file_path=file_path) + + log.info("Load configuration from file {} successfully".format(file_path)) + + return self.exec_command(command=command) + + except IOError as e: + self.close() + message = "Configuration file not found." # Message to client + log.error("{} {}: {}".format(message, file_path, e)) # Message to log + raise exceptions.APIException(message) + + def exec_command(self, command, success_regex='', invalid_regex=None, error_regex=None): + """ + Execute a command in equipment by netconf + """ + + log.info("Trying to execute a configuration on host {}...".format(self.equipment_access.fqdn)) + + # try: + self.__try_lock() # Do nothing, will be executed by the locked method of ncclient + with self.connect() as connection: + with connection.locked(target='running'): + connection.edit_config(target='running', config=command) + + result_message = "Configuration was executed successfully on {}.".format(self.equipment_access.fqdn) + log.info(result_message) + return result_message + + # except \ No newline at end of file diff --git a/networkapi/plugins/factory.py b/networkapi/plugins/factory.py index a6ab32e1..5618fe5c 100644 --- a/networkapi/plugins/factory.py +++ b/networkapi/plugins/factory.py @@ -58,6 +58,9 @@ def get_plugin(cls, **kwargs): if re.search('C9500', modelo.upper(), re.DOTALL): from .Cisco.IOS.plugin import IOS return IOS + if re.search('CloudEngine 8875-24BQ8DQ') or re.search('CloudEngine CE8850E-32CQ'): + from .Netconf.plugin import GenericNetconf + return GenericNetconf if 'marca' in kwargs: marca = kwargs.get('marca') From 4cfc8f02559d948a4744e6ef76ebaf04e71be0c5 Mon Sep 17 00:00:00 2001 From: "renan.lopes" Date: Mon, 3 Feb 2025 15:14:33 -0300 Subject: [PATCH 74/89] finished cli to netconf --- networkapi/plugins/Netconf/BGP/Cli.py | 396 +++++++++++++++++++++++++- 1 file changed, 394 insertions(+), 2 deletions(-) diff --git a/networkapi/plugins/Netconf/BGP/Cli.py b/networkapi/plugins/Netconf/BGP/Cli.py index 13500377..12a39dcb 100644 --- a/networkapi/plugins/Netconf/BGP/Cli.py +++ b/networkapi/plugins/Netconf/BGP/Cli.py @@ -54,6 +54,7 @@ class Generic(GenericNetconf): def bgp(self): return Generic(equipment=self.equipment) + def _deploy_pre_req(self, neighbor): log.info("_deploy_pre_req") @@ -70,6 +71,7 @@ def _deploy_pre_req(self, neighbor): if not list_config_bgp.equipments.filter(id=self.equipment.id): self.deploy_list_config_bgp(list_config_bgp) + @staticmethod def _get_type_list(type_): types = { @@ -85,6 +87,73 @@ def _get_type_list(type_): return types[type_] + @staticmethod + def _read_config(filename): + """ + Return the content from template_file + """ + + try: + file_handle = open(filename, 'r') + template_content = Template(file_handle.read()) + file_handle.close() + + except IOError, e: + log.error('Error opening template file for read: %s' % filename) + raise Exception(e) + + except Exception, e: + log.error('Syntax error when parsing template: %s' % e) + raise Exception(e) + + return template_content + + + @staticmethod + def _save_config(filename, config): + """ + Write config in template file + """ + + try: + file_handle = open(filename, 'w') + log.debug(filename) + file_handle.write(config) + file_handle.close() + + except IOError, e: + log.error('Error writting to config gile: %s' % filename) + raise e + + + @staticmethod + def _generate_template_dict_neighbor(neighbor): + """ + Make a dictionary to use in template + """ + + key_dict = { + 'AS_NUMBER': neighbor.local_asn.name, + 'LOCAL_IP': str(neighbor.local_ip), + 'VRF_NAME': neighbor.remote_ip.networkipv4.vlan.ambiente.default_vrf.internal_name, + 'REMOTE_IP': str(neighbor.remote_ip), + 'REMOTE_AS': neighbor.remote_asn.name, + 'ROUTE_MAP_IN': neighbor.peer_group.route_map_in.name, + 'ROUTE_MAP_OUT': neighbor.peer_group.route_map_out.name, + 'PASSWORD': neighbor.password, + 'TIMER_KEEPALIVE': neighbor.timer_keepalive, + 'TIMER_TIMEOUT': neighbor.timer_timeout, + 'DESCRIPTION': neighbor.description, + 'SOFT_RECONFIGURATION': neighbor.soft_reconfiguration, + 'NEXT_HOP_SELF': neighbor.next_hop_self, + 'REMOVE_PRIVATE_AS': neighbor.remove_private_as, + 'COMMUNITY': neighbor.community, + 'GROUP': 'GROUPT_{}'.format(neighbor.remote_ip) + } + + return key_dict + + def _generate_template_dict_route_map(self, route_map): """ Make a dictionary to use in template @@ -112,9 +181,276 @@ def _generate_template_dict_route_map(self, route_map): return key_dict + + def _get_equipment_template(self, template_type): + """ + Return a script by equipment and template_type + """ + + try: + return eqpt_models.EquipamentoRoteiro.search( + None, self.equipment.id, template_type + ).uniqueResult() + + except Exception as e: + log.error('Template type %s not found. Error: %s' %(template_type, e)) + raise self.exceptions.BGPTemplateException() + + + def _load_template_file(self, template_type): + """ + Load template file with specific type related to equipment + + :template_type: Type of template to be loaded + + :returns: template string + """ + + equipment_template = self._get_equipment_template(template_type=template_type) + + filename = BGP_CONFIG_TEMPLATE_PATH + '/' + equipment_template.roteiro.roteiro + + template_file = self._read_config(filename=filename) + + return template_file + + + def _get_template_config(self, template_type, config): + """ + Load template file and render values in VARs + """ + + try: + template_file = self._load_template_file(template_type=template_type) + config_to_be_saved = template_type.render(Context(config)) + + except KeyError as err: + log.error('Error %s' % err) + raise deploy_exc.InvalidKeyException(err) + + except Exception as err: + log.error('Error: %s' % err) + raise self.exceptions.BGPTemplateException(err) + + return config_to_be_saved + + + def _generate_config_file(self, types, template_type, config): + """ + Load a template and write a file with the rended output + + :returns: filename with relative path to settings.TFTPBOOT_FILES_PATH + """ + + request_id = getattr(local, 'request_id', NO_REQUEST_ID) + + filename_out = 'bgp_{}_{}_config_{}'.format( + types, self.equipment.id, request_id + ) + + filename = BGP_CONFIG_FILES_PATH + filename_out + rel_file_to_deploy = BGP_CONFIG_TOAPPLY_REL_PATH + filename_out + + config = self._get_template_config(template_type=template_type, config=config) + self._save_config(filename=filename, config=config) + + return rel_file_to_deploy + + + def _apply_config(self, filename): + + log.info("_apply_config") + + if self.equipment.maintenance: + raise AllEquipmentsAreInMaintenanceException() + + self.copyScriptFileToConfig(filename=filename, destination='running-config') + + + def _deploy_config_in_equipment(self, rel_filename): + + path = os.path.abspath(TFTPBOOT_FILES_PATH + rel_filename) + + if not path.startswith(TFTPBOOT_FILES_PATH): + raise deploy_exc.InvalidFilenameException(rel_filename) + + return self._apply_config(filename=rel_filename) + + def _operate_equipment(self, types, template_type, config): - # TODO - return + + self.connect() + file_to_deploy = self._generate_config_file( + types=types, template_type=template_type, config=config + ) + self._deploy_config_in_equipment(file_to_deploy) + + + def _generate_template_dict_list_config_bgp(self, list_config_bgp): + """ + Make a dictionary to use in template + """ + + log.info("_generate_template_dict_list_config_bgp") + + key_dict = { + 'TYPE': self._get_type_list(list_config_bgp.type)['config_list'], + 'NAME': list_config_bgp.name, + 'CONFIG': list_config_bgp.config + } + + return key_dict + + + def _undeploy_pre_req(self, neighbor, ip_version): + + log.info("_undeploy_pre_req") + + # Concatenate RouteMapEntries Lists + route_map_in = neighbor.peer_group.route_map_in + route_map_out = neighbor.peer_group.route_map_out + + neighbors_v4 = NeighborV4.objects.filter(Q( + Q(peer_group__route_map_in=route_map_in) | + Q(peer_group__route_map_out=route_map_in) + )).filter(created=True) + + neighbors_v6 = NeighborV6.objects.filter(Q( + Q(peer_group__route_map_in=route_map_in) | + Q(peer_group__route_map_out=route_map_in) + )).filter(created=True) + + neighbors_v4 = neighbors_v4.exclude(Q(id=neighbor.id)) + neighbors_v6 = neighbors_v6.exclude(Q(id=neighbor.id)) + + if not neighbors_v4 and not neighbors_v6: + try: + self.undeploy_route_map(route_map_in) + + except Exception as e: + log.error("Error while undeploying route-map. Error: {}".format(e)) + + neighbors_v4 = NeighborV4.objects.filter(Q( + Q(peer_group__route_map_in=route_map_out) | + Q(peer_group__route_map_out=route_map_out) + )).filter(created=True) + + neighbors_v6 = NeighborV6.objects.filter(Q( + Q(peer_group__route_map_in=route_map_out) | + Q(peer_group__route_map_out=route_map_out) + )).filter(created=True) + + neighbors_v4 = neighbors_v4.exclude(Q(id=neighbor.id)) + neighbors_v6 = neighbors_v6.exclude(Q(id=neighbor.id)) + + if not neighbors_v4 and not neighbors_v6: + try: + self._undeploy_route_map(route_map=route_map_out) + + except Exception as e: + log.error("Error while undeploying route-map. Error: {}".format(e)) + + # List Config BGP + if not neighbors_v4 and not neighbors_v6: + rms = route_map_in.route_map_entries | \ + route_map_out.route_map_entries + + for rm_entry in rms: + list_config_bgp = rm_entry.list_config_bgp + + neighbors_v4 = NeighborV4.objects.filter(Q( + Q(peer_group__route_map_in__routemapentry__list_config_bgp=list_config_bgp) | + Q(peer_group__route_map_out__routemapentry__list_config_bgp=list_config_bgp) + )).filter(created=True) + + neighbors_v6 = NeighborV6.objects.filter(Q( + Q(peer_group__route_map_in__routemapentry__list_config_bgp=list_config_bgp) | + Q(peer_group__route_map_out__routemapentry__list_config_bgp=list_config_bgp) + )).filter(created=True) + + neighbors_v4 = neighbors_v4.exclude(Q(id=neighbor.id)) + neighbors_v6 = neighbors_v6.exclue(Q(id=neighbor.id)) + + if not neighbors_v4 and not neighbors_v6: + try: + self.undeploy_list_config_bgp(list_config_bgp=list_config_bgp) + + except Exception as e: + log.error("Error while undeploying prefix-list. Error: {}".format(e)) + + + def _operate(self, types, template_type, config): + + file_to_deploy = self._generate_config_file( + types=types, + template_type=template_type, + config=config + ) + self._deploy_config_in_equipment(rel_filename=file_to_deploy) + self.close() + + + def _undeploy_route_map(self, route_map): + """ + Undeploy route map + """ + + config = self._generate_template_dict_route_map(route_map=route_map) + + self._operate( + types='route_map', + template_type=self.TEMPLATE_ROUTE_MAP_REMOVE, + config=config + ) + + + def _open(self): + + self.connect() + + + def undeploy_neighbor(self, neighbor): + """ + Undeploy neighbor + """ + + ip_version = IPAddress(str(neighbor.remote_ip)).version + + template_type = self.TEMPLATE_NEIGHBOR_V4_REMOVE \ + if ip_version == 4 else self.TEMPLATE_NEIGHBOR_V6_REMOVE + + config = self._generate_template_dict_neighbor(neighbor=neighbor) + + self._open() + self._operate( + types='neighbor', + template_type=template_type, + config=config + ) + + self._undeploy_pre_req( + neighbor=neighbor, + ip_version=ip_version + ) + + self.close() + + + def deploy_list_config_bgp(self, list_config_bgp): + """ + Deploy prefix list + """ + + log.info("deploy_list_config_bgp") + + config = self._generate_template_dict_list_config_bgp(list_config_bgp=list_config_bgp) + + self._operate_equipment( + types='list_config_bgp', + template_type=self.TEMPLATE_LIST_CONFIG_ADD, + config=config + ) + def deploy_route_map(self, route_map): """ @@ -130,3 +466,59 @@ def deploy_route_map(self, route_map): ) + def undeploy_list_config_bgp(self, list_config_bgp): + """ + Undeploy prefix list + """ + + log.info("Undeploy list config BGP") + + config = self._generate_template_dict_list_config_bgp(list_config_bgp=list_config_bgp) + + self._operate_equipment( + types='list_config_bgp', + template_type=self.TEMPLATE_LIST_CONFIG_REMOVE, + config=config + ) + + + def deploy_neighbor(self, neighbor): + """ + Deploy neighbor + """ + + self._deploy_pre_req(neighbor=neighbor) + + ip_version = IPAddress(str(neighbor.remote_ip)).version + + template_type = self.TEMPLATE_NEIGHBOR_V4_ADD if ip_version == 4 else \ + self.TEMPLATE_NEIGHBOR_V6_ADD + + config = self._generate_template_dict_neighbor(neighbor=neighbor) + + self._operate_equipment( + types='neighbor', + template_type=template_type, + config=config + ) + + + def undeploy_route_map(self, route_map): + """ + Undeply route map + """ + + config = self._generate_template_dict_route_map(route_map=route_map) + + self._operate( + types='route_map', + template_type=self.TEMPLATE_ROUTE_MAP_REMOVE, + config=config + ) + + + def _close(self): + + self.close() + + From 3049a45c2b117a670ec1010151f1fe1049ad6414 Mon Sep 17 00:00:00 2001 From: "renan.lopes" Date: Mon, 3 Feb 2025 15:16:31 -0300 Subject: [PATCH 75/89] better lint --- networkapi/plugins/Netconf/BGP/Cli.py | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/networkapi/plugins/Netconf/BGP/Cli.py b/networkapi/plugins/Netconf/BGP/Cli.py index 12a39dcb..8814d8eb 100644 --- a/networkapi/plugins/Netconf/BGP/Cli.py +++ b/networkapi/plugins/Netconf/BGP/Cli.py @@ -35,7 +35,6 @@ from networkapi.settings import BGP_CONFIG_TEMPLATE_PATH from networkapi.settings import BGP_CONFIG_TOAPPLY_REL_PATH from networkapi.settings import TFTPBOOT_FILES_PATH -from networkapi.plugins.Juniper.JUNOS.plugin import JUNOS from networkapi.plugins.Netconf.plugin import GenericNetconf log = logging.getLogger(__name__) @@ -54,7 +53,6 @@ class Generic(GenericNetconf): def bgp(self): return Generic(equipment=self.equipment) - def _deploy_pre_req(self, neighbor): log.info("_deploy_pre_req") @@ -71,7 +69,6 @@ def _deploy_pre_req(self, neighbor): if not list_config_bgp.equipments.filter(id=self.equipment.id): self.deploy_list_config_bgp(list_config_bgp) - @staticmethod def _get_type_list(type_): types = { @@ -86,7 +83,6 @@ def _get_type_list(type_): } return types[type_] - @staticmethod def _read_config(filename): """ @@ -108,7 +104,6 @@ def _read_config(filename): return template_content - @staticmethod def _save_config(filename, config): """ @@ -125,7 +120,6 @@ def _save_config(filename, config): log.error('Error writting to config gile: %s' % filename) raise e - @staticmethod def _generate_template_dict_neighbor(neighbor): """ @@ -153,7 +147,6 @@ def _generate_template_dict_neighbor(neighbor): return key_dict - def _generate_template_dict_route_map(self, route_map): """ Make a dictionary to use in template @@ -181,7 +174,6 @@ def _generate_template_dict_route_map(self, route_map): return key_dict - def _get_equipment_template(self, template_type): """ Return a script by equipment and template_type @@ -196,7 +188,6 @@ def _get_equipment_template(self, template_type): log.error('Template type %s not found. Error: %s' %(template_type, e)) raise self.exceptions.BGPTemplateException() - def _load_template_file(self, template_type): """ Load template file with specific type related to equipment @@ -214,7 +205,6 @@ def _load_template_file(self, template_type): return template_file - def _get_template_config(self, template_type, config): """ Load template file and render values in VARs @@ -234,7 +224,6 @@ def _get_template_config(self, template_type, config): return config_to_be_saved - def _generate_config_file(self, types, template_type, config): """ Load a template and write a file with the rended output @@ -256,7 +245,6 @@ def _generate_config_file(self, types, template_type, config): return rel_file_to_deploy - def _apply_config(self, filename): log.info("_apply_config") @@ -266,7 +254,6 @@ def _apply_config(self, filename): self.copyScriptFileToConfig(filename=filename, destination='running-config') - def _deploy_config_in_equipment(self, rel_filename): path = os.path.abspath(TFTPBOOT_FILES_PATH + rel_filename) @@ -276,7 +263,6 @@ def _deploy_config_in_equipment(self, rel_filename): return self._apply_config(filename=rel_filename) - def _operate_equipment(self, types, template_type, config): self.connect() @@ -285,7 +271,6 @@ def _operate_equipment(self, types, template_type, config): ) self._deploy_config_in_equipment(file_to_deploy) - def _generate_template_dict_list_config_bgp(self, list_config_bgp): """ Make a dictionary to use in template @@ -301,7 +286,6 @@ def _generate_template_dict_list_config_bgp(self, list_config_bgp): return key_dict - def _undeploy_pre_req(self, neighbor, ip_version): log.info("_undeploy_pre_req") @@ -378,7 +362,6 @@ def _undeploy_pre_req(self, neighbor, ip_version): except Exception as e: log.error("Error while undeploying prefix-list. Error: {}".format(e)) - def _operate(self, types, template_type, config): file_to_deploy = self._generate_config_file( @@ -389,7 +372,6 @@ def _operate(self, types, template_type, config): self._deploy_config_in_equipment(rel_filename=file_to_deploy) self.close() - def _undeploy_route_map(self, route_map): """ Undeploy route map @@ -403,12 +385,10 @@ def _undeploy_route_map(self, route_map): config=config ) - def _open(self): self.connect() - def undeploy_neighbor(self, neighbor): """ Undeploy neighbor @@ -435,7 +415,6 @@ def undeploy_neighbor(self, neighbor): self.close() - def deploy_list_config_bgp(self, list_config_bgp): """ Deploy prefix list @@ -451,7 +430,6 @@ def deploy_list_config_bgp(self, list_config_bgp): config=config ) - def deploy_route_map(self, route_map): """ Deploy route map @@ -465,7 +443,6 @@ def deploy_route_map(self, route_map): 'route_map', self.TEMPLATE_ROUTE_MAP_ADD, config ) - def undeploy_list_config_bgp(self, list_config_bgp): """ Undeploy prefix list @@ -481,7 +458,6 @@ def undeploy_list_config_bgp(self, list_config_bgp): config=config ) - def deploy_neighbor(self, neighbor): """ Deploy neighbor @@ -502,7 +478,6 @@ def deploy_neighbor(self, neighbor): config=config ) - def undeploy_route_map(self, route_map): """ Undeply route map @@ -516,9 +491,7 @@ def undeploy_route_map(self, route_map): config=config ) - def _close(self): self.close() - From 7a2af8c13b0f381c0f39601d22c6a18f6eaf0d20 Mon Sep 17 00:00:00 2001 From: "renan.lopes" Date: Tue, 4 Feb 2025 18:01:05 -0300 Subject: [PATCH 76/89] started to add logs on methods --- networkapi/plugins/Netconf/BGP/Cli.py | 111 +++++++++++++++++++++++++- networkapi/plugins/Netconf/plugin.py | 57 ++++++++++--- networkapi/plugins/factory.py | 7 +- 3 files changed, 153 insertions(+), 22 deletions(-) diff --git a/networkapi/plugins/Netconf/BGP/Cli.py b/networkapi/plugins/Netconf/BGP/Cli.py index 8814d8eb..befcb71e 100644 --- a/networkapi/plugins/Netconf/BGP/Cli.py +++ b/networkapi/plugins/Netconf/BGP/Cli.py @@ -64,13 +64,28 @@ def _deploy_pre_req(self, neighbor): route_map_out.route_map_entries for rm_entry in rms: + log.info(rm_entry) list_config_bgp = rm_entry.list_config_bgp if not list_config_bgp.equipments.filter(id=self.equipment.id): + log.info("Deploying list config BGP on equipment. Equipment ID: '%s'." % self.equipment.id) self.deploy_list_config_bgp(list_config_bgp) + # Deploying routemap In on equipment + if not route_map_in.equipments.filter(id=self.equipment.id): + log.info("Deploying routemap in on equipment. Equipment ID: '%s'" % self.equipment.id) + self.deploy_route_map(neighbor.peer_group.route_map_id) + + # Deploying routemap Out on equipment + if not route_map_out.equipments.filter(id=self.equipment.id): + log.info("Deploying routemap out on equipment. Equipment ID: '%s'" % self.equipment.id) + self.deploy_route_map(neighbor.peer_group.route_map_out) + + @staticmethod def _get_type_list(type_): + log.info("Getting type list...") + types = { 'P': { 'config_list': 'prefix-list', @@ -81,6 +96,8 @@ def _get_type_list(type_): 'route_map': '' }, } + + log.info(types[type_]) return types[type_] @staticmethod @@ -89,10 +106,17 @@ def _read_config(filename): Return the content from template_file """ + log.info("Reading config from file: '%s'" % filename) + try: file_handle = open(filename, 'r') template_content = Template(file_handle.read()) + + log.info("Template content:") + log.info(template_content) + file_handle.close() + log.info('File closed.') except IOError, e: log.error('Error opening template file for read: %s' % filename) @@ -110,11 +134,15 @@ def _save_config(filename, config): Write config in template file """ + log.info("Saving config to file.") + log.info("Filename: %s" % filename) + log.info("Config: %s" % config) + try: file_handle = open(filename, 'w') - log.debug(filename) file_handle.write(config) file_handle.close() + log.info("File closed.") except IOError, e: log.error('Error writting to config gile: %s' % filename) @@ -126,6 +154,8 @@ def _generate_template_dict_neighbor(neighbor): Make a dictionary to use in template """ + log.info("Generating a template dict to neighbor... Neighbor ID: '%s'" % neighbor.id) + key_dict = { 'AS_NUMBER': neighbor.local_asn.name, 'LOCAL_IP': str(neighbor.local_ip), @@ -142,9 +172,11 @@ def _generate_template_dict_neighbor(neighbor): 'NEXT_HOP_SELF': neighbor.next_hop_self, 'REMOVE_PRIVATE_AS': neighbor.remove_private_as, 'COMMUNITY': neighbor.community, - 'GROUP': 'GROUPT_{}'.format(neighbor.remote_ip) + 'GROUP': 'GROUP_{}'.format(neighbor.remote_ip) } + log.info(key_dict) + return key_dict def _generate_template_dict_route_map(self, route_map): @@ -152,6 +184,8 @@ def _generate_template_dict_route_map(self, route_map): Make a dictionary to use in template """ + log.info("Generate template dict for routemap. Routemap name: '%s'" % route_map.name) + entries = [] for entry_obj in route_map.routemapentry_set.all(): @@ -172,6 +206,8 @@ def _generate_template_dict_route_map(self, route_map): 'ENTRIES': entries } + log.info(key_dict) + return key_dict def _get_equipment_template(self, template_type): @@ -179,6 +215,8 @@ def _get_equipment_template(self, template_type): Return a script by equipment and template_type """ + log.info("Getting equipment's template... Template type: '%s'" % template_type) + try: return eqpt_models.EquipamentoRoteiro.search( None, self.equipment.id, template_type @@ -197,11 +235,16 @@ def _load_template_file(self, template_type): :returns: template string """ + log.info("Loading template file...") + equipment_template = self._get_equipment_template(template_type=template_type) + log.info("Equipment's template: '%s'" % equipment_template) filename = BGP_CONFIG_TEMPLATE_PATH + '/' + equipment_template.roteiro.roteiro + log.info("Filename: '%s'" % filename) template_file = self._read_config(filename=filename) + log.info("Template file: '%s'" % template_file) return template_file @@ -210,9 +253,12 @@ def _get_template_config(self, template_type, config): Load template file and render values in VARs """ + log.info("Getting template config...") + try: template_file = self._load_template_file(template_type=template_type) - config_to_be_saved = template_type.render(Context(config)) + config_to_be_saved = template_file.render(Context(config)) + log.info(config_to_be_saved) except KeyError as err: log.error('Error %s' % err) @@ -231,6 +277,8 @@ def _generate_config_file(self, types, template_type, config): :returns: filename with relative path to settings.TFTPBOOT_FILES_PATH """ + log.info("Generating config file...") + request_id = getattr(local, 'request_id', NO_REQUEST_ID) filename_out = 'bgp_{}_{}_config_{}'.format( @@ -240,8 +288,14 @@ def _generate_config_file(self, types, template_type, config): filename = BGP_CONFIG_FILES_PATH + filename_out rel_file_to_deploy = BGP_CONFIG_TOAPPLY_REL_PATH + filename_out + log.info("Filename: '%s'" % filename) + log.info("Relative file to deploy: '%s'" % rel_file_to_deploy) + config = self._get_template_config(template_type=template_type, config=config) + log.info("Config generated successfully.") + self._save_config(filename=filename, config=config) + log.info("Config saved successfully.") return rel_file_to_deploy @@ -253,9 +307,12 @@ def _apply_config(self, filename): raise AllEquipmentsAreInMaintenanceException() self.copyScriptFileToConfig(filename=filename, destination='running-config') + log.info("Configuration in file: '%s' successfully applyied on equipment" % filename) def _deploy_config_in_equipment(self, rel_filename): + log.info("Deploying config on equipment. Relative filename: '%s'." % rel_filename) + path = os.path.abspath(TFTPBOOT_FILES_PATH + rel_filename) if not path.startswith(TFTPBOOT_FILES_PATH): @@ -265,11 +322,20 @@ def _deploy_config_in_equipment(self, rel_filename): def _operate_equipment(self, types, template_type, config): + log.info("Operate equipment method...") + self.connect() + file_to_deploy = self._generate_config_file( types=types, template_type=template_type, config=config ) + log.info("Configuration file generated successfully") + self._deploy_config_in_equipment(file_to_deploy) + log.info("Configuration deployed on equipment successfully") + + self.close() + log.info("Connection closed successfully.") def _generate_template_dict_list_config_bgp(self, list_config_bgp): """ @@ -284,6 +350,8 @@ def _generate_template_dict_list_config_bgp(self, list_config_bgp): 'CONFIG': list_config_bgp.config } + log.info(key_dict) + return key_dict def _undeploy_pre_req(self, neighbor, ip_version): @@ -307,9 +375,14 @@ def _undeploy_pre_req(self, neighbor, ip_version): neighbors_v4 = neighbors_v4.exclude(Q(id=neighbor.id)) neighbors_v6 = neighbors_v6.exclude(Q(id=neighbor.id)) + log.info("Neighbors V4: '%s'." % neighbors_v4) + log.info("Neighbors V6: '%s'." % neighbors_v6) + if not neighbors_v4 and not neighbors_v6: + log.info("No neighbors founded...") try: self.undeploy_route_map(route_map_in) + log.info("Routemap '%s' undeployed successfully." % route_map_in) except Exception as e: log.error("Error while undeploying route-map. Error: {}".format(e)) @@ -327,9 +400,14 @@ def _undeploy_pre_req(self, neighbor, ip_version): neighbors_v4 = neighbors_v4.exclude(Q(id=neighbor.id)) neighbors_v6 = neighbors_v6.exclude(Q(id=neighbor.id)) + log.info("Neighbors V4: '%s'." % neighbors_v4) + log.info("Neighbors V6: '%s'." % neighbors_v6) + if not neighbors_v4 and not neighbors_v6: + log.info("No neighbors founded...") try: self._undeploy_route_map(route_map=route_map_out) + log.info("Routemap '%s' undeployed successfully." % route_map_out) except Exception as e: log.error("Error while undeploying route-map. Error: {}".format(e)) @@ -341,6 +419,7 @@ def _undeploy_pre_req(self, neighbor, ip_version): for rm_entry in rms: list_config_bgp = rm_entry.list_config_bgp + log.info("List config BGP: '%s'." % list_config_bgp) neighbors_v4 = NeighborV4.objects.filter(Q( Q(peer_group__route_map_in__routemapentry__list_config_bgp=list_config_bgp) | @@ -355,29 +434,45 @@ def _undeploy_pre_req(self, neighbor, ip_version): neighbors_v4 = neighbors_v4.exclude(Q(id=neighbor.id)) neighbors_v6 = neighbors_v6.exclue(Q(id=neighbor.id)) + log.info("Neighbors V4: '%s'." % neighbors_v4) + log.info("Neighbors V6: '%s'." % neighbors_v6) + if not neighbors_v4 and not neighbors_v6: + log.info("No neighbors founded...") try: self.undeploy_list_config_bgp(list_config_bgp=list_config_bgp) + log.info("List config BGP '%s' undeployed successfully." % list_config_bgp) except Exception as e: log.error("Error while undeploying prefix-list. Error: {}".format(e)) def _operate(self, types, template_type, config): + log.info("_operate method") + file_to_deploy = self._generate_config_file( types=types, template_type=template_type, config=config ) + + log.info("File to Deploy: '%s'." % file_to_deploy) + self._deploy_config_in_equipment(rel_filename=file_to_deploy) + log.info("Configuration successfully deployed on equipment.") + self.close() + log.info("Netconf session closed.") def _undeploy_route_map(self, route_map): """ Undeploy route map """ + log.info("Undelpoy routemap method started... Routemap: '%s'" % route_map) + config = self._generate_template_dict_route_map(route_map=route_map) + log.info("Configuration successfully generated.") self._operate( types='route_map', @@ -387,19 +482,26 @@ def _undeploy_route_map(self, route_map): def _open(self): + log.info("Openning Netconf session...") self.connect() + log.info("Session openned succesfully.") def undeploy_neighbor(self, neighbor): """ Undeploy neighbor """ + log.info("Undeploy neighbor method started... Neighbor: '%s'" % neighbor) + ip_version = IPAddress(str(neighbor.remote_ip)).version template_type = self.TEMPLATE_NEIGHBOR_V4_REMOVE \ if ip_version == 4 else self.TEMPLATE_NEIGHBOR_V6_REMOVE + log.info("Template type: '%s'." % template_type) + config = self._generate_template_dict_neighbor(neighbor=neighbor) + log.info("Configuration dict generated successfuly. Config: '%s'" % config) self._open() self._operate( @@ -412,6 +514,7 @@ def undeploy_neighbor(self, neighbor): neighbor=neighbor, ip_version=ip_version ) + log.info("Pre req undeployed successfully.") self.close() @@ -420,7 +523,7 @@ def deploy_list_config_bgp(self, list_config_bgp): Deploy prefix list """ - log.info("deploy_list_config_bgp") + log.info("Deploy list config BGP method started... List Config BGP: '%s'." % list_config_bgp) config = self._generate_template_dict_list_config_bgp(list_config_bgp=list_config_bgp) diff --git a/networkapi/plugins/Netconf/plugin.py b/networkapi/plugins/Netconf/plugin.py index a103b7eb..bc7c7bd1 100644 --- a/networkapi/plugins/Netconf/plugin.py +++ b/networkapi/plugins/Netconf/plugin.py @@ -8,6 +8,8 @@ log = logging.getLogger(__name__) class GenericNetconf(BasePlugin): + session_manager: manager = None + def __try_lock(self): """ Try lock to equipment, not necessary in Ncclient @@ -46,14 +48,13 @@ def connect(self) -> manager.connect: ### Runs connection ### try: - with manager.connect( + self.session_manager = manager.connect( host = device, port = self.connection_port, username = username, password = password, hostkey_verify = False - ) as m: - return m + ) ### Exception handler except IOError, e: @@ -62,7 +63,6 @@ def connect(self) -> manager.connect: except Exception, e: log.error('Error connecting to host %s:%s' % (device, e)) - def apply_config_to_equipment(self, config, use_vrf=None, tarqet='running'): try: @@ -133,14 +133,45 @@ def exec_command(self, command, success_regex='', invalid_regex=None, error_rege log.info("Trying to execute a configuration on host {}...".format(self.equipment_access.fqdn)) - # try: - self.__try_lock() # Do nothing, will be executed by the locked method of ncclient - with self.connect() as connection: - with connection.locked(target='running'): - connection.edit_config(target='running', config=command) + try: + self.__try_lock() # Do nothing, will be executed by the locked method of ncclient + # with self.connect() as connection: + # with connection.locked(target='running'): + # connection.edit_config(target='running', config=command) + + with self.session_manager.locked(target='running'): + self.session_manager.edit_config(target='running', config=command) + + result_message = "Configuration was executed successfully on {}.".format(self.equipment_access.fqdn) + log.info(result_message) + return result_message - result_message = "Configuration was executed successfully on {}.".format(self.equipment_access.fqdn) - log.info(result_message) - return result_message + except Exception as e: + message = "Error while excute netconf command on equipment %s" % self.equipment_access.fqdn + log.error(message) + log.error(e) + + raise exceptions.APIException(message) + + def close(self): + """ + Disconnect session from the equipment + + :returns: True if success or raise an exception on any error + """ + + try: + if self.session_manager: + self.session_manager.close_session() + return True + + else: + raise Exception("session_manager is None.") + + except Exception as e: + message = "Error while calling close session method on equipment %s" % self.equipment_access.fqdn + log.error(message) + log.error(e) + + raise exceptions.APIException(message) - # except \ No newline at end of file diff --git a/networkapi/plugins/factory.py b/networkapi/plugins/factory.py index 5618fe5c..e3735773 100644 --- a/networkapi/plugins/factory.py +++ b/networkapi/plugins/factory.py @@ -58,15 +58,12 @@ def get_plugin(cls, **kwargs): if re.search('C9500', modelo.upper(), re.DOTALL): from .Cisco.IOS.plugin import IOS return IOS - if re.search('CloudEngine 8875-24BQ8DQ') or re.search('CloudEngine CE8850E-32CQ'): - from .Netconf.plugin import GenericNetconf - return GenericNetconf if 'marca' in kwargs: marca = kwargs.get('marca') if re.search('HUAWEI', marca.upper(), re.DOTALL): - from .Huawei import Generic - return Generic + from .Netconf.plugin import GenericNetconf + return GenericNetconf if re.search('F5', marca.upper(), re.DOTALL): from .F5.Generic import Generic return Generic From 5686762f7607ee81bf465d92080e00cfec1db2a4 Mon Sep 17 00:00:00 2001 From: "renan.lopes" Date: Wed, 5 Feb 2025 10:34:54 -0300 Subject: [PATCH 77/89] Logs for CLI created --- networkapi/plugins/Netconf/BGP/Cli.py | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/networkapi/plugins/Netconf/BGP/Cli.py b/networkapi/plugins/Netconf/BGP/Cli.py index befcb71e..c94e5315 100644 --- a/networkapi/plugins/Netconf/BGP/Cli.py +++ b/networkapi/plugins/Netconf/BGP/Cli.py @@ -526,75 +526,92 @@ def deploy_list_config_bgp(self, list_config_bgp): log.info("Deploy list config BGP method started... List Config BGP: '%s'." % list_config_bgp) config = self._generate_template_dict_list_config_bgp(list_config_bgp=list_config_bgp) + log.info("Dict list config BGP generated successfully. Config: '%s'" % config) self._operate_equipment( types='list_config_bgp', template_type=self.TEMPLATE_LIST_CONFIG_ADD, config=config ) + log.info("List config BGP successfully deployed.") def deploy_route_map(self, route_map): """ Deploy route map """ - log.info("Deploy route map") + log.info("Deploy route map method started...") config = self._generate_template_dict_route_map(route_map) + log.info("Dict config for routemap created successfully... Config: '%s'" % config) self._operate_equipment( 'route_map', self.TEMPLATE_ROUTE_MAP_ADD, config ) + log.info("Routemap successfully deployed.") def undeploy_list_config_bgp(self, list_config_bgp): """ Undeploy prefix list """ - log.info("Undeploy list config BGP") + log.info("Undeploy list config BGP method started.") config = self._generate_template_dict_list_config_bgp(list_config_bgp=list_config_bgp) + log.info("Dict for list config BGP created. Config: '%s'" % config) self._operate_equipment( types='list_config_bgp', template_type=self.TEMPLATE_LIST_CONFIG_REMOVE, config=config ) + log.info("List config BGP successfully undeployed.") def deploy_neighbor(self, neighbor): """ Deploy neighbor """ + log.info("Deploy neighbor method started...") + self._deploy_pre_req(neighbor=neighbor) + log.info("Pre req successfully deployed...") ip_version = IPAddress(str(neighbor.remote_ip)).version template_type = self.TEMPLATE_NEIGHBOR_V4_ADD if ip_version == 4 else \ self.TEMPLATE_NEIGHBOR_V6_ADD + log.info("Template type: '%s'." % template_type) config = self._generate_template_dict_neighbor(neighbor=neighbor) + log.info("Dict for neighbor config successfully generated. Config: '%s'" % config) self._operate_equipment( types='neighbor', template_type=template_type, config=config ) + log.info("Neighbor deployed successfully.") def undeploy_route_map(self, route_map): """ Undeply route map """ + log.info("Undeploy routemap method started...") + config = self._generate_template_dict_route_map(route_map=route_map) + log.info("Dict for routemap config generated successfully. Config: '%s'" % config) self._operate( types='route_map', template_type=self.TEMPLATE_ROUTE_MAP_REMOVE, config=config ) + log.info("Routemap deployed successfully.") def _close(self): - + log.info("Close connection method started") self.close() + log.info("Connection closed successfully.") From 9d6d9d2789687d00f9d0e50c9ca6cdb57e09f057 Mon Sep 17 00:00:00 2001 From: "renan.lopes" Date: Wed, 5 Feb 2025 11:38:34 -0300 Subject: [PATCH 78/89] logs finished --- networkapi/plugins/Netconf/plugin.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/networkapi/plugins/Netconf/plugin.py b/networkapi/plugins/Netconf/plugin.py index bc7c7bd1..f1154b68 100644 --- a/networkapi/plugins/Netconf/plugin.py +++ b/networkapi/plugins/Netconf/plugin.py @@ -16,7 +16,7 @@ def __try_lock(self): """ return True - def connect(self) -> manager.connect: + def connect(self): """ Connects to equipment using NCClient to provide Netconf access @@ -24,13 +24,15 @@ def connect(self) -> manager.connect: :raises: IOError: If can't connect to host Exception: to any other unhandled exceptions - :return: - NCClient connect object + :return: None """ + log.info("Connection to equipment method started") + ### If equipment access was not provided, then search the access ### if self.equipment_access is None: try: + log.info("Searching for equipment access...") self.equipment_access = EquipamentoAcesso.search( None, self.equipment, 'netconf').uniqueResult() except Exception: @@ -48,6 +50,7 @@ def connect(self) -> manager.connect: ### Runs connection ### try: + log.info("Starting connection to '%s' using NCClient..." % device) self.session_manager = manager.connect( host = device, port = self.connection_port, @@ -55,6 +58,7 @@ def connect(self) -> manager.connect: password = password, hostkey_verify = False ) + log.info('Connection succesfully...') ### Exception handler except IOError, e: @@ -65,11 +69,12 @@ def connect(self) -> manager.connect: def apply_config_to_equipment(self, config, use_vrf=None, tarqet='running'): + log.info("Starting method to apply config on equipment... Config: '%s'" % config) try: if use_vrf is None: use_vrf = self.management_vrf - log.info("Config to apply: '%s'", % config) + log.info("Config to apply: '%s'" % config) response = self.connect.edit_config(tarqet=tarqet, config=config) log.info(response) @@ -108,6 +113,7 @@ def copyScriptFileToConfig(self, filename, use_vrf='', destination=''): # 'filename' was defined in super class, but in plugin junos the 'file_path' will be used instead file_path = filename file_path = self.check_configuration_file_exists(file_path) + log.info("Configuration for file '%s' is valid." % file_path) try: command_file = open(file_path, "r") @@ -135,10 +141,6 @@ def exec_command(self, command, success_regex='', invalid_regex=None, error_rege try: self.__try_lock() # Do nothing, will be executed by the locked method of ncclient - # with self.connect() as connection: - # with connection.locked(target='running'): - # connection.edit_config(target='running', config=command) - with self.session_manager.locked(target='running'): self.session_manager.edit_config(target='running', config=command) @@ -159,10 +161,11 @@ def close(self): :returns: True if success or raise an exception on any error """ - + log.info("Close connection started...") try: if self.session_manager: self.session_manager.close_session() + log.info('Connection closed successfully.') return True else: From e1fff973f321b0c1f19047ed0d0808cab3ccfaa3 Mon Sep 17 00:00:00 2001 From: "renan.lopes" Date: Thu, 6 Feb 2025 10:08:23 -0300 Subject: [PATCH 79/89] better lint --- networkapi/api_deploy/facade.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/networkapi/api_deploy/facade.py b/networkapi/api_deploy/facade.py index b2e34ddb..4c1405f6 100644 --- a/networkapi/api_deploy/facade.py +++ b/networkapi/api_deploy/facade.py @@ -41,7 +41,7 @@ log = logging.getLogger(__name__) -def _applyconfig(equipment: Equipamento, filename, equipment_access: EquipamentoAcesso=None, source_server=None, port=22): +def _applyconfig(equipment, filename, equipment_access=None, source_server=None, port=22): """Apply configuration file on equipment Args: From 557b92cccdf8ff799513b552375ec90f64ccbb85 Mon Sep 17 00:00:00 2001 From: "renan.lopes" Date: Fri, 23 May 2025 12:08:16 -0300 Subject: [PATCH 80/89] changed plugin to make a request instead of apply in equipment by netconf due incompatibility --- networkapi/plugins/Netconf/plugin.py | 172 +++++++++++++++++++++------ 1 file changed, 135 insertions(+), 37 deletions(-) diff --git a/networkapi/plugins/Netconf/plugin.py b/networkapi/plugins/Netconf/plugin.py index f1154b68..a4c30bf5 100644 --- a/networkapi/plugins/Netconf/plugin.py +++ b/networkapi/plugins/Netconf/plugin.py @@ -3,12 +3,21 @@ from networkapi.equipamento.models import EquipamentoAcesso from networkapi.plugins.base import BasePlugin import logging +from networkapi.system.facade import get_value +import paramiko +import requests, json, os +from django.db.utils import DatabaseError +from networkapi.system.exceptions import VariableDoesNotExistException + log = logging.getLogger(__name__) class GenericNetconf(BasePlugin): - session_manager: manager = None + session_manager = None + alternative_variable_base_path_list = ['path_to_tftpboot'] + alternative_static_base_path_list = ['/mnt/scripts/tftpboot/'] + def __try_lock(self): """ @@ -29,6 +38,8 @@ def connect(self): log.info("Connection to equipment method started") + + ### If equipment access was not provided, then search the access ### if self.equipment_access is None: try: @@ -42,23 +53,40 @@ def connect(self): raise exceptions.InvalidEquipmentAccessException() ### End block ### - ### Getting device access data ### - device = self.equipment_access.fqdn - username = self.equipment_access.user - password = self.equipment_access.password - ### End block ### - - ### Runs connection ### + #Bypassing connection try: - log.info("Starting connection to '%s' using NCClient..." % device) - self.session_manager = manager.connect( - host = device, - port = self.connection_port, - username = username, - password = password, - hostkey_verify = False - ) - log.info('Connection succesfully...') + pass + + # ### Getting device access data ### + # device = self.equipment_access.fqdn + # username = self.equipment_access.user + # password = self.equipment_access.password + # ### End block ### + + # ### Runs connection ### + # try: + # log.info("Starting connection to '%s' using NCClient..." % device) + # # transport = paramiko.Transport((device, 22)) + # # transport.get_security_options().kex = ( + # # 'curve25519-sha256', + # # 'diffie-hellman-group14-sha1', + # # 'diffie-hellman-group-exchange-sha256', + # # ) + # # transport.get_security_options().ciphers = ( + # # 'aes128-ctr', 'aes256-ctr' + # # ) + + # self.session_manager = manager.connect( + # host = device, + # port = self.connect_port, + # username = username, + # password = password, + # # hostkey_verify = False, + # # allow_agent=False, + # # look_for_keys=False, + + # ) + # log.info('Connection succesfully...') ### Exception handler except IOError, e: @@ -93,6 +121,61 @@ def ensure_privilege_level(self, privilege_level=None): """ return True + def check_configuration_has_content(self, command, file_path): + pass + + def check_configuration_file_exists(self, file_path): + + """ + This function try to find and build (if necessary) the configuration file path. The priorities are: + (1) build the full path from system variable base and relative file path ('file_path'); or + (2) build the full path from static variable base and relative file path ('file_path'); or + (3) return the relative path it self ('file_path') + + :param str file_path: Relative path, examples: + 'networkapi/plugins/Juniper/JUNOS/samples/sample_command.txt' or + 'networkapi/generated_config/interface/int-d_24823_config_ROR9BX3ATQG93TALJAMO2G' + + :return: Return a valid configuration file path string. Ex.: + 'networkapi/plugins/Juniper/JUNOS/samples/sample_command.txt' or + '/mnt/scripts/tftpboot/networkapi/generated_config/interface/int-d_24823_config_ROR9BX3ATQG93TALJAMO2G' + """ + + log.info("Checking configuration file exist: {}".format(file_path)) + + # Check in system variables + for variable in self.alternative_variable_base_path_list: + try: + base_path = get_value(variable) + if base_path != "": + result_path = base_path + file_path + if os.path.isfile(result_path): + log.info("Configuration file {} was found by system variable {}!".format(result_path, variable)) + return result_path + except (DatabaseError, VariableDoesNotExistException): + # DatabaseError means that variable table do not exist + pass + except Exception as e: + log.warning("Unknown error while calling networkapi.system.facade.get_value({}): {} {} ".format( + variable, e.__class__, e)) + + # Check possible static variables + for static_path in self.alternative_static_base_path_list: + result_path = static_path + file_path + if os.path.isfile(result_path): + log.info("Configuration file {} was found by static variable {}!".format(result_path, static_path)) + return result_path + + # Check if relative path is valid (for dev tests) + if os.path.isfile(file_path): + log.info("Configuration file {} was found by relative path".format(file_path)) + return file_path + + message = "An error occurred while finding configuration file." + log.error("{} Could not find in: relative path ('{}'), system variables ({}) or static paths ({})".format( + message, file_path, self.alternative_variable_base_path_list, self.alternative_static_base_path_list)) + raise exceptions.APIException(message) + def copyScriptFileToConfig(self, filename, use_vrf='', destination=''): """ Receives the file path (usually in /mnt/scripts/tftpboot/networkapi/generated_config/interface/) @@ -120,9 +203,9 @@ def copyScriptFileToConfig(self, filename, use_vrf='', destination=''): command = command_file.read() # Check if Configuration is not empty and raises exception if not contain - self.check_configuration_has_content(command=command, file_path=file_path) + # self.check_configuration_has_content(command=command, file_path=file_path) - log.info("Load configuration from file {} successfully".format(file_path)) + # log.info("Load configuration from file {} successfully".format(file_path)) return self.exec_command(command=command) @@ -141,8 +224,22 @@ def exec_command(self, command, success_regex='', invalid_regex=None, error_rege try: self.__try_lock() # Do nothing, will be executed by the locked method of ncclient - with self.session_manager.locked(target='running'): - self.session_manager.edit_config(target='running', config=command) + # with self.session_manager.locked(target='running'): + # self.session_manager.edit_config(target='running', config=command) + + response = requests.post( + url="http://localhost:5000/deploy", + headers={"Content-type": "application/json"}, + data=json.dumps({ + "address": self.equipment_access.fqdn, + "username": self.equipment_access.user, + "password": self.equipment_access.password, + "configuration": command + }) + ) + + if response.status_code != 200: + raise Exception result_message = "Configuration was executed successfully on {}.".format(self.equipment_access.fqdn) log.info(result_message) @@ -161,20 +258,21 @@ def close(self): :returns: True if success or raise an exception on any error """ - log.info("Close connection started...") - try: - if self.session_manager: - self.session_manager.close_session() - log.info('Connection closed successfully.') - return True - - else: - raise Exception("session_manager is None.") - - except Exception as e: - message = "Error while calling close session method on equipment %s" % self.equipment_access.fqdn - log.error(message) - log.error(e) - - raise exceptions.APIException(message) + # log.info("Close connection started...") + pass + # try: + # if self.session_manager: + # self.session_manager.close_session() + # log.info('Connection closed successfully.') + # return True + + # else: + # raise Exception("session_manager is None.") + + # except Exception as e: + # message = "Error while calling close session method on equipment %s" % self.equipment_access.fqdn + # log.error(message) + # log.error(e) + + # raise exceptions.APIException(message) From 5ebd43dda6b98b6739c5590a378e12970b48aa3f Mon Sep 17 00:00:00 2001 From: "renan.lopes" Date: Fri, 23 May 2025 14:42:59 -0300 Subject: [PATCH 81/89] code cleanning --- networkapi/plugins/Netconf/plugin.py | 64 +++------------------------- 1 file changed, 6 insertions(+), 58 deletions(-) diff --git a/networkapi/plugins/Netconf/plugin.py b/networkapi/plugins/Netconf/plugin.py index a4c30bf5..476e05c2 100644 --- a/networkapi/plugins/Netconf/plugin.py +++ b/networkapi/plugins/Netconf/plugin.py @@ -53,47 +53,16 @@ def connect(self): raise exceptions.InvalidEquipmentAccessException() ### End block ### - #Bypassing connection + # Bypassing connection due python version incompatibility try: pass - # ### Getting device access data ### - # device = self.equipment_access.fqdn - # username = self.equipment_access.user - # password = self.equipment_access.password - # ### End block ### - - # ### Runs connection ### - # try: - # log.info("Starting connection to '%s' using NCClient..." % device) - # # transport = paramiko.Transport((device, 22)) - # # transport.get_security_options().kex = ( - # # 'curve25519-sha256', - # # 'diffie-hellman-group14-sha1', - # # 'diffie-hellman-group-exchange-sha256', - # # ) - # # transport.get_security_options().ciphers = ( - # # 'aes128-ctr', 'aes256-ctr' - # # ) - - # self.session_manager = manager.connect( - # host = device, - # port = self.connect_port, - # username = username, - # password = password, - # # hostkey_verify = False, - # # allow_agent=False, - # # look_for_keys=False, - - # ) - # log.info('Connection succesfully...') - ### Exception handler except IOError, e: - log.error('Could not connect to host %s: %s' % (device, e)) - raise exceptions.ConnectionException(device) + log.error('Could not connect to host %s: %s' % (self.equipment_access.fqdn, e)) + raise exceptions.ConnectionException(self.equipment_access.fqdn) except Exception, e: - log.error('Error connecting to host %s:%s' % (device, e)) + log.error('Error connecting to host %s:%s' % (self.equipment_access.fqdn, e)) def apply_config_to_equipment(self, config, use_vrf=None, tarqet='running'): @@ -202,11 +171,6 @@ def copyScriptFileToConfig(self, filename, use_vrf='', destination=''): command_file = open(file_path, "r") command = command_file.read() - # Check if Configuration is not empty and raises exception if not contain - # self.check_configuration_has_content(command=command, file_path=file_path) - - # log.info("Load configuration from file {} successfully".format(file_path)) - return self.exec_command(command=command) except IOError as e: @@ -224,8 +188,7 @@ def exec_command(self, command, success_regex='', invalid_regex=None, error_rege try: self.__try_lock() # Do nothing, will be executed by the locked method of ncclient - # with self.session_manager.locked(target='running'): - # self.session_manager.edit_config(target='running', config=command) + # Here we make a request to a microservice that runs in docker with python 3 response = requests.post( url="http://localhost:5000/deploy", @@ -258,21 +221,6 @@ def close(self): :returns: True if success or raise an exception on any error """ - # log.info("Close connection started...") + # Not necessary pass - # try: - # if self.session_manager: - # self.session_manager.close_session() - # log.info('Connection closed successfully.') - # return True - - # else: - # raise Exception("session_manager is None.") - - # except Exception as e: - # message = "Error while calling close session method on equipment %s" % self.equipment_access.fqdn - # log.error(message) - # log.error(e) - - # raise exceptions.APIException(message) From 70ef91aa40e75ac403f976a20379399dd49d77f4 Mon Sep 17 00:00:00 2001 From: "renan.lopes" Date: Fri, 23 May 2025 15:44:40 -0300 Subject: [PATCH 82/89] better condition to choose netconf --- networkapi/api_deploy/facade.py | 7 ++++++- networkapi/plugins/factory.py | 9 ++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/networkapi/api_deploy/facade.py b/networkapi/api_deploy/facade.py index 4c1405f6..1dda24a8 100644 --- a/networkapi/api_deploy/facade.py +++ b/networkapi/api_deploy/facade.py @@ -65,8 +65,13 @@ def _applyconfig(equipment, filename, equipment_access=None, source_server=None, # TODO: Handle exceptions from the following methods and generate response # for the caller + tipo_acesso = EquipamentoAcesso.search(None, + equipment, + ).uniqueResult() + if tipo_acesso is None: + return 'Equipment has no Access.' - equip_plugin = PluginFactory.factory(equipment) + equip_plugin = PluginFactory.factory(equipment, tipo_acesso=tipo_acesso.tipo_acesso.protocolo) equip_plugin.connect() equip_plugin.ensure_privilege_level() vrf = equip_plugin.equipment_access.vrf.internal_name if equip_plugin.equipment_access.vrf else None diff --git a/networkapi/plugins/factory.py b/networkapi/plugins/factory.py index e3735773..552177ca 100644 --- a/networkapi/plugins/factory.py +++ b/networkapi/plugins/factory.py @@ -35,6 +35,9 @@ def plugin_exists(cls, **kwargs): @classmethod def get_plugin(cls, **kwargs): + if 'tipo_acesso' in kwargs and kwargs.get('tipo_acesso') == 'netconf': + from .Netconf.plugin import GenericNetconf + return GenericNetconf if 'modelo' in kwargs: modelo = kwargs.get('modelo') @@ -61,9 +64,9 @@ def get_plugin(cls, **kwargs): if 'marca' in kwargs: marca = kwargs.get('marca') - if re.search('HUAWEI', marca.upper(), re.DOTALL): - from .Netconf.plugin import GenericNetconf - return GenericNetconf + # if re.search('HUAWEI', marca.upper(), re.DOTALL): + # from .Netconf.plugin import GenericNetconf + # return GenericNetconf if re.search('F5', marca.upper(), re.DOTALL): from .F5.Generic import Generic return Generic From bcbc69e12ff308f18521b51782dbd715375ad4a0 Mon Sep 17 00:00:00 2001 From: Iuri Malinoski Date: Tue, 17 Jun 2025 17:04:33 -0300 Subject: [PATCH 83/89] Debugs and notes added at Port Channel DELETE request --- networkapi/api_interface/facade.py | 12 ++++++++++++ .../resource/InterfaceChannelResource.py | 19 ++++++++++++++++--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/networkapi/api_interface/facade.py b/networkapi/api_interface/facade.py index ee149ab6..5c294dfe 100644 --- a/networkapi/api_interface/facade.py +++ b/networkapi/api_interface/facade.py @@ -290,6 +290,9 @@ def get_interface_by_ids(interface_ids): def generate_delete_file(user, equip_id, interface_list, channel): + + log.info("generate_delete_file equip_id:%s interface_list:%s channel:%s", equip_id, interface_list, channel) + try: INTERFACE_CONFIG_TOAPPLY_REL_PATH = get_variable( 'interface_config_toapply_rel_path') @@ -297,6 +300,11 @@ def generate_delete_file(user, equip_id, interface_list, channel): 'interface_config_files_path') TEMPLATE_REMOVE_CHANNEL = get_variable('template_remove_channel') TEMPLATE_REMOVE_INTERFACE = get_variable('template_remove_interface') + + log.debug('INTERFACE_CONFIG_TOAPPLY_REL_PATH:%s', INTERFACE_CONFIG_TOAPPLY_REL_PATH) + log.debug('INTERFACE_CONFIG_FILES_PATH:%s', INTERFACE_CONFIG_FILES_PATH) + log.debug('TEMPLATE_REMOVE_CHANNEL:%s', TEMPLATE_REMOVE_CHANNEL) + log.debug('TEMPLATE_REMOVE_INTERFACE:%s', TEMPLATE_REMOVE_INTERFACE) except ObjectDoesNotExist: raise var_exceptions.VariableDoesNotExistException( 'Erro buscando a variável INTERFACE_CONFIG_TEMPLATE_PATH,' @@ -350,9 +358,12 @@ def generate_delete_file(user, equip_id, interface_list, channel): def delete_channel(user, equip_id, interface_list, channel): + log.info('delete_channel equip_id:%s interface_list:%s channel:%s', equip_id, interface_list, channel) + file_to_deploy = generate_delete_file( user, equip_id, interface_list, channel) + log.debug('file_to_deploy: %s', file_to_deploy) # TODO Deploy config file try: lockvar = LOCK_EQUIPMENT % (equip_id) @@ -510,6 +521,7 @@ def _load_template_file(equipment_id, template_type): filename_in = INTERFACE_CONFIG_TEMPLATE_PATH + \ equipment_template.roteiro.roteiro + log.debug("filename_in: %s", filename_in) # Read contents from file try: diff --git a/networkapi/interface/resource/InterfaceChannelResource.py b/networkapi/interface/resource/InterfaceChannelResource.py index c6498a7d..b2eff32c 100644 --- a/networkapi/interface/resource/InterfaceChannelResource.py +++ b/networkapi/interface/resource/InterfaceChannelResource.py @@ -277,11 +277,15 @@ def handle_get(self, request, user, *args, **kwargs): return self.response_error(1) def handle_delete(self, request, user, *args, **kwargs): - """Trata uma requisição DELETE para excluir um port channel - URL: /channel/delete// + """ + Delete port channel from interface id (table 'interfaces'), ex.: + DELETE /channel/delete/73886/ + + Not tested: + DELETE /channel/delete// """ try: - self.log.info('Delete Channel') + self.log.debug('Delete Channel request:%s', request) # User permission if not has_perm(user, AdminPermission.EQUIPMENT_MANAGEMENT, AdminPermission.WRITE_OPERATION): @@ -290,30 +294,39 @@ def handle_delete(self, request, user, *args, **kwargs): raise UserNotAuthorizedError(None) interface_id = kwargs.get('channel_name') + self.log.info('interface_id: %s', interface_id) interface = Interface.get_by_pk(int(interface_id)) equip_list = [] + # Getting port channel try: interface.channel.id channel = interface.channel except: channel = interface.ligacao_front.channel pass + self.log.debug('channel id:%s name:%s', channel.id, channel) + + # Getting all interfaces used by port channel try: interfaces = Interface.objects.all().filter(channel__id=channel.id) except: return self.response(dumps_networkapi({})) + self.log.debug('interfaces: %s', interfaces) + # Getting all equipment from interfaces (switches, ex.: LF-CM-AH18-1 and LF-CM-AH18-2) for i in interfaces: equip_list.append(i.equipamento.id) equip_list = set(equip_list) equip_dict = dict() + self.log.debug('equip_list: %s', equip_list) for e in equip_list: equip_dict[str(e)] = interfaces.filter(equipamento__id=e) tipo = TipoInterface() tipo = tipo.get_by_name('access') + # For each equipment (leaf), remove port channel for e in equip_dict: for i in equip_dict.get(e): try: From 929639b2fd90ade345f2d7be41fbebdb636d8f44 Mon Sep 17 00:00:00 2001 From: "renan.lopes" Date: Tue, 17 Jun 2025 18:07:08 -0300 Subject: [PATCH 84/89] removed config tag from templates --- networkapi/plugins/Netconf/plugin.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/networkapi/plugins/Netconf/plugin.py b/networkapi/plugins/Netconf/plugin.py index 476e05c2..425c1193 100644 --- a/networkapi/plugins/Netconf/plugin.py +++ b/networkapi/plugins/Netconf/plugin.py @@ -190,6 +190,8 @@ def exec_command(self, command, success_regex='', invalid_regex=None, error_rege self.__try_lock() # Do nothing, will be executed by the locked method of ncclient # Here we make a request to a microservice that runs in docker with python 3 + ultimate_template = '{}'.format(command) + response = requests.post( url="http://localhost:5000/deploy", headers={"Content-type": "application/json"}, @@ -197,7 +199,7 @@ def exec_command(self, command, success_regex='', invalid_regex=None, error_rege "address": self.equipment_access.fqdn, "username": self.equipment_access.user, "password": self.equipment_access.password, - "configuration": command + "configuration": ultimate_template }) ) From c85f955a813096ec8aada4e180819d8c6896c210 Mon Sep 17 00:00:00 2001 From: "renan.lopes" Date: Fri, 27 Jun 2025 15:19:50 -0300 Subject: [PATCH 85/89] moved tipo acesso query to the base factory plugin --- networkapi/api_deploy/facade.py | 12 ++++++------ networkapi/plugins/factory.py | 17 +++++++++++++++-- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/networkapi/api_deploy/facade.py b/networkapi/api_deploy/facade.py index 1dda24a8..2b307e92 100644 --- a/networkapi/api_deploy/facade.py +++ b/networkapi/api_deploy/facade.py @@ -65,13 +65,13 @@ def _applyconfig(equipment, filename, equipment_access=None, source_server=None, # TODO: Handle exceptions from the following methods and generate response # for the caller - tipo_acesso = EquipamentoAcesso.search(None, - equipment, - ).uniqueResult() - if tipo_acesso is None: - return 'Equipment has no Access.' + # tipo_acesso = EquipamentoAcesso.search(None, + # equipment, + # ).uniqueResult() + # if tipo_acesso is None: + # return 'Equipment has no Access.' - equip_plugin = PluginFactory.factory(equipment, tipo_acesso=tipo_acesso.tipo_acesso.protocolo) + equip_plugin = PluginFactory.factory(equipment) equip_plugin.connect() equip_plugin.ensure_privilege_level() vrf = equip_plugin.equipment_access.vrf.internal_name if equip_plugin.equipment_access.vrf else None diff --git a/networkapi/plugins/factory.py b/networkapi/plugins/factory.py index 552177ca..69ae9442 100644 --- a/networkapi/plugins/factory.py +++ b/networkapi/plugins/factory.py @@ -15,6 +15,7 @@ # limitations under the License. import logging import re +from networkapi.equipamento.models import Equipamento, EquipamentoAcesso from networkapi.plugins.SDN.ODL.Generic import ODLPlugin @@ -34,8 +35,13 @@ def plugin_exists(cls, **kwargs): @classmethod def get_plugin(cls, **kwargs): - if 'tipo_acesso' in kwargs and kwargs.get('tipo_acesso') == 'netconf': + if 'bgp' in kwargs: + bgp = kwargs.get('bgp') + if bgp: + from .Netconf.BGP.Cli import Generic + return Generic + from .Netconf.plugin import GenericNetconf return GenericNetconf if 'modelo' in kwargs: @@ -109,7 +115,14 @@ def factory(cls, equipment, **kwargs): marca = equipment.modelo.marca.nome modelo = equipment.modelo.nome - plugin_class = cls.get_plugin(modelo=modelo, marca=marca, **kwargs) + tipo_acesso = EquipamentoAcesso.search(None, + equipment, + ).uniqueResult() + + if tipo_acesso is None: + return 'Equipment has no Access.' + + plugin_class = cls.get_plugin(modelo=modelo, marca=marca, tipo_acesso=tipo_acesso.tipo_acesso.protocolo, **kwargs) if type(plugin_class) == type(ODLPlugin): version = 'BERYLLIUM' From 075586f099bd0c740ef5e4f4daf791c92ffcc155 Mon Sep 17 00:00:00 2001 From: "renan.lopes" Date: Mon, 30 Jun 2025 18:05:24 -0300 Subject: [PATCH 86/89] fixed bgp deploy --- networkapi/plugins/Netconf/BGP/Cli.py | 32 ++++++++++++++++++--------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/networkapi/plugins/Netconf/BGP/Cli.py b/networkapi/plugins/Netconf/BGP/Cli.py index c94e5315..c3725190 100644 --- a/networkapi/plugins/Netconf/BGP/Cli.py +++ b/networkapi/plugins/Netconf/BGP/Cli.py @@ -17,6 +17,7 @@ import logging import os +from HTMLParser import HTMLParser from django.db.models import Q from django.template import Context @@ -66,20 +67,21 @@ def _deploy_pre_req(self, neighbor): for rm_entry in rms: log.info(rm_entry) list_config_bgp = rm_entry.list_config_bgp + # log.debug(dir(neighbor.peer_group)) - if not list_config_bgp.equipments.filter(id=self.equipment.id): - log.info("Deploying list config BGP on equipment. Equipment ID: '%s'." % self.equipment.id) - self.deploy_list_config_bgp(list_config_bgp) + # if not list_config_bgp.equipments.filter(id=self.equipment.id): + # log.info("Deploying list config BGP on equipment. Equipment ID: '%s'." % self.equipment.id) + # self.deploy_list_config_bgp(list_config_bgp) - # Deploying routemap In on equipment - if not route_map_in.equipments.filter(id=self.equipment.id): - log.info("Deploying routemap in on equipment. Equipment ID: '%s'" % self.equipment.id) - self.deploy_route_map(neighbor.peer_group.route_map_id) + # # Deploying routemap In on equipment + # if not route_map_in.equipments.filter(id=self.equipment.id): + # log.info("Deploying routemap in on equipment. Equipment ID: '%s'" % self.equipment.id) + # self.deploy_route_map(neighbor.peer_group.route_map_in) - # Deploying routemap Out on equipment - if not route_map_out.equipments.filter(id=self.equipment.id): - log.info("Deploying routemap out on equipment. Equipment ID: '%s'" % self.equipment.id) - self.deploy_route_map(neighbor.peer_group.route_map_out) + # # Deploying routemap Out on equipment + # if not route_map_out.equipments.filter(id=self.equipment.id): + # log.info("Deploying routemap out on equipment. Equipment ID: '%s'" % self.equipment.id) + # self.deploy_route_map(neighbor.peer_group.route_map_out) @staticmethod @@ -183,6 +185,7 @@ def _generate_template_dict_route_map(self, route_map): """ Make a dictionary to use in template """ + log.debug(dir(route_map)) log.info("Generate template dict for routemap. Routemap name: '%s'" % route_map.name) @@ -257,6 +260,13 @@ def _get_template_config(self, template_type, config): try: template_file = self._load_template_file(template_type=template_type) + # Instancia o parser para desescapar entidades HTML + if config.get('CONFIG'): + converter = HTMLParser() + + # Copia o dicionário e faz o unescape apenas no campo 'CONFIG' + config['CONFIG'] = converter.unescape(config['CONFIG']) + config_to_be_saved = template_file.render(Context(config)) log.info(config_to_be_saved) From 3892ebb1be7881ba0a1d8e22e3ec29d074b0e06e Mon Sep 17 00:00:00 2001 From: "renan.lopes" Date: Fri, 26 Sep 2025 17:55:35 -0300 Subject: [PATCH 87/89] starting to fix rack provision to support new topology --- networkapi/api_rack/provision.py | 71 ++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 32 deletions(-) diff --git a/networkapi/api_rack/provision.py b/networkapi/api_rack/provision.py index 8c93fd6e..ad5bf0aa 100644 --- a/networkapi/api_rack/provision.py +++ b/networkapi/api_rack/provision.py @@ -49,6 +49,7 @@ def replace_file(filein, fileout, dicionario): try: # Write contents to file. # Using mode 'w' truncates the file. + log.debug("Salvando arquivo: %s" % fileout) file_handle = open(fileout, 'w') file_handle.write(file_string) file_handle.close() @@ -430,6 +431,7 @@ def spine_provision(self, rack, equips): ### TO BERRINI ## To pop Berrini we use new variables, this make the new cross topology and old topology run to. + log.debug(spine_num) if spine_num == 1: variablestochangespine1["VLANBORDA2LEAF"] = str(vlanBO[spine_num]) variablestochangespine1["VLANBORDA2CACHOSLEAF"] = str(vlanBOCA[spine_num]) @@ -497,14 +499,14 @@ def spine_provision(self, rack, equips): variablestochangespine1["INT_LF_2{}UPLINK".format(interface2_counter)] = iface.get("eq_interface") variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[0].get("nome") variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[1].get("nome") - variablestochangespine1["PO2CHANNEL"] = variablestochangespine1["SINGLE21INT"].split('/')[-1].split(':')[0] + variablestochangespine1["NUM_CHANNEL"] = variablestochangespine1["SINGLE21INT"].split('/')[-1].split(':')[0] interface2_counter += 1 elif iface_name[:3] == self.spine_prefix and int(iface_name[-1]) == 1: variablestochangespine1["SINGLE1{}INT".format(interface1_counter)] = iface.get("interface") variablestochangespine1["INT_LF_1{}UPLINK".format(interface1_counter)] = iface.get("eq_interface") - variablestochangespine1["PO1CHANNEL"] = variablestochangespine1["SINGLE11INT"].split('/')[-1].split(':')[0] + variablestochangespine1["NUM_CHANNEL"] = variablestochangespine1["SINGLE11INT"].split('/')[-1].split(':')[0] variablestochangespine1["DESCRIPTION1CONNECT"] = equips_sorted[0].get("nome") variablestochangespine1["DESCRIPTION2CONNECT"] = equips_sorted[1].get("nome") interface1_counter += 1 @@ -584,32 +586,34 @@ def spine_provision(self, rack, equips): #### ANOTHER BERRINI BLOCK ## Here we invert the variables of description, due unique template to diferent spines ## without this invertion, the description run well on spine 2 but on spine 1 they are inverted + + log.debug(variablestochangeleaf1) if int(equip.get('nome')[-1]) == 2: ### Here we must have to invert the variables to leaf2, due the new topology - sp1_hostname = variablestochangeleaf1["SP1_HOSTNAME"] - sp2_hostname = variablestochangeleaf1["SP2_HOSTNAME"] - variablestochangeleaf1["SP1_HOSTNAME"] = sp2_hostname - variablestochangeleaf1["SP2_HOSTNAME"] = sp1_hostname - - if1_sp1 = variablestochangeleaf1['INTERFACE1_SP1'] - if2_sp1 = variablestochangeleaf1['INTERFACE2_SP1'] - if3_sp1 = variablestochangeleaf1['INTERFACE3_SP1'] - if4_sp1 = variablestochangeleaf1['INTERFACE4_SP1'] - - if1_sp2 = variablestochangeleaf1['INTERFACE1_SP2'] - if2_sp2 = variablestochangeleaf1['INTERFACE2_SP2'] - if3_sp2 = variablestochangeleaf1['INTERFACE3_SP2'] - if4_sp2 = variablestochangeleaf1['INTERFACE4_SP2'] - - variablestochangeleaf1['INTERFACE1_SP1'] = if1_sp2 - variablestochangeleaf1['INTERFACE2_SP1'] = if2_sp2 - variablestochangeleaf1['INTERFACE3_SP1'] = if3_sp2 - variablestochangeleaf1['INTERFACE4_SP1'] = if4_sp2 - - variablestochangeleaf1['INTERFACE1_SP2'] = if1_sp1 - variablestochangeleaf1['INTERFACE2_SP2'] = if2_sp1 - variablestochangeleaf1['INTERFACE3_SP2'] = if3_sp1 - variablestochangeleaf1['INTERFACE4_SP2'] = if4_sp1 + # sp1_hostname = variablestochangeleaf1["SP1_HOSTNAME"] + # sp2_hostname = variablestochangeleaf1["SP2_HOSTNAME"] + # variablestochangeleaf1["SP1_HOSTNAME"] = sp2_hostname + # variablestochangeleaf1["SP2_HOSTNAME"] = sp1_hostname + + # if1_sp1 = variablestochangeleaf1['INTERFACE1_SP1'] + # if2_sp1 = variablestochangeleaf1['INTERFACE2_SP1'] + # if3_sp1 = variablestochangeleaf1['INTERFACE3_SP1'] + # if4_sp1 = variablestochangeleaf1['INTERFACE4_SP1'] + + # if1_sp2 = variablestochangeleaf1['INTERFACE1_SP2'] + # if2_sp2 = variablestochangeleaf1['INTERFACE2_SP2'] + # if3_sp2 = variablestochangeleaf1['INTERFACE3_SP2'] + # if4_sp2 = variablestochangeleaf1['INTERFACE4_SP2'] + + # variablestochangeleaf1['INTERFACE1_SP1'] = if1_sp2 + # variablestochangeleaf1['INTERFACE2_SP1'] = if2_sp2 + # variablestochangeleaf1['INTERFACE3_SP1'] = if3_sp2 + # variablestochangeleaf1['INTERFACE4_SP1'] = if4_sp2 + + # variablestochangeleaf1['INTERFACE1_SP2'] = if1_sp1 + # variablestochangeleaf1['INTERFACE2_SP2'] = if2_sp1 + # variablestochangeleaf1['INTERFACE3_SP2'] = if3_sp1 + # variablestochangeleaf1['INTERFACE4_SP2'] = if4_sp1 vlan_ber_be1= variablestochangeleaf1["VLANBERBELEAFSP1"] vlan_ber_be2= variablestochangeleaf1["VLANBERBELEAFSP2"] @@ -631,13 +635,16 @@ def spine_provision(self, rack, equips): variablestochangeleaf1["VLANBERBORDACACHOSLEAFSP2"] = vlan_ber_bc1 variablestochangeleaf1["VLANBERBORDACACHOSBLEAFSP1"] = vlan_ber_bcb2 variablestochangeleaf1["VLANBERBORDACACHOSBLEAFSP2"] = vlan_ber_bcb1 - as_spine1 = variablestochangeleaf1["ASSPINE1"] - as_spine2 = variablestochangeleaf1["ASSPINE2"] - variablestochangeleaf1["ASSPINE1"] = as_spine2 - variablestochangeleaf1["ASSPINE2"] = as_spine1 + # as_spine1 = variablestochangeleaf1["ASSPINE1"] + # as_spine2 = variablestochangeleaf1["ASSPINE2"] + # variablestochangeleaf1["ASSPINE1"] = as_spine2 + # variablestochangeleaf1["ASSPINE2"] = as_spine1 + + # variablestochangeleaf1['LFPO1'] = variablestochangeleaf1['INTERFACE1_SP1'].split('/')[-1].split(':')[0] + # variablestochangeleaf1['LFPO2'] = variablestochangeleaf1['INTERFACE1_SP2'].split('/')[-1].split(':')[0] + variablestochangeleaf1["BASE_NETWORK_HOST_FE_IPV4"] = variablestochangeleaf1["NET_HOST_FE_IPV4"].split("/")[0] - variablestochangeleaf1['LFPO1'] = variablestochangeleaf1['INTERFACE1_SP1'].split('/')[-1].split(':')[0] - variablestochangeleaf1['LFPO2'] = variablestochangeleaf1['INTERFACE1_SP2'].split('/')[-1].split(':')[0] + variablestochangeleaf1["BASE_NETWORK_HOST_BE_IPV4"] = variablestochangeleaf1["NET_HOST_BE_IPV4"].split("/")[0] ### End Berrini Block From b401d1ff1b151415093051380938e6ae2b6d9848 Mon Sep 17 00:00:00 2001 From: "renan.lopes" Date: Thu, 2 Oct 2025 17:45:54 -0300 Subject: [PATCH 88/89] finished code --- networkapi/api_rack/provision.py | 48 +++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/networkapi/api_rack/provision.py b/networkapi/api_rack/provision.py index ad5bf0aa..a9b67116 100644 --- a/networkapi/api_rack/provision.py +++ b/networkapi/api_rack/provision.py @@ -586,13 +586,15 @@ def spine_provision(self, rack, equips): #### ANOTHER BERRINI BLOCK ## Here we invert the variables of description, due unique template to diferent spines ## without this invertion, the description run well on spine 2 but on spine 1 they are inverted - + variablestochangeleaf1['DFS_SOURCE_IP'] = '10.126.24.12' + variablestochangeleaf1['DFS_PEER_IP'] = '10.126.24.13' + variablestochangeleaf1["INT_GERENCIA_OOB"] = "47" log.debug(variablestochangeleaf1) if int(equip.get('nome')[-1]) == 2: ### Here we must have to invert the variables to leaf2, due the new topology # sp1_hostname = variablestochangeleaf1["SP1_HOSTNAME"] - # sp2_hostname = variablestochangeleaf1["SP2_HOSTNAME"] - # variablestochangeleaf1["SP1_HOSTNAME"] = sp2_hostname + sp2_hostname = variablestochangeleaf1["SP2_HOSTNAME"] + variablestochangeleaf1["SP1_HOSTNAME"] = sp2_hostname # variablestochangeleaf1["SP2_HOSTNAME"] = sp1_hostname # if1_sp1 = variablestochangeleaf1['INTERFACE1_SP1'] @@ -600,12 +602,12 @@ def spine_provision(self, rack, equips): # if3_sp1 = variablestochangeleaf1['INTERFACE3_SP1'] # if4_sp1 = variablestochangeleaf1['INTERFACE4_SP1'] - # if1_sp2 = variablestochangeleaf1['INTERFACE1_SP2'] + if1_sp2 = variablestochangeleaf1['INTERFACE1_SP2'] # if2_sp2 = variablestochangeleaf1['INTERFACE2_SP2'] # if3_sp2 = variablestochangeleaf1['INTERFACE3_SP2'] # if4_sp2 = variablestochangeleaf1['INTERFACE4_SP2'] - # variablestochangeleaf1['INTERFACE1_SP1'] = if1_sp2 + variablestochangeleaf1['INTERFACE1_SP1'] = if1_sp2 # variablestochangeleaf1['INTERFACE2_SP1'] = if2_sp2 # variablestochangeleaf1['INTERFACE3_SP1'] = if3_sp2 # variablestochangeleaf1['INTERFACE4_SP1'] = if4_sp2 @@ -615,6 +617,15 @@ def spine_provision(self, rack, equips): # variablestochangeleaf1['INTERFACE3_SP2'] = if3_sp1 # variablestochangeleaf1['INTERFACE4_SP2'] = if4_sp1 + vlan_bo_leaf_sp1 = variablestochangeleaf1["VLANBORDALEAFSP1"] + vlan_bo_leaf_sp2 = variablestochangeleaf1["VLANBORDALEAFSP2"] + + variablestochangeleaf1["VLANBORDALEAFSP1"] = vlan_bo_leaf_sp2 + variablestochangeleaf1["INT_GERENCIA_OOB"] = "48" + # variablestochangeleaf1["VLANBORDALEAFSP1"] = str(vlanBO[spn]) + # variablestochangeleaf1["VLANBORDALEAFSP2"] = str(vlanBO[spn + 1]) + + vlan_ber_be1= variablestochangeleaf1["VLANBERBELEAFSP1"] vlan_ber_be2= variablestochangeleaf1["VLANBERBELEAFSP2"] vlan_ber_fe1= variablestochangeleaf1["VLANBERFELEAFSP1"] @@ -635,9 +646,12 @@ def spine_provision(self, rack, equips): variablestochangeleaf1["VLANBERBORDACACHOSLEAFSP2"] = vlan_ber_bc1 variablestochangeleaf1["VLANBERBORDACACHOSBLEAFSP1"] = vlan_ber_bcb2 variablestochangeleaf1["VLANBERBORDACACHOSBLEAFSP2"] = vlan_ber_bcb1 + + variablestochangeleaf1['DFS_SOURCE_IP'] = '10.126.24.13' + variablestochangeleaf1['DFS_PEER_IP'] = '10.126.24.12' # as_spine1 = variablestochangeleaf1["ASSPINE1"] - # as_spine2 = variablestochangeleaf1["ASSPINE2"] - # variablestochangeleaf1["ASSPINE1"] = as_spine2 + as_spine2 = variablestochangeleaf1["ASSPINE2"] + variablestochangeleaf1["ASSPINE1"] = as_spine2 # variablestochangeleaf1["ASSPINE2"] = as_spine1 # variablestochangeleaf1['LFPO1'] = variablestochangeleaf1['INTERFACE1_SP1'].split('/')[-1].split(':')[0] @@ -646,6 +660,13 @@ def spine_provision(self, rack, equips): variablestochangeleaf1["BASE_NETWORK_HOST_BE_IPV4"] = variablestochangeleaf1["NET_HOST_BE_IPV4"].split("/")[0] + variablestochangeleaf1["BASE_NETWORK_HOST_FE_IPV6"] = variablestochangeleaf1["NET_HOST_FE_IPV6"].split("/")[0] + variablestochangeleaf1["BASE_NETWORK_HOST_BE_IPV6"] = variablestochangeleaf1["NET_HOST_BE_IPV6"].split("/")[0] + variablestochangeleaf1['BASE_MASK_HOST_BE_IPV6'] = variablestochangeleaf1["NET_HOST_BE_IPV6"].split("/")[1] + + variablestochangeleaf1['BASE_NETWORK_HOST_BO_DSR_IPV6'] = variablestochangeleaf1['NET_HOST_BO_DSR_IPV6'].split('/')[0] + variablestochangeleaf1['BASE_MASK_HOST_BO_DSR_IPV6'] = variablestochangeleaf1['NET_HOST_BO_DSR_IPV6'].split('/')[1] + ### End Berrini Block variablestochangeleaf1["ID_VLT"] = str(id_vlt[j]) @@ -727,6 +748,7 @@ def oob_provision(self, equips): variablestochangeoob["OWN_IP_MGMT"] = oob.get("ip_mngt") variablestochangeoob["HOSTNAME_OOB"] = oob.get("nome") variablestochangeoob["HOSTNAME_RACK"] = self.rack.nome + log.debug(equips_sorted) fileinoob = path_to_guide + oob.get("roteiro") fileoutoob = path_to_config + oob.get("nome") + ".cfg" @@ -735,6 +757,18 @@ def oob_provision(self, equips): nome = equip.get("nome") log.debug(str(nome)) roteiro = equip.get("roteiro") + + ### To Pop Berrini + base_leaf_hostname = "LF-" + variablestochangeoob['HOSTNAME_OOB'].split('-')[1] + "-R"+ str(self.rack.numero) +"-" + variablestochangeoob['LEAF1_HOSTNAME'] = base_leaf_hostname + "1" + variablestochangeoob['LEAF2_HOSTNAME'] = base_leaf_hostname + "2" + + variablestochangecore1["CHANNEL_NUMBER"] = str(self.rack.numero) + variablestochangecore2["CHANNEL_NUMBER"] = str(self.rack.numero) + variablestochangecore1["RACK_NUMBER"] = str(self.rack.numero) + variablestochangecore2["RACK_NUMBER"] = str(self.rack.numero) + ### End Block + if nome[:3] == self.leaf_prefix: if nome[-1] == "1": variablestochangeoob["HOSTNAME_LF1"] = nome From fc332ab1c217ebd61accb14faab3a657a163ef5e Mon Sep 17 00:00:00 2001 From: "renan.lopes" Date: Wed, 29 Oct 2025 11:22:18 -0300 Subject: [PATCH 89/89] bugfix at equiptoacesso resource --- networkapi/infrastructure/xml_utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/networkapi/infrastructure/xml_utils.py b/networkapi/infrastructure/xml_utils.py index 356ab7db..2c92110c 100644 --- a/networkapi/infrastructure/xml_utils.py +++ b/networkapi/infrastructure/xml_utils.py @@ -55,7 +55,8 @@ def _add_text_node(value, node, doc): if not isinstance(value, StringTypes): text = '%s' % unicode(value) else: - text = r'%s' % value.replace('%', '%%') + # text = r'%s' % value.replace('%', '%%') + text = value try: textNode = doc.createTextNode(text)