summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhochikong <1097225749@qq.com>2016-09-05 14:55:11 +0800
committerhochikong <1097225749@qq.com>2016-09-05 14:55:11 +0800
commit600e47d4aa71de2eada4e260a41968f5d7f9cc2d (patch)
treea3910549bc7bf51eb2f27ce3ff333b6aac014d3e
parentb6d33086cfecf091a1d4f2afc4bbf4607e4a327c (diff)
downloadpython-vyos-mgmt-600e47d4aa71de2eada4e260a41968f5d7f9cc2d.tar.gz
python-vyos-mgmt-600e47d4aa71de2eada4e260a41968f5d7f9cc2d.zip
Fix some logic error in commit()
Fix the readme add a new exception rewrite the error handle in router.py
-rwxr-xr-xREADME.md77
-rw-r--r--vymgmt/base_exceptions/base.py8
-rw-r--r--vymgmt/mgmt_common.py33
-rw-r--r--vymgmt/router.py136
4 files changed, 164 insertions, 90 deletions
diff --git a/README.md b/README.md
index f697cbc..3abbc47 100755
--- a/README.md
+++ b/README.md
@@ -16,29 +16,28 @@ Use this library to send the configuration commands to VyOS.
###Requirement:pexpect(pxssh)
+###Platform:Python2 and 3
+
##Basic Example
Set a description for eth0:
>>> from vymgmt.router import Router
>>> vyos = Router('192.168.225.2','vyos:vyos')
>>> vyos.login()
- 'Result : Login successfully.'
>>> vyos.configure()
- 'Result : Active configure mode successfully.'
>>> vyos.set("interfaces ethernet eth0 description 'eth0'")
- 'Result : Configured successfully'
+ >>> vyos.status()
+ {'save': 'No', 'status': 'login', 'configure': 'Yes', 'commit': 'No'}
>>> vyos.commit()
- 'Result : Commit successfully.'
>>> vyos.status()
- {'status': 'login', 'commit': 'Yes', 'save': 'No', 'configure': 'Yes'}
- >>> vyos.exit()
- 'Error : You should save first.'
+ {'save': 'No', 'status': 'login', 'configure': 'Yes', 'commit': 'Yes'}
>>> vyos.save()
- 'Result : Save successfully.'
+ >>> vyos.status()
+ {'save': 'Yes', 'status': 'login', 'configure': 'Yes', 'commit': 'Yes'}
>>> vyos.exit()
- 'Result : Exit configure mode successfully.'
>>> vyos.logout()
- 'Result : Logout successfully.'
+ >>> vyos.status()
+ {'save': None, 'status': 'logout', 'configure': None, 'commit': None}
Because we have save the configuration,so if you reboot the VyOS system but the static router still works.
@@ -78,14 +77,12 @@ You should import class Router from vymgmt.router,the use address and "username:
Then,you can use login() to login vyos1:
>>> vyos1.login()
- 'Result : Login successfully.'
-If there are no problems,this method will return a string message to user.
+If there are no problems,this method will return nothing to user.
By now,you can use configure() and execute configuration commands:
>>> vyos1.configure()
- 'Result : Active configure mode successfully.'
You can use status() method to get the status of this instance:
@@ -115,9 +112,8 @@ Oh,NO!I just forgot the netmask.But you can see,if your input has mistakes,this
Now,let's use a correct configuration:
>>> vyos1.set("interfaces ethernet eth1 address '192.168.10.5/24'")
- 'Result : Configured successfully'
-Well,I set address for eth1 now.
+Well,I have set the address for eth1 now.
Let's check the status now:
@@ -129,12 +125,10 @@ You can see,"commit" and "save" are "No",so,you must commit and save it.
Commit:
>>> vyos1.commit()
- 'Result : Commit successfully.'
Save it:
>>> vyos1.save()
- 'Result : Save successfully.'
Let's check the status again:
@@ -144,9 +138,7 @@ Let's check the status again:
You see,the value of "commit" and "save" have changed to "Yes",now I can exit the configure mode and logout.But if you don't commit and save,you still can use "vyos1.exit(force=True)" to exit and discard what you have configured:
>>> vyos1.exit()
- 'Result : Exit configure mode successfully.'
>>> vyos1.logout()
- 'Result : Logout successfully.'
>>> vyos1.status()
{'status': 'logout', 'commit': None, 'save': None, 'configure': None}
@@ -181,60 +173,53 @@ I have set two test vms' gateway.Now login vyos1,configure the rip network:
>>> from vymgmt.router import Router
>>> vyos1 = Router('192.168.225.2','vyos:vyos')
>>> vyos1.login()
- 'Result : Login successfully.'
>>> vyos1.configure()
- 'Result : Active configure mode successfully.'
First,we should add a new lo address:
>>> vyos1.set("interfaces loopback lo address 1.1.1.1/32")
- 'Result : Configured successfully'
Then configure rip networks:
>>> vyos1.set("protocols rip network 192.168.225.0/24")
- 'Result : Configured successfully'
>>> vyos1.set("protocols rip network 192.168.10.0/24")
- 'Result : Configured successfully'
And the last step:
>>> vyos1.set("protocols rip redistribute connected")
- 'Result : Configured successfully'
-Sometimes,you may forget to commit or save,the library will return a message and refuse to exit:
+Sometimes,you may forget to commit or save,the library will raise an exception and refuse to exit:
>>> vyos1.status()
{'status': 'login', 'commit': 'No', 'save': 'No', 'configure': 'Yes'}
- >>> vyos1.exit()
- 'Error : You should commit first.'
+ >>> vyos1.exit()
+ Traceback (most recent call last):
+ File "<stdin>", line 1, in <module>
+ File "build/bdist.linux-x86_64/egg/vymgmt/router.py", line 233, in exit
+ vymgmt.base_exceptions.base.MaintenanceError:
+ Error : You should commit first.
>>> vyos1.save()
- 'Error : You need to commit first!'
+ Traceback (most recent call last):
+ File "<stdin>", line 1, in <module>
+ File "build/bdist.linux-x86_64/egg/vymgmt/router.py", line 185, in save
+ vymgmt.base_exceptions.base.MaintenanceError:
+ Error : You need to commit first!
Therefore,we should execute commit() and save():
>>> vyos1.commit()
- 'Result : Commit successfully.'
>>> vyos1.save()
- 'Result : Save successfully.'
Then on vyos2,we can configure rip network:
>>> vyos2 = Router('192.168.10.6','vyos:vyos')
>>> vyos2.login()
- 'Result : Login successfully.'
>>> vyos2.configure()
- 'Result : Active configure mode successfully.'
>>> vyos2.set("protocols rip network 192.168.10.0/24")
- 'Result : Configured successfully'
>>> vyos2.set("protocols rip network 192.168.157.0/24")
- 'Result : Configured successfully'
>>> vyos2.set("protocols rip redistribute connected")
- 'Result : Configured successfully'
>>> vyos2.commit()
- 'Result : Commit successfully.'
>>> vyos2.save()
- 'Result : Save successfully.'
Then check it on test1:
@@ -265,15 +250,6 @@ On test3:
rtt min/avg/max/mdev = 1.036/1.241/1.381/0.127 ms
Now,maybe you are understand how to use this library to configure VyOS.
-
-
-
-
-
-
-
-
-
#All Methods
##status():
@@ -322,7 +298,7 @@ Basic 'set' method,execute the set command in VyOS.
Example:
config: "interfaces ethernet eth0 description 'eth0'"
-The minimal c method.
+The minimal configuration method.
##delete(config)
Basic 'delete' method,execute the delete command in VyOS.
@@ -382,6 +358,11 @@ This exception class is for all failures which do not covered by exceptions abov
When this exception raise,the error message from VyOS will displayed.
+##vymgmt.base_exceptions.MaintenanceError()
+
+This exception class is for all maintenance method such login(),logout(),configure() has errors.
+
+When this exception raise,the error message from VyOS will displayed.
diff --git a/vymgmt/base_exceptions/base.py b/vymgmt/base_exceptions/base.py
index dc80840..839224b 100644
--- a/vymgmt/base_exceptions/base.py
+++ b/vymgmt/base_exceptions/base.py
@@ -13,3 +13,11 @@ class CommonError(Error):
def __str__(self):
return prefix + self.error_message
+
+
+class MaintenanceError(Error):
+ def __init__(self, message):
+ self.error_message = message
+
+ def __str__(self):
+ return prefix + self.error_message
diff --git a/vymgmt/mgmt_common.py b/vymgmt/mgmt_common.py
index 1ccb96a..1153c54 100644
--- a/vymgmt/mgmt_common.py
+++ b/vymgmt/mgmt_common.py
@@ -1,5 +1,7 @@
# Copyright (c) 2016 Hochikong
+CODEC = 'utf8'
+
def messenger(obj, config):
"""This method used for sending configuration to VyOS
@@ -11,8 +13,9 @@ def messenger(obj, config):
try:
obj.sendline(config)
obj.prompt()
- if len(obj.before) > obj.before.index('\r\n') + 2:
- return obj.before
+ result = decodetool(obj.before, CODEC)
+ if len(result) > result.index('\r\n') + 2:
+ return result
else:
return "Result : Configured successfully"
except Exception as e:
@@ -26,12 +29,34 @@ def committer(obj, config):
:param config: A configuration string
:return: A message or an error
"""
+ exception_string = "enhanced syslogd: rsyslogd"
try:
obj.sendline(config)
obj.prompt()
- if len(obj.before) > obj.before.index('\r\n') + 2:
- return obj.before
+ result = decodetool(obj.before, CODEC)
+ if len(result) > result.index('\r\n') + 2:
+ if exception_string in result:
+ return "Result : Commit successfully"
+ else:
+ return result
else:
return "Result : Commit successfully"
except Exception as e:
return e
+
+
+def decodetool(target, codec):
+ """This method is used for decoding obj.before to string when run this
+ library under python3
+
+ :param target: The obj.before
+ :param codec: The codec use to decode
+ :return:
+ """
+ try:
+ if type(target) == str:
+ return target
+ if type(target) == bytes:
+ return target.decode(codec)
+ except Exception as e:
+ return e
diff --git a/vymgmt/router.py b/vymgmt/router.py
index 15fea9e..6b342f7 100644
--- a/vymgmt/router.py
+++ b/vymgmt/router.py
@@ -1,11 +1,11 @@
# Copyright (c) 2016 Hochikong
-from pxssh import pxssh
+from pexpect import pxssh
from .mgmt_common import messenger, committer
from .base_exceptions.exceptions_for_set_and_delete import ConfigPathError, ConfigValueError
from .base_exceptions.exceptions_for_commit import CommitFailed, CommitConflict
-from .base_exceptions.base import CommonError
+from .base_exceptions.base import CommonError, MaintenanceError
from .error_distinguish import distinguish_for_set, distinguish_for_delete, distinguish_for_commit
@@ -21,7 +21,7 @@ class Router(object):
self.__divi = self.__cred.index(":")
self.__username = ''.join(self.__cred[:self.__divi])
self.__passwd = ''.join(self.__cred[self.__divi+1:])
- self.__conn = pxssh()
+ self.__conn = pxssh.pxssh()
self.__status = {"status": None, "commit": None, "save": None, "configure": None}
self.__basic_string = {0: 'set ', 1: 'delete '}
@@ -37,43 +37,54 @@ class Router(object):
:return: A message or an error
"""
+ has_error = None
try:
if self.__conn.login(self.__address, self.__username, self.__passwd) is True:
self.__status["status"] = "login"
- return "Result : Login successfully."
else:
- return "Error : Connect Failed."
+ has_error = 'Type1'
except Exception as e:
return e
+ if has_error == 'Type1':
+ raise MaintenanceError("Error : Connect Failed.")
+
def logout(self):
"""Logout the router
:return: A message or an error
"""
+ has_error = None
try:
if self.__status["commit"] == "No":
- return "Error : You should commit and exit configure mode first."
+ has_error = 'Type1'
if self.__status["save"] == "No":
- return "Error : You should save and exit configure mode first."
+ has_error = 'Type2'
if self.__status["configure"] == "Yes":
- return "Error : You should exit configure mode first."
+ has_error = 'Type3'
self.__conn.close()
self.__status["status"] = "logout"
self.__status["configure"] = None
- self.__conn = pxssh()
- return "Result : Logout successfully."
+ self.__conn = pxssh.pxssh()
except Exception as e:
return e
+ if has_error == 'Type1':
+ raise MaintenanceError("Error : You should commit and exit configure mode first.")
+ if has_error == 'Type2':
+ raise MaintenanceError("Error : You should save and exit configure mode first.")
+ if has_error == 'Type3':
+ raise MaintenanceError("Error : You should exit configure mode first.")
+
def configure(self):
"""Enter the VyOS configure mode
:return: A message or an error
"""
+ has_error = None
try:
if self.__status["status"] == "login":
if self.__status["configure"] is not "Yes":
@@ -81,40 +92,55 @@ class Router(object):
self.__conn.prompt(0)
self.__conn.set_unique_prompt()
self.__status["configure"] = "Yes"
- return "Result : Active configure mode successfully."
else:
- return "Error : In configure mode now!"
+ has_error = 'Type1'
else:
- return "Error : Router object not connect to a router."
+ has_error = 'Type2'
except Exception as e:
return e
+ if has_error == 'Type1':
+ raise MaintenanceError("Error : In configure mode now!")
+ if has_error == 'Type2':
+ raise MaintenanceError("Error : Router object not connect to a router.")
+
def commit(self):
"""Commit the configuration changes
:return: A message or an error
"""
+ has_error = None
+ result = None
+ res = None
try:
if self.__status["status"] == "login":
if self.__status["configure"] == "Yes":
if self.__status["commit"] is None:
- return "Error : You don't need to commit."
+ has_error = 'Type1'
if self.__status["commit"] == "No":
res = committer(self.__conn, "commit")
if "Result" in res:
self.__status["commit"] = "Yes"
- return "Result : Commit successfully."
else:
result = distinguish_for_commit(res)
else:
- return "Error : You have commit!"
+ has_error = 'Type2'
else:
- return "Error : Router not in configure mode!"
+ has_error = 'Type3'
else:
- return "Error : Router object not connect to a router."
+ has_error = 'Type4'
except Exception as e:
return e
+ if has_error == 'Type1':
+ raise MaintenanceError("Error : You don't need to commit.")
+ if has_error == 'Type2':
+ raise MaintenanceError("Error : You have commit!")
+ if has_error == 'Type3':
+ raise MaintenanceError("Error : Router not in configure mode!")
+ if has_error == 'Type4':
+ raise MaintenanceError("Error : Router object not connect to a router.")
+
if result == "CommitFailed":
raise CommitFailed(res)
elif result == "CommitConflict":
@@ -125,36 +151,50 @@ class Router(object):
:return: A message or an error
"""
+ has_error = None
try:
if self.__status["status"] == "login":
if self.__status["configure"] == "Yes":
if self.__status["commit"] == "Yes":
if self.__status["save"] is None:
- return "Error : You don't need to save."
+ has_error = 'Type1'
if self.__status["save"] == "No":
self.__conn.sendline("save")
self.__conn.prompt(0)
self.__status["save"] = "Yes"
- return "Result : Save successfully."
else:
- return "Error : You have saved!"
+ has_error = 'Type2'
elif self.__status["commit"] is None:
- return "Error : You don't need to save."
+ has_error = 'Type3'
else:
- return "Error : You need to commit first!"
+ has_error = 'Type4'
else:
- return "Error : Router not in configure mode!"
+ has_error = 'Type5'
else:
- return "Error : Router object not connect to a router."
+ has_error = 'Type6'
except Exception as e:
return e
+ if has_error == 'Type1':
+ raise MaintenanceError("Error : You don't need to save.")
+ if has_error == 'Type2':
+ raise MaintenanceError("Error : You have saved!")
+ if has_error == 'Type3':
+ raise MaintenanceError("Error : You don't need to save.")
+ if has_error == 'Type4':
+ raise MaintenanceError("Error : You need to commit first!")
+ if has_error == 'Type5':
+ raise MaintenanceError("Error : Router not in configure mode!")
+ if has_error == 'Type6':
+ raise MaintenanceError("Error : Router object not connect to a router.")
+
def exit(self, force=False):
"""Exit VyOS configure mode
:param force: True or False
:return: A message or an error
"""
+ has_error = None
try:
if self.__status["status"] == "login":
if self.__status["configure"] == "Yes":
@@ -164,7 +204,6 @@ class Router(object):
self.__status["configure"] = "No"
self.__status["save"] = None
self.__status["commit"] = None
- return "Result : Exit configure mode successfully."
else:
if self.__status["commit"] == "Yes":
if self.__status["save"] == "Yes":
@@ -173,23 +212,30 @@ class Router(object):
self.__status["configure"] = "No"
self.__status["save"] = None
self.__status["commit"] = None
- return "Result : Exit configure mode successfully."
else:
- return "Error : You should save first."
+ has_error = 'Type1'
elif self.__status["commit"] is None:
self.__conn.sendline("exit")
self.__conn.prompt()
self.__status['configure'] = "No"
- return "Result : Exit configure mode successfully."
else:
- return "Error : You should commit first."
+ has_error = 'Type2'
else:
- return "Error : You are not in configure mode,need not exit."
+ has_error = 'Type3'
else:
- return "Error : Router object not connect to a router."
+ has_error = 'Type4'
except Exception as e:
return e
+ if has_error == 'Type1':
+ raise MaintenanceError("Error : You should save first.")
+ if has_error == 'Type2':
+ raise MaintenanceError("Error : You should commit first.")
+ if has_error == 'Type3':
+ raise MaintenanceError("Error : You are not in configure mode,no need to exit.")
+ if has_error == 'Type4':
+ raise MaintenanceError("Error : Router object not connect to a router.")
+
def set(self, config):
"""Basic 'set' method,execute the set command in VyOS
@@ -197,6 +243,9 @@ class Router(object):
e.g. 'protocols static route ... next-hop ... distance ...'
:return: A message or an error
"""
+ has_error = None
+ result = None
+ res = None
full_config = self.__basic_string[0] + config
try:
if self.__status["status"] == "login":
@@ -211,16 +260,20 @@ class Router(object):
pass
else:
self.__status["save"] = "No"
- return res
else:
result = distinguish_for_set(res)
else:
- return "Error : You are not in configure mode."
+ has_error = 'Type1'
else:
- return "Error : Router object not connect to a router."
+ has_error = 'Type2'
except Exception as e:
return e
+ if has_error == 'Type1':
+ raise MaintenanceError("Error : You are not in configure mode.")
+ if has_error == 'Type2':
+ raise MaintenanceError("Error : Router object not connect to a router.")
+
if result == "ConfigPathError":
raise ConfigPathError(res)
elif result == "ConfigValueError":
@@ -235,6 +288,9 @@ class Router(object):
e.g. 'protocols static route ... next-hop ... distance ...'
:return: A message or an error
"""
+ has_error = None
+ result = None
+ res = None
full_config = self.__basic_string[1] + config
try:
if self.__status["status"] == "login":
@@ -249,16 +305,20 @@ class Router(object):
pass
else:
self.__status["save"] = "No"
- return res
else:
result = distinguish_for_delete(res)
else:
- return "Error : You are not in configure mode."
+ has_error = 'Type1'
else:
- return "Error : Router object not connect to a router."
+ has_error = 'Type2'
except Exception as e:
return e
+ if has_error == 'Type1':
+ raise MaintenanceError("Error : You are not in configure mode.")
+ if has_error == 'Type2':
+ raise MaintenanceError("Error : Router object not connect to a router.")
+
if result == "ConfigPathError":
raise ConfigPathError(res)
elif result == "ConfigValueError":