# -*-coding:utf-8-*-
import re
import socket
import paramiko
import sys
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
if __name__ == "__main__":
xml = '''
<?xml version="1.0" encoding="UTF-8"?>
<rpc message-id="1002" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<get-config>
<source>
<running/>
</source>
<filter type="subtree">
<time-ranges>
</time-ranges>
</filter>
</get-config>
</rpc>
'''
netconf_client = NetconfClient("172.0.0.1","830","test","test_test")
print(netconf_client.send_request(xml))