# -*-coding:utf-8-*- import re import socket import time import paramiko import sys from lxml import etree HELLO_MSG = ''' <?xml version="1.0" encoding="UTF-8"?> <hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <capabilities> <capability>urn:ietf:params:netconf:base:1.0</capability> <capability>urn:ietf:params:netconf:capability:writable-running:1.0</capability> <capability>urn:ietf:params:netconf:capability:candidate:1.0</capability> <capability>urn:ietf:params:netconf:capability:confirmed-commit:1.0</capability> </capabilities> </hello> ''' config = { "interval": 30, "retry_times": 1, "timeout": 300, #wait timeout } class NetconfClient(object): def __init__(self, ip, port, user, password): self.configdict = { 'protocol': "netconf", 'username': user, 'password': password, 'host': ip, 'port': port, } self.channel = None def connect_device(self): try: self.ssh = None #socket.setdefaulttimeout(1) self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.settimeout(3600) self.sock.connect((self.configdict['host'], int(self.configdict['port']))) self.ssh = paramiko.Transport(self.sock) self.ssh.connect(username=self.configdict['username'], password=self.configdict['password']) return True except Exception as e: print("[connect_device]:%s" % e) self.close() return False def connect_channel(self): try: self.channel = self.ssh.open_session() self.channel.invoke_subsystem('netconf') self.channel.settimeout(config['timeout']) return True except Exception as e: print("[connect_channel]:%s" % e) self.close() return False def send_hello(self): self.status = False try: if not self.channel: if True == self.connect_device() and self.connect_channel(): self.get_connect_recv() self.handle_send_message(HELLO_MSG) self.status = True else: return False return True except Exception as e: print("[send_hello]:%s" % e) return False def send_request(self, data): self.status = False ret = None try: if not self.channel: if self.connect_device() and self.connect_channel(): self.get_connect_recv() self.handle_send_message(HELLO_MSG) self.status = True else: return "ERROR:connect failed" except Exception as e: return "ERROR:[send_request]::%s" % e ret = self.get_data(data) return ret def get_data(self, filter): filter = "".join([line.strip() for line in filter.split("\n")]) try: self.handle_send_message(filter) ret = self.get_connect_recv() except: print("get_connect_recv Error at Function get_config2") return "" return ret def get_connect_recv(self): data = "" while True: if data.find(']]>]]>') != -1: data = data.replace(']]>]]>', '') break elif data.find('rpc-reply>') != -1: break try: data += bytes.decode(self.channel.recv(1024),"utf8","ignore") except Exception as e: print("[get_connect_recv]:%s",e) break return data def handle_send_message(self, msg): msg = msg.replace("\"xmlns:", "\" xmlns:") self.channel.send(msg+ "]]>]]>") def close(self): try: if self.ssh != None: self.ssh.close() self.ssh = None if self.channel != None: self.channel.close() self.channel = None if self.sock != None: self.sock.close() self.sock = None except: pass def __del__(self): self.close() if __name__ == "__main__": str_xml = ''' <rpc message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <edit-data xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-nmda" xmlns:ds="urn:ietf:params:xml:ns:yang:ietf-datastores"> <datastore>ds:startup</datastore> <default-operation>merge</default-operation> <config> <mplane-info xmlns="urn:o-ran:mplane-interfaces:1.0"> <searchable-mplane-access-vlans-info> <vlan-range> <lowest-vlan-id>20</lowest-vlan-id> <highest-vlan-id>25</highest-vlan-id> </vlan-range> </searchable-mplane-access-vlans-info> </mplane-info> </config> </edit-data> </rpc>''' unlock_xml=''' <rpc message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <get-data xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-nmda" xmlns:ds="urn:ietf:params:xml:ns:yang:ietf-datastores"> <datastore>ds:startup</datastore> </get-data> </rpc>''' tree = etree.fromstring(str_xml) new_tree = etree.tostring(tree).decode("utf-8") netconf_client = NetconfClient("192.168.1.23", "830", "root", "Bestwishs4you!") print("Connect NETCONF success!!!") time.sleep(1) print(netconf_client.send_request(unlock_xml))
paramiko connect NETCONF
于 2024-03-14 16:33:37 首次发布