diff --git a/_modules/node.py b/_modules/node.py --- a/_modules/node.py +++ b/_modules/node.py @@ -259,3 +259,59 @@ return private_network return network + + +def _resolve_gre_tunnels_for_router(network, netmask): + tunnels = [] + + for node, tunnel in __pillar__.get(f"{network}_gre_tunnels", {}).items(): + tunnels.append( + { + "description": f"{network}_to_{node}", + "interface": tunnel["router"]["interface"], + "src": tunnel["router"]["addr"], + "dst": tunnel["node"]["addr"], + "netmask": netmask, + "icann_src": get("network")["canonical_public_ipv4"], + "icann_dst": get("network", node)["canonical_public_ipv4"], + } + ) + + return tunnels + + +def resolve_gre_tunnels(): + """ + A function to get the GRE tunnels for a node + + CLI Example: + salt * node.resolve_gre_tunnels + """ + gre_tunnels = [] + + for network, network_args in __pillar__.get("networks", {}).items(): + if __grains__["id"] == network_args["router"]: + gre_tunnels += _resolve_gre_tunnels_for_router( + network, network_args["netmask"] + ) + continue + + tunnel = __salt__["pillar.get"](f"{network}_gre_tunnels:{__grains__['id']}") + if not tunnel: + continue + + gre_tunnels.append( + { + "description": f"{network}_via_{network_args['router']}", + "interface": tunnel["node"].get("interface", "gre0"), + "src": tunnel["node"]["addr"], + "dst": tunnel["router"]["addr"], + "netmask": network_args["netmask"], + "icann_src": get("network")["canonical_public_ipv4"], + "icann_dst": get("network", network_args["router"])[ + "canonical_public_ipv4" + ], + } + ) + + return gre_tunnels diff --git a/pillar/core/network.sls b/pillar/core/network.sls --- a/pillar/core/network.sls +++ b/pillar/core/network.sls @@ -1,29 +1,49 @@ networks: drake: netmask: 255.255.255.0 - addr: - cloudhugger: 172.27.27.28 - router-001: 172.27.27.1 - windriver: 172.27.27.35 - ysul: 172.27.27.33 + router: router-001 -gre_tunnels: - windriver: - wind-cloud: - interface: gre0 - network: drake - to: cloudhugger - - wind-ysul: - interface: gre0 - network: drake - to: ysul +# ------------------------------------------------------------- +# Drake - GRE tunnels +# +# Describe GRE tunnels between a node and {networks.drake.router} +# +# {id}: +# router: +# interface: gre0, gre1, ... / increment for each tunnel +# addr: The tunnel IPv4 on the router in 172.27.27.240/28 +# +# node: +# interface: Not needed on Linux as the interface name will be +# descriptive: gre-drake_via_{networks.drake.router} +# +# Not needed on FreeBSD if default value "gre0" is fine. +# If there is several GRE tunnels, can be gre1, gre2, etc. +# +# addr: The canonical IPv4 for the server in 172.27.27.0/24 +# +# IP should be sync between the pillar and the Operations grimoire +# at https://agora.nasqueron.org/Operations_grimoire/Network +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +drake_gre_tunnels: ysul: - wind-ysul: &gre_drake_to_windriver + router: interface: gre0 - network: drake - to: windriver + addr: 172.27.27.252 + node: + addr: 172.27.27.33 cloudhugger: - wind-cloud: *gre_drake_to_windriver + router: + interface: gre1 + addr: 172.27.27.253 + node: + addr: 172.27.27.28 + + windriver: + router: + interface: gre2 + addr: 172.27.27.254 + node: + addr: 172.27.27.35 diff --git a/roles/core/network/gre.sls b/roles/core/network/gre.sls --- a/roles/core/network/gre.sls +++ b/roles/core/network/gre.sls @@ -6,51 +6,26 @@ # License: Trivial work, not eligible to copyright # ------------------------------------------------------------- -{% set network = salt['node.get']('network') %} -{% set gre_tunnels = salt['pillar.get']("gre_tunnels:" + grains['id'], {}) %} +{% from "roles/core/network/map.jinja" import gre with context %} {% set boot_loader = namespace(gre=false) %} # ------------------------------------------------------------- # Tunnels network configuration files # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -{% for description, tunnel in gre_tunnels.items() %} +{% for tunnel in salt['node.resolve_gre_tunnels']() %} {% set boot_loader.gre = True %} -{% set tunnel_network = pillar['networks'][tunnel['network']] %} -{% if grains['os'] == 'FreeBSD' %} -/etc/rc.conf.d/netif/gre_{{ description }}: +{{ gre.config_path }}{{ tunnel["description"] }}: file.managed: - - source: salt://roles/core/network/files/FreeBSD/netif_gre.rc + - source: salt://roles/core/network/files/{{ gre.source_path }} - makedirs: True - template: jinja - - context: - description: {{ description }} - interface: {{ tunnel['interface'] }} - - src: {{ tunnel_network['addr'][grains['id']] }} - dst: {{ tunnel_network['addr'][tunnel['to']] }} - - icann_src: {{ network['ipv4_address'] }} - icann_dst: {{ salt['node.get']('network', tunnel['to'])['ipv4_address'] }} -{% endif %} - + - defaults: {{ tunnel }} {% if grains['os_family'] == 'Debian' %} -/etc/network/interfaces.d/10-gre-{{ description }}: - file.managed: - - source: salt://roles/core/network/files/Debian/10-gre.jinja - - makedirs: True - - template: jinja - context: interface: gre-{{ description }} - - src: {{ tunnel_network['addr'][grains['id']] }} - dst: {{ tunnel_network['addr'][tunnel['to']] }} - netmask: {{ tunnel_network['netmask'] }} - - icann_src: {{ network['ipv4_address'] }} - icann_dst: {{ salt['node.get']('network', tunnel['to'])['ipv4_address'] }} {% endif %} {% endfor %} diff --git a/roles/core/network/map.jinja b/roles/core/network/map.jinja --- a/roles/core/network/map.jinja +++ b/roles/core/network/map.jinja @@ -32,3 +32,20 @@ "suffix": "device", }, }) %} + +# ------------------------------------------------------------- +# GRE tunnels configuration by OS/distro +# +# See interface configuration for the documentation. +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +{% set gre = salt['grains.filter_by']({ + 'FreeBSD': { + "config_path": "/etc/rc.conf.d/netif/gre_", + "source_path": "FreeBSD/netif_gre.rc", + }, + 'Debian': { + "config_path": "/etc/network/interfaces.d/10-gre-", + "source_path": "Debian/10-gre.jinja", + }, +}) %}