Compare commits

...

7 Commits

Author SHA1 Message Date
2d2362815b Ok Fini 2025-11-27 14:57:15 +01:00
bd4bc7cb24 Fin Projet avant bonus 2025-11-27 14:06:29 +01:00
0b7d66777e Question 25 2025-11-27 13:20:04 +01:00
558a4c30f7 Projet 2025-11-27 11:59:36 +01:00
39f8b87743 fin TP3 2025-11-20 22:01:23 +01:00
ff878558f9 Fin TP3 2025-11-19 21:18:33 +01:00
f3f157318a TP3-Question 13 2025-11-18 19:31:26 +01:00
53 changed files with 6123 additions and 99 deletions

View File

@@ -6,6 +6,9 @@ name = "pypi"
[packages] [packages]
jinja2 = "*" jinja2 = "*"
nornir = "*" nornir = "*"
nornir-utils = "*"
nornir-napalm = "*"
nornir-netmiko = "*"
[dev-packages] [dev-packages]

976
TP_03/Pipfile.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,10 @@
router ospf 1
router-id 1.1.1.1
network 172.16.10.0 0.0.0.255 area 0
network 172.16.20.0 0.0.0.255 area 0
network 172.16.100.0 0.0.0.63 area 0
end

View File

@@ -0,0 +1,10 @@
interface g2/0.10
vrrp 10 ip 172.16.10.252
vrrp 10 priority 100
interface g2/0.20
vrrp 20 ip 172.16.20.252
vrrp 20 priority 100

View File

@@ -1,10 +1,7 @@
interface g3/0 interface g3/0
encapsulation dot1Q no shutdown
description "**NO DESCRIPTION**"
ip address
exit exit
interface g3/0.10 interface g3/0.10
encapsulation dot1Q 10 encapsulation dot1Q 10
description "Gateway for teacher vlan" description "Gateway for teacher vlan"

View File

@@ -0,0 +1,10 @@
router ospf 1
router-id 4.4.4.4
network 172.16.30.0 0.0.0.255 area 0
network 172.16.40.0 0.0.0.255 area 0
network 172.16.100.64 0.0.0.63 area 0
end

View File

@@ -0,0 +1,10 @@
interface g3/0.10
vrrp 10 ip 172.16.30.252
vrrp 10 priority 100
interface g3/0.20
vrrp 20 ip 172.16.40.252
vrrp 20 priority 100

View File

@@ -0,0 +1,10 @@
interface g2/0.10
vrrp 10 ip 172.16.10.252
vrrp 10 priority 100
interface g2/0.20
vrrp 20 ip 172.16.20.252
vrrp 20 priority 100

View File

@@ -0,0 +1,10 @@
interface g3/0.10
vrrp 10 ip 172.16.30.252
vrrp 10 priority 100
interface g3/0.20
vrrp 20 ip 172.16.40.252
vrrp 20 priority 100

View File

@@ -0,0 +1,10 @@
router ospf 1
router-id 2.2.2.2
network 172.16.10.0 0.0.0.255 area 0
network 172.16.20.0 0.0.0.255 area 0
network 172.16.100.0 0.0.0.63 area 0
end

View File

@@ -0,0 +1,14 @@
interface g2/0.10
vrrp 10 ip 172.16.10.252
vrrp 10 priority 110
vrrp 10 preempt
exit
interface g2/0.20
vrrp 20 ip 172.16.20.252
vrrp 20 priority 110
vrrp 20 preempt
exit

View File

@@ -1,10 +1,7 @@
interface g3/0 interface g3/0
encapsulation dot1Q no shutdown
description "**NO DESCRIPTION**"
ip address
exit exit
interface g3/0.10 interface g3/0.10
encapsulation dot1Q 10 encapsulation dot1Q 10
description "Gateway for teacher vlan" description "Gateway for teacher vlan"

View File

@@ -0,0 +1,10 @@
router ospf 1
router-id 3.3.3.3
network 172.16.30.0 0.0.0.255 area 0
network 172.16.40.0 0.0.0.255 area 0
network 172.16.100.64 0.0.0.63 area 0
end

View File

@@ -0,0 +1,14 @@
interface g3/0.10
vrrp 10 ip 172.16.30.252
vrrp 10 priority 110
vrrp 10 preempt
exit
interface g3/0.20
vrrp 20 ip 172.16.40.252
vrrp 20 priority 110
vrrp 20 preempt
exit

View File

@@ -0,0 +1,8 @@
{
"id_router": "1.1.1.1",
"networks": [
"172.16.10.0 0.0.0.255",
"172.16.20.0 0.0.0.255",
"172.16.100.0 0.0.0.63"
]
}

View File

@@ -0,0 +1,8 @@
{
"id_router": "4.4.4.4",
"networks": [
"172.16.30.0 0.0.0.255",
"172.16.40.0 0.0.0.255",
"172.16.100.64 0.0.0.63"
]
}

View File

@@ -0,0 +1,8 @@
{
"id_router": "2.2.2.2",
"networks": [
"172.16.10.0 0.0.0.255",
"172.16.20.0 0.0.0.255",
"172.16.100.0 0.0.0.63"
]
}

View File

@@ -0,0 +1,8 @@
{
"id_router": "3.3.3.3",
"networks": [
"172.16.30.0 0.0.0.255",
"172.16.40.0 0.0.0.255",
"172.16.100.64 0.0.0.63"
]
}

View File

@@ -9,6 +9,7 @@ R1-CPE-BAT-A:
device_model: C7200 device_model: C7200
locality: lyon locality: lyon
building: A building: A
room: 001
R2-CPE-BAT-A: R2-CPE-BAT-A:
hostname: 172.16.100.126 hostname: 172.16.100.126

1019
TP_03/nornir.log Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -28,10 +28,22 @@ def create_config_cpe_lyon_batA():
R1_LYON_BAT_A_data = load_json_data_from_file(file_path='data/R1_CPE_LYON_BAT_A.json') R1_LYON_BAT_A_data = load_json_data_from_file(file_path='data/R1_CPE_LYON_BAT_A.json')
R1_LYON_BAT_A_config = render_network_config(template_name='vlan_router.j2', data=R1_LYON_BAT_A_data) R1_LYON_BAT_A_config = render_network_config(template_name='vlan_router.j2', data=R1_LYON_BAT_A_data)
R2_LYON_BAT_A_config_vrrp = render_network_config(template_name='vrrp_router.j2', data=R2_LYON_BAT_A_data)
R1_LYON_BAT_A_config_vrrp = render_network_config(template_name='vrrp_router.j2', data=R1_LYON_BAT_A_data)
R2_LYON_BAT_A_config_ospf_data = load_json_data_from_file(file_path='data/R2_CPE_LYON_BAT_A_OSPF.json')
R2_LYON_BAT_A_config_ospf = render_network_config(template_name='config_ospf.j2', data=R2_LYON_BAT_A_config_ospf_data)
R1_LYON_BAT_A_config_ospf_data = load_json_data_from_file(file_path='data/R1_CPE_LYON_BAT_A_OSPF.json')
R1_LYON_BAT_A_config_ospf = render_network_config(template_name='config_ospf.j2', data=R1_LYON_BAT_A_config_ospf_data)
return { return {
'esw1': ESW1_CPE_LYON_BAT_A_config, 'esw1': ESW1_CPE_LYON_BAT_A_config,
'r1': R1_LYON_BAT_A_config, 'r1': R1_LYON_BAT_A_config,
'r2': R2_LYON_BAT_A_config 'r2': R2_LYON_BAT_A_config,
'r1_vrrp' : R1_LYON_BAT_A_config_vrrp,
'r2_vrrp' : R2_LYON_BAT_A_config_vrrp,
'r1_ospf' : R1_LYON_BAT_A_config_ospf,
'r2_ospf' : R2_LYON_BAT_A_config_ospf
} }
def create_config_cpe_lyon_batB(): def create_config_cpe_lyon_batB():
@@ -44,10 +56,22 @@ def create_config_cpe_lyon_batB():
R1_LYON_BAT_B_data = load_json_data_from_file(file_path='data/R1_CPE_LYON_BAT_B.json') R1_LYON_BAT_B_data = load_json_data_from_file(file_path='data/R1_CPE_LYON_BAT_B.json')
R1_LYON_BAT_B_config = render_network_config(template_name='vlan_router.j2', data=R1_LYON_BAT_B_data) R1_LYON_BAT_B_config = render_network_config(template_name='vlan_router.j2', data=R1_LYON_BAT_B_data)
R2_LYON_BAT_B_config_vrrp = render_network_config(template_name='vrrp_router.j2', data=R2_LYON_BAT_B_data)
R1_LYON_BAT_B_config_vrrp = render_network_config(template_name='vrrp_router.j2', data=R1_LYON_BAT_B_data)
R2_LYON_BAT_B_config_ospf_data = load_json_data_from_file(file_path='data/R2_CPE_LYON_BAT_B_OSPF.json')
R2_LYON_BAT_B_config_ospf = render_network_config(template_name='config_ospf.j2', data=R2_LYON_BAT_B_config_ospf_data)
R1_LYON_BAT_B_config_ospf_data = load_json_data_from_file(file_path='data/R1_CPE_LYON_BAT_B_OSPF.json')
R1_LYON_BAT_B_config_ospf = render_network_config(template_name='config_ospf.j2', data=R1_LYON_BAT_B_config_ospf_data)
return { return {
'esw1': ESW1_CPE_LYON_BAT_B_config, 'esw1': ESW1_CPE_LYON_BAT_B_config,
'r1': R1_LYON_BAT_B_config, 'r1': R1_LYON_BAT_B_config,
'r2': R2_LYON_BAT_B_config 'r2': R2_LYON_BAT_B_config,
'r1_vrrp' : R1_LYON_BAT_B_config_vrrp,
'r2_vrrp' : R2_LYON_BAT_B_config_vrrp,
'r1_ospf' : R1_LYON_BAT_B_config_ospf,
'r2_ospf' : R2_LYON_BAT_B_config_ospf
} }
if __name__ == "__main__": if __name__ == "__main__":
@@ -61,10 +85,18 @@ if __name__ == "__main__":
save_built_config('config/R1_CPE_LYON_BAT_A.conf', config.get('r1')) save_built_config('config/R1_CPE_LYON_BAT_A.conf', config.get('r1'))
save_built_config('config/R2_CPE_LYON_BAT_A.conf', config.get('r2')) save_built_config('config/R2_CPE_LYON_BAT_A.conf', config.get('r2'))
save_built_config('config/ESW1_CPE_LYON_BAT_A.conf', config.get('esw1')) save_built_config('config/ESW1_CPE_LYON_BAT_A.conf', config.get('esw1'))
save_built_config('config/R1_CPE_LYON_BAT_A_VRRP.conf', config.get('r1_vrrp'))
save_built_config('config/R2_CPE_LYON_BAT_A_VRRP.conf', config.get('r2_vrrp'))
save_built_config('config/R1_CPE_LYON_BAT_A_OSPF.conf', config.get('r1_ospf'))
save_built_config('config/R2_CPE_LYON_BAT_A_OSPF.conf', config.get('r2_ospf'))
#question 5: #question 5:
config = create_config_cpe_lyon_batB() config = create_config_cpe_lyon_batB()
save_built_config('config/R1_CPE_LYON_BAT_B.conf', config.get('r1')) save_built_config('config/R1_CPE_LYON_BAT_B.conf', config.get('r1'))
save_built_config('config/R2_CPE_LYON_BAT_B.conf', config.get('r2')) save_built_config('config/R2_CPE_LYON_BAT_B.conf', config.get('r2'))
save_built_config('config/ESW1_CPE_LYON_BAT_B.conf', config.get('esw1')) save_built_config('config/ESW1_CPE_LYON_BAT_B.conf', config.get('esw1'))
save_built_config('config/R1_CPE_LYON_BAT_B_VRRP.conf', config.get('r1_vrrp'))
save_built_config('config/R2_CPE_LYON_BAT_B_VRRP.conf', config.get('r2_vrrp'))
save_built_config('config/R1_CPE_LYON_BAT_B_OSPF.conf', config.get('r1_ospf'))
save_built_config('config/R2_CPE_LYON_BAT_B_OSPF.conf', config.get('r2_ospf'))

View File

@@ -1,46 +1,66 @@
from nornir import InitNornir from nornir import InitNornir
from nornir.core.task import Task, Result
from nornir_utils.plugins.functions import print_result
from nornir_napalm.plugins.tasks import napalm_get,napalm_configure, napalm_cli
from nornir_netmiko.tasks import netmiko_send_config,netmiko_send_command, netmiko_save_config, netmiko_commit
def question_13(nr): def question_13(nr):
pass for key in nr.__dict__.keys():
print(f" - {key}")
def question_14(nr): def question_14(nr):
pass print(nr.inventory.hosts)
print(type(nr.inventory.hosts))
def question_15(nr): def question_15(nr):
pass print(nr.inventory.hosts["R1-CPE-BAT-A"])
print(type(nr.inventory.hosts["R1-CPE-BAT-A"]))
def question_16(nr): def question_16(nr):
pass print(dir(nr.inventory.hosts["R1-CPE-BAT-A"]))
first_host = list(nr.inventory.hosts.values())[0]
print(f"Adresse IP (hostname): {first_host.hostname}")
print(f"Username: {first_host.username}")
print(f"Password: {first_host.password}")
def question_17(nr): def question_17(nr):
pass print(dir(nr.inventory.hosts["R1-CPE-BAT-A"]))
def question_18(nr): def question_18(nr):
pass print(nr.inventory.hosts["R1-CPE-BAT-A"].data["room"])
def question_19(nr): def question_19(nr):
pass print(nr.inventory.groups)
def question_20(nr): def question_20(nr):
pass print(nr.inventory.hosts.get('R1-CPE-BAT-A').groups)
def question_21(nr): def question_21(nr):
pass print(nr.inventory.hosts.get('R1-CPE-BAT-A').groups[0].keys())
def question_22(nr): def question_22(nr):
pass print(nr.inventory.hosts.get('R1-CPE-BAT-A').groups[0].get('vendor'))
def question_23(nr): def question_23(nr):
pass for host_name in nr.inventory.hosts:
print(nr.inventory.hosts.get(host_name).hostname)
def question_24(nr): def question_24(nr):
pass print(nr.filter(device_type='router').inventory.hosts.keys())
def question_25(nr): def question_25(nr):
pass print(nr.filter(device_type='router_switch').inventory.hosts.keys())
def hello_world(task: Task) -> Result:
return Result(
host=task.host,
result=f"{task.host.name} says hello world!"
)
def question_26(nr): def question_26(nr):
pass result = nr.run(task=hello_world)
print(result)
def question_27(nr): def question_27(nr):
result = nr.run(task=hello_world) result = nr.run(task=hello_world)
@@ -51,31 +71,170 @@ def question_29(nr):
print_result(result) print_result(result)
def question_30(nr): def question_30(nr):
pass host = nr.filter(device_type='router_switch')
print_result(host.run(task=hello_world))
def display_interfaces(task):
task.run(
task=napalm_cli,
commands=["show ip interface brief"]
)
def question_32(nr): def question_32(nr):
pass filtre = nr.filter(device_type='router')
result = filtre.run(task=display_interfaces)
print_result(result)
def get_arp_table(task):
task.run(
task=napalm_get,
getters=["arp_table"]
)
def configure_loopback_r1(task):
task.run(
task=napalm_configure,
configuration="""
interface Lo1
ip address 1.1.1.1 255.255.255.255
description Loopback pour R1-CPE-BAT-A
"""
)
def configure_loopback_r2(task):
task.run(
task=napalm_configure,
configuration="""
interface Lo1
ip address 2.2.2.2 255.255.255.255
description Loopback pour R2-CPE-BAT-A
"""
)
def question_33(nr):
pass
def question_34(nr): def question_34(nr):
pass R1 = nr.filter(name='R1-CPE-BAT-A')
result_R1 = R1.run(task=configure_loopback_r1)
R2 = nr.filter(name='R2-CPE-BAT-A')
result_R2 = R2.run(task=configure_loopback_r2)
print_result(result_R1)
print_result(result_R2)
def save_running_config(task):
# Exécute la commande de sauvegarde de la configuration
task.run(
task=napalm_cli,
commands=["wr"]
)
def question_35(nr): def question_35(nr):
pass result = nr.run(task=save_running_config)
print_result(result)
def question_36(nr): def question_36(nr):
pass filtre = nr.filter(device_type='router')
result = filtre.run(task=netmiko_send_command,command_string="show ip interface brief")
print_result(result)
def configure_loopback2_r1(task):
config_commands = [
"interface loopback 2",
"ip address 1.1.1.2 255.255.255.255",
"description Loopback2 pour R1-CPE-BAT-A"
]
task.run(task=netmiko_send_config, config_commands=config_commands)
def configure_loopback2_r2(task):
config_commands = [
"interface loopback 2",
"ip address 2.2.2.3 255.255.255.255",
"description Loopback2 pour R2-CPE-BAT-A"
]
task.run(task=netmiko_send_config, config_commands=config_commands)
def question_37(nr): def question_37(nr):
pass result_r1 = nr.filter(name='R1-CPE-BAT-A').run(task=configure_loopback2_r1)
result_r2 = nr.filter(name='R2-CPE-BAT-A').run(task=configure_loopback2_r2)
print_result(result_r1)
print_result(result_r2)
def question_38(nr): def question_38(nr):
pass filtreR1 = nr.filter(name='R1-CPE-BAT-A')
resultR1 = filtreR1.run(task=netmiko_save_config)
filtreR2 = nr.filter(name='R2-CPE-BAT-A')
resultR2 = filtreR2.run(task=netmiko_save_config)
print_result(resultR1)
print_result(resultR2)
def deploy_config_from_file(task: Task, config_file: str) -> Result:
"""Déploie la configuration depuis un fichier sur un équipement via Nornir/Netmiko."""
with open(config_file, "r") as f:
commands = f.read().splitlines()
result = task.run(task=netmiko_send_config, config_commands=commands)
print_result(result)
result = task.run(task=netmiko_save_config)
print_result(result)
return result
def deploy_vrrp(task):
vrrp_filename = task.host.name.replace("-", "_").replace("CPE", "CPE_LYON") + "_VRRP.conf"
task.run(
task=deploy_config_from_file,
config_file=f"config/{vrrp_filename}",
name=f"Déploiement VRRP {task.host.name}"
)
def deploy_ospf(task):
vrrp_filename = task.host.name.replace("-", "_").replace("CPE", "CPE_LYON") + "_OSPF.conf"
task.run(
task=deploy_config_from_file,
config_file=f"config/{vrrp_filename}",
name=f"Déploiement VRRP {task.host.name}"
)
def deploy_to_hosts(nr, host_patterns):
"""Déploie les configurations pour tous les hôtes et ajoute le fichier VRRP pour les routers."""
for pattern in host_patterns:
# Filtrer uniquement par nom pour tous
filtered_hosts = nr.filter(name=pattern)
if not filtered_hosts.inventory.hosts:
print(f"Aucun hôte correspondant à '{pattern}'")
continue
# Déploiement des configs principales
def deploy_main(task):
filename = task.host.name.replace("-", "_").replace("CPE", "CPE_LYON") + ".conf"
task.run(
task=deploy_config_from_file,
config_file=f"config/{filename}",
name=f"Déploiement config {task.host.name}"
)
filtered_hosts.run(task=deploy_main)
# Déploiement VRRP uniquement pour les routers
routers = nr.filter(device_type="router")
routers.run(task=deploy_vrrp)
routers.run(task=deploy_ospf)
def question_39(nr): def question_39(nr):
pass host_patterns = [
'R1-CPE-BAT-A',
'R2-CPE-BAT-A',
'R1-CPE-BAT-B',
'R2-CPE-BAT-B',
'ESW1-CPE-BAT-A',
'ESW1-CPE-BAT-BS'
]
deploy_to_hosts(nr, host_patterns)
def question_39_d(nr): def question_39_d(nr):
pass pass
@@ -101,7 +260,7 @@ if __name__ == "__main__":
#question_24(nr) #question_24(nr)
#question_25(nr) #question_25(nr)
#question_26(nr) #question_26(nr)
question_27(nr) #question_27(nr)
#question_29(nr) #question_29(nr)
#question_30(nr) #question_30(nr)
@@ -112,7 +271,7 @@ if __name__ == "__main__":
#question_36(nr) #question_36(nr)
#question_37(nr) #question_37(nr)
#question_38(nr) #question_38(nr)
#question_39(nr) question_39(nr)
#question_39_d(nr) #question_39_d(nr)
#question_40(nr) #question_40(nr)

View File

@@ -0,0 +1,6 @@
router ospf 1
router-id {{ id_router }}
{% for network in networks %}
network {{ network }} area 0
{% endfor %}
end

View File

@@ -4,7 +4,7 @@ interface {{ interface.name }}
no shutdown no shutdown
exit exit
{%- elif "3/0" == interface.name %} {%- elif "g3/0" == interface.name %}
interface {{ interface.name }} interface {{ interface.name }}
no shutdown no shutdown
exit exit

18
fastprod_backend/Pipfile Normal file
View File

@@ -0,0 +1,18 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
flask = "*"
nornir = "*"
pyyaml = "*"
nornir-napalm = "*"
nornir-netmiko = "*"
nornir-utils = "*"
flask-cors = "*"
[dev-packages]
[requires]
python_version = "3.12"

1121
fastprod_backend/Pipfile.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,168 @@
!
upgrade fpd auto
version 12.4
service timestamps debug datetime msec
service timestamps log datetime msec
no service password-encryption
!
hostname R1-CPE-BAT-A
!
boot-start-marker
boot-end-marker
!
logging message-counter syslog
!
no aaa new-model
ip source-route
no ip icmp rate-limit unreachable
ip cef
!
!
!
!
no ip domain lookup
ip domain name r1.cpe.local
no ipv6 cef
!
multilink bundle-name authenticated
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
file prompt quiet
username cisco privilege 15 password 0 cisco
archive
log config
hidekeys
!
!
!
!
!
ip tcp synwait-time 5
ip ssh version 2
ip scp server enable
!
!
!
!
interface Loopback1
description Loopback pour R1-CPE-BAT-A
ip address 1.1.1.1 255.255.255.255
!
interface Loopback2
description Loopback2 pour R1-CPE-BAT-A
ip address 1.1.1.2 255.255.255.255
!
interface Loopback10
description created from config file uploaded from postman
ip address 10.10.10.10 255.255.255.255
!
interface FastEthernet0/0
ip address 172.16.100.62 255.255.255.192
duplex half
!
interface Serial1/0
no ip address
shutdown
serial restart-delay 0
!
interface Serial1/1
ip address 10.1.1.1 255.255.255.252
shutdown
serial restart-delay 0
!
interface Serial1/2
no ip address
shutdown
serial restart-delay 0
!
interface Serial1/3
no ip address
shutdown
serial restart-delay 0
!
interface GigabitEthernet2/0
no ip address
negotiation auto
!
interface GigabitEthernet2/0.10
description "Gateway for teacher vlan"
encapsulation dot1Q 10
ip address 172.16.10.253 255.255.255.0
vrrp 10 ip 172.16.10.252
!
interface GigabitEthernet2/0.20
description "Gateway for student vlan"
encapsulation dot1Q 20
ip address 172.16.20.253 255.255.255.0
vrrp 20 ip 172.16.20.252
!
interface GigabitEthernet2/0.99
encapsulation dot1Q 99
ip address 172.16.100.125 255.255.255.192
vrrp 99 ip 172.16.100.124
!
router ospf 1
router-id 1.1.1.1
log-adjacency-changes
passive-interface FastEthernet0/0
passive-interface GigabitEthernet2/0.99
network 10.1.1.0 0.0.0.3 area 0
network 172.16.10.0 0.0.0.255 area 0
network 172.16.20.0 0.0.0.255 area 0
network 172.16.100.0 0.0.0.63 area 0
network 172.16.100.64 0.0.0.63 area 0
!
ip forward-protocol nd
no ip http server
no ip http secure-server
!
!
!
no cdp log mismatch duplex
!
!
!
!
!
!
control-plane
!
!
!
!
!
!
!
gatekeeper
shutdown
!
!
line con 0
exec-timeout 0 0
privilege level 15
logging synchronous
stopbits 1
line aux 0
exec-timeout 0 0
privilege level 15
logging synchronous
stopbits 1
line vty 0 4
login local
transport input ssh
!
end

View File

@@ -0,0 +1,146 @@
from flask import Flask,jsonify,request,abort, make_response,send_file
from werkzeug.exceptions import HTTPException
from nornir import InitNornir
from flask_cors import CORS
import os
from werkzeug.utils import secure_filename
import json
ALLOWED_EXTENSIONS = {'conf'}
UPLOAD_FOLDER = 'fastprod/upload_files/'
def init_nornir():
app.config['nr'] = InitNornir(config_file="fastprod/inventory/config.yaml")
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
CORS(app)
from services.devices import ( get_inventory, add_device,get_device_by_name,delete_device,get_device_interfaces,get_device_interfaces_ip,get_device_technical_info)
from services.config import (get_config_by_device,run_config_from_file_by_device)
from services.tasks import (run_show_commands_by_device,run_config_commands_by_device)
from services.snapshots import (get_snapshot_by_name,create_snapshot_by_device,get_snapshots_by_device)
init_nornir()
@app.route("/")
def hello_world():
return jsonify({
"env": "DEV",
"name": "fastprod_backend",
"version": 1.0
})
@app.route("/devices", methods=['GET', 'POST'])
def devices():
if request.method == 'GET':
init_nornir()
devices = get_inventory()
return jsonify(devices=devices, total_count=len(devices))
if request.method == 'POST':
data = request.get_json()
new_device = add_device(data)
return jsonify(device=new_device)
@app.route("/devices/<device_name>", methods=['GET', 'DELETE'])
def device_by_name(device_name):
if request.method == 'GET':
device = get_device_by_name(device_name)
return jsonify(device=device)
if request.method == 'DELETE':
device = get_device_by_name(device_name)
delete_device(device)
return jsonify(message="Device deleted")
@app.route("/devices/<device_name>/interfaces", methods=['GET'])
def get_interfaces(device_name):
device = get_device_by_name(device_name)
interfaces = get_device_interfaces(device)
return jsonify(interfaces=interfaces)
@app.route("/devices/<device_name>/interfaces/ip", methods=['GET'])
def get_interfaces_ip(device_name):
if request.method == 'GET':
device = get_device_by_name(device_name)
interfaces_ip = get_device_interfaces_ip(device)
return jsonify(interfaces_ip=interfaces_ip)
@app.route("/devices/<device_name>/facts", methods=['GET'])
def get_technical_info(device_name):
if request.method == 'GET':
device = get_device_by_name(device_name)
technical_info = get_device_technical_info(device)
return jsonify(facts=technical_info)
@app.route("/devices/<device_name>/config", methods=['GET','POST'])
def get_config(device_name):
device = get_device_by_name(device_name)
if request.method == 'GET':
config = get_config_by_device(device)
return jsonify(interfaces_ip=config)
if request.method == 'POST':
if request.files.to_dict(flat=False).get('config_file'):
file = request.files['config_file']
if not allowed_file(file.filename):
abort(make_response(jsonify(message="file extension not allowed"), 403))
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
result = run_config_from_file_by_device(device,file_path=os.path.join(app.config['UPLOAD_FOLDER'], filename))
return jsonify(result=result)
if request.get_json().get('mode') == 'enable':
commands = request.get_json().get('commands')
result = run_show_commands_by_device(device, commands=commands)
return jsonify(result=result)
if request.get_json().get('mode') == 'config':
commands = request.get_json().get('commands')
result = run_config_commands_by_device(device, commands=commands)
return jsonify(result=result, commands=commands)
@app.route("/devices/<device_name>/snapshots", methods=['GET','POST'])
def snapshot(device_name):
device = get_device_by_name(device_name)
print(device)
if request.method == 'GET':
data = get_snapshots_by_device(device)
return jsonify({
"result": True,
"snapshots": data
})
if request.method == 'POST':
snapshot_path = create_snapshot_by_device(device)
return jsonify({
"result": True,
"snapshots": snapshot_path
})
@app.route("/snapshots/<path:filename>", methods=['GET'])
def snapshot_by_name(filename):
if request.method == 'GET':
try:
return send_file('snapshots/'+filename)
except FileNotFoundError:
abort(make_response(jsonify(message="snapshot not found"), 404))
@app.errorhandler(HTTPException)
def handle_exception(e):
"""Return JSON instead of HTML for HTTP errors."""
# start with the correct headers and status code from the error
response = e.get_response()
# replace the body with JSON
response.data = json.dumps({
"code": e.code,
"name": e.name,
"description": e.description,
})
response.content_type = "application/json"
return response

View File

@@ -0,0 +1,10 @@
inventory:
plugin: SimpleInventory
options:
host_file: "fastprod/inventory/hosts.yaml"
group_file: "fastprod/inventory/groups.yaml"
defaults_file: "fastprod/inventory/defaults.yaml"
runner:
plugin: threaded
options:
num_workers: 20

View File

@@ -0,0 +1,2 @@
username: cisco
password: cisco

View File

@@ -0,0 +1,4 @@
ios:
platform: ios
data:
vendor: Cisco

View File

@@ -0,0 +1,67 @@
ESW1-CPE-BAT-A:
data:
building: A
device_model: C3725
device_name: ESW1-CPE-BAT-A
device_type: router_switch
locality: lyon
groups:
- ios
hostname: 172.16.100.123
port: 22
ESW1-CPE-BAT-B:
data:
building: B
device_model: C3725
device_name: ESW1-CPE-BAT-B
device_type: router_switch
locality: lyon
groups:
- ios
hostname: 172.16.100.187
port: 22
R1-CPE-BAT-A:
data:
building: A
device_model: C7200
device_name: R1-CPE-BAT-A
device_type: router
locality: lyon
room: 1
groups:
- ios
hostname: 172.16.100.125
port: 22
R1-CPE-BAT-B:
data:
building: B
device_model: C7200
device_name: R1-CPE-BAT-B
device_type: router
locality: lyon
groups:
- ios
hostname: 172.16.100.189
port: 22
R2-CPE-BAT-A:
data:
building: A
device_model: C7200
device_name: R2-CPE-BAT-A
device_type: router
locality: lyon
groups:
- ios
hostname: 172.16.100.126
port: 22
R2-CPE-BAT-B:
data:
building: B
device_model: C7200
device_name: R2-CPE-BAT-B
device_type: router
locality: lyon
groups:
- ios
hostname: 172.16.100.190
port: 22

View File

@@ -0,0 +1,19 @@
from api import app
from nornir_napalm.plugins.tasks import napalm_get, napalm_configure, napalm_cli
from nornir.core.task import Task, Result
from nornir_utils.plugins.functions import print_result
from nornir_netmiko.tasks import netmiko_send_config, netmiko_send_command, netmiko_save_config,netmiko_commit
def get_config_by_device(device):
nr = app.config.get('nr')
result = nr.filter(device_name=device.get('name')).run(task=napalm_get, getters=["get_config"])
return result[device.get('name')][0].result.get("get_config")
def run_config_from_file_by_device(device=None, file_path=None):
nr = app.config.get('nr')
if device and file_path:
result = nr.filter(device_name=device.get('name')).run(task=netmiko_send_config,config_file=file_path)
print_result(result)
return result[device.get('name')].changed

View File

@@ -0,0 +1,70 @@
from api import app
from flask import Flask,jsonify,request,abort, make_response
from utils.inventory import *
from nornir import InitNornir
from nornir_utils.plugins.functions import print_result
from nornir_napalm.plugins.tasks import napalm_get,napalm_configure, napalm_cli
from nornir_netmiko.tasks import netmiko_send_config,netmiko_send_command, netmiko_save_config, netmiko_commit
def get_inventory():
hosts = app.config.get('nr').inventory.dict().get('hosts').keys()
return list(map(lambda item: app.config.get('nr').inventory.dict().get('hosts').get(item), hosts))
def add_device(device):
device = add_item_to_hosts_yaml(item=device)
return device
def get_device_by_name(name):
host = app.config.get('nr').inventory.hosts.get(name)
if not host:
abort(make_response(jsonify(message="device not found"), 404))
return host.dict()
def delete_device(device):
try:
delete_item_from_hosts_yaml(item=device)
except Exception as e:
abort(make_response(jsonify(message="Unable to delete this device", error=str(e)), 500))
def get_device_interfaces(device):
nr = app.config.get('nr')
result = nr.filter(device_name=device.get('name')).run(task=napalm_get,
getters=["get_interfaces"])
print_result(result)
print(result)
interfaces = result[device.get('name')][0].result.get('get_interfaces')
return list(map(lambda item: dict(name=item, **interfaces.get(item)), interfaces))
def get_device_technical_info(device):
nr = app.config.get('nr')
result = nr.filter(device_name=device.get('name')).run(
task=napalm_get,
getters=["get_facts"]
)
print_result(result)
facts = result[device.get('name')][0].result.get('get_facts')
return {
"hostname": facts.get("hostname"),
"vendor": facts.get("vendor"),
"model": facts.get("model"),
"serial_number": facts.get("serial_number"),
"os_version": facts.get("os_version"),
"uptime": facts.get("uptime"),
}
def get_device_interfaces_ip(device):
nr = app.config.get('nr')
result = nr.filter(device_name=device.get('name')).run(task=napalm_get,
getters=["get_interfaces_ip"])
print_result(result)
interfaces = result[device.get('name')][0].result.get('get_interfaces_ip')
def transformer(item):
ip_address = list(interfaces.get(item).get('ipv4').keys())[0]
prefix_length = interfaces.get(item).get('ipv4').get(list(interfaces.get(item).get('ipv4').keys())[0]).get('prefix_length')
return dict(name=item, ip=ip_address, prefix_length=prefix_length)
return list(map(lambda item: transformer(item), interfaces))
#return interfaces

View File

@@ -0,0 +1,35 @@
import os
from datetime import datetime
from api import app
from services.config import get_config_by_device
from flask import Flask,jsonify,request,abort, make_response
snapshot_directory = 'fastprod/snapshots'
def get_snapshot_by_name(name):
files = os.listdir()
snapshots = []
for file in files:
file_device_name = file.split('_')[0]
if name == file:
snapshots.append(dict(file=file, path=snapshot_directory, at=file.split('_')[1].split('.')[0]))
return snapshots
def create_snapshot_by_device(device=None):
nr = app.config.get('nr')
config = get_config_by_device(device)
timestamp = datetime.now().strftime('%Y%m%d%H%M%S')
file_path = os.path.join(snapshot_directory, f"{device.get('name')}_{timestamp}.conf")
with open(file_path, 'w') as file:
file.write(config.get('running'))
return file_path
def get_snapshots_by_device(device):
files = os.listdir(snapshot_directory)
snapshots = []
for file in files:
file_device_name = file.split('_')[0]
if file_device_name == device.get('name'):
snapshots.append(dict(file=file, path=snapshot_directory, at=file.split('_')[1].split('.')[0]))
return snapshots

View File

@@ -0,0 +1,35 @@
from api import app
from nornir_napalm.plugins.tasks import napalm_get, napalm_configure, napalm_cli
from nornir.core.task import Task, Result
from nornir_utils.plugins.functions import print_result
from nornir_netmiko.tasks import netmiko_send_config, netmiko_send_command, netmiko_save_config,netmiko_commit
def run_show_commands_by_device(device=None, commands=[]):
nr = app.config.get('nr')
commands_sent = []
if device:
if len(commands) > 1:
for command in commands:
result = nr.filter(device_name=device.get('name')).run(task=napalm_cli,
commands=[command])
print_result(result)
output = result[device.get('name')][0].result.get(command)
commands_sent.append(dict(command=command, result=output))
output = commands_sent
else:
result = nr.filter(device_name=device.get('name')).run(task=napalm_cli,
commands=commands)
output = result[device.get('name')][0].result.get(commands[0])
commands_sent.append(dict(command=commands[0], result= output))
output = commands_sent
return output
def run_config_commands_by_device(device=None, commands=[]):
nr = app.config.get('nr')
commands_sent = []
if device:
result = nr.filter(device_name=device.get('name')).run(task=netmiko_send_config,
config_commands=[commands])
print_result(result)
return result[device.get('name')].changed

View File

@@ -0,0 +1,236 @@
!
version 12.4
service timestamps debug datetime msec
service timestamps log datetime msec
no service password-encryption
no service dhcp
!
hostname ESW1-CPE-BAT-A
!
boot-start-marker
boot-end-marker
!
!
no aaa new-model
memory-size iomem 5
no ip routing
no ip icmp rate-limit unreachable
no ip cef
!
!
!
!
no ip domain lookup
ip domain name esw1.local
!
multilink bundle-name authenticated
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
macro name add_vlan
end
vlan database
vlan $v
exit
@
macro name del_vlan
end
vlan database
no vlan $v
exit
@
!
vtp file nvram:vlan.dat
username cisco privilege 15 password 0 cisco
archive
log config
hidekeys
!
!
!
!
ip tcp synwait-time 5
ip ssh version 2
!
!
!
!
interface Loopback1
no ip address
!
interface FastEthernet0/0
description *** Unused for Layer2 EtherSwitch ***
no ip address
no ip route-cache
duplex auto
speed auto
!
interface FastEthernet0/1
description *** Unused for Layer2 EtherSwitch ***
no ip address
no ip route-cache
shutdown
duplex auto
speed auto
!
interface FastEthernet1/0
switchport mode trunk
duplex full
speed 100
!
interface FastEthernet1/1
description "port vlan teacher"
switchport access vlan 10
duplex full
speed 100
!
interface FastEthernet1/2
description "port vlan student"
switchport access vlan 20
duplex full
speed 100
!
interface FastEthernet1/3
duplex full
speed 100
!
interface FastEthernet1/4
switchport mode trunk
duplex full
speed 100
!
interface FastEthernet1/5
duplex full
speed 100
!
interface FastEthernet1/6
duplex full
speed 100
!
interface FastEthernet1/7
duplex full
speed 100
!
interface FastEthernet1/8
duplex full
speed 100
!
interface FastEthernet1/9
duplex full
speed 100
!
interface FastEthernet1/10
duplex full
speed 100
!
interface FastEthernet1/11
duplex full
speed 100
!
interface FastEthernet1/12
duplex full
speed 100
!
interface FastEthernet1/13
duplex full
speed 100
!
interface FastEthernet1/14
switchport mode trunk
duplex full
speed 100
!
interface FastEthernet1/15
switchport mode trunk
duplex full
speed 100
!
interface FastEthernet2/0
no ip address
no ip route-cache
shutdown
duplex auto
speed auto
!
interface Vlan1
no ip address
no ip route-cache
!
interface Vlan99
ip address 172.16.100.123 255.255.255.192
!
ip forward-protocol nd
!
!
no ip http server
no ip http secure-server
!
no cdp log mismatch duplex
!
!
!
!
!
!
control-plane
!
!
!
!
!
!
!
!
!
banner exec ^C
***************************************************************
This is a normal Router with a Switch module inside (NM-16ESW)
It has been pre-configured with hard-coded speed and duplex
To create vlans use the command "vlan database" in exec mode
After creating all desired vlans use "exit" to apply the config
To view existing vlans use the command "show vlan-switch brief"
Alias(exec) : vl - "show vlan-switch brief" command
Alias(configure): va X - macro to add vlan X
Alias(configure): vd X - macro to delete vlan X
***************************************************************
^C
alias configure va macro global trace add_vlan $v
alias configure vd macro global trace del_vlan $v
alias exec vl show vlan-switch brief
!
line con 0
exec-timeout 0 0
privilege level 15
logging synchronous
line aux 0
exec-timeout 0 0
privilege level 15
logging synchronous
line vty 0 4
login local
transport input ssh
!
!
end

View File

@@ -0,0 +1,236 @@
!
version 12.4
service timestamps debug datetime msec
service timestamps log datetime msec
no service password-encryption
no service dhcp
!
hostname ESW1-CPE-BAT-A
!
boot-start-marker
boot-end-marker
!
!
no aaa new-model
memory-size iomem 5
no ip routing
no ip icmp rate-limit unreachable
no ip cef
!
!
!
!
no ip domain lookup
ip domain name esw1.local
!
multilink bundle-name authenticated
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
macro name add_vlan
end
vlan database
vlan $v
exit
@
macro name del_vlan
end
vlan database
no vlan $v
exit
@
!
vtp file nvram:vlan.dat
username cisco privilege 15 password 0 cisco
archive
log config
hidekeys
!
!
!
!
ip tcp synwait-time 5
ip ssh version 2
!
!
!
!
interface Loopback1
no ip address
!
interface FastEthernet0/0
description *** Unused for Layer2 EtherSwitch ***
no ip address
no ip route-cache
duplex auto
speed auto
!
interface FastEthernet0/1
description *** Unused for Layer2 EtherSwitch ***
no ip address
no ip route-cache
shutdown
duplex auto
speed auto
!
interface FastEthernet1/0
switchport mode trunk
duplex full
speed 100
!
interface FastEthernet1/1
description "port vlan teacher"
switchport access vlan 10
duplex full
speed 100
!
interface FastEthernet1/2
description "port vlan student"
switchport access vlan 20
duplex full
speed 100
!
interface FastEthernet1/3
duplex full
speed 100
!
interface FastEthernet1/4
switchport mode trunk
duplex full
speed 100
!
interface FastEthernet1/5
duplex full
speed 100
!
interface FastEthernet1/6
duplex full
speed 100
!
interface FastEthernet1/7
duplex full
speed 100
!
interface FastEthernet1/8
duplex full
speed 100
!
interface FastEthernet1/9
duplex full
speed 100
!
interface FastEthernet1/10
duplex full
speed 100
!
interface FastEthernet1/11
duplex full
speed 100
!
interface FastEthernet1/12
duplex full
speed 100
!
interface FastEthernet1/13
duplex full
speed 100
!
interface FastEthernet1/14
switchport mode trunk
duplex full
speed 100
!
interface FastEthernet1/15
switchport mode trunk
duplex full
speed 100
!
interface FastEthernet2/0
no ip address
no ip route-cache
shutdown
duplex auto
speed auto
!
interface Vlan1
no ip address
no ip route-cache
!
interface Vlan99
ip address 172.16.100.123 255.255.255.192
!
ip forward-protocol nd
!
!
no ip http server
no ip http secure-server
!
no cdp log mismatch duplex
!
!
!
!
!
!
control-plane
!
!
!
!
!
!
!
!
!
banner exec ^C
***************************************************************
This is a normal Router with a Switch module inside (NM-16ESW)
It has been pre-configured with hard-coded speed and duplex
To create vlans use the command "vlan database" in exec mode
After creating all desired vlans use "exit" to apply the config
To view existing vlans use the command "show vlan-switch brief"
Alias(exec) : vl - "show vlan-switch brief" command
Alias(configure): va X - macro to add vlan X
Alias(configure): vd X - macro to delete vlan X
***************************************************************
^C
alias configure va macro global trace add_vlan $v
alias configure vd macro global trace del_vlan $v
alias exec vl show vlan-switch brief
!
line con 0
exec-timeout 0 0
privilege level 15
logging synchronous
line aux 0
exec-timeout 0 0
privilege level 15
logging synchronous
line vty 0 4
login local
transport input ssh
!
!
end

View File

@@ -0,0 +1,168 @@
!
upgrade fpd auto
version 12.4
service timestamps debug datetime msec
service timestamps log datetime msec
no service password-encryption
!
hostname R1-CPE-BAT-A
!
boot-start-marker
boot-end-marker
!
logging message-counter syslog
!
no aaa new-model
ip source-route
no ip icmp rate-limit unreachable
ip cef
!
!
!
!
no ip domain lookup
ip domain name r1.cpe.local
no ipv6 cef
!
multilink bundle-name authenticated
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
file prompt quiet
username cisco privilege 15 password 0 cisco
archive
log config
hidekeys
!
!
!
!
!
ip tcp synwait-time 5
ip ssh version 2
ip scp server enable
!
!
!
!
interface Loopback1
description Loopback pour R1-CPE-BAT-A
ip address 1.1.1.1 255.255.255.255
!
interface Loopback2
description Loopback2 pour R1-CPE-BAT-A
ip address 1.1.1.2 255.255.255.255
!
interface Loopback10
description created from config file uploaded from postman
ip address 10.10.10.10 255.255.255.255
!
interface FastEthernet0/0
ip address 172.16.100.62 255.255.255.192
duplex half
!
interface Serial1/0
no ip address
shutdown
serial restart-delay 0
!
interface Serial1/1
ip address 10.1.1.1 255.255.255.252
shutdown
serial restart-delay 0
!
interface Serial1/2
no ip address
shutdown
serial restart-delay 0
!
interface Serial1/3
no ip address
shutdown
serial restart-delay 0
!
interface GigabitEthernet2/0
no ip address
negotiation auto
!
interface GigabitEthernet2/0.10
description "Gateway for teacher vlan"
encapsulation dot1Q 10
ip address 172.16.10.253 255.255.255.0
vrrp 10 ip 172.16.10.252
!
interface GigabitEthernet2/0.20
description "Gateway for student vlan"
encapsulation dot1Q 20
ip address 172.16.20.253 255.255.255.0
vrrp 20 ip 172.16.20.252
!
interface GigabitEthernet2/0.99
encapsulation dot1Q 99
ip address 172.16.100.125 255.255.255.192
vrrp 99 ip 172.16.100.124
!
router ospf 1
router-id 1.1.1.1
log-adjacency-changes
passive-interface FastEthernet0/0
passive-interface GigabitEthernet2/0.99
network 10.1.1.0 0.0.0.3 area 0
network 172.16.10.0 0.0.0.255 area 0
network 172.16.20.0 0.0.0.255 area 0
network 172.16.100.0 0.0.0.63 area 0
network 172.16.100.64 0.0.0.63 area 0
!
ip forward-protocol nd
no ip http server
no ip http secure-server
!
!
!
no cdp log mismatch duplex
!
!
!
!
!
!
control-plane
!
!
!
!
!
!
!
gatekeeper
shutdown
!
!
line con 0
exec-timeout 0 0
privilege level 15
logging synchronous
stopbits 1
line aux 0
exec-timeout 0 0
privilege level 15
logging synchronous
stopbits 1
line vty 0 4
login local
transport input ssh
!
end

View File

@@ -0,0 +1,168 @@
!
upgrade fpd auto
version 12.4
service timestamps debug datetime msec
service timestamps log datetime msec
no service password-encryption
!
hostname R1-CPE-BAT-A
!
boot-start-marker
boot-end-marker
!
logging message-counter syslog
!
no aaa new-model
ip source-route
no ip icmp rate-limit unreachable
ip cef
!
!
!
!
no ip domain lookup
ip domain name r1.cpe.local
no ipv6 cef
!
multilink bundle-name authenticated
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
file prompt quiet
username cisco privilege 15 password 0 cisco
archive
log config
hidekeys
!
!
!
!
!
ip tcp synwait-time 5
ip ssh version 2
ip scp server enable
!
!
!
!
interface Loopback1
description Loopback pour R1-CPE-BAT-A
ip address 1.1.1.1 255.255.255.255
!
interface Loopback2
description Loopback2 pour R1-CPE-BAT-A
ip address 1.1.1.2 255.255.255.255
!
interface Loopback10
description created from config file uploaded from postman
ip address 10.10.10.10 255.255.255.255
!
interface FastEthernet0/0
ip address 172.16.100.62 255.255.255.192
duplex half
!
interface Serial1/0
no ip address
shutdown
serial restart-delay 0
!
interface Serial1/1
ip address 10.1.1.1 255.255.255.252
shutdown
serial restart-delay 0
!
interface Serial1/2
no ip address
shutdown
serial restart-delay 0
!
interface Serial1/3
no ip address
shutdown
serial restart-delay 0
!
interface GigabitEthernet2/0
no ip address
negotiation auto
!
interface GigabitEthernet2/0.10
description "Gateway for teacher vlan"
encapsulation dot1Q 10
ip address 172.16.10.253 255.255.255.0
vrrp 10 ip 172.16.10.252
!
interface GigabitEthernet2/0.20
description "Gateway for student vlan"
encapsulation dot1Q 20
ip address 172.16.20.253 255.255.255.0
vrrp 20 ip 172.16.20.252
!
interface GigabitEthernet2/0.99
encapsulation dot1Q 99
ip address 172.16.100.125 255.255.255.192
vrrp 99 ip 172.16.100.124
!
router ospf 1
router-id 1.1.1.1
log-adjacency-changes
passive-interface FastEthernet0/0
passive-interface GigabitEthernet2/0.99
network 10.1.1.0 0.0.0.3 area 0
network 172.16.10.0 0.0.0.255 area 0
network 172.16.20.0 0.0.0.255 area 0
network 172.16.100.0 0.0.0.63 area 0
network 172.16.100.64 0.0.0.63 area 0
!
ip forward-protocol nd
no ip http server
no ip http secure-server
!
!
!
no cdp log mismatch duplex
!
!
!
!
!
!
control-plane
!
!
!
!
!
!
!
gatekeeper
shutdown
!
!
line con 0
exec-timeout 0 0
privilege level 15
logging synchronous
stopbits 1
line aux 0
exec-timeout 0 0
privilege level 15
logging synchronous
stopbits 1
line vty 0 4
login local
transport input ssh
!
end

View File

@@ -0,0 +1,168 @@
!
upgrade fpd auto
version 12.4
service timestamps debug datetime msec
service timestamps log datetime msec
no service password-encryption
!
hostname R1-CPE-BAT-A
!
boot-start-marker
boot-end-marker
!
logging message-counter syslog
!
no aaa new-model
ip source-route
no ip icmp rate-limit unreachable
ip cef
!
!
!
!
no ip domain lookup
ip domain name r1.cpe.local
no ipv6 cef
!
multilink bundle-name authenticated
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
file prompt quiet
username cisco privilege 15 password 0 cisco
archive
log config
hidekeys
!
!
!
!
!
ip tcp synwait-time 5
ip ssh version 2
ip scp server enable
!
!
!
!
interface Loopback1
description Loopback pour R1-CPE-BAT-A
ip address 1.1.1.1 255.255.255.255
!
interface Loopback2
description Loopback2 pour R1-CPE-BAT-A
ip address 1.1.1.2 255.255.255.255
!
interface Loopback10
description created from config file uploaded from postman
ip address 10.10.10.10 255.255.255.255
!
interface FastEthernet0/0
ip address 172.16.100.62 255.255.255.192
duplex half
!
interface Serial1/0
no ip address
shutdown
serial restart-delay 0
!
interface Serial1/1
ip address 10.1.1.1 255.255.255.252
shutdown
serial restart-delay 0
!
interface Serial1/2
no ip address
shutdown
serial restart-delay 0
!
interface Serial1/3
no ip address
shutdown
serial restart-delay 0
!
interface GigabitEthernet2/0
no ip address
negotiation auto
!
interface GigabitEthernet2/0.10
description "Gateway for teacher vlan"
encapsulation dot1Q 10
ip address 172.16.10.253 255.255.255.0
vrrp 10 ip 172.16.10.252
!
interface GigabitEthernet2/0.20
description "Gateway for student vlan"
encapsulation dot1Q 20
ip address 172.16.20.253 255.255.255.0
vrrp 20 ip 172.16.20.252
!
interface GigabitEthernet2/0.99
encapsulation dot1Q 99
ip address 172.16.100.125 255.255.255.192
vrrp 99 ip 172.16.100.124
!
router ospf 1
router-id 1.1.1.1
log-adjacency-changes
passive-interface FastEthernet0/0
passive-interface GigabitEthernet2/0.99
network 10.1.1.0 0.0.0.3 area 0
network 172.16.10.0 0.0.0.255 area 0
network 172.16.20.0 0.0.0.255 area 0
network 172.16.100.0 0.0.0.63 area 0
network 172.16.100.64 0.0.0.63 area 0
!
ip forward-protocol nd
no ip http server
no ip http secure-server
!
!
!
no cdp log mismatch duplex
!
!
!
!
!
!
control-plane
!
!
!
!
!
!
!
gatekeeper
shutdown
!
!
line con 0
exec-timeout 0 0
privilege level 15
logging synchronous
stopbits 1
line aux 0
exec-timeout 0 0
privilege level 15
logging synchronous
stopbits 1
line vty 0 4
login local
transport input ssh
!
end

View File

@@ -0,0 +1,168 @@
!
upgrade fpd auto
version 12.4
service timestamps debug datetime msec
service timestamps log datetime msec
no service password-encryption
!
hostname R1-CPE-BAT-A
!
boot-start-marker
boot-end-marker
!
logging message-counter syslog
!
no aaa new-model
ip source-route
no ip icmp rate-limit unreachable
ip cef
!
!
!
!
no ip domain lookup
ip domain name r1.cpe.local
no ipv6 cef
!
multilink bundle-name authenticated
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
file prompt quiet
username cisco privilege 15 password 0 cisco
archive
log config
hidekeys
!
!
!
!
!
ip tcp synwait-time 5
ip ssh version 2
ip scp server enable
!
!
!
!
interface Loopback1
description Loopback pour R1-CPE-BAT-A
ip address 1.1.1.1 255.255.255.255
!
interface Loopback2
description Loopback2 pour R1-CPE-BAT-A
ip address 1.1.1.2 255.255.255.255
!
interface Loopback10
description created from config file uploaded from postman
ip address 10.10.10.10 255.255.255.255
!
interface FastEthernet0/0
ip address 172.16.100.62 255.255.255.192
duplex half
!
interface Serial1/0
no ip address
shutdown
serial restart-delay 0
!
interface Serial1/1
ip address 10.1.1.1 255.255.255.252
shutdown
serial restart-delay 0
!
interface Serial1/2
no ip address
shutdown
serial restart-delay 0
!
interface Serial1/3
no ip address
shutdown
serial restart-delay 0
!
interface GigabitEthernet2/0
no ip address
negotiation auto
!
interface GigabitEthernet2/0.10
description "Gateway for teacher vlan"
encapsulation dot1Q 10
ip address 172.16.10.253 255.255.255.0
vrrp 10 ip 172.16.10.252
!
interface GigabitEthernet2/0.20
description "Gateway for student vlan"
encapsulation dot1Q 20
ip address 172.16.20.253 255.255.255.0
vrrp 20 ip 172.16.20.252
!
interface GigabitEthernet2/0.99
encapsulation dot1Q 99
ip address 172.16.100.125 255.255.255.192
vrrp 99 ip 172.16.100.124
!
router ospf 1
router-id 1.1.1.1
log-adjacency-changes
passive-interface FastEthernet0/0
passive-interface GigabitEthernet2/0.99
network 10.1.1.0 0.0.0.3 area 0
network 172.16.10.0 0.0.0.255 area 0
network 172.16.20.0 0.0.0.255 area 0
network 172.16.100.0 0.0.0.63 area 0
network 172.16.100.64 0.0.0.63 area 0
!
ip forward-protocol nd
no ip http server
no ip http secure-server
!
!
!
no cdp log mismatch duplex
!
!
!
!
!
!
control-plane
!
!
!
!
!
!
!
gatekeeper
shutdown
!
!
line con 0
exec-timeout 0 0
privilege level 15
logging synchronous
stopbits 1
line aux 0
exec-timeout 0 0
privilege level 15
logging synchronous
stopbits 1
line vty 0 4
login local
transport input ssh
!
end

View File

@@ -0,0 +1,168 @@
!
upgrade fpd auto
version 12.4
service timestamps debug datetime msec
service timestamps log datetime msec
no service password-encryption
!
hostname R1-CPE-BAT-A
!
boot-start-marker
boot-end-marker
!
logging message-counter syslog
!
no aaa new-model
ip source-route
no ip icmp rate-limit unreachable
ip cef
!
!
!
!
no ip domain lookup
ip domain name r1.cpe.local
no ipv6 cef
!
multilink bundle-name authenticated
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
file prompt quiet
username cisco privilege 15 password 0 cisco
archive
log config
hidekeys
!
!
!
!
!
ip tcp synwait-time 5
ip ssh version 2
ip scp server enable
!
!
!
!
interface Loopback1
description Loopback pour R1-CPE-BAT-A
ip address 1.1.1.1 255.255.255.255
!
interface Loopback2
description Loopback2 pour R1-CPE-BAT-A
ip address 1.1.1.2 255.255.255.255
!
interface Loopback10
description created from config file uploaded from postman
ip address 10.10.10.10 255.255.255.255
!
interface FastEthernet0/0
ip address 172.16.100.62 255.255.255.192
duplex half
!
interface Serial1/0
no ip address
shutdown
serial restart-delay 0
!
interface Serial1/1
ip address 10.1.1.1 255.255.255.252
shutdown
serial restart-delay 0
!
interface Serial1/2
no ip address
shutdown
serial restart-delay 0
!
interface Serial1/3
no ip address
shutdown
serial restart-delay 0
!
interface GigabitEthernet2/0
no ip address
negotiation auto
!
interface GigabitEthernet2/0.10
description "Gateway for teacher vlan"
encapsulation dot1Q 10
ip address 172.16.10.253 255.255.255.0
vrrp 10 ip 172.16.10.252
!
interface GigabitEthernet2/0.20
description "Gateway for student vlan"
encapsulation dot1Q 20
ip address 172.16.20.253 255.255.255.0
vrrp 20 ip 172.16.20.252
!
interface GigabitEthernet2/0.99
encapsulation dot1Q 99
ip address 172.16.100.125 255.255.255.192
vrrp 99 ip 172.16.100.124
!
router ospf 1
router-id 1.1.1.1
log-adjacency-changes
passive-interface FastEthernet0/0
passive-interface GigabitEthernet2/0.99
network 10.1.1.0 0.0.0.3 area 0
network 172.16.10.0 0.0.0.255 area 0
network 172.16.20.0 0.0.0.255 area 0
network 172.16.100.0 0.0.0.63 area 0
network 172.16.100.64 0.0.0.63 area 0
!
ip forward-protocol nd
no ip http server
no ip http secure-server
!
!
!
no cdp log mismatch duplex
!
!
!
!
!
!
control-plane
!
!
!
!
!
!
!
gatekeeper
shutdown
!
!
line con 0
exec-timeout 0 0
privilege level 15
logging synchronous
stopbits 1
line aux 0
exec-timeout 0 0
privilege level 15
logging synchronous
stopbits 1
line vty 0 4
login local
transport input ssh
!
end

View File

@@ -0,0 +1,168 @@
!
upgrade fpd auto
version 12.4
service timestamps debug datetime msec
service timestamps log datetime msec
no service password-encryption
!
hostname R1-CPE-BAT-A
!
boot-start-marker
boot-end-marker
!
logging message-counter syslog
!
no aaa new-model
ip source-route
no ip icmp rate-limit unreachable
ip cef
!
!
!
!
no ip domain lookup
ip domain name r1.cpe.local
no ipv6 cef
!
multilink bundle-name authenticated
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
file prompt quiet
username cisco privilege 15 password 0 cisco
archive
log config
hidekeys
!
!
!
!
!
ip tcp synwait-time 5
ip ssh version 2
ip scp server enable
!
!
!
!
interface Loopback1
description Loopback pour R1-CPE-BAT-A
ip address 1.1.1.1 255.255.255.255
!
interface Loopback2
description Loopback2 pour R1-CPE-BAT-A
ip address 1.1.1.2 255.255.255.255
!
interface Loopback10
description created from config file uploaded from postman
ip address 10.10.10.10 255.255.255.255
!
interface FastEthernet0/0
ip address 172.16.100.62 255.255.255.192
duplex half
!
interface Serial1/0
no ip address
shutdown
serial restart-delay 0
!
interface Serial1/1
ip address 10.1.1.1 255.255.255.252
shutdown
serial restart-delay 0
!
interface Serial1/2
no ip address
shutdown
serial restart-delay 0
!
interface Serial1/3
no ip address
shutdown
serial restart-delay 0
!
interface GigabitEthernet2/0
no ip address
negotiation auto
!
interface GigabitEthernet2/0.10
description "Gateway for teacher vlan"
encapsulation dot1Q 10
ip address 172.16.10.253 255.255.255.0
vrrp 10 ip 172.16.10.252
!
interface GigabitEthernet2/0.20
description "Gateway for student vlan"
encapsulation dot1Q 20
ip address 172.16.20.253 255.255.255.0
vrrp 20 ip 172.16.20.252
!
interface GigabitEthernet2/0.99
encapsulation dot1Q 99
ip address 172.16.100.125 255.255.255.192
vrrp 99 ip 172.16.100.124
!
router ospf 1
router-id 1.1.1.1
log-adjacency-changes
passive-interface FastEthernet0/0
passive-interface GigabitEthernet2/0.99
network 10.1.1.0 0.0.0.3 area 0
network 172.16.10.0 0.0.0.255 area 0
network 172.16.20.0 0.0.0.255 area 0
network 172.16.100.0 0.0.0.63 area 0
network 172.16.100.64 0.0.0.63 area 0
!
ip forward-protocol nd
no ip http server
no ip http secure-server
!
!
!
no cdp log mismatch duplex
!
!
!
!
!
!
control-plane
!
!
!
!
!
!
!
gatekeeper
shutdown
!
!
line con 0
exec-timeout 0 0
privilege level 15
logging synchronous
stopbits 1
line aux 0
exec-timeout 0 0
privilege level 15
logging synchronous
stopbits 1
line vty 0 4
login local
transport input ssh
!
end

View File

@@ -0,0 +1,168 @@
!
upgrade fpd auto
version 12.4
service timestamps debug datetime msec
service timestamps log datetime msec
no service password-encryption
!
hostname R1-CPE-BAT-A
!
boot-start-marker
boot-end-marker
!
logging message-counter syslog
!
no aaa new-model
ip source-route
no ip icmp rate-limit unreachable
ip cef
!
!
!
!
no ip domain lookup
ip domain name r1.cpe.local
no ipv6 cef
!
multilink bundle-name authenticated
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
file prompt quiet
username cisco privilege 15 password 0 cisco
archive
log config
hidekeys
!
!
!
!
!
ip tcp synwait-time 5
ip ssh version 2
ip scp server enable
!
!
!
!
interface Loopback1
description Loopback pour R1-CPE-BAT-A
ip address 1.1.1.1 255.255.255.255
!
interface Loopback2
description Loopback2 pour R1-CPE-BAT-A
ip address 1.1.1.2 255.255.255.255
!
interface Loopback10
description created from config file uploaded from postman
ip address 10.10.10.10 255.255.255.255
!
interface FastEthernet0/0
ip address 172.16.100.62 255.255.255.192
duplex half
!
interface Serial1/0
no ip address
shutdown
serial restart-delay 0
!
interface Serial1/1
ip address 10.1.1.1 255.255.255.252
shutdown
serial restart-delay 0
!
interface Serial1/2
no ip address
shutdown
serial restart-delay 0
!
interface Serial1/3
no ip address
shutdown
serial restart-delay 0
!
interface GigabitEthernet2/0
no ip address
negotiation auto
!
interface GigabitEthernet2/0.10
description "Gateway for teacher vlan"
encapsulation dot1Q 10
ip address 172.16.10.253 255.255.255.0
vrrp 10 ip 172.16.10.252
!
interface GigabitEthernet2/0.20
description "Gateway for student vlan"
encapsulation dot1Q 20
ip address 172.16.20.253 255.255.255.0
vrrp 20 ip 172.16.20.252
!
interface GigabitEthernet2/0.99
encapsulation dot1Q 99
ip address 172.16.100.125 255.255.255.192
vrrp 99 ip 172.16.100.124
!
router ospf 1
router-id 1.1.1.1
log-adjacency-changes
passive-interface FastEthernet0/0
passive-interface GigabitEthernet2/0.99
network 10.1.1.0 0.0.0.3 area 0
network 172.16.10.0 0.0.0.255 area 0
network 172.16.20.0 0.0.0.255 area 0
network 172.16.100.0 0.0.0.63 area 0
network 172.16.100.64 0.0.0.63 area 0
!
ip forward-protocol nd
no ip http server
no ip http secure-server
!
!
!
no cdp log mismatch duplex
!
!
!
!
!
!
control-plane
!
!
!
!
!
!
!
gatekeeper
shutdown
!
!
line con 0
exec-timeout 0 0
privilege level 15
logging synchronous
stopbits 1
line aux 0
exec-timeout 0 0
privilege level 15
logging synchronous
stopbits 1
line vty 0 4
login local
transport input ssh
!
end

View File

@@ -0,0 +1,168 @@
!
upgrade fpd auto
version 12.4
service timestamps debug datetime msec
service timestamps log datetime msec
no service password-encryption
!
hostname R1-CPE-BAT-A
!
boot-start-marker
boot-end-marker
!
logging message-counter syslog
!
no aaa new-model
ip source-route
no ip icmp rate-limit unreachable
ip cef
!
!
!
!
no ip domain lookup
ip domain name r1.cpe.local
no ipv6 cef
!
multilink bundle-name authenticated
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
file prompt quiet
username cisco privilege 15 password 0 cisco
archive
log config
hidekeys
!
!
!
!
!
ip tcp synwait-time 5
ip ssh version 2
ip scp server enable
!
!
!
!
interface Loopback1
description Loopback pour R1-CPE-BAT-A
ip address 1.1.1.1 255.255.255.255
!
interface Loopback2
description Loopback2 pour R1-CPE-BAT-A
ip address 1.1.1.2 255.255.255.255
!
interface Loopback10
description created from config file uploaded from postman
ip address 10.10.10.10 255.255.255.255
!
interface FastEthernet0/0
ip address 172.16.100.62 255.255.255.192
duplex half
!
interface Serial1/0
no ip address
shutdown
serial restart-delay 0
!
interface Serial1/1
ip address 10.1.1.1 255.255.255.252
shutdown
serial restart-delay 0
!
interface Serial1/2
no ip address
shutdown
serial restart-delay 0
!
interface Serial1/3
no ip address
shutdown
serial restart-delay 0
!
interface GigabitEthernet2/0
no ip address
negotiation auto
!
interface GigabitEthernet2/0.10
description "Gateway for teacher vlan"
encapsulation dot1Q 10
ip address 172.16.10.253 255.255.255.0
vrrp 10 ip 172.16.10.252
!
interface GigabitEthernet2/0.20
description "Gateway for student vlan"
encapsulation dot1Q 20
ip address 172.16.20.253 255.255.255.0
vrrp 20 ip 172.16.20.252
!
interface GigabitEthernet2/0.99
encapsulation dot1Q 99
ip address 172.16.100.125 255.255.255.192
vrrp 99 ip 172.16.100.124
!
router ospf 1
router-id 1.1.1.1
log-adjacency-changes
passive-interface FastEthernet0/0
passive-interface GigabitEthernet2/0.99
network 10.1.1.0 0.0.0.3 area 0
network 172.16.10.0 0.0.0.255 area 0
network 172.16.20.0 0.0.0.255 area 0
network 172.16.100.0 0.0.0.63 area 0
network 172.16.100.64 0.0.0.63 area 0
!
ip forward-protocol nd
no ip http server
no ip http secure-server
!
!
!
no cdp log mismatch duplex
!
!
!
!
!
!
control-plane
!
!
!
!
!
!
!
gatekeeper
shutdown
!
!
line con 0
exec-timeout 0 0
privilege level 15
logging synchronous
stopbits 1
line aux 0
exec-timeout 0 0
privilege level 15
logging synchronous
stopbits 1
line vty 0 4
login local
transport input ssh
!
end

View File

@@ -0,0 +1,3 @@
interface loopback 10
ip add 10.10.10.10 255.255.255.255
description created from config file uploaded from postman

View File

@@ -0,0 +1,28 @@
import yaml
def update_hosts_yaml(file_path="fastprod/inventory/hosts.yaml", items=None):
if items:
with open(file_path, 'w') as yaml_file:
yaml.safe_dump(items, yaml_file)
return True
def add_item_to_hosts_yaml(file_path="fastprod/inventory/hosts.yaml", save=True, item=None):
with open(file_path, 'r') as yaml_file:
hosts = yaml.safe_load(yaml_file)
new_hosts = hosts.copy()
new_hosts[item.get('data').get('device_name')] = item
if save:
update_hosts_yaml(items=new_hosts)
return new_hosts[item.get('data').get('device_name')]
def delete_item_from_hosts_yaml(yaml_file_path="fastprod/inventory/hosts.yaml", save=True,item=None, ):
with open(yaml_file_path,'r') as yaml_file:
hosts = yaml.safe_load(yaml_file)
new_hosts = hosts.copy()
del new_hosts[item.get('data').get('device_name')]
if save:
update_hosts_yaml(items=new_hosts)
return True

267
fastprod_backend/nornir.log Normal file
View File

@@ -0,0 +1,267 @@
2025-11-27 10:29:07,377 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_interfaces']} on 1 hosts
2025-11-27 10:30:31,532 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_interfaces']} on 1 hosts
2025-11-27 10:32:16,142 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_interfaces']} on 1 hosts
2025-11-27 10:33:00,527 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_interfaces']} on 1 hosts
2025-11-27 10:42:31,649 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_interfaces_ip']} on 1 hosts
2025-11-27 10:43:18,016 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_interfaces_ip']} on 1 hosts
2025-11-27 10:44:05,459 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_interfaces_ip']} on 1 hosts
2025-11-27 10:44:18,600 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_interfaces_ip']} on 1 hosts
2025-11-27 10:47:29,054 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_interfaces_ip']} on 1 hosts
2025-11-27 10:47:38,118 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_interfaces_ip']} on 1 hosts
2025-11-27 10:49:17,515 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_interfaces_ip']} on 1 hosts
2025-11-27 10:50:27,409 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_interfaces_ip']} on 1 hosts
2025-11-27 10:55:14,616 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_facts']} on 1 hosts
2025-11-27 10:55:35,609 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_facts']} on 1 hosts
2025-11-27 11:03:38,869 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_config']} on 1 hosts
2025-11-27 11:11:30,181 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_interfaces']} on 1 hosts
2025-11-27 11:12:43,941 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_interfaces']} on 1 hosts
2025-11-27 11:12:47,660 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_config']} on 1 hosts
2025-11-27 11:12:58,676 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_config']} on 1 hosts
2025-11-27 11:13:05,327 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_config']} on 1 hosts
2025-11-27 11:13:07,216 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_config']} on 1 hosts
2025-11-27 11:13:17,120 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_config']} on 1 hosts
2025-11-27 11:17:14,064 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_interfaces']} on 1 hosts
2025-11-27 11:17:51,306 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_interfaces']} on 1 hosts
2025-11-27 11:18:37,859 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_interfaces']} on 1 hosts
2025-11-27 11:18:53,937 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_interfaces']} on 1 hosts
2025-11-27 11:23:38,281 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_interfaces']} on 1 hosts
2025-11-27 11:29:27,867 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_config']} on 1 hosts
2025-11-27 11:29:31,935 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_config']} on 1 hosts
2025-11-27 11:34:46,926 - nornir.core - INFO - run() - Running task 'napalm_cli' with args {'commands': ['show ip route']} on 1 hosts
2025-11-27 11:35:32,732 - nornir.core - INFO - run() - Running task 'napalm_cli' with args {'commands': ['show ip route']} on 1 hosts
2025-11-27 11:40:04,424 - nornir.core - INFO - run() - Running task 'napalm_cli' with args {'commands': ['show ip route']} on 1 hosts
2025-11-27 11:40:04,522 - nornir.core - INFO - run() - Running task 'napalm_cli' with args {'commands': ['show ip interfaces brief']} on 1 hosts
2025-11-27 11:52:28,952 - nornir.core - INFO - run() - Running task 'netmiko_send_config' with args {'config_commands': [['interface loopback 8', 'ip add 8.8.8.8 255.255.255.255', 'description created_from_postman']]} on 1 hosts
2025-11-27 11:52:29,772 - nornir.core.task - ERROR - start() - Host 'R1-CPE-BAT-A': task 'netmiko_send_config' failed with traceback:
Traceback (most recent call last):
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/nornir/core/task.py", line 98, in start
r = self.task(self, **self.params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/nornir_netmiko/tasks/netmiko_send_config.py", line 38, in netmiko_send_config
result = net_connect.send_config_set(config_commands=config_commands, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/netmiko/base_connection.py", line 111, in wrapper_decorator
return_val = func(self, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/netmiko/base_connection.py", line 2294, in send_config_set
[True for cmd in config_commands_tmp if re.search(bypass_commands, cmd)]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/re/__init__.py", line 177, in search
return _compile(pattern, flags).search(string)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: expected string or bytes-like object, got 'list'
2025-11-27 13:16:50,900 - nornir.core - INFO - run() - Running task 'netmiko_send_config' with args {'config_file': 'fastprod/upload_files/R1-CPE-BAT-A_loopback.conf'} on 1 hosts
2025-11-27 13:18:50,146 - nornir.core - INFO - run() - Running task 'netmiko_send_config' with args {'config_file': 'fastprod/upload_files/R1-CPE-BAT-A_loopback.conf'} on 1 hosts
2025-11-27 13:37:51,507 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_config']} on 1 hosts
2025-11-27 13:38:36,507 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_config']} on 1 hosts
2025-11-27 13:39:25,827 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_config']} on 1 hosts
2025-11-27 13:41:20,882 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_config']} on 1 hosts
2025-11-27 13:47:08,252 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_config']} on 1 hosts
2025-11-27 13:47:38,160 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_config']} on 1 hosts
2025-11-27 13:47:55,759 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_config']} on 1 hosts
2025-11-27 13:48:27,889 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_config']} on 1 hosts
2025-11-27 13:48:56,963 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_config']} on 1 hosts
2025-11-27 13:51:12,137 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_config']} on 1 hosts
2025-11-27 13:52:20,289 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_config']} on 1 hosts
2025-11-27 13:52:47,032 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_config']} on 1 hosts
2025-11-27 13:53:07,676 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_config']} on 1 hosts
2025-11-27 13:53:27,844 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_config']} on 1 hosts
2025-11-27 13:55:22,325 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_config']} on 1 hosts
2025-11-27 14:27:45,418 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_interfaces']} on 1 hosts
2025-11-27 14:27:45,421 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_facts']} on 1 hosts
2025-11-27 14:27:45,425 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_interfaces_ip']} on 1 hosts
2025-11-27 14:27:58,534 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_facts']} on 1 hosts
2025-11-27 14:28:03,171 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_config']} on 1 hosts
2025-11-27 14:28:26,673 - nornir.core - INFO - run() - Running task 'napalm_cli' with args {'commands': ['show ip int br']} on 1 hosts
2025-11-27 14:29:34,616 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_facts']} on 1 hosts
2025-11-27 14:31:40,826 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_facts']} on 1 hosts
2025-11-27 14:31:47,954 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_facts']} on 1 hosts
2025-11-27 14:34:06,500 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_facts']} on 1 hosts
2025-11-27 14:34:06,510 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_interfaces']} on 1 hosts
2025-11-27 14:34:06,526 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_interfaces_ip']} on 1 hosts
2025-11-27 14:34:09,203 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_config']} on 1 hosts
2025-11-27 14:34:19,454 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_interfaces_ip']} on 1 hosts
2025-11-27 14:34:20,018 - nornir.core.task - ERROR - start() - Host 'ESW1-CPE-BAT-A': task 'napalm_get' failed with traceback:
Traceback (most recent call last):
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/nornir/core/task.py", line 98, in start
r = self.task(self, **self.params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/nornir_napalm/plugins/tasks/napalm_get.py", line 44, in napalm_get
result[g] = method(**options)
^^^^^^^^^^^^^^^^^
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/napalm/ios/ios.py", line 1215, in get_interfaces
output = self._send_command(command)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/napalm/ios/ios.py", line 208, in _send_command
output = self.device.send_command(command)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/netmiko/base_connection.py", line 111, in wrapper_decorator
return_val = func(self, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/netmiko/utilities.py", line 667, in wrapper_decorator
return func(self, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/netmiko/base_connection.py", line 1791, in send_command
new_data = self.command_echo_read(cmd=cmd, read_timeout=10)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/netmiko/base_connection.py", line 1494, in command_echo_read
new_data = self.read_until_pattern(
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/netmiko/base_connection.py", line 755, in read_until_pattern
raise ReadTimeout(msg)
netmiko.exceptions.ReadTimeout:
Pattern not detected: 'show\\ interfaces' in output.
Things you might try to fix this:
1. Adjust the regex pattern to better identify the terminating string. Note, in
many situations the pattern is automatically based on the network device's prompt.
2. Increase the read_timeout to a larger value.
You can also look at the Netmiko session_log or debug log for more information.
2025-11-27 14:34:20,648 - nornir.core.task - ERROR - start() - Host 'ESW1-CPE-BAT-A': task 'napalm_get' failed with traceback:
Traceback (most recent call last):
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/nornir/core/task.py", line 98, in start
r = self.task(self, **self.params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/nornir_napalm/plugins/tasks/napalm_get.py", line 44, in napalm_get
result[g] = method(**options)
^^^^^^^^^^^^^^^^^
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/napalm/ios/ios.py", line 3676, in get_config
output = self._send_command(command)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/napalm/ios/ios.py", line 208, in _send_command
output = self.device.send_command(command)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/netmiko/base_connection.py", line 111, in wrapper_decorator
return_val = func(self, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/netmiko/utilities.py", line 667, in wrapper_decorator
return func(self, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/netmiko/base_connection.py", line 1791, in send_command
new_data = self.command_echo_read(cmd=cmd, read_timeout=10)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/netmiko/base_connection.py", line 1494, in command_echo_read
new_data = self.read_until_pattern(
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/netmiko/base_connection.py", line 755, in read_until_pattern
raise ReadTimeout(msg)
netmiko.exceptions.ReadTimeout:
Pattern not detected: 'show\\ running\\-config' in output.
Things you might try to fix this:
1. Adjust the regex pattern to better identify the terminating string. Note, in
many situations the pattern is automatically based on the network device's prompt.
2. Increase the read_timeout to a larger value.
You can also look at the Netmiko session_log or debug log for more information.
2025-11-27 14:34:26,321 - nornir.core - WARNING - run() - Task 'napalm_get' has not been run 0 hosts selected
2025-11-27 14:34:29,743 - nornir.core - WARNING - run() - Task 'napalm_get' has not been run 0 hosts selected
2025-11-27 14:35:36,177 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_facts']} on 1 hosts
2025-11-27 14:35:36,181 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_interfaces_ip']} on 1 hosts
2025-11-27 14:35:36,182 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_interfaces']} on 1 hosts
2025-11-27 14:35:58,683 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_config']} on 1 hosts
2025-11-27 14:40:22,059 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_facts']} on 1 hosts
2025-11-27 14:40:22,065 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_interfaces_ip']} on 1 hosts
2025-11-27 14:40:22,069 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_interfaces']} on 1 hosts
2025-11-27 14:40:30,793 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_interfaces']} on 1 hosts
2025-11-27 14:40:30,804 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_facts']} on 1 hosts
2025-11-27 14:40:30,817 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_interfaces_ip']} on 1 hosts
2025-11-27 14:40:36,971 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_config']} on 1 hosts
2025-11-27 14:40:43,753 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_interfaces_ip']} on 1 hosts
2025-11-27 14:40:43,762 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_facts']} on 1 hosts
2025-11-27 14:40:43,767 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_interfaces']} on 1 hosts
2025-11-27 14:43:35,049 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_interfaces']} on 1 hosts
2025-11-27 14:43:35,051 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_interfaces_ip']} on 1 hosts
2025-11-27 14:43:35,053 - nornir.core - INFO - run() - Running task 'napalm_get' with args {'getters': ['get_facts']} on 1 hosts
2025-11-27 14:43:45,140 - nornir.core.task - ERROR - start() - Host 'R1-CPE-BAT-A': task 'napalm_get' failed with traceback:
Traceback (most recent call last):
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/nornir/core/task.py", line 98, in start
r = self.task(self, **self.params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/nornir_napalm/plugins/tasks/napalm_get.py", line 44, in napalm_get
result[g] = method(**options)
^^^^^^^^^^^^^^^^^
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/napalm/ios/ios.py", line 1215, in get_interfaces
output = self._send_command(command)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/napalm/ios/ios.py", line 208, in _send_command
output = self.device.send_command(command)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/netmiko/base_connection.py", line 111, in wrapper_decorator
return_val = func(self, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/netmiko/utilities.py", line 667, in wrapper_decorator
return func(self, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/netmiko/base_connection.py", line 1791, in send_command
new_data = self.command_echo_read(cmd=cmd, read_timeout=10)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/netmiko/base_connection.py", line 1494, in command_echo_read
new_data = self.read_until_pattern(
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/netmiko/base_connection.py", line 755, in read_until_pattern
raise ReadTimeout(msg)
netmiko.exceptions.ReadTimeout:
Pattern not detected: 'show\\ interfaces' in output.
Things you might try to fix this:
1. Adjust the regex pattern to better identify the terminating string. Note, in
many situations the pattern is automatically based on the network device's prompt.
2. Increase the read_timeout to a larger value.
You can also look at the Netmiko session_log or debug log for more information.
2025-11-27 14:43:45,145 - nornir.core.task - ERROR - start() - Host 'R1-CPE-BAT-A': task 'napalm_get' failed with traceback:
Traceback (most recent call last):
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/nornir/core/task.py", line 98, in start
r = self.task(self, **self.params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/nornir_napalm/plugins/tasks/napalm_get.py", line 44, in napalm_get
result[g] = method(**options)
^^^^^^^^^^^^^^^^^
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/napalm/ios/ios.py", line 1316, in get_interfaces_ip
show_ip_interface = self._send_command(command)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/napalm/ios/ios.py", line 208, in _send_command
output = self.device.send_command(command)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/netmiko/base_connection.py", line 111, in wrapper_decorator
return_val = func(self, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/netmiko/utilities.py", line 667, in wrapper_decorator
return func(self, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/netmiko/base_connection.py", line 1791, in send_command
new_data = self.command_echo_read(cmd=cmd, read_timeout=10)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/netmiko/base_connection.py", line 1494, in command_echo_read
new_data = self.read_until_pattern(
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/cpe/.local/share/virtualenvs/fastprod_backend-xSm6n0LL/lib/python3.12/site-packages/netmiko/base_connection.py", line 755, in read_until_pattern
raise ReadTimeout(msg)
netmiko.exceptions.ReadTimeout:
Pattern not detected: 'show\\ ip\\ interface' in output.
Things you might try to fix this:
1. Adjust the regex pattern to better identify the terminating string. Note, in
many situations the pattern is automatically based on the network device's prompt.
2. Increase the read_timeout to a larger value.
You can also look at the Netmiko session_log or debug log for more information.

3
fastprod_backend/start.sh Executable file
View File

@@ -0,0 +1,3 @@
#!/bin/bash
export FLASK_APP=fastprod/api.py
pipenv run flask run --host=0.0.0.0 --port=5000