Page MenuHomeDevCentral

D2595.id6617.diff
No OneTemporary

D2595.id6617.diff

diff --git a/_modules/node.py b/_modules/node.py
--- a/_modules/node.py
+++ b/_modules/node.py
@@ -315,3 +315,87 @@
)
return gre_tunnels
+
+
+def get_gateway(network):
+ # For tunnels, gateway is the tunnel endpoint
+ tunnel = __salt__["pillar.get"](f"{network}_gre_tunnels:{__grains__['id']}")
+ if tunnel:
+ return tunnel["router"]["addr"]
+
+ return __salt__["pillar.get"](f"networks:{network}:default_gateway")
+
+
+def _get_static_route(cidr, gateway):
+ if __grains__["os_family"] == "FreeBSD":
+ return f"-net {cidr} {gateway}"
+
+ if __grains__["kernel"] == "Linux":
+ return f"{cidr} via {gateway}"
+
+ raise ValueError("No static route implementation for " + __grains__["os_family"])
+
+
+def _get_default_route(gateway):
+ if __grains__["os_family"] == "FreeBSD":
+ return f"default {gateway}"
+
+ if __grains__["kernel"] == "Linux":
+ return f"default via {gateway}"
+
+ raise ValueError("No static route implementation for " + __grains__["os_family"])
+
+
+def _get_interface_route(ip, interface):
+ if __grains__["os_family"] == "FreeBSD":
+ return f"-net {ip}/32 -interface {interface}"
+
+ if __grains__["kernel"] == "Linux":
+ return f"{ip} dev {interface}"
+
+ raise ValueError("No static route implementation for " + __grains__["os_family"])
+
+
+def _get_routes_for_private_networks():
+ """
+ Every node, excepted the routeur, should have a route
+ for the private network CIDR to the router.
+
+ For GRE tunnels, the gateway is the tunnel endpoint.
+ In other cases, the gateway is the main router (private) IP.
+
+ """
+ routes = {}
+
+ for network, network_args in __pillar__.get("networks", {}).items():
+ if network_args["router"] == __grains__["id"]:
+ continue
+
+ gateway = get_gateway(network)
+ routes[f"private_{network}"] = _get_static_route(network_args["cidr"], gateway)
+
+ return routes
+
+
+def get_routes():
+ routes = {}
+
+ interfaces = _get_property("network:interfaces", __grains__["id"], {})
+ for interface_name, interface in interfaces.items():
+ flags = interface.get("flags", [])
+
+ if "gateway" in interface.get("ipv4", {}):
+ gateway = interface["ipv4"]["gateway"]
+
+ if "ipv4_ovh_failover" in flags:
+ routes[f"{interface_name}_gateway"] = _get_interface_route(
+ gateway, interface["device"]
+ )
+
+ if __grains__["os_family"] != "RedHat":
+ # On RHEL/CentOS/Rocky, legacy network scripts take care of this with GATEWAY=
+ routes[f"{interface_name}_default"] = _get_default_route(gateway)
+
+ routes.update(_get_routes_for_private_networks())
+
+ return routes
diff --git a/pillar/core/network.sls b/pillar/core/network.sls
--- a/pillar/core/network.sls
+++ b/pillar/core/network.sls
@@ -1,7 +1,13 @@
networks:
drake:
+ cidr: 172.27.27.0/24
netmask: 255.255.255.0
+
+ # router-001 acts as a gateway for all nodes
+ # For GRE tunnels, gateway is probably the tunnel endpoint
+ # The other nodes can use the default_gateway IP.
router: router-001
+ default_gateway: 172.27.27.1
# -------------------------------------------------------------
# Drake - GRE tunnels
diff --git a/pillar/nodes/nodes.sls b/pillar/nodes/nodes.sls
--- a/pillar/nodes/nodes.sls
+++ b/pillar/nodes/nodes.sls
@@ -50,7 +50,7 @@
canonical_public_ipv4: 51.255.124.11
interfaces:
- ens192:
+ public:
device: ens192
uuid: 6e05ebea-f2fd-4ca1-a21f-78a778664d8c
ipv4:
@@ -58,7 +58,7 @@
netmask: 255.255.255.252
gateway: 91.121.86.254
- ens224:
+ intranought:
device: ens224
uuid: 8e8ca793-b2eb-46d8-9266-125aba6d06c4
ipv4:
@@ -77,7 +77,7 @@
canonical_public_ipv4: 51.255.124.9
interfaces:
- ens192:
+ public:
device: ens192
uuid: ef7370c5-5060-4d89-82bb-dbeabf4a35f6
ipv4:
@@ -85,7 +85,7 @@
netmask: 255.255.255.252
gateway: 91.121.86.254
- ens224:
+ intranought:
device: ens224
uuid: 3fd0b9f8-ecc3-400d-bc61-3ba21d0b6337
ipv4:
@@ -99,20 +99,21 @@
roles:
- router
network:
- ipv4_ovh_failover: True
ipv6_tunnel: False
canonical_public_ipv4: 51.255.124.8
interfaces:
- vmx0:
+ public:
device: vmx0
ipv4:
address: 51.255.124.8
netmask: 255.255.255.252
gateway: 91.121.86.254
+ flags:
+ - ipv4_ovh_failover
- vmx1:
+ intranought:
device: vmx1
ipv4:
address: 172.27.27.1
diff --git a/roles/core/network/files/FreeBSD/routing_ipv4.rc b/roles/core/network/files/FreeBSD/routing_ipv4.rc
--- a/roles/core/network/files/FreeBSD/routing_ipv4.rc
+++ b/roles/core/network/files/FreeBSD/routing_ipv4.rc
@@ -12,10 +12,7 @@
# Changes to this file may cause incorrect behavior
# and will be lost if the state is redeployed.
# </auto-generated>
-{% if ipv4_ovh_failover %}
-static_routes="net1 net2"
-route_net1="-net {{ ipv4_gateway }}/32 -interface {{ ipv4_interface }}"
-route_net2="default {{ ipv4_gateway }}"
-{%- else -%}
-defaultrouter="{{ ipv4_gateway }}"
-{% endif -%}
+static_routes={{ " ".join(routes.keys()) }}
+{% for key, value in routes.items() %}
+route_{{ key }}="{{ value }}"
+{% endfor -%}
diff --git a/roles/core/network/files/FreeBSD/routing_ipv4.rc b/roles/core/network/files/Linux/routes.conf
copy from roles/core/network/files/FreeBSD/routing_ipv4.rc
copy to roles/core/network/files/Linux/routes.conf
--- a/roles/core/network/files/FreeBSD/routing_ipv4.rc
+++ b/roles/core/network/files/Linux/routes.conf
@@ -1,9 +1,9 @@
# -------------------------------------------------------------
-# Network — rc configuration
+# Network — routes configuration
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Project: Nasqueron
# License: Trivial work, not eligible to copyright
-# Source file: roles/core/network/files/FreeBSD/routing_ipv4.rc
+# Source file: roles/core/network/files/Linux/routes.conf
# -------------------------------------------------------------
#
# <auto-generated>
@@ -12,10 +12,6 @@
# Changes to this file may cause incorrect behavior
# and will be lost if the state is redeployed.
# </auto-generated>
-{% if ipv4_ovh_failover %}
-static_routes="net1 net2"
-route_net1="-net {{ ipv4_gateway }}/32 -interface {{ ipv4_interface }}"
-route_net2="default {{ ipv4_gateway }}"
-{%- else -%}
-defaultrouter="{{ ipv4_gateway }}"
-{% endif -%}
+{%- for route in routes.values() %}
+{{ route }}
+{%- endfor -%}
diff --git a/roles/core/network/files/FreeBSD/routing_ipv4.rc b/roles/core/network/files/Linux/routes.service
copy from roles/core/network/files/FreeBSD/routing_ipv4.rc
copy to roles/core/network/files/Linux/routes.service
--- a/roles/core/network/files/FreeBSD/routing_ipv4.rc
+++ b/roles/core/network/files/Linux/routes.service
@@ -1,9 +1,9 @@
# -------------------------------------------------------------
-# Network — rc configuration
+# Network — routes configuration
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Project: Nasqueron
# License: Trivial work, not eligible to copyright
-# Source file: roles/core/network/files/FreeBSD/routing_ipv4.rc
+# Source file: roles/core/network/files/Linux/routes.service
# -------------------------------------------------------------
#
# <auto-generated>
@@ -12,10 +12,17 @@
# Changes to this file may cause incorrect behavior
# and will be lost if the state is redeployed.
# </auto-generated>
-{% if ipv4_ovh_failover %}
-static_routes="net1 net2"
-route_net1="-net {{ ipv4_gateway }}/32 -interface {{ ipv4_interface }}"
-route_net2="default {{ ipv4_gateway }}"
-{%- else -%}
-defaultrouter="{{ ipv4_gateway }}"
-{% endif -%}
+
+[Unit]
+Description=Apply static routes through ip routes
+ConditionPathExists=/etc/routes.conf
+Documentation=https://agora.nasqueron.org/Operations_grimoire/Network
+After=network.target
+
+[Service]
+ExecStart=/usr/sbin/routes
+Type=oneshot
+RemainAfterExit=yes
+
+[Install]
+WantedBy=multi-user.target
diff --git a/roles/core/network/files/Linux/routes.sh b/roles/core/network/files/Linux/routes.sh
new file mode 100755
--- /dev/null
+++ b/roles/core/network/files/Linux/routes.sh
@@ -0,0 +1,37 @@
+#!/bin/sh
+
+# -------------------------------------------------------------
+# Network — routes configuration for Linux systems
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Project: Nasqueron
+# License: Trivial work, not eligible to copyright
+# Source file: roles/core/network/files/Linux/routes.sh
+# Dependencies: iproute
+# GNU xargs for -r
+# -------------------------------------------------------------
+#
+# <auto-generated>
+# This file is managed by our rOPS SaltStack repository.
+#
+# Changes to this file may cause incorrect behavior
+# and will be lost if the state is redeployed.
+# </auto-generated>
+
+ROUTES_CONFIG_PATH=/etc/routes.conf
+
+# Runs as root only
+test -z $UID && UID=$(id -u)
+if [ "$UID" -ne 0 ]; then
+ echo This script must be run as root. >&2
+ exit 1
+fi
+
+# Warn about configuration missing
+if [ ! -f $ROUTES_CONFIG_PATH ]; then
+ echo No routes configuration file found at $ROUTES_CONFIG_PATH >&2
+ exit 2
+fi
+
+# Apply routes
+# Ignore comments and blank line, pass the remaining lines to `ip route`
+grep '^[^#]' $ROUTES_CONFIG_PATH | xargs -L 1 -r ip route replace
diff --git a/roles/core/network/files/RedHat/ifcfg b/roles/core/network/files/RedHat/ifcfg
--- a/roles/core/network/files/RedHat/ifcfg
+++ b/roles/core/network/files/RedHat/ifcfg
@@ -30,3 +30,6 @@
ONBOOT=yes
IPADDR={{ interface.ipv4.address }}
PREFIX={{ prefix }}
+{% if "ipv4" in interface and "gateway" in interface["ipv4"] %}
+GATEWAY={{ interface.ipv4.gateway }}
+{% endif %}
diff --git a/roles/core/network/init.sls b/roles/core/network/init.sls
--- a/roles/core/network/init.sls
+++ b/roles/core/network/init.sls
@@ -10,6 +10,7 @@
- .ipv4
- .ipv6
- .gre
+ - .routes
# Drake can be configured as:
#
diff --git a/roles/core/network/ipv4.sls b/roles/core/network/ipv4.sls
--- a/roles/core/network/ipv4.sls
+++ b/roles/core/network/ipv4.sls
@@ -35,18 +35,3 @@
{% endfor %}
-# -------------------------------------------------------------
-# Routes
-# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-{% if grains['os'] == 'FreeBSD' %}
-/etc/rc.conf.d/routing/ipv4:
- file.managed:
- - source: salt://roles/core/network/files/FreeBSD/routing_ipv4.rc
- - makedirs: True
- - template: jinja
- - context:
- ipv4_gateway: {{ network['ipv4_gateway'] }}
- ipv4_interface: {{ network['ipv4_interface'] }}
- ipv4_ovh_failover: {{ salt['node.has']('network:ipv4_ovh_failover') }}
-{% endif %}
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
@@ -49,3 +49,20 @@
"source_path": "Debian/10-gre.jinja",
},
}) %}
+
+# -------------------------------------------------------------
+# Routes configuration by OS/distro
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+{% set routes_config = salt['grains.filter_by']({
+ 'FreeBSD': {
+ "config_path": "/etc/rc.conf.d/routing/managed",
+ "source_path": "FreeBSD/routing_ipv4.rc",
+ "provider": "os"
+ },
+ 'RedHat': {
+ "config_path": "/etc/routes.conf",
+ "source_path": "Linux/routes.conf",
+ "provider": "custom-service"
+ }
+}, default="RedHat") %}
diff --git a/roles/core/network/routes.sls b/roles/core/network/routes.sls
new file mode 100644
--- /dev/null
+++ b/roles/core/network/routes.sls
@@ -0,0 +1,40 @@
+# -------------------------------------------------------------
+# Salt — Network
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Project: Nasqueron
+# License: Trivial work, not eligible to copyright
+# -------------------------------------------------------------
+
+{% from "roles/core/network/map.jinja" import routes_config with context %}
+
+# -------------------------------------------------------------
+# Routes
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+{{ routes_config["config_path"] }}:
+ file.managed:
+ - source: salt://roles/core/network/files/{{ routes_config["source_path"] }}
+ - makedirs: True
+ - template: jinja
+ - context:
+ routes: {{ salt["node.get_routes"]() }}
+
+# -------------------------------------------------------------
+# Systemd unit for Linux systems using our /etc/routes.conf
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+{% if routes_config["provider"] == "custom-service" %}
+
+/usr/sbin/routes:
+ file.managed:
+ - source: salt://roles/core/network/files/Linux/routes.sh
+ - mode: 0755
+
+/etc/systemd/system/routes.service:
+ file.managed:
+ - source: salt://roles/core/network/files/Linux/routes.service
+ service.running:
+ - name: routes
+ - enable: true
+
+{% endif %}

File Metadata

Mime Type
text/plain
Expires
Fri, Nov 15, 07:43 (5 h, 31 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2246204
Default Alt Text
D2595.id6617.diff (13 KB)

Event Timeline