From 25b51367ea29b07b4e4427979266b6a372ac7baf Mon Sep 17 00:00:00 2001 From: Attila Farkas <x394097@fi.muni.cz> Date: Wed, 15 Apr 2020 13:26:13 +0200 Subject: [PATCH] modify exception handeling --- create.py | 54 ++++-------------------- modules/border_router.py | 7 +--- modules/file_manager.py | 81 +++++++++++++++++++++++------------- modules/preprocessing.py | 30 +++++++++---- modules/vagrant_generator.py | 14 ++----- 5 files changed, 89 insertions(+), 97 deletions(-) diff --git a/create.py b/create.py index 289c21d..ea506e7 100644 --- a/create.py +++ b/create.py @@ -14,53 +14,15 @@ from modules.input_file_validator import validate_device_definitions from modules.preprocessing import preprocess -""" Parsing the input arguments. """ flags = dict() +input_file_name = parse_input_args(sys.argv, flags) +device_definitions = open_yaml(input_file_name) -try: - input_file_name = parse_input_args(sys.argv, flags) -except Exception: - print("Input arguments could not be parsed.") - sys.exit(1) +validate_device_definitions(device_definitions) +preprocess(device_definitions, flags) +prepare_directories(device_definitions) -""" Parsing the definitions file. """ -try: - device_definitions = open_yaml(input_file_name) -except Exception: - print("Definitions file could not be parsed.") - sys.exit(1) - -""" Validating device definitions. """ -try: - validate_device_definitions(device_definitions) -except Exception: - print("Device definition validation was not sussessful.") - sys.exit(1) - -""" Preprocessing the definitions before device creation. """ -try: - preprocess(device_definitions, flags) -except Exception: - print("Preprocessing was not successful.") - sys.exit(1) - -""" Preparing the directory structure. """ -try: - prepare_directories(device_definitions) -except Exception: - print("Directory structure was not created.") - sys.exit(1) - -""" Generating Vagrantfile. """ -try: - generate_vagrantfile(device_definitions, flags) -except Exception: - print("Vagrantfile was not created.") - sys.exit(1) - -""" Generating ansible playbooks. """ -#try: +generate_vagrantfile(device_definitions, flags) generate_playbooks(device_definitions, flags) -#except Exception: -# print("Playbooks could not be created.") -# sys.exit(1) + +print("Sandbox was successfully created.") diff --git a/modules/border_router.py b/modules/border_router.py index 1a60353..68cffc6 100644 --- a/modules/border_router.py +++ b/modules/border_router.py @@ -20,7 +20,6 @@ def _are_br_parameters_free(definitions): if net_mapping["ip"] == BORDER_ROUTER_IP: return False - for router_mapping in definitions["router_mappings"]: if router_mapping["ip"] == BORDER_ROUTER_IP: return False @@ -34,8 +33,7 @@ def _create_mappings_to_border_router(definitions): for router in definitions["routers"]: num = definitions["routers"].index(router) + 5 if num > 255: - print("Error: Too many routers.") - raise IndexError + raise IndexError("Too many routers.") ip = BORDER_ROUTER_IP[:(0-len(str(num)))] ip += str(num) @@ -54,8 +52,7 @@ def create_border_router(definitions): # TODO this should be later moved to input check if not _are_br_parameters_free(definitions): - print("Error: A device with the same name as border router already exists.") - raise ValueError + raise ValueError("A device with the same name as border router already exists.") _create_mappings_to_border_router(definitions) diff --git a/modules/file_manager.py b/modules/file_manager.py index 9bf0091..75524ea 100644 --- a/modules/file_manager.py +++ b/modules/file_manager.py @@ -1,23 +1,25 @@ """ This module handles file imports and creations in general. """ import os -from jinja2 import Environment, FileSystemLoader -from shutil import copyfile, rmtree -from yaml import dump, safe_load +import shutil +import sys + +import jinja2 +import yaml OUTPUT_DIRECTORY = "sandbox" def open_yaml(file_name): """ Opens and returns a file from the argument. """ + try: - input_file = open(str(file_name)) - return safe_load(input_file) + with open(str(file_name)) as input_file: + return yaml.safe_load(input_file) + except yaml.YAMLError: + cleanup_and_exit("Could not parse yaml file " + str(file_name) + ".") except IOError: - print("Error: Cannot open the required file: " + str(file_name)) - raise - finally: - input_file.close() + cleanup_and_exit("Could not open yaml file " + str(file_name) + ".") def copy_template_file(template, destination): @@ -26,10 +28,9 @@ def copy_template_file(template, destination): """ try: - copyfile("templates/" + template, "sandbox/" + destination) + shutil.copyfile("templates/" + template, "sandbox/" + destination) except IOError: - print("Error: cannot write to this location.") - raise + cleanup_and_exit("Could not copy template file " + str(file_name) + ".") def dump_to_yaml(data, filename): @@ -39,14 +40,13 @@ def dump_to_yaml(data, filename): :param filename: name of the target file """ + file_path = OUTPUT_DIRECTORY + "/" + str(filename) + try: - stream = open(OUTPUT_DIRECTORY + "/" + filename, 'w') - dump(data, stream) + with open(file_path, 'w') as stream: + yaml.dump(data, stream) except IOError: - print("Error: cannot write to this location.") - raise - finally: - stream.close() + cleanup_and_exit("Could not create yaml file " + file_path + ".") def generate_file(template, filename, **template_args): @@ -69,16 +69,29 @@ def _write_to_file(filename, output_string): new_file = open(OUTPUT_DIRECTORY + "/" + filename, "w") new_file.write(output_string) except IOError: - print("Error: cannot write to this location.") - raise + cleanup_and_exit("Could not create file " + str(filename) + ".") def _load_template(template_name): """ Returns a loaded jinja2 template. """ - template_loader = FileSystemLoader(searchpath="templates") - template_env = Environment(loader=template_loader, trim_blocks=True, lstrip_blocks=True) - return template_env.get_template(template_name) + try: + template_loader = jinja2.FileSystemLoader(searchpath="templates") + template_env = jinja2.Environment(loader=template_loader, trim_blocks=True, lstrip_blocks=True) + return template_env.get_template(template_name) + except jinja2.TemplateNotFound: + cleanup_and_exit("Could not find template " + str(template_name) + ".") + + +def _copy_directory(source, destination): + """ Copies directory recursively form templates directory to the + destination. + """ + + try: + shutil.copytree("./templates/" + source, destination) + except OSError: + cleanup_and_exit("Could not copy directory " + str(source) + ".") def _create_provisioning_directories(directory, device_definitions): @@ -109,20 +122,32 @@ def _create_provisioning_directories(directory, device_definitions): except FileExistsError: pass except IOError: - print("Could not create directories for provisioning.") - raise + cleanup_and_exit("Could not create directories for provisioning.") def prepare_directories(device_definitions): """ Prepares the necessary directory structure. """ - rmtree(OUTPUT_DIRECTORY, True) + shutil.rmtree(OUTPUT_DIRECTORY, True) try: os.mkdir(OUTPUT_DIRECTORY) except IOError: - print("Could not create directory ./" + OUTPUT_DIRECTORY + ".") - raise + cleanup_and_exit("Could not create directory ./" + OUTPUT_DIRECTORY + ".") _create_provisioning_directories("base_provisioning", device_definitions) _create_provisioning_directories("provisioning", device_definitions) + + _copy_directory("interface", OUTPUT_DIRECTORY + "/base_provisioning/roles/interface") + _copy_directory("common", OUTPUT_DIRECTORY + "/base_provisioning/roles/common") + + +def cleanup_and_exit(error): + """ A cleanup function that is called in case of an error. """ + + # TODO cleanup + + print("Sandbox creation was NOT successful:") + print("Error: ", error) + + sys.exit(1) diff --git a/modules/preprocessing.py b/modules/preprocessing.py index 5f97a38..01054bf 100644 --- a/modules/preprocessing.py +++ b/modules/preprocessing.py @@ -8,6 +8,20 @@ from modules.file_manager import open_yaml FLAVORS = open_yaml("conf/flavors.yml") ROUTER_ATTRIBUTES = open_yaml("conf/router_attributes.yml") +def _add_missing_tags(definitions): + """ Adds necessary structures to the input if they are missing. """ + + if "routers" not in definitions: + definitions["routers"] = [] + if "router_mappings" not in definitions: + definitions["router_mappings"] = [] + if "hosts" not in definitions: + definitions["hosts"] = [] + if "net_mappings" not in definitions: + definitions["net_mappings"] = [] + if "networks" not in definitions: + definitions["networks"] = [] + def _configure_routers(definitions): """ Adds predefined parameters to all routers if they are not defined in @@ -44,21 +58,23 @@ def preprocess(definitions, flags): :param flags: a structure with command line flags """ + try: + _add_missing_tags(definitions) + except Exception: + cleanup_and_exit("Preprocessing not successful: Could not add missing tags.") + try: if "border_router" in flags and flags["border_router"]: create_border_router(definitions) - except Exception: - print("Could not create border router.") - raise + except (ValueError, IndexError) as e: + cleanup_and_exit("Preprocessing not successful: Could not create border router (" + e + ")") try: _configure_routers(definitions) except Exception: - print("Could not add router configurations to definitions.") - raise + cleanup_and_exit("Preprocessing not successful: Could not add router configurations to definitions.") try: _add_flavors(definitions) except Exception: - print("Could not add flavor.") - raise + cleanup_and_exit("Preprocessing not successful: Could not add flavors.") diff --git a/modules/vagrant_generator.py b/modules/vagrant_generator.py index d02f949..fd01571 100644 --- a/modules/vagrant_generator.py +++ b/modules/vagrant_generator.py @@ -183,14 +183,6 @@ def generate_vagrantfile(input_definitions, flags): :param flags: command line flags """ - try: - vagrant_definitions = _build_vagrant_definitions(input_definitions, flags) - except Exception: - print("Could not create definitions for Vagrantfile.") - raise - - try: - generate_file("vagrantfile", "Vagrantfile", defs=vagrant_definitions) - except Exception: - print("Could not generate Vagrantfile.") - raise + vagrant_definitions = _build_vagrant_definitions(input_definitions, flags) + + generate_file("vagrantfile", "Vagrantfile", defs=vagrant_definitions) -- GitLab