前回の取得データ
前回取得し変更したXMLはこちら
ios-xe1.xml
<config>
<native xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-native">
<interface>
<GigabitEthernet>
<name>2</name>
<description>connect to IOS-XE2</description>
<ip>
<address>
<primary>
<address>12.0.0.1</address>
<mask>255.255.255.0</mask>
</primary>
</address>
<ospf xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-ospf">
<process-id>
<id>1</id>
<area>0</area>
</process-id>
<network>point-to-point</network>
</ospf>
</ip>
<mop>
<enabled>false</enabled>
<sysid>false</sysid>
</mop>
<negotiation xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-ethernet">
<auto>true</auto>
</negotiation>
</GigabitEthernet>
<GigabitEthernet>
<name>3</name>
<description>connect to IOS-XE3</description>
<ip>
<address>
<primary>
<address>13.0.0.1</address>
<mask>255.255.255.0</mask>
</primary>
</address>
<ospf xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-ospf">
<process-id>
<id>1</id>
<area>0</area>
</process-id>
<network>point-to-point</network>
</ospf>
</ip>
<mop>
<enabled>false</enabled>
<sysid>false</sysid>
</mop>
<negotiation xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-ethernet">
<auto>true</auto>
</negotiation>
</GigabitEthernet>
<GigabitEthernet>
<name>4</name>
<description>connect to IOS-XE4</description>
<ip>
<address>
<primary>
<address>14.0.0.1</address>
<mask>255.255.255.0</mask>
</primary>
</address>
<ospf xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-ospf">
<process-id>
<id>1</id>
<area>0</area>
</process-id>
<network>point-to-point</network>
</ospf>
</ip>
<mop>
<enabled>false</enabled>
<sysid>false</sysid>
</mop>
<negotiation xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-ethernet">
<auto>true</auto>
</negotiation>
</GigabitEthernet>
</interface>
<router>
<ospf xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-ospf">
<id>1</id>
<router-id>1.1.1.1</router-id>
</ospf>
</router>
</native>
</config>
ios-xe2.xml
<config>
<native xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-native">
<interface>
<GigabitEthernet>
<name>2</name>
<description>connect to IOS-XE1</description>
<ip>
<address>
<primary>
<address>12.0.0.2</address>
<mask>255.255.255.0</mask>
</primary>
</address>
<ospf xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-ospf">
<process-id>
<id>1</id>
<area>0</area>
</process-id>
<network>point-to-point</network>
</ospf>
</ip>
<mop>
<enabled>false</enabled>
<sysid>false</sysid>
</mop>
<negotiation xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-ethernet">
<auto>true</auto>
</negotiation>
</GigabitEthernet>
<GigabitEthernet>
<name>3</name>
<description>connect to IOS-XE4</description>
<ip>
<address>
<primary>
<address>24.0.0.2</address>
<mask>255.255.255.0</mask>
</primary>
</address>
<ospf xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-ospf">
<process-id>
<id>1</id>
<area>0</area>
</process-id>
<network>point-to-point</network>
</ospf>
</ip>
<mop>
<enabled>false</enabled>
<sysid>false</sysid>
</mop>
<negotiation xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-ethernet">
<auto>true</auto>
</negotiation>
</GigabitEthernet>
<GigabitEthernet>
<name>4</name>
<description>connect to IOS-XE3</description>
<ip>
<address>
<primary>
<address>23.0.0.2</address>
<mask>255.255.255.0</mask>
</primary>
</address>
<ospf xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-ospf">
<process-id>
<id>1</id>
<area>0</area>
</process-id>
<network>point-to-point</network>
</ospf>
</ip>
<mop>
<enabled>false</enabled>
<sysid>false</sysid>
</mop>
<negotiation xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-ethernet">
<auto>true</auto>
</negotiation>
</GigabitEthernet>
</interface>
<router>
<ospf xmlns="http://cisco.com/ns/yang/Cisco-IOS-XE-ospf">
<id>1</id>
<router-id>2.2.2.2</router-id>
</ospf>
</router>
</native>
</config>
取得したデータをPythonで送信。
device-templates
++ios-xe1.xml
++ios-xe2.xml
deploy_ospf_netconf.py
.envrc
.envrcについては以前使ったユーザーネームとパスワードのファイル
deploy_opsf_netconf.py
import os
from ncclient import manager
def import_template(template_name: str) -> bool:
try:
with open(f"./device-templates/{template_name}") as fd:
payload = fd.read()
except:
print(f"Failed to open ./device-templates/{template_name} file")
return False
if not payload.strip().startswith("<config"):
print(f"Template {template_name} content must begin with <config> tag.")
return False
device_name = template_name.strip(".xml")
print(f"\nDeploying template configuration to {device_name}...\n")
with manager.connect(
host = device_name,
port = "830",
username = os.environ["ROUTER_USERNAME"],
password = os.environ["ROUTER_PASSWORD"],
hostkey_verify = False
) as m:
try:
m.edit_config(config=payload,target="running")
print(f"\nOSPF Configuration Deployed to {device_name} Successfully")
except Exception as e:
print(e)
print(f"\nFailed to deploy OSPF Configuration{device_name}")
return True
def main() -> None:
result = True
with os.scandir("./device-templates") as pd:
for entry in pd:
if entry.is_file() and entry.name.endswith(".xml"):
result &= import_template(template_name=entry.name)
if not result:
exit(1)
if __name__ =="__main__":
main()
実行
ローカルの名前解決に名前を登録してから実行する。
/etc/hosts
#下記を追加
10.255.101 ios-xe1
10.255.102 ios-xe2
#source .envrc
#python deploy_ospf_netconf.py
Deploying templae configuration to ios-xe2...
OSPF Configuration Deployed to ios-xe2 Successfully
Deploying templae configuration to ios-xe1...
OSPF Configuration Deployed to ios-xe1 Successfully
IOS-XE1#sh ip ospf neighbor
IOS-XE1#
*Nov 25 18:33:42.064: %SEC_LOGIN-5-LOGIN_SUCCESS: Login Success [user: admin] [Source: 10.255.1.51] [localp
ort: 22] at 18:33:42 UTC Mon Nov 25 2024
*Nov 25 18:33:53.549: %SYS-6-LOGOUT: User admin has exited tty session 1(10.255.1.51)
*Nov 25 18:36:18.103: %DMI-5-AUTH_PASSED: R0/0: dmiauthd: User 'admin' authenticated successfully from 10.2
55.1.51:34774 and was authorized for netconf over ssh. External groups: PRIV15
*Nov 25 18:36:25.329: %OSPF-6-DFT_OPT: Protocol timers for fast convergence are Enabled.
*Nov 25 18:36:26.209: %OSPF-5-ADJCHG: Process 1, Nbr 3.3.3.3 on GigabitEthernet3 from LOADING to FULL, Load
ing Done
*Nov 25 18:36:26.210: %OSPF-5-ADJCHG: Process 1, Nbr 4.4.4.4 on GigabitEthernet4 from LOADING to FULL, Load
ing Done
*Nov 25 18:36:26.047: %DMI-5-CONFIG_I: R0/0: nesd: Configured from NETCONF/RESTCONF by admin, transaction-i
d 59
*Nov 25 18:36:33.117: %OSPF-5-ADJCHG: Process 1, Nbr 2.2.2.2 on GigabitEthernet2 from LOADING to FULL, Load
ing Done
IOS-XE1#sh ip ospf neighbor
Neighbor ID Pri State Dead Time Address Interface
2.2.2.2 0 FULL/ - 00:00:31 12.0.0.2 GigabitEthernet2
3.3.3.3 0 FULL/ - 00:00:38 13.0.0.3 GigabitEthernet3
4.4.4.4 0 FULL/ - 00:00:38 14.0.0.4 GigabitEthernet4
IOS-XE1#
IOS-XE2#sh ip ospf neighbor
IOS-XE2#
*Nov 25 18:35:20.778: %SEC_LOGIN-5-LOGIN_SUCCESS: Login Success [user: admin] [Source: 10.255.1.51] [localp
ort: 22] at 18:35:20 UTC Mon Nov 25 2024
*Nov 25 18:35:24.340: %SYS-6-LOGOUT: User admin has exited tty session 1(10.255.1.51)
*Nov 25 18:35:59.236: %DMI-5-AUTH_PASSED: R0/0: dmiauthd: User 'admin' authenticated successfully from 10.2
55.1.51:59034 and was authorized for netconf over ssh. External groups: PRIV15
*Nov 25 18:36:04.672: %OSPF-6-DFT_OPT: Protocol timers for fast convergence are Enabled.
*Nov 25 18:36:05.344: %DMI-5-CONFIG_I: R0/0: nesd: Configured from NETCONF/RESTCONF by admin, transaction-i
d 39
*Nov 25 18:36:09.776: %OSPF-5-ADJCHG: Process 1, Nbr 4.4.4.4 on GigabitEthernet3 from LOADING to FULL, Load
ing Done
*Nov 25 18:36:10.046: %OSPF-5-ADJCHG: Process 1, Nbr 3.3.3.3 on GigabitEthernet4 from LOADING to FULL, Load
ing Done
*Nov 25 18:36:33.366: %OSPF-5-ADJCHG: Process 1, Nbr 1.1.1.1 on GigabitEthernet2 from LOADING to FULL, Load
ing Donesh ip ospf neighbor
Neighbor ID Pri State Dead Time Address Interface
3.3.3.3 0 FULL/ - 00:00:36 23.0.0.3 GigabitEthernet4
4.4.4.4 0 FULL/ - 00:00:32 24.0.0.4 GigabitEthernet3
1.1.1.1 0 FULL/ - 00:00:38 12.0.0.1 GigabitEthernet2
IOS-XE2#
まとめ
・XML記法は独自性が高いので覚えるのは大変。ルーターを設定してそこから取ってきた方がいいかも。
・ダイアグラムの対称性がずれてるのには注意。
・TryのErrorはExceptionで常にひろう。