"""This module contains functions for preprocessing. They are supposed to be called after validating the input but before device creation. """ import itertools from modules.border_router import create_border_router from modules.controller import create_controller from modules.file_manager import open_yaml, cleanup_and_exit FLAVORS = open_yaml("conf/flavors.yml") ROUTER_ATTRIBUTES = open_yaml("conf/router_attributes.yml") DUMMY_ROUTER_NAME = "dummy-router" def _add_missing_tags(definitions): """Add 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): """Add predefined parameters to all routers. Adds them if they are not defined in the source yaml. """ for router in definitions["routers"]: for parameter, value in ROUTER_ATTRIBUTES.items(): if parameter not in router: router[parameter] = value def _add_extra_arguments(definitions, flags): """Add extra arguments to definitions if they are not present.""" if "border_router" in flags and flags["ansible_local"]: for device in itertools.chain(definitions["hosts"], definitions["routers"]): if "synced_folder" not in device and "communicator" not in device: device["synced_folder"] = "\".\", \"/vagrant\", type: \"rsync"\ "\", rsync__exclude: \".git/\"" def _add_flavors(definitions): """Change flavor attribute to cpus and memory.""" for host in definitions["hosts"]: if "flavor" in host and host["flavor"]: if host["flavor"] not in FLAVORS: print("Error: Not supported flavor: " + host["flavor"]) raise AttributeError if "memory" not in host: host["memory"] = FLAVORS[host["flavor"]]["memory"] if "cpus" not in host: host["cpus"] = FLAVORS[host["flavor"]]["cores"] host.pop("flavor") def _delete_dummy_router(definitions): """Delete dummy router if it is defined.""" for router in definitions["routers"]: if router["name"] == DUMMY_ROUTER_NAME: definitions["routers"].remove(router) return def _add_usb_passthrough(definitions): """Add usb passthrough to devices""" for host in definitions["hosts"]: if "extra" in host and host["extra"]: if "usb_passthrough" in host["extra"]: host["vb_customize"] = '["modifyvm", :id, "--usb", "on"]' def _find_windows_boxes(definitions): """Find and return list of host names with windows boxes.""" windows_hosts = [] for host in definitions["hosts"]: if "windows" in host["base_box"]["image"].lower(): windows_hosts.append(host["name"]) return windows_hosts def _add_windows_attributes(host): """Add vagrant attributes to windows hosts""" host["communicator"] = "winrm" host["winrm_username"] = "windows" host["winrm_password"] = "vagrant" def preprocess(definitions, flags): """Run preprocessing. Handles perations that need to be done before the actual device creation. :param definitions: device definition structure :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: _delete_dummy_router(definitions) except Exception: cleanup_and_exit("Preprocessing not successful: " "Could not delete dummy router.") try: if "border_router" in flags and flags["border_router"]: create_border_router(definitions) except (ValueError, IndexError) as error: cleanup_and_exit("Preprocessing not successful: " "Could not create border router (" + error + ")") windows_hosts = _find_windows_boxes(definitions) try: if windows_hosts: create_controller(definitions) except (ValueError, IndexError) as error: cleanup_and_exit("Preprocessing not successful: " "Could not create controller (" + error + ")") try: for host in definitions["hosts"]: if host["name"] in windows_hosts: _add_windows_attributes(host) except (ValueError, IndexError) as error: cleanup_and_exit("Preprocessing not successful: " "Could not create controller (" + error + ")") try: _configure_routers(definitions) except Exception: cleanup_and_exit("Preprocessing not successful: " "Could not add router configurations to definitions.") try: _add_extra_arguments(definitions, flags) except Exception: cleanup_and_exit("Preprocessing not successful: " "Could not add extra arguments to definitions.") try: _add_flavors(definitions) except Exception: cleanup_and_exit("Preprocessing not successful: " "Could not add flavors.") try: _add_usb_passthrough(definitions) except Exception: cleanup_and_exit("Preprocessing not successful: " "Could not add USB passthrough.")