139 lines
3.9 KiB
Python
139 lines
3.9 KiB
Python
|
|
#!/usr/bin/env python3
|
||
|
|
"""
|
||
|
|
gNMI gRPC Configuration Script
|
||
|
|
===============================
|
||
|
|
Enables gRPC dial-in telemetry on all 9 IOS-XR routers so that
|
||
|
|
Telegraf (or any gNMI collector) can subscribe to streaming
|
||
|
|
telemetry data.
|
||
|
|
|
||
|
|
What this script applies per router:
|
||
|
|
- gRPC server on port 57400 with TLS disabled
|
||
|
|
- YANG model: Cisco-IOS-XR-man-ems-cfg
|
||
|
|
|
||
|
|
Router targets:
|
||
|
|
CORE-01 (10.100.0.100)
|
||
|
|
CORE-02 (10.100.0.200)
|
||
|
|
R9K-01 (10.100.0.1) through R9K-07 (10.100.0.7)
|
||
|
|
"""
|
||
|
|
|
||
|
|
from ncclient import manager
|
||
|
|
import sys
|
||
|
|
|
||
|
|
GRPC_NS = 'http://cisco.com/ns/yang/Cisco-IOS-XR-man-ems-cfg'
|
||
|
|
|
||
|
|
ROUTERS = [
|
||
|
|
('10.100.0.100', 'CORE-01'),
|
||
|
|
('10.100.0.200', 'CORE-02'),
|
||
|
|
('10.100.0.1', 'R9K-01'),
|
||
|
|
('10.100.0.2', 'R9K-02'),
|
||
|
|
('10.100.0.3', 'R9K-03'),
|
||
|
|
('10.100.0.4', 'R9K-04'),
|
||
|
|
('10.100.0.5', 'R9K-05'),
|
||
|
|
('10.100.0.6', 'R9K-06'),
|
||
|
|
('10.100.0.7', 'R9K-07'),
|
||
|
|
]
|
||
|
|
|
||
|
|
GRPC_CONFIG_XML = """
|
||
|
|
<config>
|
||
|
|
<grpc xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-man-ems-cfg">
|
||
|
|
<port>57400</port>
|
||
|
|
<no-tls/>
|
||
|
|
</grpc>
|
||
|
|
</config>
|
||
|
|
"""
|
||
|
|
|
||
|
|
|
||
|
|
def configure_router(mgmt_ip, label):
|
||
|
|
"""Apply gRPC configuration via NETCONF edit-config + commit."""
|
||
|
|
print(f"\n{'─'*60}")
|
||
|
|
print(f" Configuring {label} ({mgmt_ip})")
|
||
|
|
print(f"{'─'*60}")
|
||
|
|
print(f" Applying: gRPC port=57400 no-tls")
|
||
|
|
|
||
|
|
try:
|
||
|
|
with manager.connect(
|
||
|
|
host=mgmt_ip,
|
||
|
|
port=830,
|
||
|
|
username='webui',
|
||
|
|
password='cisco',
|
||
|
|
hostkey_verify=False,
|
||
|
|
device_params={'name': 'iosxr'},
|
||
|
|
timeout=20,
|
||
|
|
) as m:
|
||
|
|
print(" → Applying gRPC configuration...")
|
||
|
|
m.edit_config(target='candidate', config=GRPC_CONFIG_XML)
|
||
|
|
|
||
|
|
print(" → Committing...")
|
||
|
|
m.commit()
|
||
|
|
print(f" ✓ {label} done.")
|
||
|
|
return True
|
||
|
|
|
||
|
|
except Exception as e:
|
||
|
|
print(f" ✗ ERROR on {label}: {e}")
|
||
|
|
return False
|
||
|
|
|
||
|
|
|
||
|
|
def verify_router(mgmt_ip, label):
|
||
|
|
"""Re-read running config to confirm the grpc block is present."""
|
||
|
|
try:
|
||
|
|
with manager.connect(
|
||
|
|
host=mgmt_ip, port=830, username='webui', password='cisco',
|
||
|
|
hostkey_verify=False, device_params={'name': 'iosxr'}, timeout=10
|
||
|
|
) as m:
|
||
|
|
filt_grpc = """<filter>
|
||
|
|
<grpc xmlns="http://cisco.com/ns/yang/Cisco-IOS-XR-man-ems-cfg">
|
||
|
|
<port/>
|
||
|
|
<no-tls/>
|
||
|
|
</grpc>
|
||
|
|
</filter>"""
|
||
|
|
r_grpc = m.get_config(source='running', filter=filt_grpc)
|
||
|
|
|
||
|
|
has_grpc = '<port>57400</port>' in str(r_grpc)
|
||
|
|
has_notls = '<no-tls' in str(r_grpc)
|
||
|
|
|
||
|
|
g = '✓' if has_grpc else '✗'
|
||
|
|
t = '✓' if has_notls else '✗'
|
||
|
|
status = 'OK' if (has_grpc and has_notls) else 'INCOMPLETE'
|
||
|
|
print(f" {label:8s} grpc-port={g} no-tls={t} [{status}]")
|
||
|
|
|
||
|
|
except Exception as e:
|
||
|
|
print(f" {label:8s} verify error: {e}")
|
||
|
|
|
||
|
|
|
||
|
|
def main():
|
||
|
|
print("gNMI gRPC Configuration Script")
|
||
|
|
print("================================")
|
||
|
|
print(f"Targets: all {len(ROUTERS)} routers")
|
||
|
|
print()
|
||
|
|
|
||
|
|
results = []
|
||
|
|
for mgmt_ip, label in ROUTERS:
|
||
|
|
ok = configure_router(mgmt_ip, label)
|
||
|
|
results.append((mgmt_ip, label, ok))
|
||
|
|
|
||
|
|
# Summary
|
||
|
|
print(f"\n{'='*60}")
|
||
|
|
print("Post-apply verification")
|
||
|
|
print('='*60)
|
||
|
|
print(f" {'Router':8s} {'gRPC Port':9s} {'No-TLS':6s} Status")
|
||
|
|
for mgmt_ip, label, ok in results:
|
||
|
|
if ok:
|
||
|
|
verify_router(mgmt_ip, label)
|
||
|
|
else:
|
||
|
|
print(f" {label:8s} skipped (apply failed)")
|
||
|
|
|
||
|
|
failed = [label for _, label, ok in results if not ok]
|
||
|
|
print()
|
||
|
|
if failed:
|
||
|
|
print(f"FAILED: {', '.join(failed)}")
|
||
|
|
sys.exit(1)
|
||
|
|
else:
|
||
|
|
print("All routers configured successfully.")
|
||
|
|
print()
|
||
|
|
print("gRPC is now listening on port 57400 (no TLS) on all routers.")
|
||
|
|
print("Next: start Telegraf with gNMI input plugin to begin collecting telemetry.")
|
||
|
|
|
||
|
|
|
||
|
|
if __name__ == '__main__':
|
||
|
|
main()
|