From 5c7c56264681faa44b2bca036973b08cecf168ae Mon Sep 17 00:00:00 2001 From: hochikong <1097225749@qq.com> Date: Wed, 24 Aug 2016 14:41:35 +0800 Subject: T133 Add a generic method set() and delete() Fix all problems from now on --- vymgmt/Router.py | 232 ------------------ vymgmt/base_exception/__init__.py | 0 vymgmt/base_exception/base.py | 15 ++ vymgmt/base_exception/exception_for_commit.py | 21 ++ .../exceptions_for_set_and_delete.py | 22 ++ vymgmt/error_distinguish.py | 64 +++++ vymgmt/mgmt_common.py | 18 ++ vymgmt/router.py | 258 +++++++++++++++++++++ 8 files changed, 398 insertions(+), 232 deletions(-) delete mode 100644 vymgmt/Router.py create mode 100644 vymgmt/base_exception/__init__.py create mode 100644 vymgmt/base_exception/base.py create mode 100644 vymgmt/base_exception/exception_for_commit.py create mode 100644 vymgmt/base_exception/exceptions_for_set_and_delete.py create mode 100644 vymgmt/error_distinguish.py create mode 100644 vymgmt/router.py diff --git a/vymgmt/Router.py b/vymgmt/Router.py deleted file mode 100644 index 326e025..0000000 --- a/vymgmt/Router.py +++ /dev/null @@ -1,232 +0,0 @@ -# Copyright (c) 2016 Hochikong - -from pxssh import pxssh -from .mgmt_common import messenger - - -class Router(object): - def __init__(self, address, cred): - """Initial a router object - - :param address: Router address,example:'192.168.10.10' - :param cred: Router user and password,example:'vyos:vyos' - """ - self.__address = address - self.__cred = list(cred) - self.__divi = self.__cred.index(":") - self.__username = ''.join(self.__cred[:self.__divi]) - self.__passwd = ''.join(self.__cred[self.__divi+1:]) - self.__conn = pxssh() - self.__status = {"status": None, "commit": None, "save": None, "configure": None} - self.__basic_string = {0: 'set ', 1: 'delete '} - - def status(self): - """Check the router object inner status - - :return: A python dictionary include the status of the router object - """ - return self.__status - - def login(self): - """Login the router - - :return: A message or an error - """ - 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." - except Exception as e: - return e - - def logout(self): - """Logout the router - - :return: A message or an error - """ - try: - self.__conn.close() - self.__status["status"] = "logout" - self.__status["configure"] = None - self.__conn = pxssh() - return "Result : Logout successfully." - except Exception as e: - return e - - def configure(self): - """Enter the VyOS configure mode - - :return: A message or an error - """ - try: - if self.__status["status"] == "login": - if self.__status["configure"] is not "Yes": - self.__conn.sendline("configure") - 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!" - else: - return "Error : Router object not connect to a router." - except Exception as e: - return e - - def commit(self): - """Commit the configuration changes - - :return: A message or an error - """ - 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." - if self.__status["commit"] == "No": - self.__conn.sendline("commit") - self.__conn.prompt() - self.__status["commit"] = "Yes" - return "Result : Commit successfully." - else: - return "Error : You have committed!" - else: - return "Error : Router not in configure mode!" - else: - return "Error : Router object not connect to a router." - except Exception as e: - return e - - def save(self): - """Save the configuration after commit - - :return: A message or an error - """ - 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." - 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!" - elif self.__status["commit"] is None: - return "Error : You don't need to save." - else: - return "Error : You need to commit first!" - else: - return "Error : Router not in configure mode!" - else: - return "Error : Router object not connect to a router." - except Exception as e: - return e - - def exit(self, force=False): - """Exit VyOS configure mode - - :param force: True or False - :return: A message or an error - """ - try: - if self.__status["status"] == "login": - if self.__status["configure"] == "Yes": - if force is True: - self.__conn.sendline("exit discard") - self.__conn.prompt() - 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": - self.__conn.sendline("exit") - self.__conn.prompt() - 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." - 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." - else: - return "Error : You are not in configure mode,need not exit." - else: - return "Error : Router object not connect to a router." - except Exception as e: - return e - - def set(self, config): - """Basic 'set' method,execute the set command in VyOS - - :param config: A configuration string. - e.g. 'protocols static route ... next-hop ... distance ...' - :return: A message or an error - """ - full_config = self.__basic_string[0] + config - try: - if self.__status["status"] == "login": - if self.__status["configure"] == "Yes": - res = messenger(self.__conn, full_config) - if "Result" in res: - if self.__status["commit"] == "No": - pass - else: - self.__status["commit"] = "No" - if self.__status["save"] == "No": - pass - else: - self.__status["save"] = "No" - return res - else: - return res - else: - return "Error : You are not in configure mode." - else: - return "Error : Router object not connect to a router." - except Exception as e: - return e - - def delete(self, config): - """Basic 'delete' method,execute the delete command in VyOS - - :param config: A configuration string. - e.g. 'protocols static route ... next-hop ... distance ...' - :return: A message or an error - """ - full_config = self.__basic_string[1] + config - try: - if self.__status["status"] == "login": - if self.__status["configure"] == "Yes": - res = messenger(self.__conn, full_config) - if "Result" in res: - if self.__status["commit"] == "No": - pass - else: - self.__status["commit"] = "No" - if self.__status["save"] == "No": - pass - else: - self.__status["save"] = "No" - return res - else: - return res - else: - return "Error : You are not in configure mode." - else: - return "Error : Router object not connect to a router." - except Exception as e: - return e diff --git a/vymgmt/base_exception/__init__.py b/vymgmt/base_exception/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/vymgmt/base_exception/base.py b/vymgmt/base_exception/base.py new file mode 100644 index 0000000..dc80840 --- /dev/null +++ b/vymgmt/base_exception/base.py @@ -0,0 +1,15 @@ +# Copyright (c) 2016 Hochikong + +prefix = "\r\n" + + +class Error(Exception): + pass + + +class CommonError(Error): + def __init__(self, message): + self.error_message = message + + def __str__(self): + return prefix + self.error_message diff --git a/vymgmt/base_exception/exception_for_commit.py b/vymgmt/base_exception/exception_for_commit.py new file mode 100644 index 0000000..26c14c4 --- /dev/null +++ b/vymgmt/base_exception/exception_for_commit.py @@ -0,0 +1,21 @@ +# Copyright (c) 2016 Hochikong + +from .base import Error + +prefix = "\r\n" + + +class CommitFailed(Error): + def __init__(self, message): + self.error_message = message + + def __str__(self): + return prefix + self.error_message + + +class CommitConflict(Error): + def __init__(self, message): + self.error_message = message + + def __str__(self): + return prefix + self.error_message diff --git a/vymgmt/base_exception/exceptions_for_set_and_delete.py b/vymgmt/base_exception/exceptions_for_set_and_delete.py new file mode 100644 index 0000000..0f65c88 --- /dev/null +++ b/vymgmt/base_exception/exceptions_for_set_and_delete.py @@ -0,0 +1,22 @@ +# Copyright (c) 2016 Hochikong + + +from .base import Error + +prefix = "\r\n" + + +class ConfigPathError(Error): + def __init__(self, message): + self.error_message = message + + def __str__(self): + return prefix + self.error_message + + +class ConfigValueError(Error): + def __init__(self, message): + self.error_message = message + + def __str__(self): + return prefix + self.error_message diff --git a/vymgmt/error_distinguish.py b/vymgmt/error_distinguish.py new file mode 100644 index 0000000..d58db2f --- /dev/null +++ b/vymgmt/error_distinguish.py @@ -0,0 +1,64 @@ +# Copyright (c) 2016 Hochikong + + +def distinguish_for_set(message): + """Distinguish the error type,PathError or ValueError + + :param message: A error message string from VyOS + :return: The type of error + """ + path_error_string = ['Configuration path:', 'is not valid'] + value_error_string = ['Value validation failed'] + all_strings = [path_error_string, value_error_string] + condition = 0 + for i in all_strings: + for x in i: + if x in message: + condition += 1 + + if condition == 2: + return "ConfigPathError" + elif condition == 1: + return "ConfigValueError" + else: + return "NonsupportButError" + + +def distinguish_for_delete(message): + """Distinguish the error type,PathError or ValueError + + :param message: A error message string from VyOS + :return: The type of error + """ + path_error_string = ['Configuration path:', 'is not valid', 'Delete failed'] + value_error_string = ['Nothing to delete', 'the specified value does not exist'] + all_strings = [path_error_string, value_error_string] + condition = 0 + + for i in all_strings: + for x in i: + if x in message: + condition += 1 + + if condition == 3: + return "ConfigPathError" + elif condition == 2: + return "ConfigValueError" + else: + return "NonsupportButError" + + +def distinguish_for_commit(message): + """Distinguish the error type + + :param message: A error message string from VyOS + :return: The type of error + """ + all_strings = ['Commit failed', 'due to another commit in progress'] + + for i in all_strings: + if i in message: + if i == all_strings[0]: + return "CommitFailed" + if i == all_strings[1]: + return "CommitConflict" diff --git a/vymgmt/mgmt_common.py b/vymgmt/mgmt_common.py index 0ed4bf0..1ccb96a 100644 --- a/vymgmt/mgmt_common.py +++ b/vymgmt/mgmt_common.py @@ -17,3 +17,21 @@ def messenger(obj, config): return "Result : Configured successfully" except Exception as e: return e + + +def committer(obj, config): + """This method used for sending commit task to VyOS + + :param obj: A connection object + :param config: A configuration string + :return: A message or an error + """ + try: + obj.sendline(config) + obj.prompt() + if len(obj.before) > obj.before.index('\r\n') + 2: + return obj.before + else: + return "Result : Commit successfully" + except Exception as e: + return e diff --git a/vymgmt/router.py b/vymgmt/router.py new file mode 100644 index 0000000..955a9ba --- /dev/null +++ b/vymgmt/router.py @@ -0,0 +1,258 @@ +# Copyright (c) 2016 Hochikong + + +from pxssh import pxssh +from mgmt_common import messenger, committer +from .base_exception.exceptions_for_set_and_delete import ConfigPathError, ConfigValueError +from .base_exception.exception_for_commit import CommitFailed, CommitConflict +from .base_exception.base import CommonError +from .error_distinguish import distinguish_for_set, distinguish_for_delete, distinguish_for_commit + + +class Router(object): + def __init__(self, address, cred): + """Initial a router object + + :param address: Router address,example:'192.168.10.10' + :param cred: Router user and password,example:'vyos:vyos' + """ + self.__address = address + self.__cred = list(cred) + self.__divi = self.__cred.index(":") + self.__username = ''.join(self.__cred[:self.__divi]) + self.__passwd = ''.join(self.__cred[self.__divi+1:]) + self.__conn = pxssh() + self.__status = {"status": None, "commit": None, "save": None, "configure": None} + self.__basic_string = {0: 'set ', 1: 'delete '} + + def status(self): + """Check the router object inner status + + :return: A python dictionary include the status of the router object + """ + return self.__status + + def login(self): + """Login the router + + :return: A message or an error + """ + 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." + except Exception as e: + return e + + def logout(self): + """Logout the router + + :return: A message or an error + """ + try: + self.__conn.close() + self.__status["status"] = "logout" + self.__status["configure"] = None + self.__conn = pxssh() + return "Result : Logout successfully." + except Exception as e: + return e + + def configure(self): + """Enter the VyOS configure mode + + :return: A message or an error + """ + try: + if self.__status["status"] == "login": + if self.__status["configure"] is not "Yes": + self.__conn.sendline("configure") + 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!" + else: + return "Error : Router object not connect to a router." + except Exception as e: + return e + + def commit(self): + """Commit the configuration changes + + :return: A message or an error + """ + 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." + 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!" + else: + return "Error : Router not in configure mode!" + else: + return "Error : Router object not connect to a router." + except Exception as e: + return e + + if result == "CommitFailed": + raise CommitFailed(res) + elif result == "CommitConflict": + raise CommitConflict(res) + + def save(self): + """Save the configuration after commit + + :return: A message or an error + """ + 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." + 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!" + elif self.__status["commit"] is None: + return "Error : You don't need to save." + else: + return "Error : You need to commit first!" + else: + return "Error : Router not in configure mode!" + else: + return "Error : Router object not connect to a router." + except Exception as e: + return e + + def exit(self, force=False): + """Exit VyOS configure mode + + :param force: True or False + :return: A message or an error + """ + try: + if self.__status["status"] == "login": + if self.__status["configure"] == "Yes": + if force is True: + self.__conn.sendline("exit discard") + self.__conn.prompt() + 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": + self.__conn.sendline("exit") + self.__conn.prompt() + 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." + 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." + else: + return "Error : You are not in configure mode,need not exit." + else: + return "Error : Router object not connect to a router." + except Exception as e: + return e + + def set(self, config): + """Basic 'set' method,execute the set command in VyOS + + :param config: A configuration string. + e.g. 'protocols static route ... next-hop ... distance ...' + :return: A message or an error + """ + full_config = self.__basic_string[0] + config + try: + if self.__status["status"] == "login": + if self.__status["configure"] == "Yes": + res = messenger(self.__conn, full_config) + if "Result" in res: + if self.__status["commit"] == "No": + pass + else: + self.__status["commit"] = "No" + if self.__status["save"] == "No": + pass + else: + self.__status["save"] = "No" + return res + else: + result = distinguish_for_set(res) + else: + return "Error : You are not in configure mode." + else: + return "Error : Router object not connect to a router." + except Exception as e: + return e + + if result == "ConfigPathError": + raise ConfigPathError(res) + elif result == "ConfigValueError": + raise ConfigValueError(res) + elif result == "NonsupportButError": + raise CommonError(res) + + def delete(self, config): + """Basic 'delete' method,execute the delete command in VyOS + + :param config: A configuration string. + e.g. 'protocols static route ... next-hop ... distance ...' + :return: A message or an error + """ + full_config = self.__basic_string[1] + config + try: + if self.__status["status"] == "login": + if self.__status["configure"] == "Yes": + res = messenger(self.__conn, full_config) + if "Result" in res: + if self.__status["commit"] == "No": + pass + else: + self.__status["commit"] = "No" + if self.__status["save"] == "No": + pass + else: + self.__status["save"] = "No" + return res + else: + result = distinguish_for_delete(res) + else: + return "Error : You are not in configure mode." + else: + return "Error : Router object not connect to a router." + except Exception as e: + return e + + if result == "ConfigPathError": + raise ConfigPathError(res) + elif result == "ConfigValueError": + raise ConfigValueError(res) + elif result == "NonsupportButError": + raise CommonError(res) -- cgit v1.2.3