From 85644c6237d0a63fcaed40537af73da5f5dca2d3 Mon Sep 17 00:00:00 2001 From: Attila Farkas <x394097@fi.muni.cz> Date: Mon, 25 May 2020 07:41:56 +0200 Subject: [PATCH] update modified files --- modules/ansible_generator.py | 4 ++ modules/routing_generator.py | 92 ++++++++++++++----------- sandbox.yml | 12 ++-- templates/common/meta/main.yml | 15 ++++ templates/common/templates/config.j2 | 3 + templates/common/templates/network.j2 | 30 ++++++++ templates/config | 8 +++ templates/device_configuration | 32 ++------- templates/hosts | 5 +- templates/interface/defaults/main.yml | 40 +++++++++++ templates/interface/handlers/main.yml | 6 ++ templates/interface/meta/main.yml | 19 +++++ templates/interface/tasks/clean.yml | 31 +++++++++ templates/interface/tasks/interface.yml | 25 +++++++ templates/interface/tasks/main.yml | 11 +++ templates/routers | 17 ++--- templates/separate_devices | 29 +++++++- templates/vagrantfile | 26 +++++++ 18 files changed, 313 insertions(+), 92 deletions(-) create mode 100644 templates/common/meta/main.yml create mode 100644 templates/common/templates/config.j2 create mode 100644 templates/common/templates/network.j2 create mode 100644 templates/interface/defaults/main.yml create mode 100644 templates/interface/handlers/main.yml create mode 100644 templates/interface/meta/main.yml create mode 100644 templates/interface/tasks/clean.yml create mode 100644 templates/interface/tasks/interface.yml create mode 100644 templates/interface/tasks/main.yml diff --git a/modules/ansible_generator.py b/modules/ansible_generator.py index 4bf98b7..bdef379 100644 --- a/modules/ansible_generator.py +++ b/modules/ansible_generator.py @@ -12,6 +12,10 @@ def _create_config_playbooks(input_definitions): copy_template_file("hosts", "base_provisioning/roles/hosts/tasks/main.yml") + if input_definitions["routers"]: + copy_template_file("routers", + "base_provisioning/roles/routers/tasks/main.yml") + for device in input_definitions["hosts"] + input_definitions["routers"]: copy_template_file("separate_devices", "base_provisioning/roles/" + device["name"] + "/tasks/main.yml") diff --git a/modules/routing_generator.py b/modules/routing_generator.py index c1f7dd3..0c19a37 100644 --- a/modules/routing_generator.py +++ b/modules/routing_generator.py @@ -46,9 +46,26 @@ def _find_iface_ip_in_network(device_name, network, input_definitions): raise AttributeError +def _find_router_ip_in_br_network(other_network, input_definitions): + """Find a router inside of a network and returns its ip in br network.""" + router = None + + for router_mapping in input_definitions["router_mappings"]: + if router_mapping["network"] == other_network: + router = router_mapping["router"] + + if not router: + return None + + for router_mapping in input_definitions["router_mappings"]: + if router_mapping["router"] == router and\ + router_mapping["network"] == BORDER_ROUTER_NETWORK_NAME: + return router_mapping["ip"] + def _create_host_routing(target_host_name, input_definitions, flags): """Generate routings for the given host.""" - routings = [] + simple_routings = [] + default_routings = [] for host_mapping in input_definitions["net_mappings"]: if host_mapping["host"] == target_host_name: @@ -57,18 +74,16 @@ def _create_host_routing(target_host_name, input_definitions, flags): if flags["border_router"]: routing_to_router = dict() - routing_to_router["default"] = True routing_to_router["interface_ip"] = mapping["ip"] gateway = _find_router_in_network(mapping["network"], input_definitions) routing_to_router["gateway"] = gateway - routings.append(routing_to_router) + default_routings.append(routing_to_router) else: for network in input_definitions["networks"]: if network["name"] == mapping["network"]: continue routing_to_other_hosts = dict() - routing_to_other_hosts["default"] = False routing_to_other_hosts["interface_ip"] = mapping["ip"] gateway = _find_router_in_network(mapping["network"], input_definitions) @@ -76,84 +91,77 @@ def _create_host_routing(target_host_name, input_definitions, flags): net_ip, mask = network["cidr"].split('/') routing_to_other_hosts["network"] = net_ip routing_to_other_hosts["netmask"] = mask - routings.append(routing_to_other_hosts) + simple_routings.append(routing_to_other_hosts) - return routings + return simple_routings, default_routings def _create_router_routing(router_name, input_definitions, flags): """Generate routings for the given router.""" - routings = [] + simple_routings = [] + default_routings = [] if flags["border_router"]: routing_to_br = dict() - routing_to_br["default"] = True interface_ip = _find_iface_ip_in_network(router_name, BORDER_ROUTER_NETWORK_NAME, input_definitions) routing_to_br["interface_ip"] = interface_ip routing_to_br["gateway"] = BORDER_ROUTER_IP - routings.append(routing_to_br) - else: - for network in input_definitions["networks"]: - if network["name"] in _find_networks_of_device(router_name, - input_definitions): - continue - routing_to_other_router = dict() - routing_to_other_router["default"] = False - interface_ip = _find_iface_ip_in_network(router_name, - network["name"], - input_definitions) - routing_to_br["interface_ip"] = interface_ip - gateway = _find_router_in_network(network["name"], - input_definitions) - routing_to_other_router["gateway"] = gateway - net_ip, mask = network["cidr"].split('/') - routing_to_other_router["network"] = net_ip - routing_to_other_router["netmask"] = mask - routings.append(routing_to_other_router) + default_routings.append(routing_to_br) - return routings + return simple_routings, default_routings def _create_border_router_routing(input_definitions, flags): """Generate routings for the border router.""" - routings = [] + simple_routings = [] + default_routings = [] for network in input_definitions["networks"]: if network["name"] == BORDER_ROUTER_NETWORK_NAME: continue routing_to_hosts = dict() - routing_to_hosts["default"] = False routing_to_hosts["interface_ip"] = BORDER_ROUTER_IP net_ip, mask = network["cidr"].split('/') routing_to_hosts["network"] = net_ip routing_to_hosts["netmask"] = mask - gateway = _find_router_in_network(network["name"], input_definitions) + gateway = _find_router_ip_in_br_network(network["name"], + input_definitions) routing_to_hosts["gateway"] = gateway - routings.append(routing_to_hosts) + simple_routings.append(routing_to_hosts) - return routings + return simple_routings, default_routings def add_routings(device_name, device_type, input_definitions, flags): - """Generate routings for the given device. + """Generate simple and default routings for the given device. Returns a list of dicts with the syntax: - - default: True/False - gateway: ip of the target device + - gateway: ip of the target device interface_ip: ip of the device on the given interface network: ip of the network (if default is False) netmask: mask of the network (if default is False) """ if not input_definitions["routers"]: - return [] + return dict() + + routings = {"simple": [], "default": []} if device_type == "host": - return _create_host_routing(device_name, input_definitions, flags) + simple, default = _create_host_routing(device_name, input_definitions, + flags) + routings["simple"].extend(simple) + routings["default"].extend(default) elif device_type == "router": if device_name != BORDER_ROUTER_NAME: - return _create_router_routing(device_name, input_definitions, - flags) - return _create_border_router_routing(input_definitions, flags) - return [] + simple, default = _create_router_routing(device_name, + input_definitions, flags) + routings["simple"].extend(simple) + routings["default"].extend(default) + else: + simple, default = _create_border_router_routing(input_definitions, + flags) + routings["simple"].extend(simple) + routings["default"].extend(default) + return routings diff --git a/sandbox.yml b/sandbox.yml index c53b54d..9a68624 100644 --- a/sandbox.yml +++ b/sandbox.yml @@ -16,24 +16,24 @@ routers: networks: - name: server-switch - cidr: 10.10.20.0/24 + cidr: 192.168.20.0/24 - name: home-switch - cidr: 10.10.30.0/24 + cidr: 192.168.30.0/24 net_mappings: - host: server network: server-switch - ip: 10.10.20.5 + ip: 192.168.20.5 - host: home network: home-switch - ip: 10.10.30.5 + ip: 192.168.30.5 router_mappings: - router: router network: server-switch - ip: 10.10.20.1 + ip: 192.168.20.1 - router: router network: home-switch - ip: 10.10.30.1 + ip: 192.168.30.1 diff --git a/templates/common/meta/main.yml b/templates/common/meta/main.yml new file mode 100644 index 0000000..edff08c --- /dev/null +++ b/templates/common/meta/main.yml @@ -0,0 +1,15 @@ + +galaxy_info: + role_name: common + author: Kamil Andoniadis + description: This role provide common macros, templates or files + licence: MIT + min_ansible_version: 2.3.3 + platforms: + - name: Debian + versions: + - all + - name: Ubuntu + versions: + - all + diff --git a/templates/common/templates/config.j2 b/templates/common/templates/config.j2 new file mode 100644 index 0000000..929abb7 --- /dev/null +++ b/templates/common/templates/config.j2 @@ -0,0 +1,3 @@ +{%- macro yaml_config_key_regexp(key) -%} + ^(#.*)?{{ key }}:.* +{%- endmacro -%} diff --git a/templates/common/templates/network.j2 b/templates/common/templates/network.j2 new file mode 100644 index 0000000..f409e1c --- /dev/null +++ b/templates/common/templates/network.j2 @@ -0,0 +1,30 @@ +{%- set common_network = namespace( + interfaces=[] +) -%} +{%- for ansible_interface in ansible_interfaces -%} + {%- set common_network.interfaces = common_network.interfaces + [hostvars[inventory_hostname]['ansible_' + ansible_interface]] -%} +{%- endfor -%} + +{%- macro mac_to_interface(mac) -%} + {{ + ( + common_network.interfaces | selectattr('macaddress', 'defined') | + selectattr('macaddress', 'equalto', mac) | map(attribute='device') | list + ) [0] | default('') + }} +{%- endmacro -%} + +{%- macro ip_to_interface(ip) -%} + {{ + ( + common_network.interfaces | selectattr('ipv4', 'defined') | selectattr('ipv4.address', 'defined') | + selectattr('ipv4.address', 'equalto', ip) | map(attribute='device') | list + ) [0] | default('') + }} +{%- endmacro -%} + +{%- macro get_inactive_interfaces() -%} + {{ + common_network.interfaces | selectattr("active", "equalto", False) | list + }} +{%- endmacro -%} diff --git a/templates/config b/templates/config index 0280902..9c73ad7 100644 --- a/templates/config +++ b/templates/config @@ -1,3 +1,4 @@ +{% if hosts %} hosts: {% for host in hosts %} - name: {{ host.name }} @@ -8,7 +9,11 @@ hosts: {{ network }}: {{ ip }} {% endfor %} {% endfor %} +{% else %} +hosts: [] +{% endif %} +{% if routers %} routers: {% for router in routers %} - name: {{ router.name }} @@ -19,3 +24,6 @@ routers: {{ network }}: {{ ip }} {% endfor %} {% endfor %} +{% else %} +routers: [] +{% endif %} diff --git a/templates/device_configuration b/templates/device_configuration index d695176..90697be 100644 --- a/templates/device_configuration +++ b/templates/device_configuration @@ -12,39 +12,21 @@ - name: Configuring hosts hosts: hosts + become: yes roles: - hosts -#- name: Configuring routers -# hosts: routers -# roles: -# - routers +- name: Configuring routers + hosts: routers + become: yes + roles: + - routers - name: Configuring devices separately hosts: all + become: yes tasks: - - name: include role include_role: name: "{{ inventory_hostname }}" ... - - - - -#- name: Configuring host {{ host.host_name }} -# hosts: hosts -# become: yes -# tasks: -#{% for network_ip in network_ips %} -# - name: Add gateway for {{ network_ip }} -# command: route add -net {{ network_ip }} gw {{ host.router_ip }} {{ host.interface }} -#{% endfor %} - - -#- name: Configuring border router -# hosts: {{ border_router_name }} -# become: yes -# roles: -# - br -#... diff --git a/templates/hosts b/templates/hosts index 05ebab4..34e8296 100644 --- a/templates/hosts +++ b/templates/hosts @@ -3,8 +3,5 @@ - name: Install net-tools apt: - name: net-tools - -# name: Delete default gateway -# command: route del default + name: "net-tools" ... diff --git a/templates/interface/defaults/main.yml b/templates/interface/defaults/main.yml new file mode 100644 index 0000000..0910da5 --- /dev/null +++ b/templates/interface/defaults/main.yml @@ -0,0 +1,40 @@ + +interface_default_file: /etc/network/interfaces +interface_directory: '{{ interface_default_file }}.d' +interface_file_name: +interface_file: ' + {%- if interface_file_name is defined and interface_file_name -%} + {{ interface_directory }}/{{ interface_file_name }} + {%- else -%} + {{ interface_default_file }} + {%- endif %}' + +interface_clean: True +interface_mtu: 1442 + +interface_ip: +interface_mac: +interface_name: +interface_default_gateway: +interface_routes: [] +# - gateway: +# network: +# mask: + +interface_device: ' + {%- import "roles/common/templates/network.j2" as network with context -%} + {%- if interface_ip is defined and interface_ip -%} + {{ network.ip_to_interface(interface_ip) | default("") }} + {%- endif -%} + {%- if interface_mac is defined and interface_mac -%} + {{ network.mac_to_interface(interface_mac) | default("") }} + {%- endif -%} + {%- if interface_name is defined and interface_name -%} + {{ interface_name }} + {%- endif -%}' +interface_identifiers: + interface_ip: '{{ interface_ip }}' + interface_mac: '{{ interface_mac }}' + interface_name: '{{ interface_name }}' +interface_condition_single_interface_identifier: '{{ interface_identifiers | dict2items | map(attribute="value") | select("string") | select("ne", "") | list | length != 1 }}' + diff --git a/templates/interface/handlers/main.yml b/templates/interface/handlers/main.yml new file mode 100644 index 0000000..34553f6 --- /dev/null +++ b/templates/interface/handlers/main.yml @@ -0,0 +1,6 @@ + +- name: interface_networking_restart + service: + name: networking + state: restarted + diff --git a/templates/interface/meta/main.yml b/templates/interface/meta/main.yml new file mode 100644 index 0000000..58ecda5 --- /dev/null +++ b/templates/interface/meta/main.yml @@ -0,0 +1,19 @@ + +dependencies: + - src: git@gitlab.ics.muni.cz:CSIRT-MU-public/ansible-roles/common.git + scm: git + +galaxy_info: + role_name: interface + author: Kamil Andoniadis + description: Basic network interface configuration + licence: MIT + min_ansible_version: 2.3.3 + platforms: + - name: Debian + versions: + - all + - name: Ubuntu + versions: + - all + diff --git a/templates/interface/tasks/clean.yml b/templates/interface/tasks/clean.yml new file mode 100644 index 0000000..36a651b --- /dev/null +++ b/templates/interface/tasks/clean.yml @@ -0,0 +1,31 @@ + +- name: find all interfaces configuration files + find: + paths: + - '{{ interface_directory }}' + register: interface_extra_files + +- set_fact: + interface_config_files: '{{ (interface_extra_files.files | map(attribute="path") | list) + [interface_default_file] }}' + +- name: remove old iface settings for retrieved interface name + replace: + path: '{{ item }}' + regexp: ^iface[ \t]{{ interface_device }}[ \t].*(\n[ \t]+.*)* + notify: interface_networking_restart + with_items: '{{ interface_config_files }}' + +- name: remove the rest of old settings for retrieved interface name + replace: + path: '{{ item }}' + regexp: '^.*(?<=\s){{ interface_device }}(?=\s).*$' + notify: interface_networking_restart + with_items: '{{ interface_config_files }}' + +- name: remove multiple consecutive new line characters + replace: + path: '{{ item }}' + regexp: '(\n)+' + replace: '\n' + with_items: '{{ interface_config_files }}' + diff --git a/templates/interface/tasks/interface.yml b/templates/interface/tasks/interface.yml new file mode 100644 index 0000000..9946165 --- /dev/null +++ b/templates/interface/tasks/interface.yml @@ -0,0 +1,25 @@ + +- name: configure interface + blockinfile: + path: '{{ interface_file }}' + create: yes + marker: '# {mark} {{ interface_device }}' + block: | + allow-hotplug {{ interface_device }} + auto {{ interface_device }} + iface {{ interface_device }} inet static + address {{ interface_ip }} + netmask {{ interface_routes[0]['mask'] }} + mtu {{ interface_mtu }} + {% if interface_default_gateway -%} + gateway {{ interface_default_gateway }} + up route add default gw {{ interface_default_gateway }} + {% endif -%} + {% if interface_routes -%} + {% for route in interface_routes -%} + post-up ip route add {{ route['network'] }}/{{ route['mask'] }} via {{ route['gateway'] }} + pre-down ip route del {{ route['network'] }}/{{ route['mask'] }} via {{ route['gateway'] }} + {% endfor %} + {% endif %} + notify: interface_networking_restart + diff --git a/templates/interface/tasks/main.yml b/templates/interface/tasks/main.yml new file mode 100644 index 0000000..7e69f74 --- /dev/null +++ b/templates/interface/tasks/main.yml @@ -0,0 +1,11 @@ + +- name: check existence of single interface identifier + fail: + msg: there must be set exactly one of [interface_ip|interface_mac|interface_name] variables, got {{ interface_identifiers }} + when: interface_condition_single_interface_identifier + +- include: clean.yml + when: interface_clean is defined and interface_clean + +- include: interface.yml + diff --git a/templates/routers b/templates/routers index 52a0275..2e1724c 100644 --- a/templates/routers +++ b/templates/routers @@ -2,16 +2,9 @@ # Configuration of all router devices - name: Enable IP forwarding - copy: - dest: "/etc/sysctl.conf" - content: "net.ipv4.ip_forward=1" - -- name: Restarting procps service - command: /etc/init.d/procps restart - -- name: Delete default gateway - command: route del default - -- name: Add default path to border router - command: route add default gw {{ border_router_ip }} eth3 + sysctl: + name: net.ipv4.ip_forward + value: '1' + sysctl_set: yes + reload: yes ... diff --git a/templates/separate_devices b/templates/separate_devices index 212d124..83f5b70 100644 --- a/templates/separate_devices +++ b/templates/separate_devices @@ -1,5 +1,28 @@ -- name: Add aliases - loop: "{{ aliases|dict2items }}" +- name: Adding aliases + loop: "{{ aliases | dict2items }}" lineinfile: path: /etc/hosts - line: {{ item.value }} "{{ item.key }}" + line: "{{ item.value }} {{ item.key }}" + +- name: Configuring nondefault routes + include_role: + name: interface + vars: + interface_ip: "{{ route.interface_ip }}" + interface_routes: + - gateway: "{{ route.gateway }}" + network: "{{ route.network }}" + mask: "{{ route.netmask }}" + loop: "{{ routings.simple }}" + loop_control: + loop_var: route + +- name: Configuring default routes + include_role: + name: interface + vars: + interface_ip: "{{ route.interface_ip }}" + interface_default_gateway: "{{ route.gateway }}" + loop: "{{ routings.default }}" + loop_control: + loop_var: route diff --git a/templates/vagrantfile b/templates/vagrantfile index ae000d7..664f569 100644 --- a/templates/vagrantfile +++ b/templates/vagrantfile @@ -49,10 +49,32 @@ {{ namespace }}.{{ item.command }} = {{ item.value }} {% endmacro -%} +{# Macro for general items (not str int or bool) #} +{% macro other(item, namespace) %} +{% if item.separator %} + {{ namespace }}.{{ item.command }} {{ item.separator }} {{ item.value }} +{% else %} + {{ namespace }}.{{ item.command }} {{ item.value }} +{% endif %} +{% endmacro -%} + {# Macro for dictionaries #} {% macro dictionary(item, namespace) %} {{ namespace }}.{{ item.command }} = { {% for key, value in item.dictionary.items() %} + {% if loop.last %} + {{ key }}: {{ value }} + {% else %} + {{ key }}: {{ value }}, + {% endif %} + {% endfor %} + } +{% endmacro -%} + +{# Macro for dictionaries #} +{% macro groups(item, namespace) %} + {{ namespace }}.groups = { + {% for key, value in item.groups.items() %} {% if loop.last %} "{{ key }}" => {{ value }} {% else %} @@ -96,12 +118,16 @@ end {{ boolean(item, namespace) -}} {% elif item.type == "integer" %} {{ integer(item, namespace) -}} +{% elif item.type == "other" %} + {{ other(item, namespace) -}} {% elif item.type == "provider" %} {{ provider(item, namespace) -}} {% elif item.type == "network" %} {{ network(item, namespace) -}} {% elif item.type == "dictionary" %} {{ dictionary(item, namespace) -}} +{% elif item.type == "groups" %} + {{ groups(item, namespace) -}} {% endif %} {% endfor %} end -- GitLab