diff --git a/generate.py b/generate.py index a8f28c37cd5fa391e889d5d8347bf95c532f3c3d..d68d4694355163ee913850587f4e8a7fab7f4ab2 100644 --- a/generate.py +++ b/generate.py @@ -1,77 +1,22 @@ #!/usr/bin/python3 import sys -import yaml import jinja2 -from modules.network_parser import add_networks, add_routers -from modules.provider import print_prov_attributes +from modules.device_creator import create_devices if (len(sys.argv) != 2): print ("Error: Expecting 1 argument (yml file).") sys.exit(); - -# Loading external files -try: - ymlfile = open(str(sys.argv[1])) - yml = yaml.safe_load(ymlfile) -except IOError: - print ("Error: file does not exist.") - -try: - mapping_file = open("name_mapping/mapping.yml") - name_mappings = yaml.safe_load(mapping_file) -except IOError: - print ("Error: cannot find mappings.") - -try: - flavors_file = open("name_mapping/flavors.yml") - flavors = yaml.safe_load(flavors_file) -except IOError: - print ("Error: cannot find the list of flavors.") - - -# Converts yaml attribute names to vagrant attribute names. -def do_mapping(name, command_type): - return name_mappings[str(command_type)][name] - -def add_formated_command(key, value): - if (key in name_mappings['string']): - devices[host['name']].append( - 'device.' + str(do_mapping(key, 'string')) - + ' = \"' + str(value) + '\"') - elif (key in name_mappings['integer']): - devices[host['name']].append( - 'device.' + str(do_mapping(key, 'integer')) - + ' = ' + str(value)) - elif (key in name_mappings['boolean']): - devices[host['name']].append( - 'device.' + str(do_mapping(key, 'boolean')) - + ' = ' + str(value).lower()) - - -# Building "devices" structure that will be passed to Jinja2 -devices = {} - -for host in yml['hosts']: - devices[host['name']] = [] - for key, value in host.items(): - if (key != 'name'): - add_formated_command(key, value) - add_networks(host['name'], yml, devices) - print_prov_attributes(host, flavors - , name_mappings['need_provider'], devices) - -for router in yml['routers']: - devices[router['name']] = [] - add_routers(router['name'], yml, devices) - +# A structure with formatted commands for each device +devices = create_devices(str(sys.argv[1])) # Generating output via Jinja2 templateLoader = jinja2.FileSystemLoader(searchpath="templates") templateEnv = jinja2.Environment(loader=templateLoader, trim_blocks=True) baseTemplate = templateEnv.get_template("base") output = baseTemplate.render(devices = devices) + print (output) diff --git a/modules/attribute_formatter.py b/modules/attribute_formatter.py new file mode 100644 index 0000000000000000000000000000000000000000..6ad8d9e95c022d441f5cae95ee50fcfd5ad24374 --- /dev/null +++ b/modules/attribute_formatter.py @@ -0,0 +1,24 @@ +def _format_and_add(key, value, mappings, device_definition): + """ Formats and adds the definition of a simple attribute. """ + + if (key in mappings['string']): + device_definition.append( + 'device.' + mappings['string'][key] + + ' = \"' + str(value) + '\"') + elif (key in mappings['integer']): + device_definition.append( + 'device.' + mappings['integer'][key] + + ' = ' + str(value)) + elif (key in mappings['boolean']): + device_definition.append( + 'device.' + mappings['boolean'][key] + + ' = ' + str(value).lower()) + + +def add_simple_commands(device, mappings, device_definition): + """ Adds definitions of string, integer and boolean vagrant attributes. """ + + for key, value in device.items(): + if (key != "name"): + _format_and_add(key, value, mappings, device_definition) + diff --git a/modules/device_creator.py b/modules/device_creator.py new file mode 100644 index 0000000000000000000000000000000000000000..f1f37d1600d077838baa6f015050e669e4a12370 --- /dev/null +++ b/modules/device_creator.py @@ -0,0 +1,74 @@ +import yaml + +from .attribute_formatter import add_simple_commands +from .provider import add_prov_attributes, add_router_specification +from .network_parser import add_networks, add_router_ip + + +def _open_yml(yml_file_name): + """ Opens the input yaml file. """ + try: + ymlfile = open(str(yml_file_name)) + yml = yaml.safe_load(ymlfile) + return yml + except IOError: + print ("Error: file does not exist.") + + +def _open_mappings(): + """ Opens the file with name mappings. """ + try: + mapping_file = open("name_mapping/mapping.yml") + mappings = yaml.safe_load(mapping_file) + return mappings + except IOError: + print ("Error: cannot find mappings.") + + +def _open_flavors(): + """ Opens the file with flavor definitions. """ + try: + flavors_file = open("name_mapping/flavors.yml") + flavors = yaml.safe_load(flavors_file) + return flavors + except IOError: + print ("Error: cannot find the list of flavors.") + + +def _create_hosts(yml, mappings, flavors): + """ Creates a dictionary with formatted definition of each host. """ + host_definitions = {} + + for host in yml['hosts']: + host_definitions[host['name']] = [] + + add_simple_commands(host, mappings, host_definitions[host['name']]) + add_networks(host["name"], yml, host_definitions) + add_prov_attributes(host, flavors + , mappings['need_provider'], host_definitions) + + return host_definitions + + +def _create_routers(yml, mappings): + """ Creates a dictionary with formatted definition of each router. """ + router_definitions = {} + + for router in yml['routers']: + router_definitions[router['name']] = [] + add_router_ip(router["name"], yml, router_definitions) + add_router_specification(router, router_definitions) + + return router_definitions + + +def create_devices(yml_file_name): + """ Returns a marged dictionary of host and router definitions. """ + + yml = _open_yml(yml_file_name) + mappings = _open_mappings() + flavors = _open_flavors() + + return dict(**_create_hosts(yml, mappings, flavors) + , **_create_routers(yml, mappings)) + diff --git a/modules/network_parser.py b/modules/network_parser.py index 365fa57a9f271cae85b33d1bb2fd76663c798448..edd93ca57ae8d3dc5dfd24c288fb69512898adaa 100644 --- a/modules/network_parser.py +++ b/modules/network_parser.py @@ -1,4 +1,6 @@ def _find_ip(hostname, mappings, device_type): + """ Finds the ip address of a device. """ + for mapping in mappings: if ((device_type == 'host' and mapping['host'] and mapping['host'] == hostname) @@ -6,41 +8,46 @@ def _find_ip(hostname, mappings, device_type): and mapping['router'] and mapping['router'] == hostname)): return mapping['ip'] -def _add_ip(hostname, mappings, device_type, devices): - devices[hostname].append( - 'device.vm.network :private_network, ip: \"' + +def _add_ip(hostname, mappings, device_type, definitions): + """ Adds a formatted ip address to a device definition. """ + + definitions[hostname].append( + "device.vm.network :private_network, ip: \"" + str(_find_ip(hostname, mappings, device_type)) + '\"') -def _add_netmask(hostname, my_network, networks, devices): + +def _add_netmask(hostname, my_network, networks, definitions): + """ Adds netmask to the end of a formatted ip definition. """ + for network in networks: if (network['name'] == my_network): address, mask = network['cidr'].split('/') - devices[hostname][-1] += (', netmask: ' + mask) + definitions[hostname][-1] += (', netmask: ' + mask) + -def add_networks(hostname, yml, devices): +def add_networks(hostname, yml, definitions): + """ Adds ip address and natmask to a host. """ if (not yml['net_mappings']): return for mapping in yml['net_mappings']: if (mapping['host'] == hostname): - _add_ip(hostname, yml['net_mappings'], 'host', devices) + _add_ip(hostname, yml['net_mappings'], 'host', definitions) if (yml['networks']): _add_netmask( hostname, mapping['network'] - , yml['networks'], devices) + , yml['networks'], definitions) -def _add_router_os(routername, devices): - router_os = 'generic/debian10' - devices[routername].append('device.vm.box = \"' + router_os + '\"') -def add_routers(routername, yml, devices): +def add_router_ip(routername, yml, definitions): + """ Adds ip address to a router. """ if (not yml['router_mappings']): return for mapping in yml['router_mappings']: if (mapping['router'] == routername): - _add_router_os(routername, devices) - _add_ip(routername, yml['router_mappings'], 'router', devices) + _add_ip(routername, yml['router_mappings'], 'router', definitions) diff --git a/modules/provider.py b/modules/provider.py index 76318572dc4b21464d1898691f662778d7c88661..daf5ff6c4f6607f90f2bc8f203c22a6618869af4 100644 --- a/modules/provider.py +++ b/modules/provider.py @@ -1,35 +1,59 @@ -def _print_flavor(host, flavors, provider_attributes, devices): +def _print_flavor(host, flavors, provider_attributes, definitions): + """ Formats and add a flavor for a device. """ + if ('memory' not in host): - devices[host['name']].append(' vb.' + definitions[host['name']].append(' vb.' + provider_attributes['memory'] + ' = ' + str(flavors[host['flavor']]['memory'])) if ('cpus' not in host): - devices[host['name']].append(' vb.' + definitions[host['name']].append(' vb.' + provider_attributes['cpus'] + ' = ' + str(flavors[host['flavor']]['cores'])) -def _add_params(host, flavors, provider_attributes, devices): + +def _add_params(host, flavors, provider_attributes, definitions): + """ Formats and adds simple provision attributes. """ + if ('memory' in host): - devices[host['name']].append(' vb.' + definitions[host['name']].append(' vb.' + provider_attributes['memory'] + ' = ' + str(host['memory'])) if ('cpus' in host): - devices[host['name']].append(' vb.' + definitions[host['name']].append(' vb.' + provider_attributes['cpus'] + ' = ' + str(host['cpus'])) if ('flavor' in host and host['flavor'] in flavors): - _print_flavor(host, flavors, provider_attributes, devices) + _print_flavor(host, flavors, provider_attributes, definitions) + def _need_provider(host, provider_attributes): + """ Checks if provision attributes are present. """ + for attribute in provider_attributes: if (attribute in host): return True return False -def print_prov_attributes(host, flavors, provider_attributes, devices): + +def add_prov_attributes(host, flavors, provider_attributes, definitions): + """ Adds provider attributes. """ + if (_need_provider(host, provider_attributes)): - devices[host['name']].append( + definitions[host['name']].append( "device.vm.provider \"virtualbox\" do |vb|") - _add_params(host, flavors, provider_attributes, devices) - devices[host['name']].append("end") + _add_params(host, flavors, provider_attributes, definitions) + definitions[host['name']].append("end") + + +def add_router_specification(router, definitions): + """ Adds the default specification for a router. """ + ROUTER_BOX = "generic/debian10" + ROUTER_MEMORY = 128 + + definitions[router['name']].append("device.vm.box = \"" + ROUTER_BOX + "\"") + definitions[router['name']].append( + "device.vm.provider \"virtualbox\" do |vb|") + definitions[router['name']].append(" vb.memory = " + str(ROUTER_MEMORY)) + definitions[router['name']].append("end") +